diff --git a/apps/remixdesktop/src/plugins/xtermPlugin.ts b/apps/remixdesktop/src/plugins/xtermPlugin.ts index 1c0569ddd3..db50d4bb94 100644 --- a/apps/remixdesktop/src/plugins/xtermPlugin.ts +++ b/apps/remixdesktop/src/plugins/xtermPlugin.ts @@ -13,8 +13,6 @@ import { findExecutable } from '../utils/findExecutable' import { spawnSync } from 'child_process' import { stripAnsi } from '../lib' import { DataBatcher } from '../lib/databatcher' -import { Worker } from 'worker_threads' -import { utilityProcess } from 'electron' export const detectDefaultShell = () => { const { env } = process @@ -66,12 +64,6 @@ const parseEnv = (env: any) => { return returnValue } - - - - - - export default defaultShell const profile: Profile = { @@ -111,7 +103,7 @@ const clientProfile: Profile = { } class XtermPluginClient extends ElectronBasePluginClient { - terminals: Electron.UtilityProcess[] = [] + terminals: pty.IPty[] = [] dataBatchers: DataBatcher[] = [] workingDir: string = '' parsedEnv: any = null @@ -125,18 +117,17 @@ class XtermPluginClient extends ElectronBasePluginClient { this.workingDir = await this.call('fs' as any, 'getWorkingDir') console.log('workingDir', this.workingDir) }) + if (!(process.platform === 'win32')) { const { stdout } = spawnSync(defaultShell, getShellEnvArgs, { encoding: 'utf8', }) this.parsedEnv = parseEnv(stdout) } - } async keystroke(key: string, pid: number): Promise { - //this.terminals[pid].write(key) - this.terminals[pid].postMessage({ type: 'write', data: key }) + this.terminals[pid].write(key) } async getShells(): Promise { @@ -157,57 +148,43 @@ class XtermPluginClient extends ElectronBasePluginClient { async createTerminal(path?: string, shell?: string): Promise { const start_time = Date.now() - return new Promise((resolve, reject) => { - let mypy: Electron.UtilityProcess = utilityProcess.fork(__dirname + '/xtermWorker.js') - const end_time_fork = Date.now() - console.log(`fork took ${end_time_fork - start_time} ms`) - - const env = this.parsedEnv || process.env - - mypy.on('message', (message: any) => { - //console.log('message', message) - if (message.type === 'spawned') { - const end_time_spawn = Date.now() - console.log(`spawn message took ${end_time_spawn - end_time_fork} ms`) - const pid = message.pid - const dataBatcher = new DataBatcher(pid) - this.dataBatchers[pid] = dataBatcher - dataBatcher.on('flush', (data: string, uid: number) => { - this.sendData(data, uid) - }) - this.terminals[pid] = mypy - const end_time = Date.now() - console.log('spawned', pid, end_time - start_time) - resolve(pid) - } - if (message.type === 'data') { - this.dataBatchers[message.pid].write(Buffer.from(message.data)) - } - if (message.type === 'exit') { - this.closeTerminal(message.pid) - } - }) - - mypy.postMessage({ - type: 'spawn', shell, args: [], options: - { - name: 'xterm-color', - cols: 40, - rows: 10, - cwd: path || process.cwd(), - env: env, - encoding: 'utf8', - } - }) + console.log('createTerminal', path, shell || defaultShell) + + + const env = this.parsedEnv || process.env + + const ptyProcess = pty.spawn(shell || defaultShell, [], { + name: 'xterm-color', + cols: 80, + rows: 20, + cwd: path || process.cwd(), + env: env, + encoding: 'utf8', + }); + const dataBatcher = new DataBatcher(ptyProcess.pid) + this.dataBatchers[ptyProcess.pid] = dataBatcher + ptyProcess.onData((data: string) => { + //console.log('data', data) + dataBatcher.write(Buffer.from(data)) + }) + ptyProcess.onExit(() => { + const pid = ptyProcess.pid + this.closeTerminal(pid) + }) + dataBatcher.on('flush', (data: string, uid: number) => { + this.sendData(data, uid) }) + this.terminals[ptyProcess.pid] = ptyProcess + const end_time = Date.now() + console.log('createTerminal', end_time - start_time) + return ptyProcess.pid } async closeTerminal(pid: number): Promise { if (this.terminals) { if (this.terminals[pid]) { try { - this.terminals[pid].postMessage({ type: 'close' }) - //this.terminals[pid].kill() + this.terminals[pid].kill() } catch (err) { // ignore } @@ -222,7 +199,7 @@ class XtermPluginClient extends ElectronBasePluginClient { async resize({ cols, rows }: { cols: number; rows: number }, pid: number) { if (this.terminals[pid]) { try { - //this.terminals[pid].postMessage({ type: 'resize', cols, rows }) + this.terminals[pid].resize(cols, rows) } catch (_err) { const err = _err as { stack: any } console.error(err.stack) @@ -234,7 +211,7 @@ class XtermPluginClient extends ElectronBasePluginClient { async closeAll(): Promise { for (const pid in this.terminals) { - this.terminals[pid].postMessage({ type: 'close' }) + this.terminals[pid].kill() delete this.terminals[pid] this.emit('close', pid) }