VimからNeovimに移行して感じたこと

この記事は[Vim Advent Calender2022](https://qiita.com/advent-calendar/2022/vim)の21日目の記事です。

去年の年末にVimからNeovimに移行してから、もうすぐで1年くらい経つので、気づいたことをまとめてみることにしました。
以下に該当する方は読んでいただくと何か発見があるかもしれません。

- VimとNeovimの違いがよくわかっていない人
- Neovimの特徴をざっと知りたい人
- VimからNeovimに移行したいと考えている人

## そもそもNeovimって何ぞや？

Neovimとは、簡単に説明すると**先進的な機能や拡張性を取り入れたVimから派生したエディタです。**
目立ったVimとの違いとして以下の点が挙げられます。

- Vimの設定にLuaというスクリプト言語が使用できる
- 本体の起動速度がVimより僅かに速い
- Neovimでしか使用できないプラグインを使用できる

Neovimが誕生した経緯ですが、後方互換を大事にする保守派とモダンな機能をガンガンVimに取り入れていきたい先進派が別れた結果、ユーザーコミュニティの内部分裂に近い形で誕生したらしいです。

https://twitter.com/shougomatsu/status/1555708916105093120

## Neovimの特徴

個人的にVimと違うなと思った点を書いてきます。

### プラグインの数が豊富

自分がVimからNeovimに移行した最大の理由はこれです。
NeovimはVimプラグインの大半がそのまま使用できる上に、**Neovimでしか使用できないプラグインもあるため、使用できるプラグインはVimに比べて豊富です。**

自分が使っているNeovim用のプラグインの中で、特に気に入っているのは以下のプラグインです。

- [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)・・・シンタックスハイライト用のプラグイン
- [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)・・・ファジーファインダー系のプラグイン

nvim-treesitterは**コードのシンタックスハイライトを楽に設定できるプラグインです。**

Vimを使っていた時はデフォルトのシンタックスハイライトが見づらいものが多かったので、ライブラリ（ReactとかVueとか）ごとにしンタックスハイライト用のプラグインを使用していたのですが、nvim-treesitterを導入してから、シンタックスハイライトはこのプラグインだけで完結できるようになりました。

telescope.nvimは**現在いるディレクトリを起点にファイルや特定の文字列（[ripgrep](https://github.com/BurntSushi/ripgrep)が必要）を曖昧検索することができるプラグインです。**

このプラグインを使用するようになってから、目的のファイルに辿り着くまでの速度が劇的に速くなりました。

### カラースキームも見やすいものが多い

使えるプラグインが多いに重複する部分ではありますが、**カラースキームもVimより見やすいテーマが多いと感じました。**
自分が使用した中だと、特に以下のテーマは見やすいと感じました。

- [github-nvim-theme](https://github.com/projekt0n/github-nvim-theme)
- [nightfox.nvim](https://github.com/EdenEast/nightfox.nvim)

現在は、nightfox.nvimを愛用しています。

### ターミナルモードが使いやすい

Neovimのターミナルモードは現在のバッファをそのまま使うような挙動になっているので、Vimのターミナルモードよりもかなり使いやすいと感じました。
Neovimに移行してから、Neovimのターミナルで作業を行う機会が多くなったと思います。

Vimにもターミナルモードは存在しますが、splitしてから画面上部にターミナルを開くような挙動になっているため、現在のバッファを使うかどうかはオプションで設定する必要があります。

参考までに自分は以下のようなキーマッピングを設定しています。

```lua
local keyset = vim.api.nvim_set_keymap
local user_command = vim.api.nvim_create_user_command

-- TerminalをVSCodeのように現在のウィンドウの下に開く
vim.api.nvim_create_autocmd({'TermOpen'}, {
  command = 'startinsert',
})

-- 常にインサートモードでTerminalを開く（水平分割）
user_command('T', 'sp | wincmd j | resize 20 | terminal <args>', { nargs = '*' })
keyset('n', 'T', ':T <cr>', { noremap = true })

-- 常にインサートモードでTerminalを開く（垂直分割）
user_command('TS', 'vs | wincmd j | resize 100 | terminal <args>', { nargs = '*' })
keyset('n', 'TS', ':TS <cr>', { noremap = true })

-- インサートモードからの離脱をspace + qにマッピング
keyset('t', '<Space>q', '<C-\\><C-n>', { silent = true })
```

### 設定をLuaで書ける

Vim自体の設定をVim scriptではなく、**Luaで書けるのもNeovimの大きなメリットの一つです。**
~~Vim scriptかきにくい...~~

語弊が生じるような書き方かもしれませんが、何らかのスクリプト言語が分かればフィーリングである程度書けるLuaでVimの設定をゴリゴリ書いていけるのは便利だなと感じました。

### その他

その他だと、今年の3月頃にエディタを縦並びで開いているときにもステータスラインが１つになる機能が実装されたのですが、画面がシンプルになってとても見やすくなりました。
→Vimだと、画面を分割するとステータスラインも分割されてしまいます。

https://github.com/neovim/neovim/issues/9342

自分は以下のような設定を行なっています。

```lua
vim.opt.laststatus = 3
```

[lualine.nvim](https://github.com/nvim-lualine/lualine.nvim)を使っている場合は以下の設定も必要です。

```lua
use {
  'nvim-lualine/lualine.nvim',
  config = function() {
    require('lualine').setup({
      options = {
        globalstatus = true,
	  }
    })
  }
}
```

**画面を分割しても、ステータスラインがめっちゃスッキリして良きです**
![スクリーンショット 2022-12-19 0.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375389/4f18e32c-b218-9393-6413-c46dac5d03ce.png)

あとは、Insertモード時のカーソルのUIが```|```になっていて見やすくなっている部分とかは地味に気に入ってます。

## 移行コストに関して
書いてる設定の量や使用しているプラグインの数に依存するとは思いますが、Vim scriptのまま移行する場合は、設定ファイルの置き場を```~/.config/nvim/```に変更して、プラグインをインストールし直せばいいだけなので、そこまで面倒ではないと思います。
お試しでNeovimを使ってみるとかだったら、この方法がおすすめだと思います。

設定ファイルを全てLuaで書き換える場合はまあまあ面倒だと思います。
Neovim用のプラグインの設定はLuaを使用する前提で書かれているので、Neovimをメインで使用していく場合は、Luaで設定を書くようにした方がいいと思います。
参考までに、自分は以下のような手順で移行を進めました。

1.  dotfilesの中に```~/.config/nvim/init.lua```を作成して、シンボリックリンクを作成
1.  LuaでNeovimのプラグインを管理できる[packer.nvim](https://github.com/wbthomason/packer.nvim)の設定を行う（Neovimの設定を全てLua化する場合はおそらくマスト）
1.  Luaで設定が書けるものはinit.luaに移したり、キーマッピングの設定などLuaで書けるものはLuaでリファクタしていく
1.  Luaで設定が書けないものは、```vim.cmd([[]])```の中に設定を移動する

LuaファイルでVim scriptを実行する場合は以下のように記述すれば、LuaファイルでVim scriptを実行できます。

```vim
vim.cmd([[
" Vim scriptがそのまま書ける
]])
```

最後まで読んでいただきましてありがとうございました。