2012-08-09 51 views
12

這可能有點偏離,但我最近搬到了zsh,並且在定製我的shell提示時遇到問題。我的.zshrc的zsh沒有重新計算我的shell提示

部分看起來是這樣的:

# 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]%}%[email protected]%m %{$fg[blue]%}%c %{$fg[yellow]%}%{$(parse_special)%} %{$reset_color%}%# " 

當我啓動終端,一切都看起來不錯;我的提示是我所期望的:

[email protected] ~ Wed Aug 8 22:56:22 PDT 2012 % 

但是,當我cd到另一個目錄,它出現在我的parse_special功能不叫再重新計算我的自定義提示(通知的日期沒有改變):

[email protected] ~ Wed Aug 8 22:56:22 PDT 2012 % cd .ssh 
[email protected] .ssh Wed Aug 8 22:56:22 PDT 2012 % cd ../workspace 
[email protected] workspace Wed Aug 8 22:56:22 PDT 2012 % 

有沒有什麼辦法可以讓zsh在每次要顯示它時重新計算提示?

非常感謝您的任何建議。


回覆cjhveal

好像PS1不喜歡得到由單引號值設定。我試過如下:

local tp1="%{$fg[green]%}%[email protected]%m%{$reset_color%}" 
PS1="${tp1}" 
print "PS1 set by tp1: ${PS1}" 
local tp2='%{$fg[green]%}%[email protected]%m%{$reset_color%}' 
PS1="${tp2}" 
print "PS1 set by tp2: ${PS1}" 

,並得到這個輸出

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

我還要補充的基礎上,cjhveal的建議,這裏是我從字面上嘗試。再次,單引號似乎搞亂了事情

function parse_special {  
    print $(date) 
} 

autoload -U colors && colors 
local prompt_user='%{$fg[green]%}%[email protected]%m%{$reset_color%}' 
local prompt_root='%{$fg[red]%}%[email protected]%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}%# " 

回答

14

我遇到了同樣的問題,同時在zsh定製我的提示。

我相信會發生這種情況,因爲當初始化提示符時,shell會將值插入字符串中一次。隨後的重新加載在提示中具有常量字符串,而不是subshel​​l內插。

相反,將涉及子殼體的所有行放入用單引號定義的變量中。然後插入該變量。

autoload -U colors && colors 

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

PS1="%{$fg[green]%}%[email protected]%m %{$fg[blue]%}%c ${parse_special} %# " 

更新:從ZyX的答案中添加這個來做出完整的解決方案。您還需要補充一點:

setopt promptsubst 

其實,我建議你抽取迅速的每一部分成這樣的變量,包括每個reset_color。這樣做可以讓您更改提示組件的順序而不更改其實現。

+0

感謝您的回覆。我覺得這是正確的解決方案,但我仍然必須做錯了什麼(請參閱我對原始文章的編輯)。似乎我不能在這裏使用單引號。 你也可以解釋爲什麼在你的回覆中使用單引號很重要嗎? var =「$(do_stuff)」的處理方式與var ='$(do_stuff)'不同? – 2012-08-09 07:08:26

+0

嘗試刪除環繞子外殼的%{%}。我不知道爲什麼,但沒有它們,它對我有用。 單引號和雙引號之間的區別在於shell如何執行插值。 var =「$(do_stuff)」立即執行子shell並插入一次結果。當您使用單引號時,該子外殼不會被解釋,並且保持爲文字常量,直到它被插入帶有雙引號的字符串爲止。然後它被執行。本質上,它一直等到提示刷新以執行子殼。 – cjhveal 2012-08-09 14:06:31

+1

@cjhveal'%{''%}'包含zsh應該認爲是零寬度的文本(通常是指示終端使用以下文本做某些事情的序列,例如更改其顏色)。如果你將非零寬度的文本放入它們中,你仍然會顯示它,但是會有一些bug(例如,當你完成zsh時,告訴終端它希望光標放在某個位置並放置文本)'%{非零寬度文本%}'會使這個位置錯誤,並且你得到的文本覆蓋了提示符並且被提示顏色着色)。 – ZyX 2012-08-09 17:18:29

7

您是一半的方式來解決這個問題:

PS1='$(date)' 

會告訴你提示$(date),但

PS1='$(date)' 
setopt promptsubst 

會告訴你提示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

+0

啊,是的設置setopt promptsubst是我失蹤的一塊。非常感謝。我將編輯上面的答案以添加該行,從而完成這兩個答案。再次感謝。 – 2012-08-09 17:22:13