gpt4 book ai didi

ZSH 提示替换问题

转载 作者:行者123 更新时间:2023-12-05 07:54:32 25 4
gpt4 key购买 nike

我已经在这里和通过 Google 搜索了几个答案,但我仍然不确定我的提示出了什么问题。

根据我读过的文档,这应该可行

setopt prompt_subst
autoload -U colors && colors
PROMPT="%{[00m[38;5;245m%}test %D%{[00m%}"

但是,我的提示如下:

[00m[38;5;245mtest 15-07-01[00m

请注意,日期扩展确实有效,因此提示替换有效。用于提示扩展的 ZSH 手册页指出 %{...%} 应该被视为原始转义码,但这似乎并没有发生。将该字符串传递给 print -P 也会产生上面的输出。我在 Internet 上找到了 ZSH 的示例提示,它们似乎也表明上述语法应该有效。参见 this举一个例子——$FG 和 $FX 数组填充了转义码并定义为 here .我通过合并上面的两个文件直接尝试了这个示例,将 setopt prompt_subst 添加到开头只是为了确保它已设置,然后获取它并且提示是一堆转义码。

以下作品

setopt prompt_subst
autoload -U colors && colors
PROMPT=$'%{\e[00m\e[38;5;245m%}test %D%{\e[00m%}'

我以正确的颜色获得了 test 15-07-01 的预期结果。

我已经在 OSX Yosimite 中的 ZSH 5.0.5、MacPorts 中的 5.0.7 和 Debian 中的 4.3.17 上进行了测试,结果相同。我知道我已经通过工作示例为我自己的问题提供了一个有效的解决方案,但我想知道为什么第一个语法没有像它应该的那样工作。

最佳答案

我认为这一切都与逃避这个永恒而永恒的问题有关。值得提醒我们自己什么是转义,简而言之:转义字符是向计算机发出的指示,表示后面的内容不应按字面意义输出。

因此存在 2 个转义问题: PROMPT="%{[00m[38;5;245m%}test %D%{[00m%}"

  1. 首先,颜色转义序列(例如 [00m )应该全部以控制字符开头,例如 \e[00m .您可能还看到它写成 ^[00m\003[00m .我怀疑发生的事情是,其中一个变体遭遇了共同的命运,即被作者的复制/粘贴或网站的框架堆栈无意中逃脱,无论是数据库中的某个地方、HTTP 渲染还是 JS 解析。您可能知道,控制字符(即 ^\e\003 )没有文字表示,比如您在键盘上按下它。这就是为什么 Web 堆栈如果在字符串中看到任何内容,可能会决定不显示任何内容。所以现在让我们更正一下:

    PROMPT="%{\e[00m\e[38;5;245m%}test %D%{\e[00m%}"

  2. 这实际上很好地引出了下一个转义问题。有点滑稽\e[实际上是 ESC 的代表,因此它本身就是一个转义序列标记,是的,它又被 \ 转义了.这是对旧的即兴重复\\\\\\\\\\有点像个笑话。现在,重要的是,我们必须清楚终端的转义表达式和提示的字符串替换之间的区别,在伪代码中:

    PROMPT="%{terminal colour stuff%}test %D%{terminal colour stuff%}"

    现在我怀疑正在发生的事情是,虽然我找不到任何文件来证明这一点,但一旦 ZSH 完成了替换,或者实际上在替换过程中,所有文字字符,无论转义符号如何,都会被提升为真实人物¹。为了进一步闹剧,这种提升可能是通过转义所有转义字符来完成的。例如,如果你真的想在命令行上打印 '\e',你必须做 echo "\\\e" .因此,要克服这个问题,我们只需要确保在将“终端颜色内容”转义序列分配给PROMPT 之前对其进行评估。这可以简单地用 $'' 来完成模式,像这样:

    PROMPT=$'%{\e[00m\e[38;5;245m%}test %D%{\e[00m%}'

    请注意 $''$()同类型和 ${} , 除了它的唯一功能是解释转义序列。

[1] 我对此的怀疑是基于这样一个事实,即您实际上可以执行以下操作:

PROMPT='$(date)'

哪里$(date)%D 的用途相同,通过为屏幕上的每个新提示输出打印一个实时版本的日期。这个具体例子说明的是PROMPT变量实际上应该被认为是一个迷你脚本的存储,而不是一个字符串(尽管这两个概念之间存在重叠,因此会造成混淆)。因此,作为脚本,字符串将首先 求值,然后然后 打印。我没有看过 ZSH 的提示渲染代码,但我认为这种评估会受益于转义序列的 native 使用。例如,如果您想将转义序列作为参数传递给提示中的命令(为每个提示呈现运行的命令)怎么办?例如,以下内容在功能上与上面讨论的提示相同:

PROMPT='%{$(print "\e[00m\e[38;5;245m")%}test $(date)%{$(print "\e[00m")%}'

转义序列按字面存储,仅在每次提示呈现时解释。

关于ZSH 提示替换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31166479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com