📝
Lua製Neovim plugin開発でhot-reloading的な体験を得る
一度requireされたモジュールはキャッシュされるため、
そのモジュールのコードを変更してもpluginの動作には反映されない。
再起動すれば当然反映されるがめんどくさすぎる。
以下のようにキャッシュを消すと次のrequireではファイルから読んでくれる。
package.loaded["myplugin.mymodule"] = nil
これを利用して、保存時にplugin配下のモジュールのキャッシュを全部削除することでhot-reloading的な体験が得られる。
⚠ Vim scriptのplugin同様にネームスペースとして固有のplugin名を使っていることが前提。
以下がコード例。開発中はlet g:myplugin_debug = 1
を設定して使う。
例だとlua/myplugin/mymodule.lua
を変更して保存するだけでMyplugin
コマンドを試行錯誤できる。
💭 ちなみにcommandやaugroupの定義はluaだとまだ面倒なのでVim scriptで書いている。
plugin/myplugin.vim
command! Myplugin lua require("myplugin/mymodule")()
if get(g:, 'myplugin_debug', v:false)
augroup myplugin_dev
autocmd!
execute 'autocmd BufWritePost' expand('<sfile>:p:h:h') .. '/*' 'lua require("myplugin/cleanup")'
augroup END
endif
lua/myplugin/cleanup.lua
local plugin_name = vim.split((...):gsub("%.", "/"), "/", true)[1]
local dir = plugin_name .. "/"
local dot = plugin_name .. "."
for key in pairs(package.loaded) do
if (vim.startswith(key, dir) or vim.startswith(key, dot) or key == plugin_name) then
package.loaded[key] = nil
end
end
リポジトリのコードに含めずとも、autocmdのpath部分を書き換えればlocal用の設定として動作する。
個人的にはテストコードのafter_eachでもcleanup.luaを実行するため、
また、どの環境でも変数1つ定義するだけで開発するためにリポジトリのコードに含めている。
Discussion