zsh没有重新计算我的shell提示符

D.C*_*.C. 14 shell zsh command-prompt

这可能有点边缘,但我最近转移到zsh并且我在定制shell提示符时遇到问题.

我的.zshrc的一部分看起来像这样:

# keeping this simple right now by just printing the date, but imagine this function would look for something specific when moving to a new directory each time
function parse_special {
    print $(date)
}

autoload -U colors && colors
PS1="%{$fg[green]%}%n@%m %{$fg[blue]%}%c %{$fg[yellow]%}%{$(parse_special)%} %{$reset_color%}%# "
Run Code Online (Sandbox Code Playgroud)

当我发射终端时,一切看起来都很好; 我的提示符合我的期望:

me@someHost ~ Wed Aug 8 22:56:22 PDT 2012 %
Run Code Online (Sandbox Code Playgroud)

但是当我cd到另一个目录时,似乎我的parse_special函数没有被再次调用来重新计算我的自定义提示(注意日期没有改变):

me@someHost ~ Wed Aug 8 22:56:22 PDT 2012 % cd .ssh 
me@someHost .ssh Wed Aug 8 22:56:22 PDT 2012 % cd ../workspace 
me@someHost workspace Wed Aug 8 22:56:22 PDT 2012 % 
Run Code Online (Sandbox Code Playgroud)

有什么办法我可以告诉zsh每次要显示它时重新计算提示吗?

非常感谢任何建议.


回复cjhveal

似乎PS1不喜欢用单引号值设置.我尝试了以下方法:

local tp1="%{$fg[green]%}%n@%m%{$reset_color%}"
PS1="${tp1}"
print "PS1 set by tp1: ${PS1}"
local tp2='%{$fg[green]%}%n@%m%{$reset_color%}'
PS1="${tp2}"
print "PS1 set by tp2: ${PS1}"
Run Code Online (Sandbox Code Playgroud)

得到了这个输出

#inner stuff was green
PS1 set by tp1: %{%}%n@%m%{%}
#everything was uncolored
PS1 set by tp2: %{$fg[green]%}%n@%m%{$reset_color%}
Run Code Online (Sandbox Code Playgroud)

我还要补充一点,根据cjhveal的建议,这是我真正尝试过的.再一次,单引号似乎搞砸了

function parse_special {    
    print $(date)
}

autoload -U colors && colors
local prompt_user='%{$fg[green]%}%n@%m%{$reset_color%}'
local prompt_root='%{$fg[red]%}%n@%m%{$reset_color%}'
local prompt_dir='%{$fg[blue]%}%c%{$reset_color%}'
local prompt_special='%{$fg[yellow]%}%{$(parse_special)%}%{$reset_color%}'
PS1="${prompt_user} ${prompt_dir}${prompt_special}%# "
Run Code Online (Sandbox Code Playgroud)

cjh*_*eal 16

我在自定义提示时遇到了同样的问题zsh.

我相信这是因为当初始化提示时,shell会将值插入字符串一次.后续重新加载在提示中具有常量字符串,而不是子shell插值.

相反,将任何涉及子壳的行放入用单引号定义的变量中.然后插入该变量.

autoload -U colors && colors

local parse_special='%{$fg[yellow]%}$(date)%{$reset_color%}'

PS1="%{$fg[green]%}%n@%m %{$fg[blue]%}%c ${parse_special} %# "
Run Code Online (Sandbox Code Playgroud)

更新:从ZyX的答案中添加此内容,为此制作完整的解决方案.你还需要添加这个:

setopt promptsubst
Run Code Online (Sandbox Code Playgroud)

事实上,我建议将提示的每个部分提取到这样的变量中,包括每个部分的reset_color.这样做可以让您更改提示组件的顺序,而无需更改其实现.

  • @cjhveal `%{` `%}` 包含 zsh 应视为零宽度的文本(通常是告诉终端对以下文本执行某些操作的序列,例如更改其颜色)。如果您在其中包含非零宽度文本,您仍然会显示它,但会出现许多错误(例如,当您完成 zsh 时,它会告诉终端它希望将光标放在某个位置并将文本放在那里。`%{非零宽度文本%}` 会使这个位置错误,并且您会得到覆盖提示并以提示颜色着色的文本)。 (2认同)

ZyX*_*ZyX 7

你解决这个问题的方法有一半:

PS1='$(date)'
Run Code Online (Sandbox Code Playgroud)

会告诉你提示$(date),但是

PS1='$(date)'
setopt promptsubst
Run Code Online (Sandbox Code Playgroud)

会告诉你提示Thu Aug 9 21:01:53 MSK 2012(取决于$LANG$LC_TIME,当然).

顺便说一句,在最新的zsh中你不需要再使用%{$fg[blue]%}了,%F{blue}前景,%K{blue}后台,%f%k重置它们和其他一些,请参见man zshmisc章节EXPANSION OF PROMPT SEQUENCES.