【问题标题】:Using vcs_info in zsh custom prompt with promptinit在 zsh 自定义提示中使用 vcs_info 和 promptinit
【发布时间】:2021-03-28 17:39:18
【问题描述】:

目前在我的.zshrc 我有以下几行来提供一些 git 信息:

autoload -Uz vcs_info
precmd_vcs_info() { vcs_info }
precmd_functions+=( precmd_vcs_info )
setopt prompt_subst
RPROMPT=\$vcs_info_msg_0_
zstyle ':vcs_info:git:*' formats '%b'

这使我的 shell 如下所示:

[me@computer dir]$                                                                  main

我想将此配置从.zshrc 移出并移到使用promptinit 初始化的自定义提示中。此配置位于我的fpath 上的一个名为prompt_mycustomprompt_setup 的文件中。配置如下:

precmd_vcs_info() {
    vcs_info
}

prompt_mycustomprompt_setup () {
    autoload -Uz add-zsh-hook vcs_info
    setopt prompt_subst
    add-zsh-hook precmd precmd_vcs_info
    RPROMPT=\$vcs_info_msg_0_
    zstyle ':vcs_info:git:*' formats '%b'

    PS1='(test)> '
}

prompt_mycustomprompt_setup "$@"

然后我从.zshrc 中删除了相关行并替换为以下行:

autoload -Uz promptinit
promptinit

prompt mycustomprompt

但是,vcs_info 没有显示,而是在我的提示中有一个恒定的静态值 $vcs_info_msg_0_

(test)>                                                         $vcs_info_msg_0_

为什么我的提示不符合预期?

【问题讨论】:

    标签: zsh prompt zshrc


    【解决方案1】:

    发生这种情况是因为函数中的语句 setopt promptsubstprompt 函数内部执行,该函数执行 setopt localoptions。因此,当prompt 返回时,该选项将重置为默认值。

    promptinit 主题应该是 set the prompt_opts array,而不是直接设置 shell 选项:

    数组prompt_opts 可以分配"bang""cr""percent""sp" 和/或"subst" 作为值。对应的setopts(promptbang等)开启,其他所有提示相关的选项都关闭。

    因此,为了提示您使用 setopt promptsubst,您应该在您的 setup 函数中执行以下操作:

    prompt_opts=(cr percent sp subst)
    

    然而,正如Zsh mailing list 中提到的,Zsh 开发人员通常建议使用promptsubst,因为这样可以

    • 在您意想不到的地方出现副作用(例如使用 print -P 时)和/或
    • 导致性能不佳(提示中的表达式比预期的要昂贵,并且每当重绘提示时都会重新计算)。

    为确保最佳性能和稳定性,我建议改为这样做:

    prompt_mycustomprompt_precmd() {
        vcs_info
        RPS1=" $vcs_info_msg_0_"
    }
    
    prompt_mycustomprompt_setup () {
        autoload -Uz vcs_info
        add-zsh-hook precmd prompt_mycustomprompt_precmd   
        zstyle ':vcs_info:git:*' formats '%b'
    
        prompt_opts=( cr percent sp )
        PS1='(test)> '
    }
    
    prompt_mycustomprompt_setup "$@"
    

    请注意,我还重命名了您的precmd 钩子函数,因为所有prompinit 钩子函数名称都应该遵循prompt_<theme>_<hook> 模式,以便在切换主题时the prompt function can automatically unhook them

    此外,promptinit 主题应该使用较短的 $PS1$RPS1 等,而不是 $PROMPT$RPROMPT 等。

    【讨论】:

    • 太棒了 - 也感谢您提供如此详细的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 2011-05-26
    相关资源
    最近更新 更多