sculptui-vscode
Version:
Visually edit your React component code from the browser
97 lines (84 loc) • 2.81 kB
text/typescript
import { window, workspace, OutputChannel, Terminal } from 'vscode';
import { fork, ChildProcess } from 'child_process';
import * as rl from 'readline';
let outputChannels: { [windowId: string]: OutputChannel | undefined } = {};
const runningProcesses: Map<number, Process> = new Map();
interface Process {
process: ChildProcess;
cmd: string;
windowId: string;
}
export function getNpmBin() {
return workspace.getConfiguration('npm')['bin'] || 'npm';
}
export function runCommandInIntegratedTerminal(
terminalId: string,
cmd: string,
args: string[],
cwd: string | undefined,
): Thenable<number> {
const cmd_args = Array.from(args);
const terminal = getTerminal(terminalId);
terminal.show();
if (cwd) {
// Replace single backslash with double backslash.
const textCwd = cwd.replace(/\\/g, '\\\\');
terminal.sendText(['cd', `"${textCwd}"`].join(' '));
}
cmd_args.splice(0, 0, cmd);
terminal.sendText(cmd_args.join(' '));
return terminal.processId;
}
export function runScriptInOutputWindow(
windowId: string,
scriptPath: string,
args: string[],
cwd: string | undefined,
env?: NodeJS.ProcessEnv,
onMessage?: (message: any, outputChannel: OutputChannel) => void,
onExit?: (code: number, signal: string, outputChannel: OutputChannel) => void,
) {
const outputChannel = getOutputChannel(windowId);
const p = fork(scriptPath, args, { cwd, env, silent: true });
runningProcesses.set(p.pid, { process: p, cmd: scriptPath, windowId });
rl.createInterface({ input: p.stdout, terminal: false }).on('line', (line: string) => {
outputChannel!.appendLine(line);
});
rl.createInterface({ input: p.stderr, terminal: false }).on('line', (line: string) => {
outputChannel!.appendLine(line);
});
p.on('message', message => {
if (onMessage) {
onMessage(message, outputChannel);
}
});
p.on('exit', (code: number, signal: string) => {
if (onExit) {
onExit(code, signal, outputChannel!);
}
runningProcesses.delete(p.pid);
});
outputChannel.show();
return p.pid;
}
export function stopScriptInOutputWindow(pid: number) {
const process = runningProcesses.get(pid);
if (process) {
process.process.kill('SIGTERM');
}
}
export function getOutputChannel(windowId: string) {
let outputChannel = outputChannels[windowId];
if (!outputChannel) {
outputChannel = window.createOutputChannel(windowId);
outputChannels[windowId] = outputChannel;
}
return outputChannel;
}
export function getTerminal(terminalId: string) {
let terminal = window.terminals.find(term => term.name === terminalId);
if (!terminal) {
terminal = window.createTerminal(terminalId);
}
return terminal;
}