繁体   English   中英

将parse_git_branch函数从bash转换为zsh(用于提示)

[英]Translate parse_git_branch function to zsh from bash (for prompt)

我在Bash中使用此功能

function parse_git_branch {
  git_status="$(git status 2> /dev/null)"
  pattern="^# On branch ([^${IFS}]*)"
  if [[ ! ${git_status}} =~ "working directory clean" ]]; then
    state="*"
  fi
  # add an else if or two here if you want to get more specific

  if [[ ${git_status} =~ ${pattern} ]]; then
    branch=${BASH_REMATCH[1]}
    echo "(${branch}${state})"
  fi
}

但我决定使用zsh。 虽然我可以在我的.zshrc中完美地使用它作为shell脚本(即使没有shebang), if [[ ! ${git_status}}错误是此行上的解析错误if [[ ! ${git_status}} if [[ ! ${git_status}} ...

我需要做些什么才能为zshell做好准备?

编辑:我得到的“实际错误”是" parse error near } ,它指的是带有奇怪的双重}} ,它适用于Bash。

编辑:这是最终的代码,只是为了好玩:

parse_git_branch() {
    git_status="$(git status 2> /dev/null)"
pattern="^# On branch ([^[:space:]]*)"
    if [[ ! ${git_status} =~ "working directory clean" ]]; then
        state="*"
    fi
    if [[ ${git_status} =~ ${pattern} ]]; then
      branch=${match[1]}
      echo "(${branch}${state})"
    fi
}

setopt PROMPT_SUBST
PROMPT='$PR_GREEN%n@$PR_GREEN%m%u$PR_NO_COLOR:$PR_BLUE%2c$PR_NO_COLOR%(!.#.$)'
RPROMPT='$PR_GREEN$(parse_git_branch)$PR_NO_COLOR'

感谢大家的耐心和帮助。

编辑:最好的答案是我们所有人: git status是瓷器(UI)。 好的脚本与GIT管道相悖。 这是最后的功能:

# The latest version of Chris' function below

PROMPT='$PR_GREEN%n@$PR_GREEN%m%u$PR_NO_COLOR:$PR_BLUE%2c$PR_NO_COLOR%(!.#.$)'
RPROMPT='$PR_GREEN$(parse_git_branch)$PR_NO_COLOR'

请注意,只有提示符是特定于zsh的。 在Bash中,它将是你的提示加上"\\$(parse_git_branch)"

这可能会更慢(更多的GIT调用,但这是一个经验问题)但它不会被GIT的变化打破(它们不会改变管道)。 这对于一个好的脚本来说非常重要。

你应该使用Git“plumbing”命令来提取你想要的信息。 “瓷器”命令(例如git status )的输出可能会随着时间的推移而改变,但“管道”命令的行为会更加稳定。

使用瓷器接口,它也可以在没有“bashisms”或“zshisms”的情况下完成(即=~匹配运算符):

parse_git_branch() {
    in_wd="$(git rev-parse --is-inside-work-tree 2>/dev/null)" || return
    test "$in_wd" = true || return
    state=''
    git update-index --refresh -q >/dev/null # avoid false positives with diff-index
    if git rev-parse --verify HEAD >/dev/null 2>&1; then
        git diff-index HEAD --quiet 2>/dev/null || state='*'
    else
        state='#'
    fi
    (
        d="$(git rev-parse --show-cdup)" &&
        cd "$d" &&
        test -z "$(git ls-files --others --exclude-standard .)"
    ) >/dev/null 2>&1 || state="${state}+"
    branch="$(git symbolic-ref HEAD 2>/dev/null)"
    test -z "$branch" && branch='<detached-HEAD>'
    echo "${branch#refs/heads/}${state}"
}

将输出集成到提示符中仍然是特定于shell的(即转义或引用$ (对于bashzsh )并设置PROMPT_SUBST(对于zsh ))。

摆脱额外} ${git_status}}应为${git_status}


一旦删除了额外的} ,我看到的唯一潜在问题是使用${BASH_REMATCH[1]} 您可以在zsh中使用它,但它需要启用该选项才能执行此操作。 正如条件表达式上的zsh文档所示,您需要使用类似的东西

if [[ ${git_status} =~ ${pattern} ]]; then
  branch=${match[1]}
  echo "(${branch}${state})"
fi

您可以使用数组match而不是$BASH_REMATCH 你也可以逃脱额外的大括号。

未经测试:

function parse_git_branch {
  git_status="$(git status 2> /dev/null)"
  pattern="^# On branch ([^${IFS}]*)"
  if [[ ! ${git_status}\} =~ "working directory clean" ]]; then
    state="*"
  fi
  # add an else if or two here if you want to get more specific

  if [[ ${git_status} =~ ${pattern} ]]; then
    branch=${match[1]}
    echo "(${branch}${state})"
  fi
}

尝试一下,看看它是否有帮助。

如果你不想学习zsh,我建议你使用另一种语言,比如Python,进行那种解析。

在github上查看git status Python解析器zsh-git-prompt项目 ,了解如何为git获取一个不错的zsh提示符。

如果您收到错误failed to compile regex: illegal byte sequence然后从IFS中删除NULL。 (将${IFS}替换${IFS} ${IFS//$'\\0'/} )。

可能是这个zsh Git存储库将包含测试,它可以给你一些线索:

为了防止任何人有兴趣看到git-prompt功能的替代解决方案,我已经在github.com上发布了这个脚本,但是为了更容易,你可以从这里获得它。

它对我很有用,希望它对你也一样。

## Setting Prompt Colour(s):
invColor="$(tput rev)";   ## tput rev - Inverse
resColor="$(tput sgr0)";  ## tput sgr0 - Reset

## Custom Prompt Colour(s):
_BlackBG="$(tput setab 0)";
bGreenFG="$(tput bold; tput setaf 2)";
bMagentaFG="$(tout bold; tput setaf 5)";
bRedFG="$(tput bold; tput setaf 1)";
bBlueFG="$(tput bold; tput setaf 4)";
bCyanFG="$(tput bold; tput setaf 6)";
bWhiteFG="$(tput bold; tput setaf 7)";

## Define Enclosing-character(s):
_Bracket="${resColor}${_BlackBG}${bWhiteFG}";
oBracket="${_Bracket}["; cBracket="${_Bracket}]${resColor}";

## Bold-Foreground Color(s):
## tput bold - Bold

function git_branch () {
# git_branch() { git name-rev HEAD 2> /dev/null | sed 's#HEAD\ \(.*\)#git::\1#'; }
    git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/git::\1/';
    return 0;
  }

## Version Control System - Active Working Copy:
function get_branch () {
    xBranch="`git_branch`";
    if [[ "${xBranch}" =~ "git::master" ]]; then
        xBranch="git::${bWhiteFG}master";
      else xBranch="`echo ${xBranch}|sed -e 's/git:://g'`";
        xBranch="branch::${bGreenFG}${xBranch}";
    fi
    if git rev-parse --git-dir >/dev/null 2>&1; then
        _pVCS="";
        if git diff --quiet 2>/dev/null >&2; then
          if [[ "${xBranch}" =~ "git::" ]]; then
              _pVCS="${bGreenFG}${xBranch}";
            else _pVCS="${bMagentaFG}${xBranch}";
          fi
          else _pVCS="${bRedFG}${xBranch}";
        fi
      else return 0;
    fi
    if [[ "${_pVCS}" =~ "no branch" ]]; then
      xTAG="`git tags|awk '{print $3}'|sed -e 's/[,;)]//g'`";
      _pVCS="${bBlueFG}tag::${bCyanFG}${xTAG}";
    fi
## Output Git Active-Repo ID:
   if [[ "${_pVCS}" =~ [::] ]]; then
      echo -ne "${oBracket}${_BlackBG}${_pVCS}${cBracket}";
   fi
#    return 0;
  }

用法:

declare PS1='\[\033[01;36m\]\u\[\033[01;31m\]@\[\033[01;32m\]\h\[\033[00m\]:\[\033[01;33m\]\w $(get_branch) \[\033[01;31m\]${XPT}\[\033[00m\] '

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM