コマンド
コマンドは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は、指定されたコマンドを実行するリンクです。ホバーテキスト、補完アイテムの詳細、またはウェブビュー内でクリック可能なリンクとして使用できます。
コマンド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);
}
})()
);
}
ウェブビュー作成時に WebviewOptions
で enableCommandUris
を設定することで、ウェブビューでコマンド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でどのように表示されるかを制御することもできます。コマンドを作成する際には、コマンド命名規則に従うようにしてください。
これで、ユーザーがコマンドパレットまたはキーバインディングを通じて 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
プロパティで使用できます。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」という言葉を使用しないようにします。