4

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

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

Я пытался получить что-то с помощью preexec hook и 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 ответ1

4

Когда вызывается функция 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!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .