Vimの補完プラグインをインストール。その2

Vimでpython-language-serverが動くようになりましたが、もう一つの本題が、いまいじってるvimrcをサポートしてくれるvim-language-server。これがnpmモジュールなんですね、実は。だって自分はTypeScript使わないから、npmもインストールしたくないし。なので、すでにDenoをインストールしているので、このvim-language-server(長いからvimlsにします)をDenoで使えないか、というあたりを攻めてみます。

Dinoは1.25以降でnpmモジュールをサポートするようになったということで、ちょっとこちらの解説を見ても今ひとつピンとこないのですが、要するにimport文やrunコマンドでnpmモジュールを指定することで、npm install相当のことをやってくれて実行できる、ということのようです。

$ pacman -Qs deno
local/deno 1.46.2-1
    A secure runtime for JavaScript and TypeScript
$ deno run npm:vim-language-server --help
✅ Granted env access to "XDG_RUNTIME_DIR".
✅ Granted sys access to "cpus".
error: Uncaught Error: Connection input stream is not set. Use arguments of createConnection or set command line parameters: '--node-ipc', '--stdio' or '--socket={number}'
(スタックトレースは省略)
$ deno run npm:vim-language-server --stdio
✅ Granted env access to "XDG_RUNTIME_DIR".
✅ Granted sys access to "cpus".

実際にはvimlsの他にstreamモジュールも必要だったので、コマンドラインからインストールしています。

$ deno
Deno 1.46.3
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> import "npm:stream"
[Module: null prototype] {
  default: <ref *1> [Function: Stream] { Stream: [Circular *1] }
}
>

importするだけでインストールしてくれるので、楽ちん。もっとも、pacmanを使わないので、アップデートはどうするんだろうとかありますが。"npm:stream@0.0.3"とかするとバージョン指定できるので、それでやるのかな。ちなみにnpmモジュールは${XDG_CACHE_HOME}/deno/npm/registry.npmjs.org/の下にダウンロードされるようです。ついでに言えば、globalインストールする方法は調べてません。

それでは、vimlsをDenoで起動してみます。

$ deno run npm:vim-language-server
┏ ⚠️  Deno requests env access to "XDG_RUNTIME_DIR".
┠─ Learn more at: https://docs.deno.com/go/--allow-env
┠─ Run again with --allow-env to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) >

なんか許可するかどうするか聞いてきました。

Denoはセキュリティ強化の観点で、環境変数やファイルへのアクセス許可、実行許可などなど、いろいろ聞いてきます。vimlsは裏で起動してくれないと困るので、プロンプトを出さないようにするためにはオプション指定が必要です。-A を指定すると、全部まとめて許可!とかやってくれるみたいですが、推奨は個別指定なので、以下のようにしました。

$ deno run --allow-sys --allow-env --allow-read --allow-run npm:vim-language-server --stdio

--allow-readと--allow-runはvim-lspから起動されるときに必要になります。またvimlsは通信方法を指定しなくてはいけないので、--stdioを指定しています。上記のコマンドで起動すると、標準入力からの入力待ちになります。ということで起動まではOK。

vimlsの起動方法がわかったので、vimrcに設定していきます。

その1ではPythonの設定をしたのでそこから始めますが、それに先立って Neovim のCheckHealthと同等のチェックをしてくれるvim-healthcheckをインストールしておきます。language serversの状態も表示してくれるので、動いているかどうかの確認は簡単にできます。

call dein#add('rhysd/vim-healthcheck')

次に、vim-lspからlsp#regster_serverに食わせるために起動コマンドを記述するのですが、どうもnpmでvimlsをインストールした場合には vim-language-server というシンボリックリンクを作成してそれを起動しているみたいです。今回はDenoから起動する必要があるので、~/binにvim-language-serverというシェルスクリプトを作成して、それを起動することにします。

$ cat ~/bin/vim-language-server
#!/bin/sh
deno run --allow-sys --allow-env --allow-read --allow-run npm:vim-language-server --stdio

当然PATHも通しておきます。

そしてvimrcはこんな感じ。

if (executable('vim-language-server'))
    augroup LspVim
        autocmd!
        autocmd User lsp_setup call lsp#register_server({
            \ 'name': 'vimls',
            \ 'cmd': {server_info->['vim-language-server']},
            \ 'allowlist': ['vim'],
            \ 'initialization_options': {
            \   'vimruntime': $VIMRUNTIME,
            \   'runtimepath': &rtp,
            \   'diagnostic': {'enable': v:true}
            \ }})
    augroup END
endif

最初は'cmd' に 'deno', 'run', ... などと試してましたが、シェルスクリプトを作成するのが一番シンプルだなと思いまして。

これでvimrcを開いて :CheckHealth すると、

lsp: health#lsp#check
=====================
## server status
  - WARNING: pylsp: not running
  - OK: vimls: running

## server configuration: pylsp
  - INFO:
    ### allowlist
    ['python']

## server configuration: vimls
  - INFO:
    ### allowlist
    ['vim']

と表示するようになりました。

そのうちRuffも入れてみようと思います。Ruffはpacmanからインストールできて、python-lsp-serverにプラグインとして組み込めるようなので、BlackやFlake8と同等の設定ができればいいなと考えています。

あと、Vimのmessages、cmdline、popupmenuを置き換えるNoiceというのもあるようで、これはおいおい試してみます。

Vimの補完プラグインをインストール。その1

 もちろんNeovimがいいんだけれど、NeovimとVimは設定を分けることができるし、ディストリビューションで標準でインストールされてるのはVimなことが多いので、Vimの環境づくり。

ちなみに現在のVimバージョンは9.1.707です。

さて、Vimの補完プラグインですが、Shougoさんが作成していたneocomplete.vimは終了し、deoplete.nvimを経て、現在はddc.vimが開発を続けられています。なので、補完フレームワークはddc.vimにして、そうするとLSPとかfileとかいろいろと補完ソースに指定することができるはず。

AURを見るとvim-ddc 0.17.0-1というパッケージソースがあるようなので、dpp.vimのようなプラグインマネージャを利用するか、pacman(自前パッケージ)を利用するか悩むところですが、AURからextraになることもないだろうし、そうするとアップデートも自分でチェックしてやることになって面倒が増えるだろうから、プラグインマネージャで行う方針にします。とりあえずはdpp.vimで考えてみることに。

ddc.vimもそうですが、dpp.vimもDenoを利用し、そのためにdenops.vimをインストールする必要があるので、まずはDenoをインストールします。こちらはpacmanでさっくり。

次にdenops.vimですが、こちらはvim-plugのようなプラグインマネージャでインストールして、と書いてあります。vimballが提供されていれば楽なんですが…。プラグインマネージャのdpp.vimをインストールするにはdenops.vimが必要で、denops.vimをインストールするにはプラグインマネージャが必要という鶏卵問題。

もうちょっとお手軽にいかないかな、と考えた結果、メンテナンスフェーズに移って開発は終了していますがdein.vimを使用することにしました。lazy.nvimに手を出してみたいけど、こちらはVimでは動かないようですし。

ということで、Dein-installer.vimの手順でインストールします。curlなら標準でインストールされているので、curlのほうで行います。さっくり。

すると$HOME/.vimrcに書くべき設定を表示してくれるので、これを.config/vim/vimrcにコピペします。ぺたぺた。

でもってdein#addのところにインストールしたいプラグインを記述します。

call dein#add('vim-denops/denops.vim')
call dein#add('vim-denops/denops-helloworld.vim')

vimrcをリロードしたら、:call dein#install() して、:DenopsHelloしてみると、ちゃんと挨拶を返してくれました。

次はddc.vimです。こちらはフレームワークなので、Vimの場合にはポップアップメニューを表示するための仕組みが必要になるので、pum.vimも必要です。それと、pumのUIを定義するためにddc-ui-pumも必要です…と言い切っちゃっていいのかどうかよくわかりませんが、一応インストールします。

call dein#add('Shougo/ddc.vim')
call dein#add('Shougo/pum.vim')
call dein#add('Shougo/ddc-ui-pum')

また、ddc.vimで入力補完を利用するにはソースプラグインとフィルタプラグインが必要です。ddc.vimはあくまでフレームワークなので。

call dein#add('Shougo/ddc-filter-sorter_rank')
call dein#add('Shougo/ddc-source-around')
call dein#add('Shougo/ddc-filter-matcher_head')

フィルタ用の設定も書き足します。

call ddc#custom#patch_global('sourceOptions', #{
      \   _: #{
      \     sorters: ['sorter_rank'],
      \   }
      \ })
call ddc#custom#patch_global('sourceOptions', #{
      \   around: #{ mark: 'A' },
      \ })
call ddc#custom#patch_global('sourceParams', #{
      \   around: #{ maxSize: 500 },
      \ })

ここまでは下準備で、次がようやく当初の目的のLSP(Language Service Protocol)のインストールです。

よく使うのはPythonなので、まずはPythonからいってみます。

PythonのLSPはMicrosoftのPyrightやPylanceなどもありますが、PyrightもPylanceはTypeScriptで記述されており、動作にはnode.jsが必要です。今回はnode.jsではなくDenoで行きたいので、これはなしの方向で。

ということで、Python LSP Serverことpylspを導入します。pylspはpipでもインストールできますが、pipだと前述したようにアップデートの管理が面倒なので、ArchLinuxのパッケージになっているpython-lsp-serverをインストールします。python-lsp-serverはSpyderプロジェクトにて開発されていたもので、Pythonで記述されているため、速度的には遅いもののnode.jsやnpmは不要です。

# sudo pacman -S python-lsp-server

また、Vim側でLSPをお話するLSPクライアントのプラグインであるvim-lspをインストールします。vim-lspはVimスクリプトで記述されていますが、重たい動作の部分をluaで実装しているため、Vimがluaをサポートしていないと利用できません。幸いArchLinuxのVimは+luaでコンパイルされているので問題なし。

call dein#add('prabirshrestha/vim-lsp')

vim-lspを使ったLSPの設定を用意にするために、vim-lsp-settingsを使ってもよいのですが、実はこれを使うとちょっとnode.jsがゴニョゴニョっぽいので自前で用意します。といっても、vim-lspのページのRegistering Serversの設定をコピペするだけ。なのでコードは省きます。これはpylsp用の設定なので、その他のLSPサーバを利用するときはそれ用の設定を加えないといけませんが、それはまたあとで。

ここまでやれば、あとはddc.vimに渡してやると動くようになります。

call ddc#custom#patch_global('sourceOptions', #{
      \   vim-lsp: #{
      \     matchers: ['matcher_head'],
      \     mark: 'lsp',
      \   },
      \ })

call ddc#custom#patch_global('sources', ['around', 'vim-lsp'])
call ddc#enable()

最後のddc#enable()をcallしないと動きませんが、結構忘れがち。これで .py のファイルを編集するときには自動でpylspが動きます。

とりあえずは動いたので、チューニングなどはおいおい :h vim-lsp などしてやっていきます。

ちなみにちなみに、Python用の高速なlinter/formatterのruffをpylspのプラグインとして利用するpython-lsp-ruffというのもあるようですが、これもまたあとで。これまで使っていたBlackとFlake8を置き換えられるかどうかの検討が必要かなと。Pythonの Ruff (linter) でコード整形もできるようになりましたでは

要約: Flake8 + Black + isort はもうすべて Ruff だけで置き換えられる。

などとあるのでちょっと気になってます。ちなみにruffはRustで書かれていますが、Rustってripgrepのアレだよねぇ、と高速っぽい印象バイアスかかってます。

それとは別に、python-lsp-blackというのもあり、こちらはBlackを使うプラグインです。どっちがいいんだろうか。それと静的型チェックを行うmypyのプラグインpylsp-mypyなんてのもあります。いずれにしてもまたあとで。

ArchLinux on WSLでどたばた。

Windows11のノートPCで、WSLでArchLinuxをインストールしようと思ってちょっと引っかかったところがあったのでメモ。

インストール自体はArchWSLのページの通りで進みましたが、pacman -Syu するとtrusted keyが云々でできませんでした。

そこで、/etc/pacman.d/gnupgをディレクトリごと削除し、また$HOMEにある .gnupg も削除してリブート、次に pacman-key --init してから、pacman-key --populate archlinux すると、archlinux.orgのarchlinux.gpgを追加してくれるので、以降は pacman -Syu できるようになりました。

  1. /etc/pacman.d/gnupgをディレクトリごと削除
  2. $HOMEにある .gnupg も削除
  3.  pacman-key --init
  4. pacman-key --populate archlinux
これ、しばらくぶりにアップデートしようとするとハマるんですよね。

Vimの補完プラグインをインストール。その4

Vimの補完プラグインをインストール。その3 で、 ddc-tabnine が使えそうです、などと書いたのですが、早速やってみました。 まず、tabnineのバイナリを用意しないといけません。がどうにもTabNineのサイトがわかりにくいので、 tabnine-nvim にあるダ...