2022/10/21

NeovimをもっとLuaLuaさせた

この記事は「NeovimをちょっとLuaLuaさせた」の続編である。あれからさらにいくつかのLua製プラグインを導入したので紹介していきたい。本シリーズはinit.luaとpacker.nvimへの移行体験を綴った「NeovimをむっちゃLuaLuaさせた」を以て最終回を迎える予定だ。(大嘘)

……まあたぶん、使用するプラグインがほぼすべてLua製になったとかでない限り、そこまで徹底して鞍替えする気にはならないと思う。なにしろ現在使用しているプラグインマネージャのdein.vimとはずいぶん長い付き合いだし、設定の書き方にもだいぶ慣れている。それに、他のマネージャを選ぶならpacker.nvimよりvim-jetpackの方がミニマルで良さそうだ。いずれにしても今のところ移行の意思はまったくない。

とりわけ既存のプラグインをLua製のものに置き換えていくにあたって、後発とて必ずしも上位互換にはなりえないことが分かったので現状はまだinit.vimとよろしくやっていく形になるだろう。なお、以下に続く設定はあくまで僕個人の例なので注意されたし。大半のプラグインを遅延起動させているため、当該の設定をコピペして用いる場合はdein_lazy.tomlに書かないと機能しない。

indent-blankline.nvim

vim-indent-guidesを置き換えた。インデントの階層を可視化するプラグイン。追加の設定でスペース幅の表示をより詳細にしたりラインをカラフルにもできる。あまりゴチャつくと逆効果ゆえ僕は単純な設定に留めている。

 1#dein_lazy.toml
 2[[plugins]]
 3 repo = 'lukas-reineke/indent-blankline.nvim'
 4 on_event = 'BufEnter'
 5 hook_source = '''
 6 lua << EOF
 7 vim.opt.list = true
 8 vim.opt.listchars:append "eol:↴"
 9 
10 require('indent_blankline').setup {
11     show_end_of_line = true,
12 }
13EOF
14'''

nvim-autopairs

auto-pairsを置き換えた。デフォルト設定での挙動が僕の性に合っていた。名前の通り、括弧やクォートの類を自動で閉じてくれる。Vimに限らずリッチな仕様のエディタやIDEでは当たり前の機能なので、今時は逆に使わない人の方が珍しいんじゃなかろうか。

1#dein_lazy.toml
2[[plugins]]
3 repo = 'windwp/nvim-autopairs'
4 on_event = 'BufEnter'
5 hook_source = '''
6 lua << EOF
7 require('nvim-autopairs').setup()
8EOF
9'''

fidget.nvim

LSPの稼働状況をクールなアニメーションで通知してくれるプラグイン。言語にもよるが意外に助かる時がある。

1#dein_lazy.toml
2[[plugins]]
3 repo = 'j-hui/fidget.nvim'
4 on_event = 'BufEnter'
5 hook_source = '''
6 lua << EOF
7 require('fidget').setup()
8EOF
9'''

lsp_lines.nvim

LSPのdiagnosticsをいい感じに拵えるプラグイン。ビルトイン機能の方はたくさん表示させるとひどく見づらかったが、こういうふうにしてくれると俄然受け入れやすい。正直、このプラグインを知るまでは機能自体をオフにしていた。

1#dein_lazy.toml
2[[plugins]]
3 repo = 'Maan2003/lsp_lines.nvim'
4 on_event = 'BufEnter'
5 hook_source = '''
6 lua << EOF
7 require('lsp_lines').setup()
8EOF
9'''

nvim-hlslens

/での検索後に出るカウンタを改良するプラグイン。該当ワードの真横に連番が現れるのでとても分かりやすい。何回分のnで目当てのワードに飛べるのかも教えてくれる。おかげでnnnnnとか連打しなくても5nで間に合うことが直感的に把握できる。

 1#dein_lazy.toml
 2[[plugins]]
 3 repo = 'kevinhwang91/nvim-hlslens'
 4 on_event = 'BufEnter'
 5 hook_source = '''
 6 lua << EOF
 7 require('hlslens').setup()
 8 local kopts = {noremap = true, silent = true}
 9 
10 vim.api.nvim_set_keymap('n', 'n',
11     [[<Cmd>execute('normal! ' . v:count1 . 'n')<CR><Cmd>lua require('hlslens').start()<CR>]],
12     kopts)
13 vim.api.nvim_set_keymap('n', 'N',
14     [[<Cmd>execute('normal! ' . v:count1 . 'N')<CR><Cmd>lua require('hlslens').start()<CR>]],
15     kopts)
16 vim.api.nvim_set_keymap('n', '*', [[*<Cmd>lua require('hlslens').start()<CR>]], kopts)
17 vim.api.nvim_set_keymap('n', '#', [[#<Cmd>lua require('hlslens').start()<CR>]], kopts)
18 vim.api.nvim_set_keymap('n', 'g*', [[g*<Cmd>lua require('hlslens').start()<CR>]], kopts)
19 vim.api.nvim_set_keymap('n', 'g#', [[g#<Cmd>lua require('hlslens').start()<CR>]], kopts)
20 
21 vim.api.nvim_set_keymap('n', '<Leader>x', ':noh<CR>', kopts)
22EOF
23'''

telescope.nvim

言わずと知れたファジーファインダー界の一大勢力。コピペ設定でもかなり賢く働いてくれるが自己流にカスタマイズするととんでもなく捗る。以前は素のfzf.vimでゴニョゴニョやっていたが、VSCodeよりもVimの使用頻度が高まるにつれて厳しさを感じはじめていた。結局、本プラグインと双璧をなすfzf-preview.vimの作者であるYuki Yano氏のアドバイスが正しかったことになる……。まさに経験者は語るというやつだ。

 1#dein.toml
 2[[plugins]]
 3 repo = 'nvim-telescope/telescope.nvim'
 4 hook_add = '''
 5 nnoremap <leader>. <cmd>lua require('telescope.builtin').find_files({hidden=true})<CR>
 6 nnoremap <leader>l <cmd>lua require('telescope.builtin').live_grep({grep_open_files=true})<CR>
 7 nnoremap <leader>k <cmd>lua require('telescope.builtin').live_grep()<CR>
 8 nnoremap <leader>b <cmd>lua require('telescope.builtin').buffers()<CR>
 9 nnoremap <leader>h <cmd>lua require('telescope.builtin').help_tags()<CR>
10 nnoremap <leader>y <cmd>lua require('telescope.builtin').registers()<CR>
11 nnoremap gd <cmd>lua require('telescope.builtin').lsp_definitions()<CR>
12 nnoremap gr <cmd>lua require('telescope.builtin').lsp_references()<CR>
13 nnoremap gi <cmd>lua require('telescope.builtin').lsp_implementations()<CR>
14 nnoremap gx <cmd>lua require('telescope.builtin').diagnostics()<CR>
15
16 lua << EOF
17 local actions = require("telescope.actions")
18 require("telescope").setup{
19   defaults = {
20     mappings = {
21       i = {
22     ["<esc>"] = actions.close
23       },
24     },
25   },
26 }
27
28 local previewers = require("telescope.previewers")
29 local Job = require("plenary.job")
30 local new_maker = function(filepath, bufnr, opts)
31   filepath = vim.fn.expand(filepath)
32   Job:new({
33     command = "file",
34     args = { "--mime-type", "-b", filepath },
35     on_exit = function(j)
36       local mime_type = vim.split(j:result()[1], "/")[1]
37       if mime_type == "text" then
38         previewers.buffer_previewer_maker(filepath, bufnr, opts)
39       else
40         vim.schedule(function()
41           vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { "BINARY" })
42         end)
43       end
44     end
45   }):sync()
46 end
47
48 require("telescope").setup {
49   defaults = {
50     buffer_previewer_maker = new_maker,
51     extensions = {
52     fzf = {
53       fuzzy = true,
54       override_generic_sorter = true,
55       override_file_sorter = true,
56       case_mode = "smart_case",
57    },
58   },
59  },
60 }
61
62 vim.api.nvim_set_keymap('n', '<leader>,', "<cmd>lua require('telescope').extensions.frecency.frecency()<CR>", {noremap = true, silent = true})
63
64EOF
65'''
66
67[[plugins]]
68 repo = 'nvim-lua/plenary.nvim'

この設定例ではソースとしてファイル検索、絞り込み、バッファ一覧、ヘルプタグ、レジスタ履歴、LSPとの連携機能を利用している。要ripgrep。また、telescope-frecency.nvimを別途導入することで標準のoldfilesより高度なMRU(Most Recently Used)を使えるように仕上げている。現状はこれで十分だが習熟次第ではさらなる拡張の余地がありそうだ。

registers.nvim

コードをヤンクした後に他所でddしたらレジスタが上書きされてしまった! ……なんて面倒を防ぐためのプラグイン。レジスタの中身をすべて一覧表示できる。僕みたいなコピペマンには絶対に欠かせない。Telescopeに乗り換えるまではよくお世話になっていた。デフォルト設定では"キーで展開される。

1#dein.toml
2[[plugins]]
3 repo = 'tversteeg/registers.nvim'
4 hook_add = '''
5 lua << EOF
6 require('registers').setup()
7EOF
8'''

新たに導入したLua製プラグインの紹介はこれで以上となる。おそらくパワーユーザにとっては目新しさに乏しいラインナップだったかと思われるが、半年以上も前に書いた前編が未だに一定のPVを呼び込んでいる様子を鑑みると、こうした基礎的な内容の記事もぼちぼち誰かの助けにはなっていそうだ。書く側としても導入に至った経緯を言語化できるのでまんざら無償の奉仕というわけでもない。今後も折りに触れて書いていくつもりである。

あわせて読ませたい

Neovimを完全にLuaLuaさせた
シリーズ最終章。感動のフィナーレ。

©2011 Rikuoh Tsujitani | Fediverse | Keyoxide | RSS | 小説