ZSH:在命令运行之前更改提示

Suz*_*Soy 5 zsh prompt hook

我想在 中有一个两行提示zsh,但在按下 后将它折叠成一个非常小的提示ENTER,这样它就不会出现在终端滚动历史记录中。键入两个命令后,终端在键入第三个命令时应如下所示:

> echo Command 1
Command 1
> echo Command 2
Command 2
+------------ Long prompt ----------+
`> echo typing a new command here…
Run Code Online (Sandbox Code Playgroud)

我试着用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 ----------+
`> 
Run Code Online (Sandbox Code Playgroud)

mpy*_*mpy 8

preexec函数被调用时,zle已经完成,因此,不能再使用 zle 小部件。

因此,您必须ENTERzle终止之前拦截按键的按下。默认情况下ENTER绑定到accept-line,但这可能取决于您已经使用的其他技巧;

$ bindkey | grep '\^M'
"^M" accept-line
Run Code Online (Sandbox Code Playgroud)

我们现在编写一个我们想要绑定的新小部件ENTER

del-prompt-accept-line() {
    OLD_PROMPT="$PROMPT"
    PROMPT="> "
    zle reset-prompt
    PROMPT="$OLD_PROMPT"
    zle accept-line
}
Run Code Online (Sandbox Code Playgroud)

逻辑取自您的方法。在最后一行中,我们调用accept-line小部件或其他任何在按下时执行的东西ENTER

最后,我们引入新的小部件zle并将其绑定到ENTER

zle -N del-prompt-accept-line
bindkey "^M" del-prompt-accept-line
Run Code Online (Sandbox Code Playgroud)

等等:

> echo foo bar
foo bar
+------------ Long prompt ----------+
`> echo this is my new command... not pressed ENTER, yet!
Run Code Online (Sandbox Code Playgroud)