Closed41

Re:ゼロから始まるNeovim生活

kyoh86kyoh86

「無用の長物で、ポリシーもなくて、そんな .vimrc が許せないなら──今、ここから始めましょう」
「なに、を……」
「テキストエディタの止まっていた起動時間を -u NONE くんが動かしてくれたみたいに、更新が止まっていると思っていた .vimrc を、今、動かすんです」
「ここから始めましょう、イチから──いいえ、ゼロから!」
「ここから。ゼロから始めよう。Neovimの物語を」
「──ゼロから始める、Neovim生活を!」

kyoh86kyoh86

秘伝のタレを捨てるとき

テキストエディタの設定が秘伝のタレと化し、メンテナンスの頃合いを迎えました。
今ある環境を疑って、ゼロから再構築を試みます。

  • 今ある設定を残しつつ、ゼロからの再構築を試す環境をととのえる
  • 使っているプラグインの廃止・置き換えを進める
  • 欲しいと思いつつ先送りにしていた機能を載せる

このメモにはその道のりを、未来の自分と誰かのために記録します。

kyoh86kyoh86

Neovimの設定を独立させる

今ある設定を残しつつ、ゼロからの再構築を試す環境をととのえる

ために、独立した環境を用意する。

kyoh86kyoh86

他の影響を受けにくいあからさまなやり方は、OSのユーザーを分けるとか、コンテナを用意するとか。

kyoh86kyoh86

ただ、いずれにせよNeovimのセットアップまでの道のりがちょっと長すぎる気はする。
GitだのPGだの、Neovim以外のところに時間を取られすぎる。これをシンプルにする活動には、またちょっと違う価値がありそうだけど、今回は見送りたい。

kyoh86kyoh86

-u another.lua でいいのでは

盲点(ではなく単なるアホな勘違い)として、 -u another.lua のように設定ファイルを切り替えるだけだと上手くいかない。
packer.nvim とかのプラグインマネージャーが、rtpたる.local/share/nvim/site/pack/*/start 配下に色々置いてしまうので、それらが読み込まれてしまうから、指定した設定ファイルと衝突を起こす。

kyoh86kyoh86

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を参照する形が取られる。

kyoh86kyoh86

なので、こういうことをすれば独立した環境は割と簡単に再現できる。

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"
kyoh86kyoh86

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 $*
kyoh86kyoh86

これをやると、Neovimの中から呼び出す色んなモノがXDG_CONFIG_HOMEを見失ってしまって良くない。普通に -u で指定出来るようにする方が良い。

kyoh86kyoh86

lazy.nvim前提だったら、lazy.nvim自体がpluginのインストール先を指定出来るので、rootを代えることで何とかなる。
今はpacker.nvimだから、 package_root を設定すれば退避できるのでは?

kyoh86kyoh86

packer.nvimのpackage_root,いじると死ぬやつだ。
自分でpackage pathをイジらないとイケなくなる。頭悪いオプションだわ…

kyoh86kyoh86

うーん、package_rootのいじり方が分からない。壊れてしまう。
ダメだな。やっぱ早いところpacker.nvim捨てるしかない。

Hidden comment
kyoh86kyoh86

ざっくり構成要素を洗う

拡張や設定の類いに何を求めているかを今の設定から軽く洗ってみる。

kyoh86kyoh86

いきなりトップダウンで洗うの無理なので、今の設定に「これはなにか」をコメントして洗って分類を試みる。

kyoh86kyoh86
  • 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の一覧を表示する

当てもなくやってることを列挙したモノ

kyoh86kyoh86

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で代えた方がよさそう

あんまり構造化できん。

kyoh86kyoh86

lazy.nvim使う

デファクト感あるし使っておこう。

any lua file in ~/.config/nvim/lua/plugins/*.lua will be automatically merged in the main plugin spec

だって。ようするに色々分割しておいても良いんだな。

kyoh86kyoh86

pluginsってのは固定文字列なのかな。
plugins/xx/init.luaも読めるらしいから両方試しておきたいな

kyoh86kyoh86

基本的には何かと名前空間被るの嫌だから、全部
lua/local下に置いときたいな。

kyoh86kyoh86

某所での情報を入手。

ローカルに置くプラグインのルートディレクトリ指定しておくと dev = true だけでローカル読むように切り替わって便利

dev.path ですよね。手元でプラグイン修正して動作確認したりするのに便利
https://github.com/folke/lazy.nvim#️-configuration

便利そうなので忘れずにやっておく。

kyoh86kyoh86

dependenciesは、明示的に読み込まれるタイミングを指定しないと読み込まれないのか。

kyoh86kyoh86

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的な処理を挟んで設定と名前のリストを作って、初期化処理たちは後から呼ぶみたいな形にするか。

kyoh86kyoh86

現環境、これの順番がイカれてるから時々おかしなことになってたんだな。formatが動いたり動かなかったり、自動でLSPがインストールされたりされなかったり。

kyoh86kyoh86

細かいプラグインたちをどうするかな。適当にひとまとめでいいか。

kyoh86kyoh86
  • 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: いらんかも。何かどう作用してるのかいまいち良くわからん。

他もちゃんと動作確認しながら入れていこう。

kyoh86kyoh86

→ 現環境にlazy.nvimが入ってないので補完受けられないのは当然である。
→入れて解決

kyoh86kyoh86

さすがにmoduleレベルでいきなりreturn書くような構造に対してtype assertionはサポートしてないっぽいので、常に

---@type LazySpec
local spec = {
 ...
}
return { spec }

みたいな書き方をせにゃならん。
毎回書くの辛いので、snippet入れよう。

kyoh86kyoh86

return { spec } である必要はない。 return spec でよろし。

kyoh86kyoh86

github_issue, user-operatorを呼ぶのをconfigの中に閉じ込めれば治るのでは?

kyoh86kyoh86

autoload/operator/user.vim があったせいかも。なくなったから上手く動くかも。

kyoh86kyoh86

-u xxx で気軽に切り替えたい

今回の件で思ったけど、やっぱり環境簡単に指定したい。
既存環境のコピーを作ってちょっと書き換えるみたいなのが特にできるとうれしい。
-u xxx が機能するとうれしい。
するてと、 stdpath 使うとダメかも。

このスクラップは2023/02/08にクローズされました