现已发布!阅读 10 月份的新功能和修复。

命令

命令在 Visual Studio Code 中触发操作。如果您曾经 配置过键绑定,那么您就已经使用过命令。命令也由扩展使用,向用户公开功能,绑定到 VS Code UI 中的操作,以及实现内部逻辑。

使用命令

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 是执行给定命令的链接。它们可以用作悬停文本、完成项详细信息或 Webview 内的点击链接。

命令 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);
      }
    })()
  );
}

传递给命令的参数列表作为 JSON 数组传递,该数组已正确 URI 编码:以下示例使用 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 来在 Webview 中启用命令 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 中有一个相应的命令 贡献

{
  "contributes": {
    "commands": [
      {
        "command": "myExtension.sayHello",
        "title": "Say Hello"
      }
    ]
  }
}

commands 贡献告诉 VS Code 您的扩展提供了给定命令,并且应该在调用该命令时激活,并且还允许您控制命令在 UI 中的显示方式。现在我们的命令将显示在命令面板中

The contributed command in the Command Palette

现在,当用户第一次从命令面板或通过键绑定调用 myExtension.sayHello 命令时,扩展将被激活,并且 registerCommand 将将 myExtension.sayHello 绑定到正确的处理程序。

注意:面向 VS Code 版本早于 1.74.0 的扩展必须为所有面向用户的命令显式注册 onCommand activationEvent,以便扩展激活并执行 registerCommand

{
  "activationEvents": ["onCommand:myExtension.sayHello"]
}

您不需要为内部命令提供 onCommand 激活事件,但必须为以下任何命令定义它们

  • 可以使用命令面板调用。
  • 可以使用键绑定调用。
  • 可以通过 VS Code UI 调用,例如通过编辑器标题栏。
  • 旨在作为其他扩展使用的 API。

控制命令在命令面板中显示的时间

默认情况下,通过 package.jsoncommands 部分贡献的所有面向用户的命令都会显示在命令面板中。但是,许多命令只在特定情况下才相关,例如当存在给定语言的活动文本编辑器或用户设置了特定配置选项时。

menus.commandPalette 贡献点允许您限制命令何时应该显示在命令面板中。它接受目标命令的 ID 和 when 子句,该子句控制何时显示命令

{
  "contributes": {
    "menus": {
      "commandPalette": [
        {
          "command": "myExtension.sayHello",
          "when": "editorLangId == markdown"
        }
      ]
    }
  }
}

现在,只有当用户在 Markdown 文件中时,myExtension.sayHello 命令才会显示在命令面板中。

启用命令

命令支持通过 enablement 属性进行启用 - 其值为 when 子句。启用适用于所有菜单和注册的键绑定。

注意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);