我试图让 zsh 提示符在每次加载新提示符时重新加载一个函数。该函数输出 的一个版本,pwd
但更短,如果 的输出pwd
是~/Downloads/Folder
该函数将输出~/D/Folder
。该函数可以工作,但如果我更改目录则不会重新加载。这是 zsh 的问题,而不是该函数的问题,因为该函数在 ksh 和 csh 中工作正常。我不使用 oh-my-zsh。函数是_collapsed_pwd
,文件是$SHELLDIR/cpwdrc
。
这是我的.zshrc
文件
export SHELLDIR="$XDG_CONFIG_HOME/shells"
export ZSH="$SHELLDIR/zsh"
export HISTFILE="$XDG_DATA_HOME"/zsh/history
autoload -U +X compinit && compinit
fpath=($ZSH/plugins/zsh-completions/src $fpath)
compinit -d $XDG_CACHE_HOME/zsh/zcompdump-artix-5.8
source $SHELLDIR/aliasrc
source $SHELLDIR/colorsrc # contians color substituions
source $SHELLDIR/cpwdrc # contains _collapsed_pwd
source $ZSH/plugins/fzf-tab/fzf-tab.zsh
source $ZSH/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
setopt prompt_subst
PS1=$(printf "${BOLD}${BLUE}%s${NORM}@%s:[${BLUE}%s${NORM}]:$ " $USER $(hostname) $(_collapsed_pwd) )
这是该函数的代码_collapsed_pwd
#!/bin/sh
## Collapsed Directory
_collapsed_pwd() {
pwd | perl -pe '
BEGIN {
binmode STDIN, ":encoding(UTF-8)";
binmode STDOUT, ":encoding(UTF-8)";
}; s|^$ENV{HOME}|~|g; s|/([^/.])[^/]*(?=/)|/$1|g; s|/\.([^/])[^/]*(?=/)|/.$1|g
'
}
答案1
.zshrc
处理时提示的内容一劳永逸。您的代码中没有任何内容表明当前目录更改时更改提示的内容。
一种解决方案是将更改提示的代码放在chpwd
钩。删除,setopt prompt_subst
因为您不会对 的内容进行任何评估PS1
。
function set_prompt {
PS1=$(printf "${BOLD}${BLUE}%s${NORM}@%s:[${BLUE}%s${NORM}]:$ " $USER $(hostname) "${$(_collapsed_pwd)//\%/%%}" )
}
chpwd_functions+=(set_prompt)
cd .
说明:
cd .
zsh 启动时触发chpwd
一次钩子,以便初始设置提示。- 如果输出包含空格,命令替换周围的双引号可防止将其拆分为单独的单词。
- 将变化
${…//\%/%%}
的输出替换为because将被解释为_collapsed_pwd
%
%%
%
迅速逃脱1.
或者,请设置prompt_subst
选项并设置PS1
为包含每次显示提示时都会计算的代码的字符串。
setopt prompt_subst
PS1='$(printf "${BOLD}${BLUE}%s${NORM}@%s:[${BLUE}%s${NORM}]:$ " $USER $(hostname) "${$(_collapsed_pwd)//\%/%%}" )'
你可以使用 zsh 来简化这个过程在提示中包含变量数据的内置功能。首先,这是一个显示当前目录的最后两个组成部分的提示:
unsetopt prompt_subst
PS1='%B%F{blue}%n%f%b@%m:[%F{blue}%2~%f]:%(!.#.$) '
要缩写目录组件,我认为您必须运行一些 zsh 代码,无论是通过钩子chpwd
还是通过prompt_subst
.为了避免与扩展相关的复杂性,请使用chpwd
钩子来设置psvar
和%v
psvar
在提示字符串中引用。
unsetopt prompt_subst
PS1='%B%F{blue}%n%f%b@%m:[%F{blue}%1v%f]:%(!.#.$) '
function abbreviate_pwd {
psvar[1]=${(%):-%~}
while [[ $psvar[1] =~ /[^/][^/]+/ ]]; do
psvar[1]=${psvar[1][1,MBEGIN+1]}${psvar[1][MEND,-1]}
done
}
chpwd_functions+=(abbreviate_pwd)
cd .
1为了获得额外的鲁棒性,$USER
(另请参阅$USERNAME
自动设置zsh
)和$(hostname)
(另请参阅$HOST
自动设置zsh
)也应受到保护,但它们通常不包含任何有问题的字符,假设您不将 的值更改为IFS
包含出现在主机名中的字符。