我试图创建一个简单的VSCode扩展程序,当我打开一个文件夹时运行一系列命令。基本上这些命令将配置我们的开发环境。我已经开始创建模板并运行了VSCode提供的示例,但我不清楚如何运行系统命令。感激任何帮助或指向与此主题相关的文档。
我试图创建一个简单的VSCode扩展程序,当我打开一个文件夹时运行一系列命令。基本上这些命令将配置我们的开发环境。我已经开始创建模板并运行了VSCode提供的示例,但我不清楚如何运行系统命令。感激任何帮助或指向与此主题相关的文档。
您的扩展环境可以访问node.js库,因此您可以使用child_process
或任何辅助库来执行命令:
const cp = require('child_process')
cp.exec('pwd', (err, stdout, stderr) => {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (err) {
console.log('error: ' + err);
}
});
socket.io
连接,允许与扩展进行通信和控制。bash -c
(非交互式 shell),并使用文件观察器获取结果。这样做更容易,但在进程完成后,用户将无法使用终端窗口(因为它是非交互式的)。出错几率更小,不需要满足socket.io依赖。TerminalWrapper
在包装器进程中运行命令,并等待文件包含结果。const cwd = '.';
const command = `node -e "console.log('hi!');"`;
const { code } = await TerminalWrapper.execInTerminal(cwd, command, {}).waitForResult();
if (code) {
const processExecMsg = `${cwd}$ ${command}`;
throw new Error(`Process failed with exit code ${code} (${processExecMsg})`);
}
bash
,然而(i)我们有一个依赖检查器,如果你没有它会警告你并解释如何获取它,(ii)使用统一的 shell,使运行命令变得更容易,因为我们现在有了一个相当强大的统一特性集,我们知道我们可以依靠它,而不仅仅能使用常见的命令执行语法,(iii)我们甚至可以运行*.sh
文件而不必担心。context.subscriptions.push(vscode.commands.registerCommand('terminalTest.createAndSend', () => {
const terminal = vscode.window.createTerminal(`Ext Terminal #${NEXT_TERM_ID++}`);
terminal.sendText("echo 'Sent text immediately after creating'");
}));
vscode.window.onDidChangeActiveTerminal(e => {
console.log(`Active terminal changed, name=${e ? e.name : 'undefined'}`);
});
function selectTerminal(): Thenable<vscode.Terminal | undefined> {
interface TerminalQuickPickItem extends vscode.QuickPickItem {
terminal: vscode.Terminal;
}
const terminals = <vscode.Terminal[]>(<any>vscode.window).terminals;
const items: TerminalQuickPickItem[] = terminals.map(t => {
return {
label: `name: ${t.name}`,
terminal: t
};
});
return vscode.window.showQuickPick(items).then(item => {
return item ? item.terminal : undefined;
});
}
......还有更多!......
(<3代表对VSCode团队及其辛勤工作的赞赏。)
onDidWriteTerminalData
事件获取输出(但是这可能永远不会成为稳定API的一部分,如此处所述)。遗憾的是,除非您将命令包装在观察应用程序中(如我上面所提出的),否则无法知道当前终端内运行的内容或是否正在运行。 - Domiimport * as cp from "child_process";
const execShell = (cmd: string) =>
new Promise<string>((resolve, reject) => {
cp.exec(cmd, (err, out) => {
if (err) {
return reject(err);
}
return resolve(out);
});
});
获取当前目录
const currentDir = await execShell('pwd');
获取当前git分支名称
const branchName = await execShell('git rev-parse --abbrev-ref HEAD');
import * as vscode from 'vscode';
import * as fs from 'fs';
async function executeAndRead(command: string): Promise<string> {
ensureTerminalExists();
const terminal = await selectTerminal();
if (terminal) {
terminal.sendText(command + ` > ${outputFile} || pwd > ${triggerFile}`);
return waitForFileUpdate(outputFile, triggerFile);
}
return Promise.reject('Could not select terminal');
}
async function waitForFileUpdate(outputFile: string, triggerFile: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
const watcher = fs.watch(triggerFile);
watcher.on('change', () => {
watcher.close();
fs.readFile(outputFile, 'utf8', (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
watcher.on('error', reject);
});
}
我的想法是按顺序修改两个文件。第二个文件大多数情况下都是虚拟的。但是当我收到第二个文件的触发器时,我知道第一个文件已经完成更新。
vscode.window.createTerminal('终端名称')
创建的新终端)? - SamTheProgrammer