【问题标题】:ZSH Theme not updating from functionZSH 主题未从功能更新
【发布时间】:2019-07-30 00:58:04
【问题描述】:

我正在尝试编写一个 ZSH 主题,该主题根据 Git 状态(如果在 git 存储库中)显示特定字符​​。我以前在 Bash 中实现过这个主题,但是在迁移到 ZSH 时遇到了一些问题。这可能是我自己的错,但如果有人能提供帮助,将不胜感激。

我的主题的相关部分:

local jobs="%{$terminfo[bold]$fg[cyan]%}[%{$fg[magenta]%}%j%{$terminfo[bold]$fg[cyan]%}]%{$reset_color%}"
local git_branch='$(git_prompt_info)%{$reset_color%}'
local current_dir="%{$terminfo[bold]$fg[orange]%}%~%{$reset_color%}"

if [[ $UID -eq 0 ]]; then
    local user_host="%{$terminfo[bold]$fg[red]%}%n@%m%{$reset_color%}"
    local user_symbol="#"
else
    local user_host="%{$terminfo[bold]$fg[green]%}%n@%{$fg[red]%}%m%{$reset_color%}"
    local user_symbol="$"
fi

function git_has_unstaged() {
  if ! $(git diff-files --quiet --ignore-submodules --); then
      echo -n "%*! ";
  fi;
}

function git_has_uncommitted() {
  if [ ! $(git diff --quiet --ignore-submodules --cached; echo "${?}") = "0" ]; then
      echo -n "%*+ ";
  fi;
}

function git_has_untracked() {
  if [ -n "$(git ls-files --others --exclude-standard)" ]; then
      echo -n "%*? ";
  fi;
}

function git_has_stashed() {
  if $(git rev-parse --verify refs/stash &>/dev/null); then
      echo -n "%*$ ";
  fi;
}

function git_status_symbols() {
  echo -n "%{$terminfo[bold]$fg[blue]%}[";
  if [ $(git rev-parse --is-inside-work-tree &>/dev/null; echo "${?}") = "0" ]; then
    #Now is it Git repo
    if [ "$(git rev-parse --is-inside-git-dir 2> /dev/null)" = "false" ]; then
      # check if the current directory is in .git before running git checks
      # Ensure the index is up to date.
      git update-index --really-refresh -q &>/dev/null;
      git_has_uncommitted;
      git_has_unstaged;
      git_has_untracked;
      git_has_stashed;
    fi;
  fi;
  echo -n "]%{$reset_color%}";
}

PROMPT="╭─${user_host} ${current_dir} ${jobs} ${git_branch} $(git_status_symbols)
╰─%B${user_symbol}%b "
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}‹"
ZSH_THEME_GIT_PROMPT_SUFFIX="›%{$reset_color%}"

我的问题是提示中的 git_status_symbols 值没有根据 fs/git 中的更新进行更新。示例:

╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ git status
On branch bored
Your branch is up to date with 'origin/bored'.

nothing to commit, working tree clean
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ touch ./t
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ git_has_untracked
%*? %                                                                                                                                                                                                                                                                                                               ╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$ zsh
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:50:37? ]
╰─$
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:52:14? ]
╰─$ rm t
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:52:16? ]
╰─$ git_has_untracked
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› [1:52:22? ]
╰─$ zsh
╭─theonlyjohnny@phoenix ~/configs [0] ‹bored› []
╰─$

如您所见,虽然我的 git_has_untracked 函数正确地回显了一个 ?,但在我启动一个新的 shell 之前提示不会反映这一点。删除未跟踪的文件后,git_has_untracked 函数不再正确地回显任何内容。这里有趣的是,时间还在更新中。创建新的 shell 后,提示再次正确。

任何帮助表示赞赏!谢谢

【问题讨论】:

    标签: git shell themes zsh


    【解决方案1】:

    这是因为您的 PROMPT 变量包含命令替换 $(git_status_symbols)。此评估在分配期间发生一次,而不是在 PROMPT 的每次扩展时发生。

    解决此问题的最简单方法是使用填充psvar 数组的precmd,然后将该值以%v 的形式插入到提示符中。例如:

    precmd () { psvar[1]=$(git_status_symbols); }
    PROMPT="╭─${user_host} ${current_dir} ${jobs} ${git_branch} %1v
    ╰─%B${user_symbol}%b "
    

    另外,请注意 zsh 有自己的 vcs 支持(用于 Git 和其他),您可能希望也可能不想利用它来代替编写自定义代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-05
      • 2011-01-09
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多