命令
命令在Visual Studio Code中触发操作。如果你曾经配置过键绑定,那么你已经使用过命令。扩展也使用命令向用户暴露功能,绑定到VS Code用户界面中的操作,并实现内部逻辑。
使用命令
VS Code 包含大量内置命令,您可以使用这些命令与编辑器交互、控制用户界面或执行后台操作。许多扩展还将其核心功能作为命令公开,供用户和其他扩展利用。
以编程方式执行命令
vscode.commands.executeCommand
API 以编程方式执行命令。这使您能够使用 VS Code 的内置功能,并基于扩展(如 VS Code 的内置 Git 和 Markdown 扩展)进行构建。
例如,editor.action.addCommentLine
命令会在活动的文本编辑器中注释当前选中的行:
import * as vscode from 'vscode';
function commentLine() {
vscode.commands.executeCommand('editor.action.addCommentLine');
}
一些命令接受控制其行为的参数。命令也可能返回结果。例如,类似API的vscode.executeDefinitionProvider
命令,查询文档中给定位置的定义。它接受文档URI和位置作为参数,并返回一个包含定义列表的承诺:
import * as vscode from 'vscode';
async function printDefinitionsForActiveEditor() {
const activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
return;
}
const definitions = await vscode.commands.executeCommand<vscode.Location[]>(
'vscode.executeDefinitionProvider',
activeEditor.document.uri,
activeEditor.selection.active
);
for (const definition of definitions) {
console.log(definition);
}
}
查找可用命令:
命令URI
命令URI是执行给定命令的链接。它们可以用作悬停文本、完成项详细信息或Web视图中的可点击链接。
命令URI使用command
方案后跟命令名称。例如,editor.action.addCommentLine
命令的命令URI是command:editor.action.addCommentLine
。这里有一个悬停提供程序,它在活动文本编辑器的当前行注释中显示一个链接:
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
vscode.languages.registerHoverProvider(
'javascript',
new (class implements vscode.HoverProvider {
provideHover(
_document: vscode.TextDocument,
_position: vscode.Position,
_token: vscode.CancellationToken
): vscode.ProviderResult<vscode.Hover> {
const commentCommandUri = vscode.Uri.parse(`command:editor.action.addCommentLine`);
const contents = new vscode.MarkdownString(`[Add comment](${commentCommandUri})`);
// To enable command URIs in Markdown content, you must set the `isTrusted` flag.
// When creating trusted Markdown string, make sure to properly sanitize all the
// input content so that only expected command URIs can be executed
contents.isTrusted = true;
return new vscode.Hover(contents);
}
})()
);
}
命令的参数列表作为已正确URI编码的JSON数组传递:以下示例使用git.stage
命令创建一个悬停链接,用于暂存当前文件:
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
vscode.languages.registerHoverProvider(
'javascript',
new (class implements vscode.HoverProvider {
provideHover(
document: vscode.TextDocument,
_position: vscode.Position,
_token: vscode.CancellationToken
): vscode.ProviderResult<vscode.Hover> {
const args = [{ resourceUri: document.uri }];
const stageCommandUri = vscode.Uri.parse(
`command:git.stage?${encodeURIComponent(JSON.stringify(args))}`
);
const contents = new vscode.MarkdownString(`[Stage file](${stageCommandUri})`);
contents.isTrusted = true;
return new vscode.Hover(contents);
}
})()
);
}
您可以在创建webview时,通过在WebviewOptions
中设置enableCommandUris
来启用webviews中的命令URI。
创建新命令
注册命令
vscode.commands.registerCommand
在你的扩展中绑定一个命令ID到一个处理函数:
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
const command = 'myExtension.sayHello';
const commandHandler = (name: string = 'world') => {
console.log(`Hello ${name}!!!`);
};
context.subscriptions.push(vscode.commands.registerCommand(command, commandHandler));
}
每当执行myExtension.sayHello
命令时,处理函数将被调用,无论是通过executeCommand
以编程方式、从VS Code UI还是通过键绑定。
创建一个面向用户的命令
vscode.commands.registerCommand
仅将命令ID绑定到处理函数。为了在命令面板中公开此命令,以便用户可以发现它,您还需要在扩展的package.json
中进行相应的命令contribution
:
{
"contributes": {
"commands": [
{
"command": "myExtension.sayHello",
"title": "Say Hello"
}
]
}
}
commands
贡献告诉 VS Code 你的扩展提供了一个给定的命令,并且当该命令被调用时应该被激活,同时也让你控制命令在用户界面中的显示方式。现在我们的命令将显示在命令面板中:
现在,当用户首次从命令面板或通过键绑定调用myExtension.sayHello
命令时,扩展将被激活,并且registerCommand
将把myExtension.sayHello
绑定到正确的处理程序。
注意: 针对VS Code 1.74.0之前版本的扩展必须显式地为所有面向用户的命令注册一个
onCommand
activationEvent
,以便扩展激活并执行registerCommand
:{ "activationEvents": ["onCommand:myExtension.sayHello"] }
你不需要为内部命令使用onCommand
激活事件,但你必须为以下任何命令定义它们:
- 可以使用命令面板调用。
- 可以使用快捷键调用。
- 可以通过VS Code UI调用,例如通过编辑器标题栏。
- 旨在作为其他扩展使用的API。
控制命令何时显示在命令面板中
默认情况下,所有通过package.json
的commands
部分贡献的用户界面命令都会显示在命令面板中。然而,许多命令只在特定情况下相关,例如当存在给定语言的活跃文本编辑器或用户设置了某些配置选项时。
menus.commandPalette
贡献点允许您限制命令何时应在命令面板中显示。它接受目标命令的ID和一个when子句,该子句控制命令何时显示:
{
"contributes": {
"menus": {
"commandPalette": [
{
"command": "myExtension.sayHello",
"when": "editorLangId == markdown"
}
]
}
}
}
现在,myExtension.sayHello
命令只会在用户处于 Markdown 文件时显示在命令面板中。
命令的启用
命令支持通过enablement
属性启用 - 其值是一个when-clause。启用适用于所有菜单和已注册的键绑定。
注意:
enablement
和菜单项的when
条件之间存在语义重叠。后者用于防止菜单中充满禁用的项目。例如,一个分析 JavaScript 正则表达式的命令应该在文件是 JavaScript 时显示,并且只有在光标位于正则表达式上时才启用。when
子句通过不为所有其他语言文件显示该命令来防止混乱。强烈建议防止菜单混乱。
最后,显示命令的菜单,如命令面板或上下文菜单,实现了不同的处理启用方式。编辑器和资源管理器的上下文菜单会渲染启用/禁用项,而命令面板则会过滤它们。
使用自定义的when子句上下文
如果您正在编写自己的VS Code扩展,并且需要通过使用when
子句上下文来启用/禁用命令、菜单或视图,而现有的键都不适合您的需求,那么您可以添加自己的上下文。
下面的第一个示例将键 myExtension.showMyCommand
设置为 true,您可以在启用命令或使用 when
属性时使用它。第二个示例存储了一个值,您可以使用 when
子句来检查酷炫的开放事物数量是否大于 2。
vscode.commands.executeCommand('setContext', 'myExtension.showMyCommand', true);
vscode.commands.executeCommand('setContext', 'myExtension.numberOfCoolOpenThings', 2);