最近コーディングの配信を行ったりしているのですが、結構 Vim に関してコメントを頂くことが多く、ちょっと今自分の状況を振り返ってみると
- 設定したのが昔すぎてうまく説明できない
- Neovim を使っているが、Vim Script でそのまま設定してたので、lua で設定したい
- そろそろ古くなっているプラグインや知らないけど便利なプラグインがあるかもしれない
などなどがあったのでこの度 Neovim の設定を lua に移行しつつ使用プラグインの見直しを行いました。 プラスで自分の環境周りも整理したかったので備忘がてら記事にまとめてみました。
エディタ周りの環境
- Mac
- モニタ2台(Display Menu)
- tmux
- Alacritty
- Neovim
エディタ周りの環境は上記のようになっています。
PC周り
開発には長年 Mac を使用していて、 モニタ2台で開発していることが多いです。モニタの解像度変更ようにはDisplay Menu というアプリを使っています。 (大きい方のモニタでコードを書いて、小さい方のモニタでブラウザを開いていることが多いです)
ターミナルアプリケーション
またターミナルアプリケーションは Alacritty を使用しています。ターミナルは可能な限りサクサク動いて欲しいので早いという評判の Alacritty を使っています。 今の所そんなに不満はないのですが、kitty が良いというのもちょこちょこ聞くのでいずれ試してみたいところです。ターミナルアプリは真剣に比較していないので暫定的なものです。
Tmux 周りの設定や使い方
tmux はターミナルの分割を行うために使用しています。 tmux を使いこなしているとは言い難いのですが、自分が一番重宝している機能はこれかなという感じです。
tmux を知ったのは結構遅かったと思うのですが、Inkdrop 作者の Takuya さんの動画がきっかけでtmuxを使い始めて動画の説明と同じようにtmuxを使っています。 コマンドベースで最初に開く window の枚数や配置・サイズを指定できるので一瞬で自分の好みのレイアウトを立ち上げられるのが便利です。
作業時のウィンドウのレイアウト
自分は多くの場合、この画像のような上1枚、下4枚のレイアウトで作業しています。下4枚はターミナル用の window で、上が Neovim 用 Window です。 下4枚では左2枚が大体 フロントとバック用のサーバをたちあげてログを流す画面になっています。右2枚はスペアで簡単なコマンドを試したり別ディレクトリのものを触りたくなったりした時に使います。
多くの場合はエディタ開きっぱなしなのですが、たまにPCを立ち上げ直したあとなどは用意したスクリプトを叩いて必ずこのウィンドウの状況を再現するようにしています。 (tmux のセッションを永続化することも可能なのようなのでそれでやるのも良いと思います。)
#!/bin/bash
set -e
tmux split-window -v -l 30%
tmux split-window -h -l 50%
tmux split-window -h -l 50%
tmux select-pane -L
tmux select-pane -L
tmux split-window -h -l 50%
tmux select-pane -U
tmux のセッションを開いた後にこれを打てばウィンドウ再現できるかと思います。
キーバインド
後にも説明しますが、ペーンの移動は Vim の中での移動とtmux 内での移動の両方があるのでそれぞれキーバインドが衝突しないように設定を行っています。 tmux.conf の中の設定でいうと下記のように設定しています。
bind -n C-h select-pane -L
bind -n C-j select-pane -D
bind -n C-k select-pane -U
bind -n C-l select-pane -R
キーバインド | 操作 |
---|---|
Ctrl + h | 左のPaneに移動 |
Ctrl + j | 下のPaneに移動 |
Ctrl + k | 上のPaneに移動 |
Ctrl + l | 右のPaneに移動 |
Vim 内での移動は Space + hjkl で行うので、ターミナル内での移動は Ctrl + hjkl で行うようにしています。
Neovim の基本設定
さて、続いては Neovim の設定についてです。 こちらはリポジトリで公開しているので、興味がある方はご確認ください。
ディレクトリ構成
ディレクトリ構成は下記のようになっています。
├── README.md
├── init.lua # 最初に読み込まれる設定ファイル
├── install.sh # LSP など依存しているライブラリのインストールをまとめたスクリプト
├── lazy-lock.json # lazy のロックファイル
└── lua # 設定ファイルを分割して書いているディレクトリ
├── base.lua # 基本の設定
├── config
│ └── lazy.lua # lazy の設定
├── keymaps.lua # プラグインに依存しないキーバインドの設定
└── plugins # lazy で読み込むプラグインの設定
├── cmp.lua # cmp 補完プラグインの設定
├── formatter.lua # formatter の設定
├── lsp.lua # lspconfig の設定
├── lualine.lua # lualine の設定
├── plugins.lua # その他設定なしで読み込めるプラグインをまとめたもの
├── tree.lua # nvim-tree の設定
├── treesitter.lua # treesitter の設定
└── whichkey.lua # whichkey の設定
Neovim では、init.lua に設定を書いておくと Neovim 起動時に設定を読み込んでくれるのでここに様々な設定やプラグインの読み込みを書いています。 とはいえ、全部の設定を一つのファイルにかくと見通しがわかりにくくなるので、上記の表のように設定を分割しています。
基本設定(base.lua)
元々の Neovim 組み込みの設定は base.lua に記述しています。
-- https://neovim.io/doc/user/quickref.html#option-list
vim.o.encoding = 'utf-8'
vim.o.number = true
vim.o.smartindent = true
vim.o.clipboard = "unnamedplus"
vim.o.list = true
vim.o.expandtab = true
vim.o.tabstop = 2
vim.o.shiftwidth = 2
vim.o.wrap = false
vim.o.termguicolors = true
vim.o.wildmenu = true
vim.o.ruler = true
vim.o.smartcase = true
vim.o.showmatch = true
vim.g.mapleader = ' ' -- Leader に Space を割り当てる
vim.g.maplocalleader = "\\"
コメントにもありますが、Neovim の設定項目は https://neovim.io/doc/user/quickref.html#option-list ここを見ると書いてあります。
Leader について
一応言及しておくべきは Leader と言って Vim を操作する際にキーバインドの先頭につけるキーをSpaceに割り当てています。 これはVim の操作をする上で最重要なキーバインドになるので、自分の使いやすいリーダーに割り当てられると良いと思います。 自分は、Vimを使い始めた当初にMedium でSpaceが使いやすいと言っている記事(記事の所在は忘れました・・・)を見つけたのでそれ以来 Space を使っています。
今回記事を書くのとVim周りの設定をluaに移行するにあたり色々な人の vimconfig をみているのですが割と Space に Leaeder を設定している方が多そうです。 参考にした Nvchad も Space に Leader を設定しているので、割と一般的な設定にも思えます。
基本のキーバインド(keymaps.lua)
プラグインによらないキーバインドは keymaps.lua に記述しています。
Vim上でのウィンドウの移動や分割、ターミナルの開閉などのキーバインドをここに書いています。
ここで
luaへの移行前は、コメントの ON/OFF をプラグインでやっていましたが、Neovimではデフォルトで gcc と入力すれば使えるのが分かったのでキーバインドを変えて使っています。 自分は Ctrl + -(ハイフン) でコメントアウトができるようにしています。
自分はコードを書いている際に頻繁に window 分割したり移動を行うので、Space + jklh でウィンドウの移動、Space+s or Space + v でウィンドウ分割をしています。
local map = vim.api.nvim_set_keymap
-- move window
map('n', '<Leader>j', '<C-w>j', { noremap = true, silent = true })
map('n', '<Leader>k', '<C-w>k', { noremap = true, silent = true })
map('n', '<Leader>l', '<C-w>l', { noremap = true, silent = true })
map('n', '<Leader>h', '<C-w>h', { noremap = true, silent = true })
-- split window
map('n', '<Leader>s', ':<C-u>sp\n', { noremap = true })
map('n', '<Leader>v', ':<C-u>vs\n', { noremap = true })
-- close window
map('n', '<Leader>w', ':<C-u>w\n', { noremap = true })
map('n', '<Leader>q', ':<C-u>q\n', { noremap = true })
map('n', '<Leader>wq', ':<C-u>wq\n', { noremap = true })
-- open terminal
map('n', '<Leader>tt', ':terminal\n', { noremap = true })
map('i', '<C-k>', '<Up>', {})
map('i', '<C-j>', '<Down>', {})
map('i', '<C-h>', '<Left>', {})
map('i', '<C-l>', '<Right>', {})
-- show diagnostics
map('n', '<Leader>d', ':lua vim.diagnostic.open_float()<CR>', { noremap = true })
-- rebind embeded command
map('n', '<C-_>', 'gcc', { noremap = false })
map('v', '<C-_>', 'gc', { noremap = false })
NeoVim のプラグイン周り(plugins/*.lua)
プラグインの設定は plugins ディレクトリ以下に分割して書いていて、個別に設定が必要ないものは plugins/plugins.lua に書きそうでないものは専用のファイルを作って管理しています。
パッケージマネージャ
lazy repo
プラグインの読み込みは lazy を使っています。lazy を設定すると plugins 配下のファイルを読み込んで plugin をセットアップしてくれます。
補完・シンタックスチェック
nvim-lspconfig repo
補完やジャンプ、定義の確認、シンタックスチェックにLSP必要なので言語別にサーバを設定できるプラグインです。
nvim-cmp repo
補完プラグインです。LSP と連携して補完を行うことができます。
nvim-treesitter repo
シンタックスハイライトやシンタックスチェックを行うために入れています。 構文解析のためのツールである treesitter と nvim-treesitter を良い感じに繋げるプラグインという理解です。 (ちょっと使い始めて日が浅いので雑な説明になっていますすみません)
普段使う言語の Parser だけ使うように設定しています。
copilot.vim repo
言わずもがな Github Copilot のVim用プラグインです。これでだいぶ補完が効く様になるのですが、そこまで使い方深堀できていないのでまた時間のある時に使い方を調べてみたいです。
ファイルエクスプローラ
nvim-tree repo
ファイルエクスプローラ用のプラグインです。ほぼ一般的なエディタについてるファイルエクスプローラと同様に使えます。 元々はNerdTree を使っていたのですが、lua 移行にともなって移行しました。 nvim-web-deviconsもインストールすれば他のIDEと同等の見た目になり、ファイルの情報もみやすくなるのでおすすめです。
エクスプローラの開閉は Space + e で行うようにしています。こういったプラグインのコマンドを実装するためのキーバインド設定は keymaps.lua でやらずここでやっています。
keys = {
{ "<leader>e", "<cmd>NvimTreeToggle<cr>", desc = "TreeToggle" },
},
デフォルトのキーバインドでは、Enter でファイルを開くときにいちいちどの Pane で開くか聞かれるのが嫌だったのでマッピングを変えています。
vim.keymap.set("n", "<CR>", api.node.open.no_window_picker, opts "Open: No Window Picker")
vim.keymap.set("n", "O", api.node.open.edit, opts "Open")
検索
ファジーファインダー telescope
高機能なファジーファインダープラグインです。ファイル検索や文字列でインクリメンタルサーチができます。 正直エディタにこれがないと辛いですよね。CUIベースのエディタとは思えないくらいリッチなUIを持っているので非常に便利です。
キーバインドは下記の様な形で頻繁に使うのですぐに使える様にしています。
キーバインド | 操作 |
---|---|
Space + p | ファイル検索 |
Space + g | 文字列検索 |
フォーマッタ
フォーマッタ conform.nvim
フォーマッタプラグインです。他のプラグインなどと同様にファイル保存時に自動でフォーマットをかけることができます。 フォーマッタは言語ごとに設定可能で自分は、gofmt, goimports, prettierd 等々を設定しています。 こちらもフォーマットをかける際のキーバインドはconform用の設定ファイルで書いています。
コードを書きながら手動でフォーマットをかけるのを好むので手動のフォーマトコマンドを設定しています。 conform では若干設定が必要なので下記の Recipe に従ってコマンドを作ってそれを呼び出す形で使っています。
見た目系
ステータスバー lualine
ステータスラインをカスタマイズするプラグインです。ステータスライン変えるだけでもかなりこなれた感じになるので試してみてみると良いと思います。 前は設定が悪かったのかステータスライン系のプラグインを入れると重くなってしまっていたので、自前で設定していましたが lualine は問題なさそうです。
カラープレビュー nvim-colorizer
カラーコードをプレビューしてくれるプラグインです。CSSを書く際にかなり便利です。 カラーコードの上に乗っかる形でプレビューされるのですが、自分的にはカラーコードの横に色を表示させたい(文字色などによって見辛くなるので)というのは多少あります。
プラグインの自作にもトライしたいので、時間がある時に作ってみたいなーなんて思っています。
その他
キーバインドヘルプ which-key
キーバインドのヘルプを表示してくれるプラグインです。自分で設定したキーバインドがわからなくなった時に便利なのでおすすめです。 また自分で設定したキーバインドが効いているかも確認できて非常に便利です。移行の際に知ったプラグインですが嬉しい発見の一つでした。
囲み文字編集 nvim-surround
こちらは移行の際の調べ物で見つけたプラグインです。動画で紹介しているものを見つけて便利そうなので入れてみました。 まだ使えこなせてはいないのですが、Vim で囲み文字を追加する際に便利そうなので使ってみようと思います。
nvim-surround | 5 Neovim Plugins To Improve Your Productivity
ds"
の様に入力するだけでワード周りのダブルクォーテーションを削除できたり、丸括弧、波括弧、角括弧なども少ないキーストロークで入力が行えるので非常に便利そうです。
まとめ
今回 lua に移行したのですが、その過程で Neovim をはじめとしたドキュメントを読み漁りました。 自分が知らないプラグインやNeovimの機能が結構あることに気づいたので、やはり定期的に設定を見直すのは必要な様です。
neovim 内で :terminal とするとターミナルが開くのですが、これを使うとターミナルとエディタ間の移動がいらなくなるので、もしかしたら tmux も使わなくて済むのかもしれないです。 今のところは慣れているtmux+neovimで運用していますが、意外とneovim だけでやっていけるのかもしれません。 (tmuxには他の機能もあるのと、vim内のターミナルの操作がどの程度使いやすいかがあるのですぐに移行はできなそう)
いずれにせよ、ここに書いたのは現時点での環境ですぐに変わることはないと思いますが徐々に変わっていくことになるかと思うので今回の様な変更があればまた記事を書きたいと思います。 また、もう少し普段 vim を使わない方向けにも記事を書いてみたいと思うので、今回の作業を違った角度から記事にもできればなと思っています。