2024年に向けてお世話になりたい Neovim プラグイン

# はじめに

世の中は猫も杓子も VSCode。新入社員に hjkl のキー移動を叩き込むなどという謎の修行を課すという光景もめっきり見なくなりました。しかしおじの両手に染み付いた Vim のキー操作はもはや取り去ることはできず、VSCode に移行しようと試みてはやれタブ移動が面倒だとか Vim エミュレーションの動きが気に食わないなどの理由から Vim に出戻りをするということを繰り返してきました。さながらスト６でパッドでモダン操作に入門しようとするが一向に手がなじまず「やっぱり棒だよね」とアケコンを愛でる格ゲーマーのよう。(スト6楽しいですよね)

どうも、Vimmerです。最近、約3年ぶりに Neovim の設定を見直しました。今までは [coc.nvim](https://github.com/neoclide/coc.nvim) を使っていたのですが、最近の Neovim 界隈では Neovim 組み込みの LSP 機能を使ったプラグインが主流になってきており、だいぶ世の中から取り残されている感が出てきたのでプラグインを全て見直しました。本記事では、今回新たに導入した主要なプラグインについて簡単に紹介して行きたいと思います。

# Plugins

## nvim-telescope/telescope.nvim

https://github.com/nvim-telescope/telescope.nvim

所謂Fuzzy Finder。ファイルやバッファー、クイックフィックスなど、様々なソースから情報を検索するUIを提供する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/36b12272-958d-1278-d3e1-adbab8f05e9e.png)


## nvim-telescope/telescope-fzf-native.nvim

https://github.com/nvim-telescope/telescope-fzf-native.nvim

Telescope の sorter として [fzf](https://github.com/junegunn/fzf) を使うためのプラグイン。

## lukas-reineke/indent-blankline.nvim

https://github.com/lukas-reineke/indent-blankline.nvim

Neovim 上でインデント表示を実現する。今まで使っていた `Yggdroot/indentLine` とは異なり `conceal` を使っていないので、JSONファイルでダブルクォートの表示とインデント表示を両立できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/d2183b96-220d-4fa1-866c-fd44e565324b.png)

## nvim-lualine/lualine.nvim

https://github.com/nvim-lualine/lualine.nvim

Status Line 系。[vim-airline/vim-airline](https://github.com/vim-airline/vim-airline) から移行。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/f7ff3d79-e487-f97d-0dac-cd9c02bb8fa5.png)

## nvim-treesitter/nvim-treesitter

https://github.com/nvim-treesitter/nvim-treesitter

言語Parser tree-sitter をNeovimで使うためのプラグイン。VimでのSyntaxハイライトは正規表現などを駆使した条件式で実現されているが、TSX (TypeScript + JSX) に完全に対応したものが無く、しばしばハイライトやインデント制御が正常に機能しない場面に遭遇することがあった。本プラグインを使うことでようやく TSX ファイルをストレスなく編集できるように。

## windwp/nvim-ts-autotag

https://github.com/windwp/nvim-ts-autotag

nvim-treesitter の拡張プラグイン。HTMLタグの閉じタグ補完のために必要。

公式READMEから引用。
```
Before        Input         After
------------------------------------
<div           >              <div></div>
<div></div>    ciwspan<esc>   <span></span>
------------------------------------
```

## anuvyklack/pretty-fold.nvim

https://github.com/anuvyklack/pretty-fold.nvim

Vim の~~見づらい~~質素な折り畳み表現をリッチにしてくれるプラグイン。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/fd5270b2-c1f1-719d-1e83-125ffa2dea30.png)

## anuvyklack/fold-preview.nvim

https://github.com/anuvyklack/fold-preview.nvim

折り畳みを開かずにPreview表示。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/04d9cf34-4815-8d8b-610c-de820bed9ab0.png)

## norcalli/nvim-colorizer.lua

https://github.com/norcalli/nvim-colorizer.lua

"#123", "rgb()" などの色表現テキストに色付け。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/f34aa8e5-ea18-7801-9f9d-03ca6f172bac.png)

## phaazon/hop.nvim

https://github.com/phaazon/hop.nvim

[EasyMotion](https://github.com/easymotion/vim-easymotion) のNeovim実装。画面上の任意の位置にジャンプ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/6daa1dbc-c445-643f-ecae-0a01886e6559.png)

*: これを書いている最中に気が付きましたが、どうやらこちらのプロジェクトは Deprecated になってしまっている模様。継続利用したい場合は [smoka7/hop.nvim](https://github.com/smoka7/hop.nvim) を使ってくださいとのこと。

## karb94/neoscroll.nvim

https://github.com/karb94/neoscroll.nvim

スクロールアニメーションプラグイン。デフォルト設定はスクロール速度が遅いのと、`<C-y>` `<C-e>` の挙動がおかしかったので次のように設定変更。

```lua
require('neoscroll').setup({
  -- Disable <C-e>, <C-y> because I faced a performance issue in a small
  -- window.
  mappings = { '<C-u>', '<C-d>', '<C-b>', '<C-f>' }
})
local t = {}
t['<C-u>'] = { 'scroll', { '-vim.wo.scroll', 'true', '125' } }
t['<C-d>'] = { 'scroll', { 'vim.wo.scroll', 'true', '125' } }
t['<C-b>'] = { 'scroll', { '-vim.api.nvim_win_get_height(0)', 'true', '250' } }
t['<C-f>'] = { 'scroll', { 'vim.api.nvim_win_get_height(0)', 'true', '250' } }
require('neoscroll.config').set_mappings(t)
```

## kylechui/nvim-surround

https://github.com/kylechui/nvim-surround

古くからお世話になっている [vim-surround](https://github.com/tpope/vim-surround) の Neovim 用実装。`"foo"` を `'foo'` や `(foo)` のように囲み文字を置換する。[treesitter と連携することでより便利になるらしい](https://github.com/kylechui/nvim-surround#lock-requirements)が、まだ使いこなせていない。


## numToStr/Comment.nvim

https://github.com/numToStr/Comment.nvim

コメント/アンコメントのトグル。

## windwp/nvim-autopairs

https://github.com/windwp/nvim-autopairs

`{}`, `()`, `""` などのペア文字入力補完。

公式READMEより引用。
```
Before        Input         After
------------------------------------
{|}           <CR>          {
                                |
                            }
------------------------------------
```

## neovim/nvim-lspconfig

https://github.com/neovim/nvim-lspconfig

Neovim の LSP 設定を簡素化するためのプラグイン。詳しくは[こちら](https://github.com/neovim/nvim-lspconfig/wiki#what-is-nvim-lspconfig-does-nvim-lspconfig-provide-a-language-server-client)を参照。

## williamboman/mason.nvim

https://github.com/williamboman/mason.nvim

nvim-lspconfig は LSP の設定を簡単にしてくれるが、Language Server のインストールまでは面倒を見てくれない。Mason を使うことで、各種 Language Server をグラフィカルに、簡単にインストールできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/8d538679-08bf-0823-6116-cab597572191.png)

## hrsh7th/nvim-cmp

https://github.com/hrsh7th/nvim-cmp

LSP、バッファファイルパスなど、様々なソースから入力補完を実現するプラグイン。とりあえず推奨設定に従っておけばよい。デフォルトで提供される Linter/Formatter は[こちら](https://github.com/creativenull/efmls-configs-nvim/blob/main/doc/SUPPORTED_LIST.md#default-configurations)で参照可能。


## creativenull/efmls-configs-nvim

https://github.com/creativenull/efmls-configs-nvim

様々な Linter、Formatter を Neovim に LSP server として組み込むプラグイン。主に ESLint と Pretter のために使用。

## nvim-tree/nvim-tree.lua

https://github.com/nvim-tree/nvim-tree.lua

所謂ファイルエクスプローラー。デフォルトで直感的なキーマッピングが設定されていて使いやすい。`<leader>ee` で現在開いているファイル位置を表示するよう設定。

```lua
init = function()
  vim.keymap.set('n',
    '<leader>ee',
    function() vim.cmd("NvimTreeFindFileToggle") end
  )
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333203/6320cfd9-ad82-33fc-fa53-fb096739a20e.png)

## antosha417/nvim-lsp-file-operations

https://github.com/antosha417/nvim-lsp-file-operations

nvim-tree.lua でファイル名変更などをしたときに、そのファイルを import しているファイルのパス指定部分を自動的に更新。

# coc.nvim からの移行で困ったことと、その対処

## Format on Save

現状、Format on Save 機能を提供しているプラグインが存在しない模様。調べたところ、自前で Autocommand を設定することで実現できるらしい。

https://github.com/neovim/nvim-lspconfig/issues/1792#issuecomment-1352782205

Format してほしくないこともたまにあるので、グローバル変数で無効化できるようにちょっと変更。
```lua
vim.g.format_on_save = 1
vim.api.nvim_create_autocmd("BufWritePre", {
  group = vim.api.nvim_create_augroup('FormatOnSave', {}),
  callback = function()
    if vim.g.format_on_save == 1 then
      vim.lsp.buf.format { async = false }
    end
  end
})
```

## TypeScript での ファイル名変更や import 補完

coc における `CocActionAsync('runCommand', 'editor.action.organizeImport')`, `coc-rename` に相当するコマンドがない。これも自前で定義することで解決。

```lua
local function organize_imports()
  local params = {
    command = "_typescript.organizeImports",
    arguments = { vim.api.nvim_buf_get_name(0) },
    title = ""
  }
  vim.lsp.buf.execute_command(params)
end

local lspconfig = require('lspconfig')
lspconfig.tsserver.setup {
  capabilities = capabilities,
  commands = {
    OrganizeImports = {
      organize_imports,
      description = "Organize Imports"
    },
    RenameFile = {
      rename_file,
      description = "Rename File"
    },
  }
}
```

`rename_file` の方は長いので以下を参照。`organize_imports` もどこかに載っていたものだと思いますが、詳細は失念。

https://github.com/neovim/neovim/issues/20784#issuecomment-1288085253

# 最後に

今回紹介したプラグインを一新したことで大分 Neovim 環境のモダン化ができたと思います。VSCode と違っていろいろと複雑な設定を書かなければいけないし、新しいプラグインのトレンドについていくにも痛みが伴いますが、その分、自分にとって快適な環境が作れますし、なにより、ほぼほぼキーボードだけで操作が完結するスピード感はやはり強みだなと感じます。また、設定ファイルの複雑さに関しても、今回 lua で書き直したことで、だいぶ解消したかなと思います。

本記事があなたの Neovim 環境改善の一助となることを祈って。

以上。