TerminalView.st
changeset 5008 2c183e39345e
parent 5006 22bdac1a5826
child 5012 0a1d65c0946c
child 5021 a24473f2d6ca
equal deleted inserted replaced
5007:045024ffa956 5008:2c183e39345e
       
     1 "{ Encoding: utf8 }"
       
     2 
     1 "
     3 "
     2  COPYRIGHT (c) 1998 by eXept Software AG
     4  COPYRIGHT (c) 1998 by eXept Software AG
     3               All Rights Reserved
     5               All Rights Reserved
     4 
     6 
     5  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
    23 		inputTranslateBackspaceToDelete autoWrapFlag masterWindow
    25 		inputTranslateBackspaceToDelete autoWrapFlag masterWindow
    24 		alternateKeypadMode noColors sizeOfOutstandingInputToBeProcessed
    26 		alternateKeypadMode noColors sizeOfOutstandingInputToBeProcessed
    25 		lineEditMode lineBuffer lineBufferCursorPosition
    27 		lineEditMode lineBuffer lineBufferCursorPosition
    26 		lineBufferHistory lineBufferHistoryPosition maxHistorySize doUTF
    28 		lineBufferHistory lineBufferHistoryPosition maxHistorySize doUTF
    27 		ignoreOutput sendControlKeys
    29 		ignoreOutput sendControlKeys
    28 		lastSelectedLineBufferHistoryPosition'
    30 		lastSelectedLineBufferHistoryPosition inputIsUTF8 outputIsUTF8
       
    31 		signalControlKeys'
    29 	classVariableNames:'Debug DebugKeyboard DefaultMaxHistorySize'
    32 	classVariableNames:'Debug DebugKeyboard DefaultMaxHistorySize'
    30 	poolDictionaries:''
    33 	poolDictionaries:''
    31 	category:'Views-TerminalViews'
    34 	category:'Views-TerminalViews'
    32 !
    35 !
    33 
    36 
    90         readerProcess           process which reads commands    
    93         readerProcess           process which reads commands    
    91                                 output and sends it to the view
    94                                 output and sends it to the view
    92 
    95 
    93         lineEditMode            if on, do readLine-alike input history and editong
    96         lineEditMode            if on, do readLine-alike input history and editong
    94 
    97 
       
    98         signalControlKeys       if on, CTRL-C sends an interrupt (for Windows)
       
    99 
    95     [class variables]:
   100     [class variables]:
    96         Debug := true           trace incoming characters
   101         Debug := true           trace incoming characters
       
   102         Debug := false           
       
   103         DebugKeyboard := true   trace outgoing characters
       
   104         DebugKeyboard := false 
    97 
   105 
    98 
   106 
    99     [start with:]
   107     [start with:]
   100         VT52TerminalView open
   108         VT52TerminalView open
   101         VT100TerminalView open
   109         VT100TerminalView open
   541      If it is set (which is the default), then send it to the terminal, otherwise perform the editor op.
   549      If it is set (which is the default), then send it to the terminal, otherwise perform the editor op.
   542      Thus, an application containing me can offer a menu function (or toggle), 
   550      Thus, an application containing me can offer a menu function (or toggle), 
   543      to control this behavior on the UI level."
   551      to control this behavior on the UI level."
   544 
   552 
   545     sendControlKeys := aBoolean
   553     sendControlKeys := aBoolean
       
   554 !
       
   555 
       
   556 signalControlKeys
       
   557     "if true (default on Windows), CTRL-C sends an interrupt to 
       
   558      the program. Otherwise, it is sent as a character (0x03)"
       
   559 
       
   560     ^ signalControlKeys
       
   561 !
       
   562 
       
   563 signalControlKeys:aBoolean
       
   564     "if true (default on Windows), CTRL-C sends an interrupt to 
       
   565      the program. Otherwise, it is sent as a character (0x03)"
       
   566 
       
   567     signalControlKeys := aBoolean
   546 !
   568 !
   547 
   569 
   548 translateNLToCRNL
   570 translateNLToCRNL
   549     ^ translateNLToCRNL
   571     ^ translateNLToCRNL
   550 
   572 
   845     "/ on the UI level.
   867     "/ on the UI level.
   846     
   868     
   847     shortCut := device keyboardMap at:aKey ifAbsent:nil.
   869     shortCut := device keyboardMap at:aKey ifAbsent:nil.
   848     (shortCut notNil and:[shortCut isSymbol]) ifTrue:[
   870     (shortCut notNil and:[shortCut isSymbol]) ifTrue:[
   849         (sendControlKeys not or:[ self hasSelection or:[ shortCut == #Paste] ]) ifTrue:[
   871         (sendControlKeys not or:[ self hasSelection or:[ shortCut == #Paste] ]) ifTrue:[
       
   872             DebugKeyboard ifTrue:[
       
   873                 Transcript showCR:'internal handling'.
       
   874             ].
   850             ^ super keyPress:shortCut x:x y:y
   875             ^ super keyPress:shortCut x:x y:y
   851         ].    
   876         ].
   852     ].    
   877     ].    
   853 
   878 
   854     seq := kbdSequences at:rawKey ifAbsent:nil.
   879     seq := kbdSequences at:rawKey ifAbsent:nil.
   855     seq notNil ifTrue:[
   880     seq notNil ifTrue:[
   856         DebugKeyboard ifTrue:[
   881         DebugKeyboard ifTrue:[
   857             Transcript show:'->' ; showCR:seq storeString.
   882             Transcript show:'seq ->' ; showCR:seq storeString.
   858         ].
   883         ].
   859         self send:(seq withoutCEscapes).
   884         self send:(seq withoutCEscapes).
   860         ^ self
   885         ^ self
   861     ].
   886     ].
   862 
   887 
   864         rest := rawKey copyFrom:5.
   889         rest := rawKey copyFrom:5.
   865         rest size == 1 ifTrue:[
   890         rest size == 1 ifTrue:[
   866             rest := rest at:1.
   891             rest := rest at:1.
   867             (rest asLowercase between:$a and:$z) ifTrue:[
   892             (rest asLowercase between:$a and:$z) ifTrue:[
   868                 DebugKeyboard ifTrue:[
   893                 DebugKeyboard ifTrue:[
   869                     Transcript show:'->' ; showCR:(Character controlCharacter:rest) storeString.
   894                     Transcript show:'ctrl ->' ; showCR:(Character controlCharacter:rest) storeString.
       
   895                 ].
       
   896                 (signalControlKeys and:[rawKey == #Ctrlc]) ifTrue:[
       
   897                     self doSendInterrupt.
       
   898                     ^ self.
   870                 ].
   899                 ].
   871                 self sendCharacter:(Character controlCharacter:rest).
   900                 self sendCharacter:(Character controlCharacter:rest).
   872                 ^ self
   901                 ^ self
   873             ].
   902             ].
   874         ]
   903         ]
   875     ].
   904     ].
   876 
   905 
   877     (rawKey startsWith:'Control') ifTrue:[
   906     ((rawKey startsWith:'Control')
       
   907         or:[ (rawKey startsWith:'Shift')
       
   908         or:[ (rawKey startsWith:'Alt')
       
   909         or:[ (rawKey = 'Ctrl')
       
   910     ]]]) ifTrue:[
       
   911         DebugKeyboard ifTrue:[
       
   912             Transcript showCR:'modifier ignored'.
       
   913         ].
   878         ^ self
   914         ^ self
   879     ].
   915     ].
   880     (rawKey startsWith:'Shift') ifTrue:[
       
   881         ^ self
       
   882     ].
       
   883     (rawKey startsWith:'Alt') ifTrue:[
       
   884         ^ self
       
   885     ].
       
   886     (rawKey startsWith:'Cmd') ifTrue:[
   916     (rawKey startsWith:'Cmd') ifTrue:[
       
   917         DebugKeyboard ifTrue:[
       
   918             Transcript showCR:'CMD handled internal'.
       
   919         ].
   887         ^ super keyPress:aKey x:x y:y
   920         ^ super keyPress:aKey x:x y:y
   888     ].
   921     ].
   889     (rawKey = 'Ctrl') ifTrue:[
       
   890         ^ self
       
   891     ].
       
   892 
   922 
   893     DebugKeyboard ifTrue:[
   923     DebugKeyboard ifTrue:[
   894         Transcript show:'unhandled key: '; showCR:rawKey.
   924         Transcript show:'unhandled: '; showCR:rawKey.
   895     ].
   925     ].
   896 
   926 
   897     "
   927     "
   898      DebugKeyboard := true
   928      DebugKeyboard := true
   899     "
   929     "
  1415 initialize
  1445 initialize
  1416 
  1446 
  1417     super initialize.
  1447     super initialize.
  1418 
  1448 
  1419     sendControlKeys := true.
  1449     sendControlKeys := true.
       
  1450     signalControlKeys := OperatingSystem isMSWINDOWSlike.
  1420     showMatchingParenthesis := false.
  1451     showMatchingParenthesis := false.
  1421     self insertMode: false.
  1452     self insertMode: false.
  1422     alwaysAppendAtEnd := false.
  1453     alwaysAppendAtEnd := false.
  1423     collectSize := 4096.
  1454     collectSize := 4096.
  1424     sizeOfOutstandingInputToBeProcessed := 0.
  1455     sizeOfOutstandingInputToBeProcessed := 0.
  1426     trimBlankLines := true.
  1457     trimBlankLines := true.
  1427     localEcho := false.
  1458     localEcho := false.
  1428     inputTranslateCRToNL := false.
  1459     inputTranslateCRToNL := false.
  1429     inputTranslateCRToCRNL := OperatingSystem isMSWINDOWSlike.
  1460     inputTranslateCRToCRNL := OperatingSystem isMSWINDOWSlike.
  1430     inputTranslateBackspaceToDelete := false.
  1461     inputTranslateBackspaceToDelete := false.
       
  1462     inputIsUTF8 := UserPreferences current terminalInputIsUTF8.
       
  1463     outputIsUTF8 := false. "/ currently unused.
  1431     autoWrapFlag := true.
  1464     autoWrapFlag := true.
  1432     noColors := false.
  1465     noColors := false.
  1433     doUTF := UserPreferences current terminalOutputIsUTF8.
  1466     doUTF := UserPreferences current terminalOutputIsUTF8.
  1434     lineEditMode := OperatingSystem isMSWINDOWSlike.
  1467     lineEditMode := OperatingSystem isMSWINDOWSlike.
  1435     maxHistorySize := maxHistorySize ? DefaultMaxHistorySize.
  1468     maxHistorySize := maxHistorySize ? DefaultMaxHistorySize.
  1775 doSendInterrupt
  1808 doSendInterrupt
  1776     "send an INT-signal to the shell (UNIX only)"
  1809     "send an INT-signal to the shell (UNIX only)"
  1777 
  1810 
  1778     |status|
  1811     |status|
  1779 
  1812 
       
  1813     DebugKeyboard ifTrue:[
       
  1814         Transcript showCR:'interrupt!!'.
       
  1815     ].
       
  1816 
  1780     shellPid notNil ifTrue:[
  1817     shellPid notNil ifTrue:[
  1781         OperatingSystem isUNIXlike ifTrue:[
  1818         OperatingSystem isUNIXlike ifTrue:[
  1782             OperatingSystem interruptProcessGroup:shellPid.
  1819             OperatingSystem interruptProcessGroup:shellPid.
  1783             OperatingSystem interruptProcess:shellPid.
  1820             OperatingSystem interruptProcess:shellPid.
  1784             "/ status := OperatingSystem childProcessWait:false pid:shellPid.
  1821             "/ status := OperatingSystem childProcessWait:false pid:shellPid.
  1785         ] ifFalse:[
  1822         ] ifFalse:[
  1786             self warn:'unimplemented for DOS'
  1823             self warn:'unimplemented for DOS'
  1787         ]
  1824         ]
       
  1825     ] ifFalse:[
       
  1826         'VT100: no shell' infoPrintCR.
  1788     ].
  1827     ].
  1789 
  1828 
  1790     "Modified: / 10.6.1998 / 17:49:49 / cg"
  1829     "Modified: / 10.6.1998 / 17:49:49 / cg"
  1791 !
  1830 !
  1792 
  1831 
  1793 doSendKillSignal
  1832 doSendKillSignal
  1794     "send a KILL-signal to the shell (UNIX only)"
  1833     "send a KILL-signal to the shell (UNIX only)"
  1795 
  1834 
  1796     |status|
  1835     |status|
  1797 
  1836 
       
  1837     DebugKeyboard ifTrue:[
       
  1838         Transcript showCR:'kill!!'.
       
  1839     ].
  1798     shellPid notNil ifTrue:[
  1840     shellPid notNil ifTrue:[
  1799         OperatingSystem isUNIXlike ifTrue:[
  1841         OperatingSystem isUNIXlike ifTrue:[
  1800             OperatingSystem killProcessGroup:shellPid.
  1842             OperatingSystem killProcessGroup:shellPid.
  1801             OperatingSystem killProcess:shellPid.
  1843             OperatingSystem killProcess:shellPid.
  1802             status := OperatingSystem childProcessWait:false pid:shellPid.
  1844             status := OperatingSystem childProcessWait:false pid:shellPid.
  1803         ] ifFalse:[
  1845         ] ifFalse:[
  1804             self warn:'unimplemented for DOS'
  1846             self warn:'unimplemented for DOS'
  1805         ]
  1847         ]
       
  1848     ] ifFalse:[
       
  1849         'VT100: no shell' infoPrintCR.
  1806     ]
  1850     ]
  1807 !
  1851 !
  1808 
  1852 
  1809 editMenu
  1853 editMenu
  1810     "return the views middleButtonMenu"
  1854     "return the views middleButtonMenu"
  1935     "Created: / 29.4.1999 / 11:07:49 / cg"
  1979     "Created: / 29.4.1999 / 11:07:49 / cg"
  1936     "Modified: / 29.4.1999 / 11:09:52 / cg"
  1980     "Modified: / 29.4.1999 / 11:09:52 / cg"
  1937 ! !
  1981 ! !
  1938 
  1982 
  1939 !TerminalView methodsFor:'misc'!
  1983 !TerminalView methodsFor:'misc'!
       
  1984 
       
  1985 debugPrintCharacter:aCharacter as:what
       
  1986     Transcript show:what; show:' <'.
       
  1987     aCharacter codePoint < 32 ifTrue:[
       
  1988         Transcript show:'\x'; show:(aCharacter codePoint hexPrintString:2)
       
  1989     ] ifFalse:[
       
  1990         Transcript show:aCharacter
       
  1991     ].
       
  1992     Transcript showCR:'>'
       
  1993 !
  1940 
  1994 
  1941 removeTrailingBlankLines
  1995 removeTrailingBlankLines
  1942     ^ self
  1996     ^ self
  1943 ! !
  1997 ! !
  1944 
  1998 
  2508     (nLines := s size) == 0 ifTrue:[^ self].
  2562     (nLines := s size) == 0 ifTrue:[^ self].
  2509     (nLines == 1 and:[(s at:1) size == 0]) ifTrue:[^ self].
  2563     (nLines == 1 and:[(s at:1) size == 0]) ifTrue:[^ self].
  2510 
  2564 
  2511     s keysAndValuesDo:[:idx :line |
  2565     s keysAndValuesDo:[:idx :line |
  2512         line notNil ifTrue:[
  2566         line notNil ifTrue:[
  2513             Debug ifTrue:[
  2567             (Debug or:[DebugKeyboard]) ifTrue:[
  2514                 Transcript showCR:'send paste line: ',line asByteArray hexPrintString
  2568                 Transcript showCR:'send paste line: ',line asByteArray hexPrintString
  2515             ].
  2569             ].
  2516         ].
  2570         ].
  2517         self shouldProcessInputInLineEditMode ifTrue:[
  2571         self shouldProcessInputInLineEditMode ifTrue:[
  2518             line do:[:ch | self keyPressInLineEditMode:ch ].
  2572             line do:[:ch | self keyPressInLineEditMode:ch ].
  2559             ].
  2613             ].
  2560         ] ifFalse:[
  2614         ] ifFalse:[
  2561             recorderStream notNil ifTrue:[
  2615             recorderStream notNil ifTrue:[
  2562                 recorderStream nextPutAll:aString
  2616                 recorderStream nextPutAll:aString
  2563             ].
  2617             ].
  2564             Debug == true ifTrue:[
  2618             (Debug or:[DebugKeyboard]) ifTrue:[
  2565                 Transcript showCR:'send <',aString,'>'
  2619                 Transcript showCR:'send <',aString,'>'
  2566             ].
  2620             ].
  2567             inStream nextPutAll:aString
  2621             inStream nextPutAll:aString
  2568         ].
  2622         ].
  2569     ].
  2623     ].
  2579 !
  2633 !
  2580 
  2634 
  2581 sendCharacter:aCharacter
  2635 sendCharacter:aCharacter
  2582     "send a single character to the underlying program's stdin"
  2636     "send a single character to the underlying program's stdin"
  2583 
  2637 
  2584     aCharacter bitsPerCharacter > 8 ifTrue:[
  2638     aCharacter codePoint > 16r7F ifTrue:[
  2585         UserPreferences current terminalInputIsUTF8 ifTrue:[
  2639         inputIsUTF8 ifTrue:[
  2586             aCharacter asString utf8Encoded do:[:each8BitChar|
  2640             aCharacter utf8Encoded do:[:eachUTFChar|
  2587                 inStream nextPut:each8BitChar.
  2641                 (Debug or:[DebugKeyboard]) ifTrue:[
       
  2642                     self debugPrintCharacter:eachUTFChar as:'send utf'.
       
  2643                 ].
       
  2644                 recorderStream notNil ifTrue:[
       
  2645                     recorderStream nextPut:eachUTFChar
       
  2646                 ].
       
  2647                 inStream nextPut:eachUTFChar.
  2588             ].
  2648             ].
  2589         ] ifFalse:[
  2649             ^ self
       
  2650         ].
       
  2651         aCharacter bitsPerCharacter > 8 ifTrue:[
  2590             "/ ignore
  2652             "/ ignore
  2591             Transcript showCR:(self class name,': invalid (non-8bit) character ignored').
  2653             Transcript showCR:(self class name,': invalid (non-8bit) character ignored').
  2592         ].
  2654             ^ self
  2593         ^ self
  2655         ].
       
  2656         "/ send normal
  2594     ].
  2657     ].
  2595 
  2658 
  2596     recorderStream notNil ifTrue:[
  2659     recorderStream notNil ifTrue:[
  2597         recorderStream nextPut:aCharacter
  2660         recorderStream nextPut:aCharacter
  2598     ].
  2661     ].
  2599     Debug == true ifTrue:[
  2662     (Debug or:[DebugKeyboard]) ifTrue:[
  2600         Transcript showCR:'send <',aCharacter,'>'
  2663         self debugPrintCharacter:aCharacter as:'send'.
  2601     ].
  2664     ].
  2602 
  2665 
  2603     inStream nextPut:aCharacter.
  2666     inStream nextPut:aCharacter.
  2604 
  2667 
  2605     "Created: / 29-07-2013 / 18:18:24 / cg"
  2668     "Created: / 29-07-2013 / 18:18:24 / cg"
  2606 !
  2669 !
  2607 
  2670 
  2608 sendLine:aString
  2671 sendLine:aString
  2609     Debug ifTrue:[
  2672     (Debug or:[DebugKeyboard]) ifTrue:[
  2610         'VT100: sendline: ' print. aString asByteArray hexPrintString printCR
  2673         'VT100: sendline: ' print. aString asByteArray hexPrintString printCR
  2611     ].
  2674     ].
  2612 
  2675 
  2613     self send:aString.
  2676     self send:aString.
  2614     self sendLineEnd
  2677     self sendLineEnd