Help us understand the problem. What is going on with this article?

VSCode 用 SystemVerilogの拡張を作る(#8)

More than 1 year has passed since last update.

コード補完

コード補完は、補完タイミングに合わせてLanguageServerにLSPリクエストが来るので、それに答える形で実現します。

補完タイミングはVSCodeのデフォルトとして

  • [Ctrl+Space] を押す
  • 単語を数文字打つ

があり、さらに onInitialize で返信した

      completionProvider: {
        resolveProvider: true,
        triggerCharacters: ['.', ':']
      },

triggerCharactersが入力されたタイミングでも来ます。
これに対して connection.onCompletion で答えればOKです。

https://microsoft.github.io/language-server-protocol/specification#textDocument_completion

に、返信のデータ構造が示されています。
サーバー側での実装例です。

connection.onCompletion((_textDocumentPosition) => {
  if (! init_done) return;
  serverlog('onCompletion.');

  let ctx   = _textDocumentPosition.context;
  let pos   = _textDocumentPosition.position;
  let uri   = _textDocumentPosition.textDocument.uri;
  let doc   = documents.get(uri);

  scanContent(doc.uri, doc.getText());
  let items = sva.getCompleteItems(uri, pos.line + 1, pos.character);

  return items;
});

scanContentがパーサーを起動しており、出来上がったデータベース(sva)からitemsを生成して返しています。
正しい構造でデータを返せれば、後はVSCodeのイケてるI/Fできれいに表示されるようになります。

データベースさえ作れれば、補完機能がこんなに簡単に実現できるので大変ありがたいです。

パーサーの実行タイミング

VSCodeで編集が行われる際、いつパーサーを使ってソースコードの解析を行い、データベースを更新するのかは自分で決めます。
候補としては、

  • connection.onCompletion
    • VSCodeがLanguageServerに補完を要求するタイミング
  • documents.onDidChangeContent
    • バッファ(ファイルではない)の内容に変化があった時
  • documents.onDidSave
    • ファイルの内容が変化した時(セーブした時)

などがあるでしょう。
documents.onDidChangeContent
はエディタのバッファが変化したときに反応しますので、1文字打つごとに実行されます。
このタイミングで解析すると一番リアルタイムな感じが出てカッコいい挙動を見せてくれます。

残念ながら、今回作ったSystemVerilogパーサーはかなり実行時間が長く、1000行前後から解析に数1000msを超え、レスポンスに難が出始めてしまいます。さらに悪いことに、onDidChangeContent イベントがキューされる挙動を見せるため、1つのリクエストに1000msもかかっていると、10文字打ち終わったら10秒かけて10回解析が走るという律儀な動作となり、最悪です。

onDidSaveだと適切なタイミングで補完が効かないため、結局、今回は補完タイミングでパーサーを走らせることにしました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away