zsh-users/zsh-autosuggestions はコマンドラインに入力された文字列からヒストリを検索し補完候補をグレイアウトした状態で提示してくれます。補完候補を使わないときはそのまま ^M を押せばグレイアウトした候補が表示から消え てそれまで入力した内容が実行されます (zsh でいう ^Menter などに bind された accept-line widgets が実行される)。

それが何らかの原因で「^M を押せばグレイアウトした候補が表示から消え」なくなります (ゴミを残す)。

つまりどういうことかというと、たとえば ls まで打ったときに補完候補として /hogehoge が出ているとします (| はカーソル)。

% ls |/hogehoge

このとき通常なら ^M を押すと

% ls
hoge.txt
% |

のように補完候補が消えて ls が実行されるわけですが、その補完候補が消えなくなりゴミを残すようになることがあります。

% ls /hogehoge
hoge.txt
% |

ls の後ろに /hogehoge が残っています。ただしゴミは表示上だけで ls/hogenoge が渡されることはありません。

この原因として ^M に別の widget が bind されている可能性が高いです。通常なら以下のように accept-line が bind されていますが、

% bindkey | grep '\^M'
"^M" accept-line
"^[^M" self-insert-unmeta

何らかの理由で以下のようにそれ以外が bind されてしまうこともあります (以下の例の「何らかの理由」は rhysd/zsh-bundle-exec をインストールしたことにより ^M に別の widget auto_bundle_exec_accept_line が bind された)。

% bindkey | grep '\^M'
"^M" auto_bundle_exec_accept_line
"^[^M" self-insert-unmeta

zsh-autosuggestions には zsh の変数として ZSH_AUTOSUGGEST_CLEAR_WIDGETS という「実行する前に補完内容を消す widget のリスト」があります。この変数に ^M に bind されている widget を登録してやればいいのです。

~/.zshrc
ZSH_AUTOSUGGEST_CLEAR_WIDGETS=(auto_bundle_exec_accept_line $ZSH_AUTOSUGGEST_CLEAR_WIDGETS)

zplug を使っている人は zsh-autosuggestions のロード後に変数の設定が行われるよう hook-load オプションを使いましょう 1

~/.zshrc
zplug "zsh-users/zsh-autosuggestions", hook-load: "ZSH_AUTOSUGGEST_CLEAR_WIDGETS=(auto_bundle_exec_accept_line $ZSH_AUTOSUGGEST_CLEAR_WIDGETS)"


  1. qop さんのご指摘により hook-load` を使った記述に修正しました。 

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.