开发者

broken bash prompt wrap line

I'm customizing my bash prompt on OsX to include git branch plus some marks of the branch state. This breaks line wrap.

I know that I have to add \[ and \] to prevent this issue, but doing so in the functions does display \[ and \] litteraly.

What can I do to escape such sequences in those functions?

Disclaimer: those are my first attempts in bash scripting.

function parse_git_dirty {
  # TODO make git status response a variable
  # [branch+] : working dir has staged changes
  if [[ $(git status 2> /dev/null | grep "to be committed") ]]
  then S=$S"$(tput setaf 2)+$(tput sgr0)"
  fi
  # [branch+] : working dir has unstaged changes
  if [[ $(git status 2> /dev/null | grep "not staged for commit") ]]
  then S=$S"$(tput setaf 1)+$(tput sgr0)"
  fi
  # [branch+] : working dir has untracked files
  if [[ $(git status 2> /dev/null | grep "tracked files") ]]
  then S=$S"$(tput setaf 1)+$(tput sgr0)"
  fi
  # [branch<] : local branch is behind origin
  if [[ $(git status 2> /dev/null | grep "Your branch is behind") ]]
  then S=$S"$(tput setaf 5)<$(tput sgr0)"
  fi
  # [branch>] : local branch is ahead origin
  if [[ $(git status 2> /dev/null | grep "branch is ahead of") ]]
  then S=$S"$(tput setaf 5)>$(tput sgr0)"
  fi
  # [branch<>] : branches have diverged
  if [[ $(git status 2> /dev/null | grep "have diverged") ]]
  then S=$S"$(tput setaf 5)<>$(tput sgr0)"
  fi
  echo $S
}
function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '开发者_如何学Go/^[^*]/d' -e 's/* \(.*\)/\1/'
}
function show_git_branch {
  if [[ $(parse_git_branch) ]]
  then echo "$(tput setaf 2)($(tput sgr0)$(parse_git_branch)$(parse_git_dirty)$(tput setaf 2))$(tput sgr0)"
  fi
}
export PS1="\u\[$(tput setaf 2)\]@\[$(tput sgr0)\]\h\[$(tput setaf 2)\]:\[$(tput sgr0)\]\W\[\$(show_git_branch)\] "


I glad to hear that you've solved the problem with your version, but I thought it might be worth pointing out that git is already distributed with a helpful and carefully thought out bash function called __git_ps1 that you can include in your PS1. For example, you could use it like this:

 export PS1='blah blah blah$(__git_ps1 " (%s)") '

If you're not in a git repository, the $(__git_ps1 " (%s)") will turn into the empty string. If you are, however, then the format string will be used. That will usually show you your current branch, but if you're in the middle of a merge or a rebase that will be shown instead.

By default __git_ps1 won't show you whether the tree is dirty or there are untracked files, since in certain repositories this could make it irritatingly slow for your bash prompt to appear. However, if you want to see this information as well, it'll show them if you set GIT_PS1_SHOWDIRTYSTATE or GIT_PS1_SHOWUNTRACKEDFILES to something non-empty.

You can find more information at the top of the git-completion.sh source file.


You need single quotes around the value in the assignment:

export PS1='\u\[$(tput setaf 2)\]@\[$(tput sgr0)\]\h\[$(tput setaf 2)\]:\[$(tput sgr0)\]\W\[$(show_git_branch)\] '

Since the contents are evaluated when the prompt is issued, you don't need double quotes as you would in other circumstances.


Thanks to Dennis, the corrected code is:

function parse_git_dirty {
  # TODO make git status response a variable
  # [branch+] : working dir has staged changes
  if [[ $(git status 2> /dev/null | grep "to be committed") ]]
  then S=$S"$(tput setaf 2)+$(tput sgr0)"
  fi
  # [branch+] : working dir has unstaged changes
  if [[ $(git status 2> /dev/null | grep "not staged for commit") ]]
  then S=$S"$(tput setaf 1)+$(tput sgr0)"
  fi
  # [branch+] : working dir has untracked files
  if [[ $(git status 2> /dev/null | grep "tracked files") ]]
  then S=$S"$(tput setaf 1)+$(tput sgr0)"
  fi
  # [branch<] : local branch is behind origin
  if [[ $(git status 2> /dev/null | grep "Your branch is behind") ]]
  then S=$S"$(tput setaf 5)<$(tput sgr0)"
  fi
  # [branch>] : local branch is ahead origin
  if [[ $(git status 2> /dev/null | grep "branch is ahead of") ]]
  then S=$S"$(tput setaf 5)>$(tput sgr0)"
  fi
  # [branch<>] : branches have diverged
  if [[ $(git status 2> /dev/null | grep "have diverged") ]]
  then S=$S"$(tput setaf 5)<>$(tput sgr0)"
  fi
  echo $S
}
function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}
function show_git_branch {
  if [[ $(parse_git_branch) ]]
  then echo "$(tput setaf 2)($(tput sgr0)$(parse_git_branch)$(parse_git_dirty)$(tput setaf 2))$(tput sgr0)"
  fi
}
export PS1='\u\[$(tput setaf 2)\]@\[$(tput sgr0)\]\h\[$(tput setaf 2)\]:\[$(tput sgr0)\]\W\[$(show_git_branch)\] '
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜