cronvel / terminal-kit

Terminal utilities for node.js
MIT License
3.12k stars 201 forks source link

Alt keys not working on OSX? #126

Open apowers313 opened 4 years ago

apowers313 commented 4 years ago

When getting key events on MacOS 10.13.6, keys combined with the alt / option key aren't being reported properly. For example, here are some examples of what I type and the events that are emitted:

ALT_A = { isCharacter: true, codepoint: 229, code: < Buffer c3 a5> } ALT_B = { isCharacter: true, codepoint: 8747, code: <Buffer e2 88 ab> } ALT_C = { isCharacter: true, codepoint: 231, code: < Buffer c3 a7> } ALT_D = { isCharacter: true, codepoint: 8706, code: <Buffer e2 88 82> } ALT_E = { isCharacter: true, codepoint: 180, code: < Buffer c2 b4> }

The terminal is iTerm and $TERM shows it as xterm-256color.

cronvel commented 4 years ago

@apowers313 In the terminal world, every terminal app like to use some unusual escape sequence (especially for keys), and, at the same time, report as an xterm terminal anyway.

In the lib/termconfig/, you should add an iTerm.js file. Look at how it works on xterm.js (which is used as the base for all other config files), and how it is derived in other config files (e.g. gnome terminal).

Also it will need some detection to work. What is $COLORTERM? Can you run ./sample/detect-terminal-test.js and output it there?

Once done, I will happily accept a PR for that! ;)

apowers313 commented 4 years ago

Thanks for the quick reply. Here's the output:

iTerm2

== Environment variable ==

$TERM: xterm-256color
$COLORTERM: truecolor
$VTE_VERSION: (undefined)

== Using simple terminal guessing ==

.guessTerminal(): {"isTTY":true,"isSSH":false,"appId":"xterm-truecolor","safe":false,"generic":"xterm-truecolor"}
Terminal name: (undefined)
Terminal app ID: (undefined)
Generic terminal: xterm-truecolor
Config file: xterm-truecolor.generic.js

Support for delta escape sequence: OK
Support for 256 colors: OK
Support for true colors: OK
Support for cursor location request: OK (x: 38, y: 52)
Support for palette request: OK
Issue #116 CURSOR_LOCATION keymap: OK
Issue #116 cursorLocation handler: OK

== Using advanced terminal detection ==

Can't get parent terminal info: Error [1]: Command failed: ps -h -o comm -p NaN
ps: Invalid process id: NaN

ps: Invalid process id: NaN
    at ChildProcess.exithandler (child_process.js:308:12)
    at ChildProcess.emit (events.js:314:20)
    at maybeClose (internal/child_process.js:1051:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:287:5)
Terminal name: (undefined)
Terminal app ID: (undefined)
Generic terminal: xterm-256color
Config file: xterm-256color.generic.js

Support for delta escape sequence: OK
Support for 256 colors: OK
Support for true colors: NO
Support for cursor location request: OK (x: 38, y: 52)
Support for palette request: OK
Issue #116 CURSOR_LOCATION keymap: OK
Issue #116 cursorLocation handler: OK

Default Mac Terminal

== Environment variable ==

$TERM: xterm-256color
$COLORTERM: (undefined)
$VTE_VERSION: (undefined)

== Using simple terminal guessing ==

.guessTerminal(): {"isTTY":true,"isSSH":false,"appId":"xterm-256color","safe":false,"generic":"xterm-256color"}
Terminal name: (undefined)
Terminal app ID: (undefined)
Generic terminal: xterm-256color
Config file: xterm-256color.generic.js

Support for delta escape sequence: OK
Support for 256 colors: OK
Support for true colors: NO
Support for cursor location request: OK (x: 38, y: 23)
Support for palette request: FAILED (Error: .getColor() timed out)
Issue #116 CURSOR_LOCATION keymap: OK
Issue #116 cursorLocation handler: OK

== Using advanced terminal detection ==

Can't get parent terminal info: Error [1]: Command failed: ps -h -o comm -p NaN
ps: Invalid process id: NaN

ps: Invalid process id: NaN
    at ChildProcess.exithandler (child_process.js:308:12)
    at ChildProcess.emit (events.js:314:20)
    at maybeClose (internal/child_process.js:1051:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:287:5)
Terminal name: (undefined)
Terminal app ID: (undefined)
Generic terminal: xterm-256color
Config file: xterm-256color.generic.js

Support for delta escape sequence: OK
Support for 256 colors: OK
Support for true colors: NO
Support for cursor location request: OK (x: 38, y: 47)
Support for palette request: FAILED (Error: .getColor() timed out)
Issue #116 CURSOR_LOCATION keymap: OK
Issue #116 cursorLocation handler: OK
apowers313 commented 4 years ago

Note that ps -h -o ppid -p ${pid} returns the following string on OSX (as opposed to just a number):

 PPID
21235

Here's a little fix in detectTerminal.js that uses match() to pull the first number from stdout:

function getParentProcess( pid ) {
    var parentPid , appName ;

    return new Promise( ( resolve , reject ) => {
        exec( 'ps -h -o ppid -p ' + pid , ( error , stdout ) => {
            if ( error ) { reject( error ) ; return ; }

            let { 0: foundPid } = stdout.match(  /.*([0-9]+)/gm ) ;
            if( ! foundPid ) throw new Error( "couldn't get parent PID" ) ;
            parentPid = parseInt( foundPid , 10 ) ;

            exec( 'ps -h -o comm -p ' + parentPid , ( error_ , stdout_ ) => {
                if ( error_ ) { reject( error_ ) ; return ; }

                appName = stdout_.trim() ;
                resolve( { pid: parentPid , appName } ) ;
            } ) ;
        } ) ;
    } ) ;
}

Doesn't really fix anything though, because I still end up with the error Terminal not found. :)

apowers313 commented 4 years ago

I've created a new termconfig for OSX, but the alt keys still aren't working. Is that because you're assuming the first byte of the scan code is going to be 0x1b (ESC) for extended sequences?


osx-256color.js

const tree = require( 'tree-kit' ) ;
const xterm256 = require( './xterm-256color.js' ) ;
const xtermGeneric = require( './xterm.generic.js' ) ;

const keymap = {
    ALT_A: '\xc3\xa5' ,
    ALT_B: '\xe2\x88\xab' ,
    ALT_C: '\xc3\xa7' ,
    ALT_D: '\xe2\x88\x82' ,
        // ...
} ;

module.exports = {
    esc: tree.extend( { own: true } , Object.create( xterm256.esc ) , xtermGeneric.esc ) ,
    keymap: tree.extend( null , keymap , Object.create( xtermGeneric.keymap ) ) ,
    handler: Object.create( xtermGeneric.handler ) ,
    support: {
        deltaEscapeSequence: true ,
        "256colors": true ,
        "24bitsColors": undefined , // DEPRECATED
        "trueColor": undefined  // maybe, maybe not
    } ,
    colorRegister: require( '../colorScheme/vga.json' )
} ;