Visual Studio Codeの拡張機能(エクステンション)開発に使えるAPIはよく考えられたものが取り揃えてある(何様)。
vscode名前空間から呼べる関数や型だけに限るとそう大層なことはできない印象を抱くかもしれないけれど、拡張機能のマニフェストファイル(package.json)も合わせると色々なことができる。
また、APIとして公開されていないけれども、Visual Studio Codeにプリセットされている機能(タスク実行や拡張機能のインストールなど)は、コマンドとして呼べるようになっている。 今回は、そこのところを含めて、コマンド系のAPIを紹介したい。
Contents
vscode.commands
vscode.commands名前空間に、コマンドの登録/取得/実行をするための関数が1packageになっている。
コマンドを登録する – registerCommand
registerCommand(command: string, callback: (args: any[]) => any, thisArg?: any): Disposable
コマンドの登録をする関数。
コマンドパレットから呼び出して使うような拡張機能を開発するなら、必ずコマンドの登録処理が要るから、お世話になる機会も多い。
簡単な使い方はTOACHの記事を見ていただくとして、引数や返り値を調べていく。
Visual Studio Codeの拡張機能をTypeScriptで作る方法
引数
command: string
コマンドのIDを渡す。 このIDに依って、コマンドパレットからの呼び出しとその処理を紐付ける。
例えばこんな風にして呼び出し部分はpackage.jsonで記述する。
1 |
"commands": [{ "command": "extension.sayHello", "title": "Hello World" }] |
この”commands”を”contributes”に書けば、extension.sayHelloというコマンドIDに紐付いた処理を、コマンドパレットから”Hello World”で呼べる。
その処理の登録部分はこんな具合。
1 |
vscode.commands.registerCommand( 'extension.sayHello', () => { // コマンドの処理 }); |
callback: (args: any[]) => any
コマンドの処理内容を記述する。上の例で解説した無名関数の部分がこれに当たる。
返り値
Disposable
拡張機能が破棄されるときにコマンドの破棄も一緒にやってもらえる。この返り値を拡張機能のactivate()に渡ってきたcontextに登録しておくだけでOK。例えばこのように……
1 2 3 4 5 6 |
export function activate(context: vscode.ExtensionContext) { var disposable = vscode.commands.registerCommand( 'extension.sayHello', () => {}); context.subscriptions.push(disposable); } |
ちなみにactivate()は、拡張機能が初回に呼び出されたタイミングで呼ばれる。このタイミングはpackage.jsonで色々変えられる(コマンドが呼ばれたとき、作業フォルダーに特定のファイルがあるとき、Visual Studio Codeが起ち上がった時など)。そこのところの解説はまた別のお話し。
コマンドを実行する – executeCommand
executeCommand<T>(command: string, …rest: any[]): Thenable
コマンドから別のコマンドを呼ぶときなど、コマンドを実行する際に使う。
引数
command: string
呼び出したいコマンドのIDを渡す。これはregisterCommand()で使っていたものと同じ。
ちなみに冒頭で触れた、Visual Studio Codeの機能の呼び出しは、その機能のコマンドIDを使えば呼び出せる。コマンドIDはここから探そう。
Visual Studio Code Key Bindings
…rest: any[]
呼び出すコマンドへの引数を渡す。
例えば、渡されたテキストをユーザーへ通知するコマンド”extension.showMessage”に対して、”Hello World”を渡すコマンド”extension.sayHello”を考える。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export function activate(context: vscode.ExtensionContext) { var showMessageCommand = vscode.commands.registerCommand( 'extension.showMessage', message => vscode.window.showInformationMessage(message)); var sayHelloCommand = vscode.commands.registerCommand( 'extension.sayHello', () => vscode.commands.executeCommand("extension.showMessage", "Hello World")); context.subscriptions.push(showMessageCommand); context.subscriptions.push(sayHelloCommand); } |
返り値
Thenable
コマンドの実行が終わった後に続いて処理ができるよう、返り値はThenableになっている。
先ほどの”Hello World”を表示した例で考えると、ユーザーへの通知が表示された後、うるさくも再びメッセージを通知したい場合にThenableな返り値が生きてくる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
export function activate(context: vscode.ExtensionContext) { var showMessageCommand = vscode.commands.registerCommand( 'extension.showMessage', message => vscode.window.showInformationMessage(message)); var sayHelloCommand = vscode.commands.registerCommand( 'extension.sayHello', () => vscode.commands .executeCommand("extension.showMessage", "Hello World") .then(() => vscode.commands.executeCommand("extension.showMessage", "Hello World"))); context.subscriptions.push(showMessageCommand); context.subscriptions.push(sayHelloCommand); } |
コマンドの取得 – getCommands
getCommands(): Thenable<string[]>
使用可能な全てのコマンドを取得するという関数。 さすがに全てのコマンドともなると数が多いのか、僕のパソコンが遅いのか、取得までに時間がかかるため、返り値はThenableとなっており、取得が終わった後に処理を続けられるようになっている。
TextEditorコマンドの登録 – registerTextEditorCommand
registerTextEditorCommand(command: string, callback: (textEditor: TextEditor, edit: TextEditorEdit) => void, thisArg?: any): Disposable
registerCommand()に似ているけれど、こちらは開いている最中のTextEditorに関するコマンドを登録する。
TextEditorを開いたり閉じたり、様々なことができる仕組みになっている。
引数
command: string
コマンドID
callback: (textEditor: TextEditor, edit: TextEditorEdit) => void
コマンドの処理を書く。引数にTextEditorとTextEditorEditを貰っているから、この引数を通してコマンドを適用していく。
開いているTextEditorを閉じるコマンド”Dismiss Editor”を考えると、こう書ける。
1 2 3 4 5 6 7 8 9 10 |
export function activate(context: vscode.ExtensionContext) { var dismissEditor = vscode.commands.registerTextEditorCommand( 'extension.dismissEditor', (editor, edit) => { editor.hide(); }); context.subscriptions.push(dismissEditor); } |
TextEditorとTextEditorEditについて詳しくはこちら
言語を越えて役立つ名著。一皮剥けたいエンジニアへ。
他のVisual Studio Code関連の記事もオススメ
Visual Studio Codeの拡張機能を公開する方法
Visual Studio Codeのコマンドパレットでリスト(Quick Pick)を出す方法
Visual Studio Codeの拡張機能をTypeScriptで作る方法
Visual Studio CodeのES6用拡張機能で爆速ES6コーディング
Visual Studio CodeでTypeScriptをトランスパイルする方法