zsh not re-computing my shell prompt

匿名 (未验证) 提交于 2019-12-03 02:29:01

问题:

This might be a bit fringe, but I recently moved to zsh and am having a problem customizing my shell prompt.

Part of my .zshrc looks like this:

# 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%}%# "

When I launch terminal, everything looks good; my prompt is what I expect:

me@someHost ~ Wed Aug 8 22:56:22 PDT 2012 %

But when I cd to another directory, it appears my parse_special function is not called again to recompute my custom prompt (notice the date is not changing):

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 % 

Is there any way I can tell zsh to recompute the prompt each time it is about to show it?

thanks a lot for any suggestions.


reply to cjhveal

It seems like PS1 does not like to get set by single quoted values. I tried the following:

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}"

And got this output

#inner stuff was green PS1 set by tp1: %{%}%n@%m%{%} #everything was uncolored PS1 set by tp2: %{$fg[green]%}%n@%m%{$reset_color%}

I should also add, based on cjhveal's suggestion, here is what I literally tried. Again, the single quotes seem to be messing things up

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}%# "

回答1:

I ran into the same problem while customizing my prompt in zsh.

I believe this happens because the shell interpolates the value into the string once, when the prompt is initialized. Subsequent reloads have the constant string in your prompt, not the subshell interpolation.

Instead, put any lines that involve subshells into a variable defined with single quotes. Then interpolate that variable instead.

autoload -U colors && colors  local parse_special='%{$fg[yellow]%}$(date)%{$reset_color%}'  PS1="%{$fg[green]%}%n@%m %{$fg[blue]%}%c ${parse_special} %# "

Update: Adding this from ZyX's answer to make a complete solution for this. You also need to add this:

setopt promptsubst

In fact, I would suggest extracting each part of your prompt into a variable like this, including a reset_color on each. Doing so lets you change the order of prompt components without changing their implementation.



回答2:

You are half the way to solving this problem:

PS1='$(date)'

will show you prompt $(date), but

PS1='$(date)' setopt promptsubst

will show you prompt Thu Aug 9 21:01:53 MSK 2012 (depends on $LANG and $LC_TIME, of course).

By the way, in the newest zsh you don’t need to use %{$fg[blue]%} anymore, there is nos %F{blue} for foreground, %K{blue} for background, %f%k for resetting them and a few others, see man zshmisc, section EXPANSION OF PROMPT SEQUENCES.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!