はじめに
公式サンプルにVSCode APIを使ったサンプルがあるので、いくつか使いそうなものをピックアップしてみました。
今回は、CompletionItemProvider
API を使って入力補完する機能を付けます。
前回
VSCode拡張機能を作ってみる1 - インストールとHelloWorld!
事前準備
まず、空のcompletion.ts
ファイルを作成し、extension.ts
で読み込んでおきます。
import * as vscode from 'vscode';
export default class Completions implements vscode.CompletionItemProvider
{
public provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]>
{
// ここに補完機能を追加していきます
return [];
}
}
plaintextにしているので対応したい言語に変更してください。
import * as vscode from 'vscode';
import Completions from "./completions";
export function activate(context: vscode.ExtensionContext)
{
const provider = vscode.languages.registerCompletionItemProvider('plaintext', new Completions());
context.subscriptions.push(provider);
}
export function deactivate() {}
Hello World!
シンプルにHello World!
を自動補完してみます。
public provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]>
{
const simpleCompletion = new vscode.CompletionItem('Hello World!');
return [simpleCompletion];
}
insertText
挿入テキストを指定できます。
insertText
がない場合はvscode.CompletionItem
のラベルが挿入されます。
public provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]>
{
const simpleCompletion = new vscode.CompletionItem('Hello World!');
simpleCompletion.insertText = 'Change the World!';
return [simpleCompletion];
}
documentation
補完候補に説明を追加できます。
public provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]>
{
const snippetCompletion = new vscode.CompletionItem('Good part of the day');
snippetCompletion.documentation = new vscode.MarkdownString("Inserts a snippet that lets you select the _appropriate_ part of the day for your greeting.");
return [snippetCompletion];
}
Snippet
SnippetString
を使って挿入テキストにスニペットを追加できます。
public provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]>
{
const snippetCompletion = new vscode.CompletionItem('Good part of the day');
snippetCompletion.insertText = new vscode.SnippetString('Good ${1|morning,afternoon,evening|}. It is ${1}, right?');
return [snippetCompletion];
}
commitCharacters
補完候補が1つまたは選択している場合、特定の文字を入力すると自動で補完が完了します。
この状態で「.」を入力すると「console.」と補完されます。
public provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]>
{
const commitCharacterCompletion = new vscode.CompletionItem('console');
commitCharacterCompletion.commitCharacters = ['.'];
commitCharacterCompletion.documentation = new vscode.MarkdownString('Press `.` to get `console.`');
return [commitCharacterCompletion];
}
command
IntelliSense
を再トリガーする補完アイテムを使ってみます。
「new」を自動補完した後、続けて同じ入力補完を実行できるようになります。
insertText
では「new」の後ろにスペースを追加しています。
Enterを押し続けると「new new new...」と連続で挿入できます。
public provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]>
{
const commandCompletion = new vscode.CompletionItem('new');
commandCompletion.insertText = 'new ';
commandCompletion.command = { command: 'editor.action.triggerSuggest', title: 'Re-trigger completions...' };
return [commandCompletion];
}
triggerCharacters
特定の文字が入力されたときだけ入力補完する場合は、CompletionItemProviderの3引数目以降に追加していきます。
「.」が入力された場合だけ実行する場合は
registerCompletionItemProvider('plaintext', new Completions(), '.');
となります。
export function activate(context: vscode.ExtensionContext)
{
const provider = vscode.languages.registerCompletionItemProvider('plaintext', new Completions(), '.');
context.subscriptions.push(provider);
}
icon
completionsのtypeを指定することで補完候補のアイコンを指定することができます。
const commandCompletion = new vscode.CompletionItem('new');
commandCompletion.kind = vscode.CompletionItemKind.Keyword;
TextDocument
入力した内容を取得し処理を追加することができます。
provideCompletionItems
の引数にvscode.TextDocument
とvscode.Position
を追加し、挿入した行を取得します。
「console.」で終わる文字だった場合にのみ、log,warn,error
の入力補完を追加します。
public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position): vscode.ProviderResult<vscode.CompletionItem[]>
{
const linePrefix = document.lineAt(position).text.substr(0, position.character);
if (!linePrefix.endsWith('console.')) {
return undefined;
}
return [
new vscode.CompletionItem('log', vscode.CompletionItemKind.Method),
new vscode.CompletionItem('warn', vscode.CompletionItemKind.Method),
new vscode.CompletionItem('error', vscode.CompletionItemKind.Method),
];
}
まとめ
入力文字取得してごにょごにょしてinsertTextするだけで便利なことできそう!