Neovimが入れ子になるのを防ぐ
はじめに
Noevimのターミナル便利ですよね。
しかし、うっかりgit commit
やkubectl edit
などをしてしまい、Neovim内のTerminal内のNeovimが立ち上がり、上手くEscできないという状況に陥りませんか。
私は陥りました。
私が行なっている対策について共有します。
動作イメージ
git commit
をすると新しいバッファが開く。通常のTerminal使用時と同じように、Neovim内のTerminalもバッファを閉じるまでブロックします。
便利ですね。
(バッファが開く位置はお好みにあわせて調整可能です)
事前準備
neovim-remoteを使います。
各々のパッケージマネージャでインストールすると良いでしょう。
Macの場合はbrewでインストール可能です。
brew install neovim-remote
Arch Linuxの場合はAURを利用します。
yay -S neovim-remote
nixはパッケージが用意されています。
お使いのパッケージマネージャにneovim-remoteが無い場合、pipxを使ってインストールすると良いです。
pipx install neovim-remote
Neovimの設定
init.lua
をお使いの場合は以下を追記します。
if vim.fn.executable('nvr') == 1 then
vim.env.EDITOR = 'nvr -cc split -c "set bufhidden=delete" --remote-wait'
end
init.vim
をお使いの場合は以下を追記します。
if executable('nvr')
let $EDITOR = 'nvr -cc split -c "set bufhidden=delete" --remote-wait'
endif
split
の部分をvsplit
にすると分割方向を変更できます。
また現在のバッファの右側に新しいバッファを開きたい場合は以下のように設定してください。
if executable('nvr')
let $EDITOR = 'nvr -cc "rightbelow vsplit" -c "set bufhidden=delete" --remote-wait'
endif
rightbelow
を付けるとsplit
やvsplit
の位置を逆に出来るのですが、-ccのあとが複数の単語になってしまうので、ダブルクォートでくくるのがポイントです。
なおtabnew
にしたい場合は専用のオプションがあるため、以下のように設定できます。こちらの方が通常のターミナルの挙動に近いかも知れませんね。
if executable('nvr')
let $EDITOR = 'nvr -c "set bufhidden=delete" --remote-tab-wait'
endif
vi
も${EDITOR}
で置き換える
仕上げ ここまで設定すれば、不意にNeovimが入れ子になることは防げます。
ただし自分で明示的にNeovimを起動した場合は入れ子になってしまいます。
これはshell側で対策します。
私は普段vi
をnvim
のaliasとして使っているので、これを$EDITOR
に書き換えます。
zshでは以下を設定しています。
if [[ -n ${EDITOR} ]]; then
alias vi=${EDITOR}
fi
fishでは以下の関数を用意しています。
function vi --wraps='$EDITOR' --description 'alias vi $EDITOR'
if test -z "$EDITOR"
command vi $argv
else
eval $EDITOR $argv
end
end
力技💪ですね。
プラグインで解決する
ここまでプラグインを使わない方法の説明をしてきましたが、いつのまにかプラグインが沢山出来ていました。
以下の記事にまとまってます。
guise.vimのREADMEにも類似プラグインがたくさん記載されているので、プラグイン選びの際は目を通すと良いでしょう。
余談
neovim-remoteは生きていた
良かった。
--remote-wait
対応状況
Neovim本体のneovim-remoteは当初Neovimに実装されていなかった:h client-server
を実現しています。
のちほどNeovimに--remote
は実装されたのですが、--remote-wait
などは実装されませんでした。そのため「新しく開いたバッファを閉じるまでTerminalをブロックする」という動作が実現できていません。
ところがNeovimでは--remote-x-y
のようなオプションを整理しようという動きがあります。
基本的には--remote
に統一し、デフォルトでTerminalをブロックしようとしています。
詳細は以下のPull Requestをご確認ください。
ちなみにNeovim 1.0の準備として以下のissueにまとまっています。
楽しみですね。
Discussion