🚀 在 VS Code 中免費取得

命令

命令會在 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 是執行指定命令的連結。它們可用於 hover 文字、完成項目詳細資料或 webview 內的按一下連結。

命令 URI 使用 command 配置,後面接著命令名稱。例如,editor.action.addCommentLine 命令的命令 URI 是 command:editor.action.addCommentLine。以下是一個 hover 提供者,會在作用中文字編輯器中目前行的註解中顯示連結

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 命令建立 hover 連結,以暫存目前的檔案

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 繫結至適當的處理常式。

注意:目標為 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 子句可防止混亂,方法是不顯示所有其他語言檔案的命令。強烈建議防止選單雜亂。

最後,顯示命令的選單 (例如命令面板或關聯式選單) 會實作不同的處理啟用方式。編輯器和檔案總管關聯式選單會呈現啟用/停用項目,而命令面板則會篩選它們。

使用自訂 when 子句內容

如果您要撰寫自己的 VS Code 擴充功能,且需要使用 when 子句內容啟用/停用命令、選單或檢視,但沒有現有的金鑰符合您的需求,則您可以新增自己的內容。

以下第一個範例會將金鑰 myExtension.showMyCommand 設定為 true,您可以在命令的啟用或搭配 when 屬性使用它。第二個範例會儲存一個值,您可以搭配 when 子句使用該值,以檢查酷炫開啟項目的數量是否大於 2。

vscode.commands.executeCommand('setContext', 'myExtension.showMyCommand', true);

vscode.commands.executeCommand('setContext', 'myExtension.numberOfCoolOpenThings', 2);

命名慣例

建立命令時,您應遵循下列命名慣例

  • 命令標題
    • 使用標題樣式的大小寫。請勿將四個或四個字母以下的介系詞 (例如 on、to、in、of、with 和 for) 大寫,除非介系詞是第一個或最後一個字。
    • 以動詞開頭來描述將執行的動作。
    • 使用名詞來描述動作的目標。
    • 避免在標題中使用「命令」。