概要
vscode拡張機能にhoverを実装するために以下を行う。
今回はlanguage serverとして実装する。
* ベースとするソースコードの入手
* 初期化処理の編集
* hover関数を実装
* hover関数をサーバに登録
ベースとするソースコードの入手
以下のリポジトリをクローンして、lsp-sampleのソースコードを使用する。
クローン後にmoduleをインストールする。
$ git clone https://github.com/microsoft/vscode-extension-samples.git $ cd vscode-extension-samples/lsp-sample $ npm install
その後vscodeでこのvscode-extension-samples/lsp-sampleを開く。
以下ではserver/src/server.tsを編集していく。
importの追加
以下のようにHoverParamsを追加でimportする。
import { createConnection, TextDocuments, Diagnostic, DiagnosticSeverity, ProposedFeatures, InitializeParams, DidChangeConfigurationNotification, CompletionItem, CompletionItemKind, TextDocumentPositionParams, TextDocumentSyncKind, InitializeResult, HoverParams, // ここを追加 Hover // ここを追加 } from 'vscode-languageserver/node';
初期化処理の編集
初期化時に設定するcapabilitiesにhoverの設定を追加する。server.tsの67行目あたりに追加すればよい。
// for hover result.capabilities.hoverProvider = true;
hover用関数を実装
hover用の関数を実装する。 server.tsの適当な場所に以下を追記する。
// for hover async function HoverSample(params:HoverParams): Promise<Hover> { var contents = "# Hover Test!\nyour hover!!!" var range = { start: { line: params.position.line, character: params.position.character }, end : { line: params.position.line, character: params.position.character+5 } } return { contents, range, } }
hover用関数をサーバに登録
実装した関数をサーバに登録する。server.tsの適当な場所に以下を追記する。
// for hover connection.onHover(params => HoverSample(params));
以上でhoverの実装ができた。
F5で拡張機能を起動し、Plain Textファイルの適当なところにマウスを持っていくとhoverで文字列が表示されるはず。
Hoverレスポンスの構造
Hoverリクエストの結果として返すデータ構造を見ていく。
以下のサイトを参考にする。
Specification
Hoverは以下の構造になっている。
/** * The result of a hover request. */ export interface Hover { /** * The hover's content */ contents: MarkedString | MarkedString[] | MarkupContent; /** * An optional range is a range inside a text document * that is used to visualize a hover, e.g. by changing the background color. */ range?: Range; }
- contentsは以下の定義で、文字列で指定できる。
type MarkedString = string | { language: string; value: string };
- rangeは以下の形式で、hoverの対象となる文字列がドキュメントのどの位置にあるかを示す。
interface Range { /** * The range's start position. */ start: Position; /** * The range's end position. */ end: Position; } interface Position { /** * Line position in a document (zero-based). */ line: uinteger; /** * Character offset on a line in a document (zero-based). The meaning of this * offset is determined by the negotiated `PositionEncodingKind`. * * If the character value is greater than the line length it defaults back * to the line length. */ character: uinteger; }
今回はHoverで通知する情報はほぼ固定だったが、これらの値を変更することで必要な情報をhoverで通知できる。