ZSH: Eingabeaufforderung ändern, kurz bevor der Befehl ausgeführt wird

963
Georges Dupéron

Ich hätte gerne eine zweizeilige Eingabeaufforderung zsh, bringe sie aber gleich nach dem Drücken zu einem sehr kleinen zusammen ENTER, so dass sie nicht im Scroll-Verlauf des Terminals angezeigt wird. Nachdem Sie zwei Befehle eingegeben haben, sollte das Terminal beim dritten Befehl so aussehen:

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

Ich habe versucht, etwas mit dem preexecHaken und zu bekommen zle reset prompt, aber ich bekomme die Fehlermeldung 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 Antwort auf die Frage

4
mpy

Wenn die preexecFunktion aufgerufen wird, zleist sie bereits beendet und daher können Zle-Widgets nicht mehr verwendet werden.

Sie müssen also das Drücken der ENTERTaste abbrechen, bevor Sie zleabbrechen. Standardmäßig ENTERist dies an gebunden accept-line, dies kann jedoch von anderen Tricks abhängen, die Sie bereits verwenden.

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

Wir schreiben jetzt ein neues Widget, an das wir ENTERstattdessen binden wollen :

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

Die Logik wird von Ihrem Ansatz übernommen. In der letzten Zeile wird das accept-lineWidget oder etwas anderes aufgerufen, das beim Drücken ausgeführt wurde ENTER.

Zum Schluss stellen wir das neue Widget vor zleund binden es an 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!