ZSH の設定でつまずいたこと
概要
トラブルの内容
ターミナルの入力で Emacs キーバインドによる移動(ctrl-a
, ctrl-e
など)を入力しても、カーソルが移動する代わりに ^E
や ^A
が入力されてしまうという症状に遭遇しました。カーソル移動に加えて ctrl-p
によるコマンド履歴の呼び出しもできないので、操作に著しい支障が生じていました。
色々調べてこの問題を解決できましたので、原因と対応策を備忘録としてメモします。
環境
- OS: NixOS on WSL2
1> nix-shell -p nix-info --run "nix-info -m"
2 - system: `"aarch64-linux"`
3 - host os: `Linux 5.15.167.4-microsoft-standard-WSL2, NixOS, 24.11 (Vicuna), 24.11.716868.60e405b241ed`
4 - multi-user?: `yes`
5 - sandbox: `yes`
6 - version: `nix-env (Nix) 2.24.14`
7 - channels(root): `"nixos-24.11, nixos-wsl"`
8 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
- ターミナル: Alacritty || Rio terminal
原因
結論から言いますと、home.nix
の home.sessionVariables.EDITOR
に nvim
を指定していることが原因でした。
もう少し説明しますと、ZSH は環境変数の EDITOR
または VISUAL
に vi
という文字列があると、キーバインドを viins
にしてしまいます。デフォルトエディタを Vim(Neovim) にする人はキーバインドも Vim と同じにするだろうと仮定しているようですが、これは流石に余計なお世話としか言いようのない挙動です。
とはいえ、デフォルトエディタを nano にするのはイヤなので、デフォルトエディタを Neovim にしたままキーバインドだけ Emacs にする必要があります。
なお、キーバインドが勝手に変更されるという点は、ZSH のコマンドラインの編集や補完やキーバインドなどの機能を提供する ZSHZLE のマニュアルに以下のとおり記述されています。
$ man zshzle ... If one of the VISUAL or EDITOR environment variables contain the string
vi' when the shell starts up then it will be
viins', oth‐ erwise it will be `emacs'. bindkey's -e and -v options provide a convenient way to override this default choice.
設定
こちらも結論から言いますと、設定ファイルの中に bindkey -e
を追加すれば OK です。私の場合、NixOS の home-manager を使って ZSH を設定していますので、home.nix
から呼び出す zsh.nix
を次のとおり変更しました。なお、デフォルトエディタは configuration.nix
で設定しています。
1# zsh.nix
2initExtra = ''
3 ABBR_SET_EXPANSION_CURSOR=1
4 ABBR_SET_LINE_CURSOR=1
5 compinit
6+ bindkey -e
7 zstyle ':completion:*:default' menu select=1
8 eval "$(direnv hook zsh)"
9'';
この設定を行ってから git add . && home-manager switch --flake .
を実行して再ログインすると、キーバインドが Emacs になり、ctrl-a
, ctrl-e
を入力するとカーソルが移動するようになります。