2012-08-09 21 views
12

Điều này có thể hơi lệch, nhưng gần đây tôi đã chuyển sang zsh và đang gặp sự cố khi tùy chỉnh dấu nhắc trình bao của tôi.zsh không tính lại dấu nhắc trình bao của tôi

Một phần của zshrc của tôi trông như thế này:

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

Khi tôi khởi động thiết bị đầu cuối, mọi thứ có vẻ tốt; nhắc tôi là những gì tôi mong đợi:

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

Nhưng khi tôi cd vào thư mục khác, nó xuất hiện chức năng parse_special của tôi không được gọi một lần nữa để recompute nhắc tôi tùy chỉnh (chú ý ngày không thay đổi):

[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 % 

Có cách nào tôi có thể yêu cầu zsh tính lại lời nhắc mỗi khi nó sắp hiển thị nó không?

cảm ơn rất nhiều vì bất kỳ đề xuất nào.


trả lời cjhveal

Nó có vẻ như PS1 không thích để có được thiết lập bởi giá trị niêm yết duy nhất. Tôi thử như sau:

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

Và có sản lượng này

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

Tôi cũng nên thêm, dựa trên gợi ý cjhveal của, đây là những gì tôi theo nghĩa đen cố gắng. Một lần nữa, các dấu nháy đơn dường như làm mọi thứ rối tung lên

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

Trả lời

14

Tôi gặp vấn đề tương tự khi tùy chỉnh lời nhắc của mình trong zsh.

Tôi tin rằng điều này xảy ra vì vỏ nội suy giá trị vào chuỗi một lần, khi lời nhắc được khởi tạo. Các lần tải lại tiếp theo có chuỗi không đổi trong lời nhắc của bạn, không phải là nội suy của vỏ con.

Thay vào đó, hãy đặt bất kỳ đường nào có liên quan đến subshells vào một biến được xác định với dấu nháy đơn. Sau đó, nội suy biến đó thay thế.

autoload -U colors && colors 

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

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

Cập nhật: Thêm từ câu trả lời của ZyX để tạo giải pháp hoàn chỉnh cho điều này. Bạn cũng cần phải thêm thông tin này:

setopt promptsubst 

Thực tế, tôi khuyên bạn nên trích xuất từng phần của lời nhắc của bạn thành biến như thế này, bao gồm reset_color trên mỗi biến. Làm như vậy cho phép bạn thay đổi thứ tự các thành phần nhanh chóng mà không thay đổi việc triển khai chúng.

+0

cảm ơn phản hồi. Tôi cảm thấy như đây là giải pháp đúng nhưng tôi vẫn phải làm điều gì đó sai (xem bản chỉnh sửa mà tôi đã thực hiện cho bài đăng gốc của mình). Có vẻ như tôi không thể sử dụng dấu nháy đơn ở đây. Bạn cũng có thể giải thích lý do tại sao sử dụng dấu nháy đơn là quan trọng trong thư trả lời của bạn? là var = "$ (do_stuff)" được xử lý khác với var = '$ (do_stuff)'? –

+0

Thử xóa% {%} được bọc quanh vỏ bọc. Tôi không biết tại sao, nhưng nó làm việc cho tôi mà không có chúng. Sự khác biệt giữa dấu nháy đơn và dấu ngoặc kép là cách vỏ thực hiện nội suy. var = "$ (do_stuff)" lập tức thực thi subshell và nội suy kết quả một lần. Khi bạn sử dụng dấu nháy đơn, subshell đó không được diễn giải, và vẫn là hằng số theo nghĩa đen cho đến thời điểm nó được nội suy thành một chuỗi có dấu ngoặc kép. Sau đó, nó được thực hiện. Về cơ bản, nó đợi cho đến khi lời nhắc được làm mới để thực hiện các subshells. – cjhveal

+1

@cjhveal '% {' '%}' kèm theo văn bản mà zsh nên xem là không có chiều rộng bằng 0 (thường là chuỗi lệnh cho thiết bị đầu cuối thực hiện một số điều với văn bản sau như thay đổi màu của nó). Nếu bạn đính kèm văn bản có độ rộng bằng 0, bạn sẽ vẫn hiển thị nó, nhưng với một số lỗi (ví dụ, khi bạn hoàn thành zsh sẽ nói cho terminal biết nó muốn con trỏ ở vị trí nào đó và đặt văn bản ở đó. '% { không-zero-width-text%} 'sẽ làm cho vị trí này sai và bạn nhận được văn bản ghi đè nhanh chóng và được tô màu trong màu nhắc). – ZyX

7

Bạn đang nửa đường đến giải quyết vấn đề này:

PS1='$(date)' 

sẽ cho bạn thấy nhắc $(date), nhưng

PS1='$(date)' 
setopt promptsubst 

sẽ cho bạn thấy nhắc Thu Aug 9 21:01:53 MSK 2012 (phụ thuộc vào $LANG$LC_TIME, tất nhiên) .

Bằng cách này, trong zsh mới nhất bạn không cần phải sử dụng %{$fg[blue]%} nữa, có nos %F{blue} cho foreground, %K{blue} cho nền, %f%k để đặt họ và một vài người khác, xem man zshmisc, phần EXPANSION OF PROMPT SEQUENCES.

+0

ah, vâng thiết lập nhắc nhở setopt là phần tôi đã mất tích. Cảm ơn rất nhiều. Tôi sẽ chỉnh sửa câu trả lời ở trên để thêm dòng đó để tạo ra câu trả lời hoàn chỉnh trong hai câu hỏi này. Cảm ơn một lần nữa. –

Các vấn đề liên quan