2016-09-21 06:27:11 -08:00
const { EventEmitter } = require ( 'events' ) ;
2016-10-02 08:54:27 -08:00
const { StringDecoder } = require ( 'string_decoder' ) ;
2016-09-21 06:27:11 -08:00
const { app } = require ( 'electron' ) ;
2016-07-01 15:50:28 -08:00
const defaultShell = require ( 'default-shell' ) ;
2016-09-21 06:27:11 -08:00
const { getDecoratedEnv } = require ( './plugins' ) ;
const { productName , version } = require ( './package' ) ;
2016-08-01 23:49:25 -08:00
const config = require ( './config' ) ;
2016-06-30 22:01:04 -08:00
2016-11-11 08:18:04 -09:00
const createPtyJsError = ( ) => new Error ( '`pty.js` failed to load. Typically this means that it was built incorrectly. Please check the `README.me` to more info.' ) ;
2016-07-13 13:06:05 -08:00
let spawn ;
try {
2016-11-11 08:18:04 -09:00
spawn = require ( 'pty.js' ) . spawn ;
2016-07-13 13:06:05 -08:00
} catch ( err ) {
2016-11-11 08:18:04 -09:00
throw createPtyJsError ( ) ;
2016-07-13 13:06:05 -08:00
}
2016-08-01 23:49:25 -08:00
const envFromConfig = config . getConfig ( ) . env || { } ;
2016-06-30 22:01:04 -08:00
module . exports = class Session extends EventEmitter {
2016-09-21 06:27:11 -08:00
constructor ( { rows , cols : columns , cwd , shell , shellArgs } ) {
2016-06-30 22:01:04 -08:00
super ( ) ;
2016-07-24 10:03:24 -08:00
const baseEnv = Object . assign ( { } , process . env , {
2016-07-26 10:26:06 -08:00
LANG : app . getLocale ( ) . replace ( '-' , '_' ) + '.UTF-8' ,
2016-07-24 10:03:24 -08:00
TERM : 'xterm-256color' ,
TERM _PROGRAM : productName ,
TERM _PROGRAM _VERSION : version
2016-08-01 23:49:25 -08:00
} , envFromConfig ) ;
2016-07-24 10:03:24 -08:00
2016-10-02 08:54:27 -08:00
const decoder = new StringDecoder ( 'utf8' ) ;
2016-08-13 11:30:17 -08:00
const defaultShellArgs = [ '--login' ] ;
2016-11-11 08:18:04 -09:00
try {
this . pty = spawn ( shell || defaultShell , shellArgs || defaultShellArgs , {
columns ,
rows ,
cwd ,
env : getDecoratedEnv ( baseEnv )
} ) ;
} catch ( err ) {
if ( /is not a function/ . test ( err . message ) ) {
throw createPtyJsError ( ) ;
} else {
throw err ;
}
}
2016-06-30 22:01:04 -08:00
2016-09-21 06:27:11 -08:00
this . pty . stdout . on ( 'data' , data => {
2016-08-19 12:19:04 -08:00
if ( this . ended ) {
return ;
}
2016-10-02 08:54:27 -08:00
this . emit ( 'data' , decoder . write ( data ) ) ;
2016-06-30 22:01:04 -08:00
} ) ;
this . pty . on ( 'exit' , ( ) => {
if ( ! this . ended ) {
this . ended = true ;
this . emit ( 'exit' ) ;
}
} ) ;
2016-07-23 16:57:47 -08:00
this . shell = shell || defaultShell ;
2016-06-30 22:01:04 -08:00
}
2016-09-21 06:27:11 -08:00
exit ( ) {
2016-06-30 22:01:04 -08:00
this . destroy ( ) ;
}
2016-09-21 06:27:11 -08:00
write ( data ) {
2016-06-30 22:01:04 -08:00
this . pty . stdin . write ( data ) ;
}
2016-11-11 08:18:04 -09:00
resize ( { cols , rows } ) {
2016-06-30 22:01:04 -08:00
try {
2016-11-11 08:18:04 -09:00
this . pty . stdout . resize ( cols , rows ) ;
2016-06-30 22:01:04 -08:00
} catch ( err ) {
2016-06-30 22:25:19 -08:00
console . error ( err . stack ) ;
2016-06-30 22:01:04 -08:00
}
}
2016-09-21 06:27:11 -08:00
destroy ( ) {
2016-07-03 12:35:45 -08:00
try {
2016-11-11 08:18:04 -09:00
this . pty . kill ( ) ;
2016-07-03 12:35:45 -08:00
} catch ( err ) {
console . error ( 'exit error' , err . stack ) ;
}
2016-06-30 22:01:04 -08:00
this . emit ( 'exit' ) ;
this . ended = true ;
}
} ;