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は、特定のコマンドを実行するリンクです。これらは、ホバーテキスト、補完アイテムの詳細、またはウェブビュー内でクリック可能なリンクとして使用できます。

コマンド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);
      }
    })()
  );
}

ウェブビューを作成する際に、WebviewOptionsenableCommandUris を設定することで、ウェブビューでコマンド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 コマンドを最初に呼び出すと、拡張機能がアクティベートされ、registerCommandmyExtension.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"
        }
      ]
    }
  }
}

これで、myExtension.sayHello コマンドは、ユーザーがMarkdownファイルにいる場合にのみコマンドパレットに表示されるようになります。

コマンドの有効化

コマンドは、enablement プロパティによる有効化をサポートしており、その値はwhen節です。有効化は、すべてのメニューと登録されたキーバインディングに適用されます。

: enablement とメニュー項目の when 条件の間には意味的な重複があります。後者は、無効な項目でいっぱいのメニューを防ぐために使用されます。例えば、JavaScriptの正規表現を分析するコマンドは、ファイルがJavaScriptである場合に表示され、カーソルが正規表現上にある場合にのみ有効になるべきです。when 節は、他のすべての言語ファイルに対してコマンドを表示しないことで、煩雑さを防ぎます。煩雑なメニューを防ぐことは強く推奨されます。

最後に、コマンドパレットやコンテキストメニューなど、コマンドを表示するメニューは、有効化の扱い方が異なります。エディターやエクスプローラーのコンテキストメニューは、有効/無効な項目をレンダリングするのに対し、コマンドパレットはそれらをフィルタリングします。

カスタムwhen節コンテキストの使用

独自のVS Code拡張機能を開発しており、when 節コンテキストを使用してコマンド、メニュー、またはビューを有効/無効にする必要があり、既存のキーがニーズに合わない場合は、独自のコンテキストを追加できます。

以下の最初の例では、キー myExtension.showMyCommand をtrueに設定しており、これはコマンドの有効化や when プロパティで使用できます。2番目の例では、開いているクールなものの数が2より大きいかどうかを確認するために when 節で使用できる値を格納しています。

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

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

命名規則

コマンドを作成する際には、以下の命名規則に従う必要があります。

  • コマンドのタイトル
    • タイトルスタイルで大文字を使用します。4文字以下の前置詞(on, to, in, of, with, forなど)は、最初または最後の単語である場合を除き、大文字にしないでください。
    • 実行されるアクションを説明するために動詞で始めます。
    • アクションのターゲットを説明するために名詞を使用します。
    • タイトルに「command」という単語を使用することは避けてください。