命令

命令用于在 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 和位置作为参数,并返回一个包含定义列表的 Promise。

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

命令的参数列表以正确进行 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,从而在 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 中进行相应的命令 contribution(贡献)。

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

commands 贡献部分告知 VS Code 你的扩展程序提供了某个命令,并应在调用该命令时激活。它还允许你控制该命令在 UI 中的显示方式。创建命令时,请务必遵守命令命名规范

The contributed command in the Command Palette

现在,当用户首次从命令面板或通过快捷键调用 myExtension.sayHello 命令时,扩展程序将会激活,并且 registerCommand 会将 myExtension.sayHello 绑定到相应的处理程序。

注意:针对 1.74.0 之前版本 VS Code 的扩展程序必须显式为所有面向用户的命令注册 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"
        }
      ]
    }
  }
}

现在,myExtension.sayHello 命令仅在用户处于 Markdown 文件中时才会显示在命令面板中。

命令的启用状态

命令支持通过 enablement 属性进行启用控制,其值为一个 when 子句。启用控制适用于所有菜单和已注册的快捷键。

注意enablement 和菜单项的 when 条件在语义上有重叠。后者用于防止菜单中充斥着禁用的项。例如,分析 JavaScript 正则表达式的命令应该在文件为 JavaScript 时显示(when),并且仅在光标位于正则表达式上时才被启用(enablement)。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);

命名规范

创建命令时,应遵循以下命名规范:

  • 命令标题
    • 使用标题式大小写(Title Case)。不要将四个字母或更短的介词(如 on、to、in、of、with 和 for)大写,除非该介词是第一个或最后一个单词。
    • 以动词开头,描述将要执行的操作。
    • 使用名词来描述操作的目标。
    • 避免在标题中使用“command”(命令)一词。
© . This site is unofficial and not affiliated with Microsoft.