Re:ゼロから始まるNeovim生活
「無用の長物で、ポリシーもなくて、そんな .vimrc
が許せないなら──今、ここから始めましょう」
「なに、を……」
「テキストエディタの止まっていた起動時間を -u NONE
くんが動かしてくれたみたいに、更新が止まっていると思っていた .vimrc
を、今、動かすんです」
「ここから始めましょう、イチから──いいえ、ゼロから!」
「ここから。ゼロから始めよう。Neovimの物語を」
「──ゼロから始める、Neovim生活を!」
秘伝のタレを捨てるとき
テキストエディタの設定が秘伝のタレと化し、メンテナンスの頃合いを迎えました。
今ある環境を疑って、ゼロから再構築を試みます。
- 今ある設定を残しつつ、ゼロからの再構築を試す環境をととのえる
- 使っているプラグインの廃止・置き換えを進める
- 欲しいと思いつつ先送りにしていた機能を載せる
このメモにはその道のりを、未来の自分と誰かのために記録します。
Neovimの設定を独立させる
今ある設定を残しつつ、ゼロからの再構築を試す環境をととのえる
ために、独立した環境を用意する。
他の影響を受けにくいあからさまなやり方は、OSのユーザーを分けるとか、コンテナを用意するとか。
ただ、いずれにせよNeovimのセットアップまでの道のりがちょっと長すぎる気はする。
GitだのPGだの、Neovim以外のところに時間を取られすぎる。これをシンプルにする活動には、またちょっと違う価値がありそうだけど、今回は見送りたい。
-u another.lua
でいいのでは
盲点(ではなく単なるアホな勘違い)として、 -u another.lua
のように設定ファイルを切り替えるだけだと上手くいかない。
packer.nvim とかのプラグインマネージャーが、rtpたる.local/share/nvim/site/pack/*/start 配下に色々置いてしまうので、それらが読み込まれてしまうから、指定した設定ファイルと衝突を起こす。
Neovimを取り巻く環境
Neovimの設定ファイルや、rtpは(素の状態だと)どうなるかというと、
:help base-directories
*base-directories* *xdg*
The "base" (root) directories conform to the XDG Base Directory Specification.
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
The $XDG_CONFIG_HOME, $XDG_DATA_HOME, $XDG_RUNTIME_DIR, and $XDG_STATE_HOME
environment variables are used if defined, else default values (listed below)
are used.
CONFIG DIRECTORY (DEFAULT) ~
*$XDG_CONFIG_HOME* Nvim: stdpath("config")
Unix: ~/.config ~/.config/nvim
Windows: ~/AppData/Local ~/AppData/Local/nvim
DATA DIRECTORY (DEFAULT) ~
*$XDG_DATA_HOME* Nvim: stdpath("data")
Unix: ~/.local/share ~/.local/share/nvim
Windows: ~/AppData/Local ~/AppData/Local/nvim-data
RUN DIRECTORY (DEFAULT) ~
*$XDG_RUNTIME_DIR* Nvim: stdpath("run")
Unix: /tmp/nvim.user/xxx /tmp/nvim.user/xxx
Windows: $TMP/nvim.user/xxx $TMP/nvim.user/xxx
STATE DIRECTORY (DEFAULT) ~
*$XDG_STATE_HOME* Nvim: stdpath("state")
Unix: ~/.local/state ~/.local/state/nvim
Windows: ~/AppData/Local ~/AppData/Local/nvim-data
Note: Throughout the user manual these defaults are used as placeholders, e.g.
"~/.config" is understood to mean "$XDG_CONFIG_HOME or ~/.config".
のように、いわゆるXDG Base Direcotryを参照する形が取られる。
なので、こういうことをすれば独立した環境は割と簡単に再現できる。
VIRTUAL_NAME="foo"
# prepare base directory
BASE_DIR="${HOME}/nvim-trial/${VIRTUAL_NAME}"
mkdir -p "${BASE_DIR}/{config,data,state}/nvim"
touch "${BASE_DIR}/config/nvim/init.lua"
# export virtual XDG directories
export XDG_CONFIG_HOME="${BASE_DIR}/config"
export XDG_DATA_HOME="${BASE_DIR}/data"
export XDG_STATE_HOME="${BASE_DIR}/state"
(mkdir
でパターン使おうとしてて草。そんなことできるわけがない)
一歩進めると、こういう何かができあがる。今回はコレを使っていこう。
#!/bin/env zsh
VIRTUAL_NAME="$1"
if [ -z "${VIRTUAL_NAME}" ]; then
echo "It requires an argument as virtual environment name"
exit 1
fi
# prepare base directory
BASE_DIR="${HOME}/nvim-trial/${VIRTUAL_NAME}"
mkdir -p "${BASE_DIR}/config/nvim"
mkdir -p "${BASE_DIR}/data/nvim"
mkdir -p "${BASE_DIR}/state/nvim"
touch "${BASE_DIR}/config/nvim/init.lua"
# export virtual XDG directories
export XDG_CONFIG_HOME="${BASE_DIR}/config"
export XDG_DATA_HOME="${BASE_DIR}/data"
export XDG_STATE_HOME="${BASE_DIR}/state"
shift
nvim $*
これをやると、Neovimの中から呼び出す色んなモノがXDG_CONFIG_HOMEを見失ってしまって良くない。普通に -u
で指定出来るようにする方が良い。
lazy.nvim前提だったら、lazy.nvim自体がpluginのインストール先を指定出来るので、rootを代えることで何とかなる。
今はpacker.nvimだから、 package_root
を設定すれば退避できるのでは?
packer.nvimのpackage_root,いじると死ぬやつだ。
自分でpackage pathをイジらないとイケなくなる。頭悪いオプションだわ…
うーん、package_rootのいじり方が分からない。壊れてしまう。
ダメだな。やっぱ早いところpacker.nvim捨てるしかない。
ざっくり構成要素を洗う
拡張や設定の類いに何を求めているかを今の設定から軽く洗ってみる。
いきなりトップダウンで洗うの無理なので、今の設定に「これはなにか」をコメントして洗って分類を試みる。
プラグインの設定をどうするか、を構造化するのは意味がなさそう。Lazy.vimの
Structuring Your Plugins
を参照するのがよさそう
- 0/1が返るvim.fnの関数をbooleanに変換する
- <C-w>で使えるウィンドウの管理系をターミナルモードにマップする
- CWDに基づいて設定を変える
- Extract outlines from markdown:
- Goの場合、補完後に変数名が邪魔になることがあるので、削除するショートカットを設定する
- HTMLファイルのインデント設定
- Indent list mark on the head of each list-item.
- Insertモードから抜けるときにIMEを自動でオフにする
- LSPのクライアント名とバッファ名のパターンの組み合わせで、無効化したいものを指定する。
- LSPの状態をJSON形式で表示する
- LSPの設定
- Luaファイルのインデント設定
- Markdownのインデント設定
- QuickFixに行番号を表示する
- Quickrunの設定
- TODOコメントを探し出す
- Telescopeの設定
- feline(statusline)にCWDのGit情報を表示する
- feline(Statusline)の設定
- local.etc.help参照
- markdownのCheckbox化・CheckboxのオンオフのToggle
- markdownのテキスト表示・編集にまつわる設定
- vim scriptファイルのインデント設定
- カーソルの表示変更
- カーソル下のファイルやらなんやらを外部プログラムで開く
- カーソル下のファイルを開いたりする
- コマンドラインのKeymapをカスタマイズ
- タブ間を移動したときに元のウインドウを選択する
- ターミナルをさっと開く
- ターミナルを便利にする
- テキストの編集と表示に関する設定
- バッファの中身から検索に引っかかるモノを抽出したバッファを作る
- バッファ中の任意のテキストをタイトルとして、CWDに対応するGitHubリポジトリにIssueを作成する
- フォーカスされたウィンドウだけCursor lineを表示する
- ルート
- 一部の特殊なファイルについて、filetypeの割り当てを上書きする
- 別名を付けて保存
- 検索と置換を切り替える
- 環境変数設定
- 空のバッファはquit時に自動で閉じる
- 空バッファを無視して閉じる
- 補完とスニペットの設定
- 言語の設定
- 設定されているKeymapの一覧を表示する
当てもなくやってることを列挙したモノ
Window/バッファ/プロジェクトの管理機能
- CWDに基づいて設定を変える
- feline(statusline)にCWDのGit情報を表示する
- feline(Statusline)の設定
- タブ間を移動したときに元のウインドウを選択する
- <C-w>で使えるウィンドウの管理系をTerminalモードにマップする
- Telescopeの設定
- Terminalをさっと開く
- 空のバッファはquit時に自動で閉じる
- カーソル下のファイルやらなんやらを外部プログラムで開く
- バッファ中の任意のテキストをタイトルとして、CWDに対応するGitHubリポジトリにIssueを作成する
検索と置換
- TODOコメントを探し出す
- バッファの中身から検索に引っかかるモノを抽出したバッファを作る
- 検索と置換を切り替える
- QuickFixに行番号を表示する
- Quickrunの設定
表示系
- カーソルの表示変更
- フォーカスされたウィンドウだけCursor lineを表示する
編集系
- Goの場合、補完後に変数名が邪魔になることがあるので、削除するショートカットを設定する
- テキストの編集と表示に関する設定
- Markdownのインデント設定
- HTMLファイルのインデント設定
- vim scriptファイルのインデント設定
- Luaファイルのインデント設定
- markdownのCheckbox化・CheckboxのオンオフのToggle
- markdownのテキスト表示・編集にまつわる設定
- Extract outlines from markdown:
- Indent list mark on the head of each list-item.
- 補完とスニペットの設定
LSPの管理
- LSPのクライアント名とバッファ名のパターンの組み合わせで、無効化したいものを指定する。
- LSPの状態をJSON形式で表示する
- LSPの設定
基本設定
- 言語の設定
- 環境変数設定
- Insertモードから抜けるときにIMEを自動でオフにする
- 一部の特殊なファイルについて、filetypeの割り当てを上書きする
- 別名を付けて保存
- ヘルプファイル編集の諸々
- コマンドラインのKeymapをカスタマイズ
いらない
- 0/1が返るvim.fnの関数をbooleanに変換する: やっぱ紛らわしいので捨てる
- 設定されているKeymapの一覧を表示する: Telescope Keymapsで代えた方がよさそう
あんまり構造化できん。
Telescope keymaps より which-key.nvimの方が目的に照らしてあってる
lazy.nvim使う
デファクト感あるし使っておこう。
any lua file in
~/.config/nvim/lua/plugins/*.lua
will be automatically merged in the main plugin spec
だって。ようするに色々分割しておいても良いんだな。
pluginsってのは固定文字列なのかな。
plugins/xx/init.luaも読めるらしいから両方試しておきたいな
基本的には何かと名前空間被るの嫌だから、全部
lua/local下に置いときたいな。
某所での情報を入手。
ローカルに置くプラグインのルートディレクトリ指定しておくと dev = true だけでローカル読むように切り替わって便利
dev.path
ですよね。手元でプラグイン修正して動作確認したりするのに便利
https://github.com/folke/lazy.nvim#️-configuration
便利そうなので忘れずにやっておく。
dependenciesは、明示的に読み込まれるタイミングを指定しないと読み込まれないのか。
LSPの設定
mason, mason-lspconfig, lsp-formatの関係が面倒くさい。
require("mason").setup({})
require("mason-lspconfig").setup({ ensure_installed = lsp_server_list })
require("lsp-format").setup({})
require("lspconfig").xxxxx.setup({})
の順で呼ばなきゃ行けない。mason-lspconfigとlspconfigで二回同じ名前を指定せにゃならんのだ。
(同じ名前で済んでるだけまだましだけど、mason時代は名前のマップが必要だった…馬鹿馬鹿しいことだ)
register的な処理を挟んで設定と名前のリストを作って、初期化処理たちは後から呼ぶみたいな形にするか。
細かいプラグインたちをどうするかな。適当にひとまとめでいいか。
- noice.nvim: 未だにちょっとbuggyなので避けておく。guise.vimとの衝突案件が解決すれば入れ直すかも。
- treesitter-context: 入れてみて思ったけど別に要らんなコレ。そんなアホみたいに長い処理はあまり多くないし、あったらあったで
<C-w>s[\ap
とかして適当に戻ってみる気がする。 - treesitter treesitter-contextがいなくなったので、もはや使ってない。消す。
- telescope-frecency.nvim telescope x mr.vim を作ったときにいらんかもなとは思ってたけど案の定もういらない。消す。
- vim-textobj-xmlattr: 使わん…消す。
- Comment.nvim: ちょっとキーマップ使いにくいのでもうちょっと違うマップ考える
- hlslens: ちょっとうるさいかもなあ。消すか、見た目調整がいる。
- gin.vim: やっぱ使わん…消す。
- tig-explorer.vim: コレも使わない…消す。
- open-browser.vim, open-browser-github.vim: いまいちなので消すかPR出して機能増強
- gitsigns.nvim: ちょっとうるさい。numberを塗ったのはやり過ぎかも。変えたい。
- vim-quotem: うーん。出来がいまいち。URLがinsteadOfで変わっちゃったりするし、言語Fenceはサポートしてない体系も多い…直そう。
- neogen: 今んとこ使い道がない。消そう。
- partedit: これもやはり使わない…消そう。
- formatter: いったんlspの方で良いはず。(たまにlspのフォーマット気に食わん場合があるので、その場合の代替として入れるのはアリだけど、lspとちゃんと調整して入れる。雑に放り込みすぎてる。
- vim-go-filetype: ちょっといらんかも。デフォのが大分良い感じ。
- vim-jp/autofmt: いらんかも。何かどう作用してるのかいまいち良くわからん。
他もちゃんと動作確認しながら入れていこう。
lazy.nvimのspec書いてるとよくcmdとかkeysとかoptsとか名前がややこしくて覚えらんないので、lua-language-serverの支援を受けたい。
なんか
型定義とか受け取れるらしい。
→ 現環境にlazy.nvimが入ってないので補完受けられないのは当然である。
→入れて解決
さすがにmoduleレベルでいきなりreturn書くような構造に対してtype assertionはサポートしてないっぽいので、常に
---@type LazySpec
local spec = {
...
}
return { spec }
みたいな書き方をせにゃならん。
毎回書くの辛いので、snippet入れよう。
return { spec }
である必要はない。 return spec
でよろし。
quickrunまで終わった。あと400行。
対象は26コのプラグイン。
プラグインは終わった。
github_issue, user-operatorを呼ぶのをconfigの中に閉じ込めれば治るのでは?
-u xxx
で気軽に切り替えたい
今回の件で思ったけど、やっぱり環境簡単に指定したい。
既存環境のコピーを作ってちょっと書き換えるみたいなのが特にできるとうれしい。
-u xxx
が機能するとうれしい。
するてと、 stdpath
使うとダメかも。