https://github.com/zsh-users/zsh/blob/master/Functions/Zle/predict-on を GPT-3.5 に投げて説明をつけてみた
# このセットの関数は、ある種の魔法の履歴検索を実装しています。
# predict-on 後、文字を入力すると、エディタは履歴を逆に検索し、入力された文字列で始まる最初の行を見つけます。
# predict-off 後、編集は通常のモードに戻り、見つかった行を元に戻します。
# 実際、predict-off を使わなくても十分です。なぜなら、行が履歴に一致しない場合、キーを追加すると通常の補完が実行されるからです。
# ただし、行の中で編集すると、残りの部分が削除される可能性があるため注意が必要です。
# 関数ベースの補完システム(これが必要です)を使用すると、ほとんどどこでもTABを入力して
# カーソルを次の「興味深い」文字位置(通常は現在の単語の終わりですが、時には単語の途中になります)に進めるはずです。
# もちろん、行全体が欲しいものになったら、カーソルを最後に移動する必要なくRETURNで受け入れることができます。
# これを使うには:
# autoload -Uz predict-on
# zle -N predict-on
# zle -N predict-off
# bindkey '...' predict-on
# bindkey '...' predict-off
# 注意: 最初に predict-on キーを入力すると、すべての関数が定義されるため、それより前に predict-off キーを入力すると無害なエラーメッセージが表示されます。
# キーが押されたときに呼び出される関数を定義
predict-on() {
# self-insert, magic-space, backward-delete-char のキーが押されたときに
# 対応する関数(insert-and-predict, delete-no-predict, delete-backward-and-predict)を呼び出す
zle -N self-insert insert-and-predict
zle -N magic-space insert-and-predict
zle -N backward-delete-char delete-backward-and-predict
zle -N delete-char-or-list delete-no-predict
# predict モードのときに冗長なメッセージを表示するかどうか
zstyle -t :predict verbose && zle -M predict-on
return 0
}
# predict モードを無効にする
predict-off() {
# zle に登録した関数を元に戻す
zle -A .self-insert self-insert
zle -A .magic-space magic-space
zle -A .backward-delete-char backward-delete-char
# predict モードのときに冗長なメッセージを表示するかどうか
zstyle -t :predict verbose && zle -M predict-off
return 0
}
# 文字を挿入して予測する関数
insert-and-predict() {
# オプションの設定(関数内でのみ有効)
setopt localoptions noshwordsplit noksharrays
# マルチラインバッファを編集中か、テキストのチャンクを貼り付けている場合は予測が望ましくない可能性がある
if [[ $LBUFFER == *$'\012'* ]] || (( PENDING ))
then
# マルチラインバッファを編集中またはテキストを貼り付けている場合は予測が不要なので、predict-off を呼び出す
zstyle -t ":predict" toggle && predict-off
zle .$WIDGET "$@"
return
elif [[ ${RBUFFER[1]} == ${KEYS[-1]} ]]
then
# 入力と同じなので次に進むだけ
((++CURSOR))
else
# 入力を LBUFFER に追加
LBUFFER="$LBUFFER$KEYS"
if [[ $LASTWIDGET == (self-insert|magic-space|backward-delete-char) ||
$LASTWIDGET == (complete-word|accept-*|predict-*|zle-line-init) ]]
then
# 最後のウィジェットが self-insert、magic-space、backward-delete-char、complete-word、accept-*
# または predict-* または zle-line-init のいずれかである場合は予測を実行
if ! zle .history-beginning-search-backward
then
RBUFFER=""
if [[ ${KEYS[-1]} != ' ' ]]
then
# 自動メニューと再帰的な完全一致の無効化
unsetopt automenu recexact
# カーソル、位置、キャラクタ数の設定
integer curs=$CURSOR pos nchar=${#LBUFFER//[^${KEYS[-1]}]}
local -a +h comppostfuncs
local crs curcontext="predict:${${curcontext:-:::}#*:}"
# 補完後の処理関数の指定
comppostfuncs=( predict-limit-list )
zle complete-word
# カーソルをどこに置くかを決定する
repeat 1
do
zstyle -s ":predict" cursor crs
case $crs in
(complete)
# 補完がカーソルを残した場所(通常は入力された文字の後)にカーソルを置く
[[ ${LBUFFER[-1]} = ${KEYS[-1]} ]] && break
;;
(key)
# または入力された文字の n 番目の出現位置にカーソルを置く
pos=${BUFFER[(in:nchar:)${KEYS[-1]}]}
if [[ pos -gt curs ]]
then
CURSOR=$pos
break
fi
;;
(*)
# または前回の位置にカーソルを置く
CURSOR=$curs
esac
done
fi
fi
else
# 最後のウィジェットがそれ以外の場合は予測を無効にする
zstyle -t ":predict" toggle && predict-off
fi
fi
return 0
}
# 後方に文字を削除して予測する関数
delete-backward-and-predict() {
if (( $#LBUFFER > 1 ))
then
setopt localoptions noshwordsplit noksharrays
# マルチラインバッファを編集中、または最後のウィジェットが self-insert、magic-space、backward-delete-char 以外の場合
# は予測が望ましくない可能性がある
if [[ $LBUFFER = *$'\012'* ||
$LASTWIDGET != (self-insert|magic-space|backward-delete-char) ]]
then
# マルチラインバッファを編集中または最後のウィジェットが self-insert、magic-space、backward-delete-char 以外の場合は予測を無効にする
zstyle -t ":predict" toggle && predict-off
LBUFFER="$LBUFFER[1,-2]"
else
# カーソルを前に移動して履歴を逆検索し、見つかったらそれを元に戻す
((--CURSOR))
zle .history-beginning-search-forward || RBUFFER=""
return 0
fi
else
# 1 文字より少ない場合は行全体を削除
zle .kill-whole-line
fi
}
# 削除して予測しない関数
delete-no-predict() {
# delete-char-or-list かつ RBUFFER が空でない場合、または予測が無効にされている場合は予測を無効にする
[[ $WIDGET != delete-char-or-list || -n $RBUFFER ]] && predict-off
zle .$WIDGET "$@"
}
# 補完リストを制限するための補助関数
predict-limit-list() {
# リストの行数が画面の行数を超えるか、
# compstate[list_max] が設定されておりかつ compstate[nmatches] が compstate[list_max] を超える場合
if (( compstate[list_lines]+BUFFERLINES > LINES ||
( compstate[list_max] != 0 &&
compstate[nmatches] > compstate[list_max] ) ))
then
# リストを空にする
compstate[list]=''
# 補完リストを常に表示する設定がされている場合はリストを強制的に表示
elif zstyle -t ":predict" list always
then
compstate[list]='force list'
fi
}
# zsh の autoloading 慣例を処理する
[[ -o kshautoload ]] || predict-on "$@"