ZSH: изменить подсказку перед запуском команды

Я хотел бы получить подсказку в две строки в zsh, но сверните его до очень маленького сразу после нажатия ENTER, чтобы он не отображался в истории прокрутки терминала. После ввода двух команд терминал должен выглядеть следующим образом при вводе третьей команды:

> echo Command 1
Command 1
> echo Command 2
Command 2
+------------ Long prompt ----------+
`> echo typing a new command here…

Я пытался получить что-то с preexec крюк и zle reset promptно я получаю ошибку widgets can only be called when ZLE is active:

$ autoload -U add-zsh-hook
$ hook_function() { OLD_PROMPT="$PROMPT"; export PROMPT="> "; zle reset-prompt; export PROMPT="$OLD_PROMPT"; }
$ PROMPT=$'+------------ Long prompt ----------+\n\`> '
+------------ Long prompt ----------+
`> add-zsh-hook preexec hook_function
+------------ Long prompt ----------+
`> echo Test
hook_function:zle: widgets can only be called when ZLE is active
Test
+------------ Long prompt ----------+
`> 

1 ответ

Решение

Когда preexec функция называется, zle уже закончен, и, следовательно, zle виджеты больше не могут быть использованы.

Таким образом, вы должны перехватить нажатие ENTER ключ перед zle завершается. По умолчанию ENTER связан с accept-line, но это может зависеть от других приемов, которые вы уже используете;

$ bindkey | grep '\^M'
"^M" accept-line

Теперь мы пишем новый виджет, к которому мы хотим привязать ENTER вместо:

del-prompt-accept-line() {
    OLD_PROMPT="$PROMPT"
    PROMPT="> "
    zle reset-prompt
    PROMPT="$OLD_PROMPT"
    zle accept-line
}

Логика взята из вашего подхода. В последней строке мы называем accept-line виджет или что-то еще, что было выполнено при нажатии ENTER,

Наконец, мы представляем новый виджет zle и привязать его к ENTER:

zle -N del-prompt-accept-line
bindkey "^M" del-prompt-accept-line

И вуаля:

> echo foo bar
foo bar
+------------ Long prompt ----------+
`> echo this is my new command... not pressed ENTER, yet!
Другие вопросы по тегам