🛠️

LSP 完全に理解した(ddu-source-lsp)

2023/06/19に公開

これは Vim駅伝 6/19の記事です。

はじめに

「ddu.vim で LSP を使うならこれ!」という決定版を作ったので宣伝します。

https://github.com/uga-rosa/ddu-source-lsp

機能紹介

Vim/Neovim両対応で、主要なクライアントは全て対応しました。

また、FF で使えそうなメソッドは全て対応しました。
Telescope.nvim の LSP 部分のスーパーセットです。
具体的には

  • lsp_definition
    • 定義ジャンプ。以下の4つを切り替え可能
      • textDocument/definition(定義)
      • textDocument/typeDefinition(型定義)
      • textDocument/declaration(宣言)
      • textDocument/implementation(実装)
    • 似たような機能なのでまとめています
    • 基本的に lsp_*kind-lsp を使用します
      • Action は openquickfix が利用可能です
      • :h ddu-kind-lsp
    • ddu-ui-ff 側の設定で、候補が一つの時は選択なしでジャンプさせることもできます
      • :h ddu-ui-ff-param-immediateAction
  • lsp_references
    • カーソル下の変数を参照している箇所の一覧
  • lsp_documentSymbol
    • カレントバッファ内のシンボル一覧
    • ハイライトとアイコンを付けていい感じの見た目にする filter-converter_lsp_symbol もこっそり同封してます
  • lsp_workspaceSymbol
    • ワークスペース内のシンボル一覧
    • 動的な絞り込みにも対応しています
  • lsp_callHierarchy
    • 関数の呼び出し関係を木構造で表示します
    • incomingCalls と outgoingCalls の二方向があります
    • ツリーの展開には ddu-ui-ff-action-expandItem を使います
  • lsp_typeHierarchy
    • 型の継承関係を木構造で表示します
    • supertypes と subtypes の二方向があります
    • こちらも展開には expandItem を使います
  • lsp_codeAction
    • 現在の選択範囲からコードアクションの一覧を取ります
      • <Cmd> を使ったマッピングで ddu#start() を呼び出さないと、正しく範囲が取れません
      • ノーマルモードからでも使えます
    • 他のソースとは異なる専用 kind (kind-lsp_codeAction) を使用するので注意してください
      • Action は apply しかありません。
    • プレビューとして、そのコードアクションを実行する前後の差分が見れます
  • lsp_diagnostic
    • バッファ番号を指定して診断結果の一覧を見れます。
    • 今のバッファ(0)や全てのバッファ(null)という指定もできます

リファレンス実装として作者の dotfiles も載せておきます。
doc と合わせて参考にしてもらえると幸いです。
https://github.com/uga-rosa/dotfiles/blob/main/nvim/lua/rc/plugins/ddu/source-lsp.lua

(lsp_diagnostic 以外の) 全てのソースで、LS が返してきた生のデータを item.data にセットしているので、興味のある方は遊んでみてください。
filter-converter_lsp_symbol のようなことができます。

おまけ

このプラグインは TypeScript で実装しています。
LSP 関連のプラグインを TypeScript で実装する利点は、公式の提供する型を使えることです。
https://www.npmjs.com/package/vscode-languageserver-types

ここの体験がかなり良かったので、今後も LSP 関連のものを作るなら TypeScript (denops.vim) を選ぶと思います。

おわりに

元々は ddu-source-nvim-lsp として作り始めました。
しかし調べてみると、既存の LSP 関連の ddu-source はどれも対応メソッドが少ないことが分かりました。
どうせほぼ生のリクエストを扱うのであれば、vim-lsp や coc.nvim も対応して全ての ddu ユーザーが使えるようにしようと頑張ってみました。
木構造までサポートした FF は他にはないので、Vim/Neovim の FF 界隈全体を見てもトップクラスの出来になったと自負しています。
是非使ってみてください!

GitHubで編集を提案

Discussion