pynvim を使って自作 neovim プラグインを作る

neovim の python プラグインである pynvim を使って自作プラグインを作ります。なお、今回は Lazyvim でプラグインを管理するところまで行います。

Last Modified: 2025/02/25



まず前提として neovim で python が使えるか確認をします。
neovim の編集画面で “:checkhealth” を実行し、以下のように python3 (or python2) が実行可能であることを確認します。
実行可能でない場合はインストール、および PATH を通してください。

Python 3 provider (optional) ~
- `g:python3_host_prog` is not set. Searching for python3 in the environment.
- Executable: /usr/bin/python3
- Python version: 3.9.20
- pynvim version: 0.5.2
- OK Latest pynvim is installed.

pynvim をインストールします。

$ pip install pynvim

インストールができたら早速作成します。

今回は $HOME/study/test-plug というディレクトリを作り、プラグインを作ります。 また、rplugin/python3/<プラグイン名> のディレクトリを作ります。(python 2 を使う場合は python3 ではなく python になります) 今回は mymodule という名前のプラグインとします。

$ pwd
/home/ec2-user/study/test-plug
$ mkdir -p rplugin/python3/mymodule

mymodule ディレクトリ配下に plugin.py ファイルを作成します。 ここではプラグインの動作を記載します。

import pynvim
import pynvim.api


@pynvim.plugin
class MyPlugin:
    def __init__(self, nvim: pynvim.api.Nvim):
        self.nvim = nvim

    @pynvim.command("ModuleHelloWorld")
    def hello_world(self) -> None:
        self.nvim.command("echom 'MyPlugin: Hello World!'")

詳しい説明はドキュメント に譲るとして、上記のコードは neovim 内で “:ModuleHelloWorld” コマンドを実行した時に “MyPlugin: Hello World” を出力するようにします。

そして、mymodule ディレクトリ配下に __init__.py ファイルを作成して plugin.py が読み込まれるようにします。

import mymodule.plugin 

from .plugin import MyPlugin as MyPlugin

assert mymodule.plugin.MyPlugin is MyPlugin

ここまでで以下のようなディレクトリツリーになってると思います。

$ tree
.
└── rplugin
    └── python3
        └── mymodule
            ├── __init__.py
            └── plugin.py

これでプラグインの作成は完了です!簡単ですね!

完成したら Lazyvim でプラグインをロードするように設定します。 。 以下のように dir にプラグインがあるディレクトリを指定します。

return {
	{
		dir = "/home/ec2-user/study/test-plug",
		build = "pip install pynvim",
		dev = true,
	},
}

最後に neovim 内で “:UpdateRemotePlugins” を実行することでロードされます。

これで “:ModuleHelloWorld” を実行して “MyPlugin: Hello World” が表示されれば成功です。

ModuleHelloWorld

なお、以下のように vimrc で記載した設定以外を読み込まないようにし、排他的に設定の確認ができます。

$ pwd
/home/ec2-user/study/test-plug
$ cat vimrc
let &runtimepath.=','.escape(expand('<sfile>:p:h'), '\,')
$ nvim -u ./vimrc

また、~/.local/share/nvim/rplugin.vim をみて、ちゃんと plugin が読み込まれているか確認できます。 自分の環境では以下のようになっていました。

" python3 plugins
call remote#host#RegisterPlugin('python3', '/home/ec2-user/study/test-plug/rplugin/python3/mymodule', [
      \ {'sync': v:false, 'name': 'ModuleHelloWorld', 'type': 'command', 'opts': {}},
     \ ])

さらに、neovim 内で “:scriptnames” を実行してプラグインが読み込まれているか確認することもできます。

:scriptnames

...
 13: ~/.local/share/nvim/rplugin.vim
...

参考