zsh 不会在提示符中重新加载函数

zsh 不会在提示符中重新加载函数

我试图让 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%vpsvar在提示字符串中引用。

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包含出现在主机名中的字符。

相关内容