⛳
dein.vimをNeovim Luaから使う
deinのtomlのような設定をlua tableで行う
deinではtomlで設定を記述できますが、deinではtomlでしか書けない記法はほぼ無く、dein#add(repo[, options])
でoptionsにDictionaryを渡しているのと同じようになっているので
vim.fn['dein#add']('vim-jp/vimdoc-ja', { merged = false })
のようにすればluaでdeinの設定を記述することが可能なはずです。
dein.luaの用意
vim.fn['dein#add']()
にプラグインの設定を渡せば良いです
local function add_plugin(repo, opts)
if opts ~= nil then
vim.fn['dein#add'](repo, opts)
else
vim.fn['dein#add'](repo)
end
end
dein#load_toml({filename}, [{options}])
と同じように使えるものを用意します。
local function load_configs(configs, shared_opts)
-- { ['vim-jp/vimdoc-ja'] = { merged = false } }
-- のようなテーブルがconfigsに渡されてくる想定
for repo, opts in pairs(configs) do
opts.repo = opts.repo or repo
-- shared_optsが渡されたらoptsにマージするが、optsで同名
-- の項目を入力していたらそれを優先したい
if shared_opts ~= nil then
for opt_name, value in pairs(shared_opts) do
opts[opt_name] = opts[opt_name] or value
end
end
add_plugin(repo, opts)
end
end
dein-tomlなら[plugins.ftplugin]
が書けると嬉しいです。
local gid = vim.api.nvim_create_augroup('__vimrc_ftplugin__', { clear = true })
--- @param ft string
--- @param plugin function
--- @param id string
local function add_ftplugin(ft, plugin, id)
vim.api.nvim_create_autocmd('FileType', {
group = gid,
pattern = ft,
callback = function(context)
local did_ftplugin = vim.b.did_user_ftplugin or {}
-- ftpluginでbuffer localなautocmdとか
-- 定義しようとしたとき、何度も実行されると
-- 困るのでdid_ftpluginを使う。
-- 複数のプラグインが同じfiletypeに対して設定をする
-- ことも考えたいのでdictionaryで持つ
if not did_ftplugin[id] then
plugin(context)
-- vim.b.did_user_ftplugin[opts.name] = true
-- ↑みたいに書いても動かなかった
did_ftplugin[id] = true
vim.b.did_user_ftplugin = did_ftplugin
end
end,
})
end
local function load_configs(configs, shared_opts)
-- { ['vim-jp/vimdoc-ja'] = { merged = false } }
-- のようなテーブルがconfigsに渡されてくる想定
for repo, opts in pairs(configs) do
opts.repo = opts.repo or repo
+ opts.name = opts.name or
+ vim.fn.fnamemodify(repo, [[:s?/$??:t:s?\c\.git\s*$??]])
-- shared_optsが渡されたらoptsにマージするが、optsで同名
-- の項目を入力していたらそれを優先したい
if shared_opts ~= nil then
for opt_name, value in pairs(shared_opts) do
opts[opt_name] = opts[opt_name] or value
end
end
+ if opts['ftplugin'] ~= nil then
+ --- @param ft string
+ --- @param plugin function
+ for ft, plugin in pairs(opts['ftplugin']) do
+ add_ftplugin(ft, function(context)
+
+ -- プラグインが読み込まれていないときは実行したくない
+ if vim.fn['dein#is_sourced'](opts.name) ~= 0 then
+ plugin(context)
+ end
+
+ end, opts.name)
+ end
+ opts['ftplugin'] = nil
+ end
add_plugin(repo, opts)
end
end
設定例
ここまで設定すれば、tomlで管理していたときと同じ雰囲気で設定を書けます。
load_configs()
を呼び出すところの周りにvim.fn['dein#begin']()
とか書いて関数を作り、その関数に設定が入っているtableを渡すように書いてやります。
以下は、fern.vimを設定している例です。
local plugins = {}
plugins['lambdalisue/fern.vim'] = {
on_cmd = 'Fern',
hook_add = function()
vim.api.nvim_create_user_command('MapFern', function()
nmap('<Plug>(filer:fs)', function()
if vim.g.fern_use_drawer then
vim.cmd.Fern { args = { '.', '-drawer', '-reveal=%' } }
vim.cmd.wincmd '='
else
vim.cmd.Fern { args = { '.', '-reveal=%' } }
end
end)
end, {})
vim.g.fern_use_drawer = false
end,
hook_source = function()
vim.g['fern#hide_cursor'] = true
vim.g['fern#keepalt_on_edit'] = false
vim.g['fern#keepjumps_on_edit'] = false
vim.g['fern#default_hidden'] = true
vim.g['fern#disable_default_mappings'] = true
end,
ftplugin = {
['fern'] = function(au_ctx)
local buflocal = {
buffer = au_ctx.buf,
nowait = true,
silent = true,
}
fn.map {
mode = 'n',
opts = buflocal,
maps = {
{ '<Space>', '<Plug>(fern-action-mark:toggle)' },
{ '<C-l>', '<Plug>(fern-action-reload:all)' },
{ 'h', '<Plug>(fern-action-collapse)' },
{ '<Enter>', '<Plug>(fern-action-open)' },
{ 'y', '<Plug>(fern-action-yank:path)' },
{ '<C-c>', '<Plug>(fern-action-cancel)' },
{ 'N', '<Plug>(fern-action-new-file)' },
{ 'K', '<Plug>(fern-action-new-dir)' },
{ 'd', '<Plug>(fern-action-trash)' },
{ 'gr', '<Plug>(fern-action-grep)' },
{ 'r', '<Plug>(fern-action-rename)' },
}
}
vim.cmd "nnoremap <buffer><nowait><silent><expr> l fern#smart#leaf('<Plug>(fern-action-open)', '<Plug>(fern-action-expand)')"
if vim.g.fern_use_drawer then
autocmd('WinLeave', {
group = augroup('FernRc', { clear = true }),
buffer = au_ctx.buf,
command = 'close',
})
nmap('q', '<Cmd>Fern . -drawer -toggle<CR>', buflocal)
else
nmap('q', '<C-o>', buflocal)
end
end,
},
}
return plugins
おわりに
ここまで紹介しておいてなんですが、実はこの設定をするとdein#save_state()
& dein#load_state()
が使えなくなるので、起動が基本的には遅くなります。
(僕のケースでは、init.lua化したことで多少速くなった分があっても40msくらい遅くなりました。)
しかし、sumneko-lua
やfolke/neodev.nvim
が使えるようになって、かなり快適に設定が書けるようになりました。
設定ファイルの携帯性は著しく下がりますが、興味のある方は是非。
Discussion