Neovimを設定ごと再起動する:restartとZR
プラグインを更新したあと、設定ファイルを大きく書き換えたあと、Neovimを起動し直したい場面は定期的に来ます。これまでは:qaで落として、ターミナルの履歴から起動コマンドを引っ張り出して、開いていたファイルを開き直す、という手順でした。Neovim 0.13の:restartは、この一連をコマンド1つにまとめます。しかもウィンドウの配置ごと復元します。
検証環境:nightlyビルドのNVIM v0.13.0-dev-1336+g8c0bf18374と安定版のNVIM v0.12.4(macOS)を実際の端末(擬似端末)で起動し、縦分割した状態から再起動して結果を記録しました。掲載しているウィンドウ数とv:startreasonの値は実行結果です。0.13は開発中なので、リリースまでに細部が変わる可能性があります。
| 操作 | これだけ覚える |
|---|---|
:restart | セッションを保存して起動し直す |
:restart! | セッションを復元せずに起動し直す |
| ZR | :restartと同じ |
:restart packupdate | 起動し直してからコマンドを実行する |
ウィンドウ配置ごと戻ってくる
ファイルを1つ開いて:vsplitでもう1つ並べた状態、つまりウィンドウが2つある状態から再起動して、戻ってきた直後の状態を記録しました。
再起動の前 再起動の後
Neovim 0.13 ウィンドウ2つ ウィンドウ2つ v:startreason = restart
Neovim 0.12.4 ウィンドウ2つ ウィンドウ1つ v:startreason = 無し
0.12.4にも:restartはありましたが、こちらは単に起動し直すだけで、分割していたウィンドウは戻ってきません。0.13は再起動の前にセッションを保存し、起動後に読み直します。:mksessionによるセッションの保存と復元を自動でやってくれる、と考えると分かりやすいです。
ヘルプが説明している手順は4段階で、セッションを保存し、:qallで止め、同じ引数で新しいサーバを起動し、セッションを復元してUIをつなぎ直します。v:startreasonを見れば、通常の起動と再起動を設定ファイル側で区別できます。
-- 再起動のときだけ何かする
if vim.v.startreason == 'restart' then
vim.notify('restarted')
end
復元してほしくないとき
設定を作り直しているときなど、まっさらな状態で立ち上げ直したい場面もあります。その場合は!を付けます。実測すると、こちらはウィンドウが1つに戻り、v:startreasonはrestart!になりました。
:restart!
キー操作としてはZRが割り当てられています。ZZ(保存して終了)やZQ(破棄して終了)の仲間で、手元で押すと:restartと同じ動きをしました。カウントを付けると挙動が変わるのが少し変わっていて、ヘルプによると1から8を付けるとセッションを復元せず、9を付けると変更の確認もせずに再起動します(カウント付きは実測していません)。
| 操作 | セッション復元 | 未保存の変更 |
|---|---|---|
| ZR | する | 確認する |
| 1〜8ZR | しない | 確認する |
| 9ZR | しない | 確認しない |
数字に意味があるわけではなく、1桁のカウントで段階を選ぶ形です。普段はZRだけ覚えておけば足ります。
再起動のついでにコマンドを走らせる
引数にコマンドを渡すと、起動し直したあとにそれを実行します。プラグインの更新と組み合わせるのがヘルプの例です。
:restart packupdate
:packupdateはvim.packのプラグインを更新するコマンドで、これも0.13で追加されました。更新してから読み込み直す、という手順が1行にまとまります。逆に「変更を捨ててから再起動」もできます。
:restart +qall!
+付きの引数は終了のしかたを指定するもので、こちらは:qall!で強制的に落としてから起動し直します。編集中のバッファが残っていて再起動が止まる、という場面で使います。
使うときの注意
ヘルプは制限を明記していて、UIとサーバが同じマシンにある場合しか動きません。リモートのNeovimにローカルのUIをつないでいる構成では使えないということです。また、起動に使った引数のうち、末尾のファイル指定と-Sで渡したセッションファイルは引き継がれません。セッションの復元はNeovim側の仕組みで行うので、二重に読み込まないための仕様です。
もうひとつ、:restartはターミナルの中で完結します。ターミナルを開き直す必要はありませんし、:terminalで開いていたシェルは当然ながら失われます。復元されるのはウィンドウ配置とバッファであって、実行中のプロセスではありません。
この検証でいちばん手間がかかったのが、再起動を機械的に試す方法を用意するところでした。--headlessではUIが無いので再起動を確認できず、結局は擬似端末を作ってキー入力を流し込む形になっています。逆に言えば、それだけ「端末の中で本当に立ち上げ直している」機能です。実際に使ってみると、縦分割した2つのウィンドウがそのまま戻ってくるのは気持ちがよく、設定をいじっている最中の往復がだいぶ楽になりました。ただ、開いていたターミナルバッファが消えるのは何度か忘れて、ビルドを流していたシェルごと落としてしまいました。
まとめ
Neovim 0.13の:restartはセッションを保存してから起動し直すので、縦分割していたウィンドウ配置ごと戻ってきます。実測では0.12.4が1ウィンドウに戻ったのに対し、0.13は2ウィンドウのまま復元されました。復元したくないときは:restart!、キー操作ではZRで、カウントを付けると復元と確認の有無を選べます。:restart packupdateのように後続のコマンドも渡せるので、プラグインを更新して読み込み直す手順が1行になります。UIとサーバが同じマシンにあることが条件で、ターミナルバッファのプロセスは戻らない点だけ気をつけておけば、設定をいじる日の往復がかなり短くなります。