博客 / 詳情

返回

vscode插件開發中文文檔教程(9)——擴展API之命令篇

vscode插件開發中文文檔教程(9)——擴展API之命令篇

原文鏈接:Commands\
作者:Microsoft\
譯者:倔強青銅三

前言

大家好,我是倔強青銅三。是一名熱情的軟件工程師,我熱衷於分享和傳播IT技術,致力於通過我的知識和技能推動技術交流與創新,歡迎關注我,微信公眾號:倔強青銅三。歡迎點贊、收藏、關注,一鍵三連!!!

擴展API之命令篇

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

要查找可用的命令:

  • 瀏覽鍵盤快捷鍵
  • 查看 VS Code 的內置高級命令 API

命令 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})`);
        // 要在 Markdown 內容中啓用命令 URI,必須設置 `isTrusted` 標誌。
        // 創建可信的 Markdown 字符串時,請確保正確清理所有輸入內容,
        // 以確保只有預期的命令 URI 能夠被執行。
        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 中添加對應的命令 contribution

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

commands contribution 告訴 VS Code,您的擴展提供了一個特定的命令,並且當該命令被調用時,擴展應該被激活。它還允許您控制命令在 UI 中的顯示方式。現在我們的命令會出現在命令面板中:

命令面板中的貢獻命令

現在,當用户首次從命令面板或通過快捷鍵調用 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 子句。啓用狀態適用於所有菜單和註冊的快捷鍵。

注意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);
最後感謝閲讀!歡迎關注我,微信公眾號倔強青銅三。歡迎點贊收藏關注,一鍵三連!!!
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.