由于 zsh 提示符的丑陋黑客攻击导致自动完成怪异

由于 zsh 提示符的丑陋黑客攻击导致自动完成怪异

目前我的 .zshrc 中有以下行:

export PROMPT=$(printf "\e[38;5;6m")%m$(printf "\e[m")%d-%h:" "

它应该以蓝色显示主机名,以正常终端颜色显示历史记录和当前工作目录。我不太确定如何描述它,但是当您指定第一个(几个)字母并且几个文件名与其匹配时,会发生意想不到的奇怪现象。很难描述,只要尝试一下就可以了。

截图:

完成前:
完成之前

点击后Tab显示可能的完成情况: 完成后

答案1

您已经完全禁止了 zsh 关于打印内容以及必须擦除/重写内容的想法,因为它显示菜单完成并允许您编辑命令行。这是因为您将该提示过于复杂化了。

  • 不要printf仅将字符串文字放入单词中。
  • 不要使用硬连线 CSI 控制序列来更改颜色。

正如我所说https://superuser.com/a/695350/38062,Z Shell 知道诸如此类的事情%F{green}不会打印序列,而无需告知;它还可以从 中计算出正确的转义序列terminfo,而无需将它们硬连线。

PROMPT="%B%F{蓝色}%m%f%b%d-%h: "

进一步阅读

答案2

Zsh 需要知道提示符的宽度才能正确定位光标位置。如果它假定提示宽度的值不正确,则在重绘命令行时,它将在错误的位置写入文本。这就是 zsh 移动到下一行以显示可能的完成后发生的情况:它在它认为应该出现的位置重新绘制要完成的命令。

您的提示包含宽度为零的转义序列:它们的效果是更改以下文本的外观。 Zsh 不知道这一点:它假设每个字符的宽度为 1,除非另有说明。要告诉 zsh 提示的一部分宽度为零,请将其括起来%{…%}

PROMPT=%{$(printf "\e[38;5;6m")%}%m%{$(printf "\e[m")%}%d-%h:" "

您可以简化这一点:无需调用printf,您可以使用$'…'语法包含反斜杠转义符。

PROMPT=$'%{\e[38;5;6m%}%m%{\e[m%}%d-%h: '

不要导出PROMPT:它是一个内部 shell 变量,而不是其他应用程序应该看到的环境变量。

Zsh 具有提示转义序列,可以通过简单的方式更改文本外观。我不确定你打算做什么38;5;6。粗体蓝色是34;1,或者使用 zsh 提示符转义,

PROMPT='%F{blue}%B%m%b%f%d-%h: '

相关内容