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

793
Georges Dupéron

Я хотел бы получить подсказку из двух строк 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 ----------+ `>  
4

1 ответ на вопрос

4
mpy

When the preexec function is called, zle is already finished and hence, zle widgets can't be used any more.

So, you have to intercept the pressing of the ENTER key before zle terminates. By default ENTER is bound to accept-line, but this might depend on other tricks you already use;

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

We now write a new widget we want to bind to ENTER instead:

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

The logic is taken from your approach. In the last line we call the accept-line widget or anything else which was executed on pressing ENTER.

Finally we introduce the new widget to zle and bind it to ENTER:

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

Et voilà:

> echo foo bar foo bar +------------ Long prompt ----------+ `> echo this is my new command... not pressed ENTER, yet!