patternbashgitMinor
Coloured bash prompt including git status and previous exit code
Viewed 0 times
previousbashstatusexitcodeincludinggitcolouredandprompt
Problem
I wanted to create a short, informational and colourful prompt.
My prompt includes:
Example:
Is there a way to achieve a similar result with less lines of code?
In
`#
# Set the prompt #
#
# Select git info displayed, see /usr/lib/git-core/git-sh-prompt for more
export GIT_PS1_SHOWDIRTYSTATE=1 # '*'=unstaged, '+'=staged
export GIT_PS1_SHOWSTASHSTATE=1 # '$'=stashed
export GIT_PS1_SHOWUNTRACKEDFILES=1 # '%'=untracked
export GIT_PS1_SHOWUPSTREAM="verbose" # 'u='=no difference, 'u+1'=ahead by 1 commit
export GIT_PS1_STATESEPARATOR='' # No space between branch and index status
export GIT_PS1_DESCRIBE_STYLE="describe" # detached HEAD style:
# contains relative to newer annotated tag (v1.6.3.2~35)
# branch relative to newer tag or branch (master~4)
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
# default exactly eatching tag
# Check if we support colours
__colour_enabled() {
local -i colors=$(tput colors 2>/dev/null)
[[ $? -eq 0 ]] && [[ $colors -gt 2 ]]
}
unset __colourise_prompt && __colour_enabled && __colourise_prompt=1
__set_bash_prompt()
{
local exit="$?" # Save the exit status of the last command
# PS1 is made from $PreGitPS1 + + $PostGitPS1
local PreGitPS1="${debian_chroot:+($debian_chroot)}"
local PostGitPS1=""
if [[ $__colourise_prompt ]]; then
export GIT_PS1_SHOWCOLORHINTS=1
# Wrap the colour codes between \[ and \], so that
# bash counts the correct number of characters for line wrapping:
local Red='\[\e[0;31m\]'; local BRed='\[\e[1;31m\]'
local Gre='\[\e[0;32m\]'; local BGre='\[\e[1;32m\]'
local Yel='\[\e[0;33m\]'; local BYel='\[\e[1;33m\]'
local Blu
My prompt includes:
- Exit status of last command (if not 0)
- Distinctive changes when root
rsync-styleuser@host:pathnamefor copy-paste goodness
- Git branch, index, modified, untracked and upstream information
- Pretty colours
Example:
Is there a way to achieve a similar result with less lines of code?
In
~/.bashrc:`#
# Set the prompt #
#
# Select git info displayed, see /usr/lib/git-core/git-sh-prompt for more
export GIT_PS1_SHOWDIRTYSTATE=1 # '*'=unstaged, '+'=staged
export GIT_PS1_SHOWSTASHSTATE=1 # '$'=stashed
export GIT_PS1_SHOWUNTRACKEDFILES=1 # '%'=untracked
export GIT_PS1_SHOWUPSTREAM="verbose" # 'u='=no difference, 'u+1'=ahead by 1 commit
export GIT_PS1_STATESEPARATOR='' # No space between branch and index status
export GIT_PS1_DESCRIBE_STYLE="describe" # detached HEAD style:
# contains relative to newer annotated tag (v1.6.3.2~35)
# branch relative to newer tag or branch (master~4)
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
# default exactly eatching tag
# Check if we support colours
__colour_enabled() {
local -i colors=$(tput colors 2>/dev/null)
[[ $? -eq 0 ]] && [[ $colors -gt 2 ]]
}
unset __colourise_prompt && __colour_enabled && __colourise_prompt=1
__set_bash_prompt()
{
local exit="$?" # Save the exit status of the last command
# PS1 is made from $PreGitPS1 + + $PostGitPS1
local PreGitPS1="${debian_chroot:+($debian_chroot)}"
local PostGitPS1=""
if [[ $__colourise_prompt ]]; then
export GIT_PS1_SHOWCOLORHINTS=1
# Wrap the colour codes between \[ and \], so that
# bash counts the correct number of characters for line wrapping:
local Red='\[\e[0;31m\]'; local BRed='\[\e[1;31m\]'
local Gre='\[\e[0;32m\]'; local BGre='\[\e[1;32m\]'
local Yel='\[\e[0;33m\]'; local BYel='\[\e[1;33m\]'
local Blu
Solution
Solid script, nicely done.
"less lines of code"
when setting
It seems an unnecessary indirection.
You could drop this line:
And change this condition:
To this:
Some color variables are defined but never used.
But I would keep them anyway,
in case you (or somebody else) want to adjust the colors later
(they are not exactly easy to remember).
To shorten the code, you could rewrite some of the
In its current form it's nicely readable and good that way.
Undefined variables
When you detect that colors are enabled, you set a bunch of variables, for example
Although it may seem unlikely that these variables are set outside this script, it can happen,
and that will be confusing and possibly annoying.
The clean solution is to make sure to set those variables to blank when colors are not enabled.
Condition without pattern matching
The
In this example you don't need pattern matching,
so I suggest to replace it with
Coding style
You mixed two styles of function declaration:
It would be better to use consistent style (I prefer the first one).
"less lines of code"
__colour_enabled is used only once,when setting
__colourise_prompt, which in turn is also used only once.It seems an unnecessary indirection.
You could drop this line:
unset __colourise_prompt && __colour_enabled && __colourise_prompt=1And change this condition:
if [[ $__colourise_prompt ]]; thenTo this:
if __colour_enabled; thenSome color variables are defined but never used.
But I would keep them anyway,
in case you (or somebody else) want to adjust the colors later
(they are not exactly easy to remember).
To shorten the code, you could rewrite some of the
if statements in cmd && ... || ... form, but I don't recommend that.In its current form it's nicely readable and good that way.
Undefined variables
When you detect that colors are enabled, you set a bunch of variables, for example
Red, BRed, Mag, None. If colors are not enabled, you don't clear these variables, but they may be used anyway later in the script. Although it may seem unlikely that these variables are set outside this script, it can happen,
and that will be confusing and possibly annoying.
The clean solution is to make sure to set those variables to blank when colors are not enabled.
Condition without pattern matching
The
== operator in [[ is useful for pattern matching.In this example you don't need pattern matching,
so I suggest to replace it with
=, which will do simple literal comparison.if [[ ${EUID} == 0 ]]; thenCoding style
You mixed two styles of function declaration:
__colour_enabled() {
# ...
}
__set_bash_prompt()
{
# ...
}It would be better to use consistent style (I prefer the first one).
Code Snippets
unset __colourise_prompt && __colour_enabled && __colourise_prompt=1if [[ $__colourise_prompt ]]; thenif __colour_enabled; thenif [[ ${EUID} == 0 ]]; then__colour_enabled() {
# ...
}
__set_bash_prompt()
{
# ...
}Context
StackExchange Code Review Q#137799, answer score: 4
Revisions (0)
No revisions yet.