[Neovim] filetype毎の設定をluaの関数単位で分ける
はじめに
以前このような記事 を書きました。
filetype毎の設定をVim scriptを使って関数単位に分けたのですが、
最近Neovimを使い始めたので、luaでも同じような設定を書いてみました。
luaで作る
例として 以下を作ってみます
-
filetype=help
の場合q
でwindowを閉じれるように設定 -
filetype=java
の場合- indentの幅4
- タブではなくスペースでインデント
-- $XDG_CONFIG_HOME/nvim/init.lua
local my_filetype = require('my.filetype')
vim.api.nvim_create_augroup('vimrc_augroup', {})
vim.api.nvim_create_autocmd('FileType', {
group = 'vimrc_augroup',
pattern = '*',
callback = function(args) my_filetype[args.match]() end
})
init.luaでは $XDG_CONFIG_HOME/nvim/lua/my/filetype.lua
を読み込みます。
読み込んだモジュールの各要素にはfiletype毎の関数が設定されているので、FileTypeイベントをトリガーにモジュール内の関数を呼び出します( my_filetype[args.match]()
の部分です。 args.match
には"help"や"java"等のfiletype毎の文字列が入ってきます)
次にfiletype.luaを作成します。
-- $XDG_CONFIG_HOME/nvim/lua/my/filetype.lua
local M = {}
local function set_indent(tab_length, is_hard_tab)
if is_hard_tab then
vim.bo.expandtab = false
else
vim.bo.expandtab = true
end
vim.bo.shiftwidth = tab_length
vim.bo.softtabstop = tab_length
vim.bo.tabstop = tab_length
end
M.help = function()
vim.api.nvim_buf_set_keymap(0, 'n', 'q', 'ZZ', { noremap = true })
end
M.java = function()
set_indent(4, false)
end
return setmetatable(M, {
__index = function()
return function()
print('Unexpected filetype!')
set_indent(2, false)
end
end
})
Mというtableにfiletype毎の関数を詰めて返しています。
(M.helpには filetype=help
用の関数を詰めています)
luaのmetatableを使ってみたかったので、想定していないfiletypeのbufferを開いた場合何かしらの関数が呼び出せるよう作りこんでいます。setmetatableで __index
キーに関数を設定するだけで完了でした。簡単...!
終わりに
metatableには __index
というキー以外にも __add
や __call
というキーも存在します。面白い。。触れる機会は当分先だと思いますが、luaでジェネレータも作れるようで、色々作ってみたいですね。
sumneko/lua-language-serverを使えば書き心地も問題なく、annotationを指定すれば型チェックも行ってくれます
元々luaはおろかNeovimも触れていなかったので、init.luaへの移植やbuiltin LSPの使い方についても慣れていない部分が多いですが、今のところは楽しく書けているので引き続きNeovim & luaで何かしらを書いていきたいと思います。
Discussion