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

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

More than 1 year has passed since last update.

LanguageServer

拡張機能エントリとは別に、サーバー用の.tsを作ります。

拡張機能が起動する際に、拡張機能からLanguageServerを起動してIPCで接続します。
これらはVSCodeのライブラリで簡単にできるようになっています。

LanguageServer:
https://github.com/Rockdoor/systemverilog/blob/master/src/server/server.ts

サンプルは公式にありますが、これがまた余計なものが多くてつかみにくい。要点はとても少ないです。

クライアント(拡張機能)との接続

サーバー側で以下のコードを記述。

let connection = lserv.createConnection(
  new lserv.IPCMessageReader(process), 
  new lserv.IPCMessageWriter(process));

で完了します。基本これだけ。

リクエストに対するレスポンス

connection.onXXXXX() {

という形で、connectionのメンバとして 接頭on+LSPリクエストの関数を実装すると対応するリクエストにレスポンスできるようになります。

何に対応するかと言うのは onInitialize という必ず起動時にやってくるメッセージに対して下記のような hogehogeProviderの内容を返してやると拡張機能側でそのLSPが有効化されます。

  return {
    capabilities: {
      textDocumentSync: documents.syncKind,
      hoverProvider: true,
      completionProvider: {
        resolveProvider: true,
        triggerCharacters: ['.', ':']
      },
      signatureHelpProvider: {
        triggerCharacters: ['(', ',']
      },
      documentSymbolProvider: true,
      definitionProvider: true,
      referencesProvider: true,
      // codeLensProvider: {
      //   resolveProvider: true
      // },
      // codeActionProvider: true,
      executeCommandProvider: {
        commands: ["sv.server.instantiateModule"]
      },
    }
  };

実際の通信を垣間見る

公式でも紹介されていますが、
https://microsoft.github.io/language-server-protocol/inspector/
が便利です。

ログをダンプしておいて、それを上記ページにアップすると視覚化してくれます。

クライアント(拡張機能)からのLanguageServerの起動と接続

拡張機能が起動されると呼ばれる activate 関数内で以下の流れを記述するとサーバーが起動されます。
注意として、serverModuleのパスは、.ts の生成コード(.js)となります。
パスを含めて出力コードがサーチされるようにserverModuleを指定します。

    // The server is implemented in node
    let serverModule = ctx.asAbsolutePath(path.join('out', 'server', 'server.js'));
    // The debug options for the server
    let debugOptions = { execArgv: ["--nolazy", "--inspect=6009"] };
    // If the extension is launched in debug mode then the debug server options are used
    // Otherwise the run options are used
    let serverOptions: vsclient.ServerOptions = {
      run : { module: serverModule, transport: vsclient.TransportKind.ipc },
      debug: { module: serverModule, transport: vsclient.TransportKind.ipc, options: debugOptions }
    }
    // Options to control the language client
    let clientOptions: vsclient.LanguageClientOptions = {
      documentSelector: [{scheme: 'file', language: 'sv'}],
      synchronize: {
        configurationSection: 'svlog',
        fileEvents: vscode.workspace.createFileSystemWatcher('**/*.{v,sv,vh,svh}')
      }
    }
    // Create the language client and start the client.
    let disposable = new vsclient.LanguageClient('svlog', 'Language server for SystemVerilog', serverOptions, clientOptions).start();

あとは debugOption として、inspectを指定しておくと、そのプロセス番号を参照してVSCodeのデバッガがアタッチでき、サーバーの動きもトレースできるようになります。

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