From c29d55e131e6c01fb37ebd0d9fe359d37c64c38e Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Mon, 3 Mar 2014 15:19:04 +0100 Subject: [PATCH] bash prompt with segments (on par with zsh) --- bash/ansi_colors | 54 ++++++++++++++++++------ bash/prompt | 95 +++++++++++++++++-------------------------- bash/prompt_segments | 73 +++++++++++++++++---------------- bash/rc | 5 +++ shell/prompt_segments | 4 ++ shell/prompt_vcs | 69 +++++++++++++++++++++++++++++++ zsh/prompt | 81 +++++------------------------------- 7 files changed, 205 insertions(+), 176 deletions(-) create mode 100644 shell/prompt_vcs diff --git a/bash/ansi_colors b/bash/ansi_colors index cc4d9ae..b5de7de 100644 --- a/bash/ansi_colors +++ b/bash/ansi_colors @@ -1,16 +1,17 @@ -local NONE="\[\033[0m\]" # reset all attributes -local DEFAULT="\[\033[0;39m\]" # reset fg to default -local BGDEFAULT="\[\033[0;49m\]" # reset bg to default +# defaults +local Z="\[\033[0m\]" # reset (zero) all attributes +local N="\[\033[0;39m\]" # reset fg to default (none) +local BGN="\[\033[0;49m\]" # reset bg to default (none) # normal colors -local K="\[\033[0;30m\]" # black -local R="\[\033[0;31m\]" # red -local G="\[\033[0;32m\]" # green -local Y="\[\033[0;33m\]" # yellow -local B="\[\033[0;34m\]" # blue -local M="\[\033[0;35m\]" # magenta -local C="\[\033[0;36m\]" # cyan -local W="\[\033[0;37m\]" # white +local K="\[\033[30m\]" # black +local R="\[\033[31m\]" # red +local G="\[\033[32m\]" # green +local Y="\[\033[33m\]" # yellow +local B="\[\033[34m\]" # blue +local M="\[\033[35m\]" # magenta +local C="\[\033[36m\]" # cyan +local W="\[\033[37m\]" # white # bright/bold colors local BK="\[\033[1;30m\]" # black @@ -32,7 +33,34 @@ local BGM="\[\033[45m\]" # magenta local BGC="\[\033[46m\]" # cyan local BGW="\[\033[47m\]" # white -local UC=$W # user's color -[[ $UID -eq "0" ]] && UC=$R # root's color +# transform color variables, if asked +for var in $color_vars; do + case "${!var}" in + "black") declare $var="$K";; + "red") declare $var="$R";; + "green") declare $var="$G";; + "yellow") declare $var="$Y";; + "blue") declare $var="$B";; + "magenta") declare $var="$M";; + "cyan") declare $var="$C";; + "white") declare $var="$W";; + "default") declare $var="$N";; + esac +done + +# transform background color variables, if asked +for var in $bg_color_vars; do + case "${!var}" in + "black") declare $var="$BGK";; + "red") declare $var="$BGR";; + "green") declare $var="$BGG";; + "yellow") declare $var="$BGY";; + "blue") declare $var="$BGB";; + "magenta") declare $var="$BGM";; + "cyan") declare $var="$BGC";; + "white") declare $var="$BGW";; + "default") declare $var="$BGN";; + esac +done # vim: ft=sh diff --git a/bash/prompt b/bash/prompt index 7829583..2d528bb 100644 --- a/bash/prompt +++ b/bash/prompt @@ -1,67 +1,46 @@ source "$DOTFILES_SHELL_DIR/prompt_segments" source "$DOTFILES_BASH_DIR/prompt_segments" -source "$DOTFILES_SHELL_DIR/prompt_utils" +source "$DOTFILES_SHELL_DIR/prompt_vcs" -# git prompt info -source $DOTFILES_SHELL_DIR/git_prompt_info -GIT_PS1_SHOWDIRTYSTATE=1 -GIT_PS1_SHOWSTASHSTATE=1 -GIT_PS1_SHOWUNTRACKEDFILES=1 +prompt_host() { + local bg='black' + local fg='white' -# dynamic prompt -set_prompt() { - # save last command exit code (requires set_prompt to be first in PROMPT_COMMAND) - local last_exit_code="$?" - - # load color vars - source "$DOTFILES_BASH_DIR/ansi_colors" - - # set up git status env vars - __git_ps1_vars - - # build prompt - PS1="" - - # opening + user@host - PS1+="${B}[${UC}\u@\h" - - # git? - if [[ -n "${GIT_PS1_NAME-}" ]]; then - # basic info - PS1+=" ${Y}${GIT_PS1_NAME}" - [[ "$GIT_PS1_STATUS" == *b* ]] && PS1+="${NONE}›" - PS1+="${NONE}›${B}${GIT_PS1_BRANCH}" - [[ "$GIT_PS1_STATUS" == *g* ]] && PS1+="${NONE}›" - PS1+="${NONE}›${G}${GIT_PS1_PREFIX}" - - # status symbols - local status="" - [[ "$GIT_PS1_STATUS" == *h* ]] && status+="${NONE}↰" - [[ "$GIT_PS1_STATUS" == *t* ]] && status+="${R}!" - [[ "$GIT_PS1_STATUS" == *u* ]] && status+="${Y}≠" - [[ "$GIT_PS1_STATUS" == *s* ]] && status+="${R}±" - [[ "$GIT_PS1_STATUS" == *n* ]] && status+="${BB}∅" - [[ -n "$status" ]] && PS1+=" ${status}" - - # action info - local action="" - [[ "$GIT_PS1_STATUS" == *R* ]] && action+=" rebase" - [[ "$GIT_PS1_STATUS" == *i* ]] && action+="-i" - [[ "$GIT_PS1_STATUS" == *A* ]] && action+=" apply" - [[ "$GIT_PS1_STATUS" == *M* ]] && action+=" merge" - [[ "$GIT_PS1_STATUS" == *B* ]] && action+=" bisect" - [[ -n "$action" ]] && PS1+="${R}${action}" - else - # no git => just a smartly truncated path - PS1+=" ${G}$(__tpwd)" + if [[ $UID -eq 0 ]]; then + bg='red' fi - # exit code - [[ $LAST_CMD_RC -ne 0 ]] && PS1+=" ${BW}${LAST_CMD_RC}" + if [[ -n $SSH_CLIENT ]]; then + fg='yellow' + fi - # closing prompt - PS1+="${B}]" - PS1+="${UC}\\$ ${NONE}" + prompt_segment $bg $fg '\u@\h' } -# vim: ft=sh +prompt_dir() { + prompt_segment green white '\w' +} + +prompt_build() { + prompt_setup_segments + CURRENT_BG='NONE' + prompt_host + if prompt_vcs_repo; then + prompt_vcs_status + prompt_vcs_action + else + prompt_dir + fi + prompt_last_rc + prompt_end + echo -n ' ' +} + +prompt_last_rc() { + [[ $LAST_CMD_RC -ne 0 ]] && prompt_segment red white "$LAST_CMD_RC" +} + +set_prompt() { + __git_ps1_vars + PS1="$(prompt_build)" +} diff --git a/bash/prompt_segments b/bash/prompt_segments index 5750687..36ac88e 100644 --- a/bash/prompt_segments +++ b/bash/prompt_segments @@ -1,3 +1,9 @@ +# prompt segments for bash + +SEGMENT_DEFAULT_BG='default' +SEGMENT_DEFAULT_FG='default' +CURRENT_BG='NONE' + lprompt_segment() { local bg fg fake_bg @@ -10,52 +16,49 @@ lprompt_segment() { fake_bg=$CURRENT_BG fi + # evaluate color vars + local color_vars="fg fake_bg" + local bg_color_vars="bg" + source "$DOTFILES_BASH_DIR/ansi_colors" + + if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then - echo -n " %{%K{$bg}%F{$fake_bg}%}$SEGMENT_SEPARATOR%{%F{$fg}%} " + echo -n " \[$bg$fake_bg\]$SEGMENT_SEPARATOR\[$fg\] " else - echo -n "%{%K{$bg}%}%{%F{$fg}%} " + echo -n "\[$bg$fg\] " fi CURRENT_BG=$1 - [[ -n $3 ]] && print -Pn $3 + shift + shift + [[ -n "$*" ]] && echo -n "$*" } # End the prompt, closing any open segments prompt_end() { + local $bg; + local $fg; + local $fake_bg; + + bg="default" + fg="default" + if [[ -n $CURRENT_BG ]]; then - echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR" - else - echo -n "%{%k%}" + fake_bg=$CURRENT_BG fi - echo -n "%{%f%}" + + # evaluate color vars + local color_vars="fg fake_bg" + local bg_color_vars="bg" + source "$DOTFILES_BASH_DIR/ansi_colors" + + if [[ -n $CURRENT_BG ]]; then + echo -n " \[$bg$fake_bg\]$SEGMENT_SEPARATOR" + else + echo -n "\[$bg\]" + fi + echo -n "\[$fg\]" CURRENT_BG='' } -rprompt_segment() { - local bg fg fake_bg prev_bg - - [[ -n $1 ]] && bg="$1" || bg='default' - [[ -n $2 ]] && fg="$2" || fg='default' - - if [[ $bg == 'default' ]]; then - fake_bg=$SEGMENT_DEFAULT_BG - else - fake_bg=$bg - fi - prev_bg=$CURRENT_BG - - if [[ $1 != $CURRENT_BG ]]; then - echo -n " %{%K{$prev_bg}%F{$fake_bg}%}$RSEGMENT_SEPARATOR%{%K{$bg}%F{$fg}%} " - else - echo -n "%{%K{$bg}%}%{%F{$fg}%} " - fi - - CURRENT_BG=$1 - [[ -n $3 ]] && print -Pn $3 -} - -rprompt_end() { - echo -n ' ' - echo -n "%{%k%f%}" - CURRENT_BG='' -} +# vim: ft=sh: diff --git a/bash/rc b/bash/rc index b78b70f..518cd5d 100644 --- a/bash/rc +++ b/bash/rc @@ -11,6 +11,11 @@ source $DOTFILES_BASH_DIR/completion source $DOTFILES_SHELL_DIR/bundler source $DOTFILES_SHELL_DIR/go +source $DOTFILES_SHELL_DIR/git_prompt_info +GIT_PS1_SHOWDIRTYSTATE=1 +GIT_PS1_SHOWSTASHSTATE=1 +GIT_PS1_SHOWUNTRACKEDFILES=1 + precmd() { LAST_CMD_RC=$? clear_incomplete_line diff --git a/shell/prompt_segments b/shell/prompt_segments index abceff4..d170c6a 100644 --- a/shell/prompt_segments +++ b/shell/prompt_segments @@ -1,3 +1,5 @@ +# prompt segments: bash and zsh + #POWERLINE_TRI_LEFT_FULL='' #POWERLINE_TRI_LEFT_EMPTY='' #POWERLINE_TRI_RIGHT_FULL='' @@ -46,3 +48,5 @@ prompt_subsegment() { echo -n " $sep " [[ -n $1 ]] && print -Pn $1 } + +# vim: ft=sh: diff --git a/shell/prompt_vcs b/shell/prompt_vcs new file mode 100644 index 0000000..18440da --- /dev/null +++ b/shell/prompt_vcs @@ -0,0 +1,69 @@ +prompt_git() { + if [[ -n $GIT_PS1_STATUS ]]; then + PROMPT_VCS_TYPE='git' + PROMPT_VCS_REF="$GIT_PS1_BRANCH" + PROMPT_VCS_WPATH="$GIT_PS1_TOPLEVEL" + PROMPT_VCS_WNAME="$GIT_PS1_NAME" + PROMPT_VCS_WPWD="$GIT_PS1_PREFIX" + [[ "$GIT_PS1_STATUS" == *t* ]] && PROMPT_VCS_DIRTY=1 + [[ "$GIT_PS1_STATUS" == *u* ]] && PROMPT_VCS_DIRTY=1 + [[ "$GIT_PS1_STATUS" == *s* ]] && PROMPT_VCS_DIRTY=1 + return 0 + else + unset PROMPT_VCS_TYPE + return 1 + fi +} + +prompt_vcs_repo() { + if prompt_git; then # TODO: || prompt_hg + local branch_icon repo_color + if prompt_is_fancy; then + branch_icon=" $POWERLINE_BRANCH " + else + branch_icon=" ⎇ " + fi + + if [[ $PROMPT_VCS_DIRTY -eq 1 ]]; then + repo_color=red + else + repo_color=blue + fi + + prompt_segment $repo_color white "$PROMPT_VCS_WNAME$branch_icon$PROMPT_VCS_REF" + [[ -n $PROMPT_VCS_WPWD ]] && prompt_segment green white "$PROMPT_VCS_WPWD" + + return 0 + else + return 1 + fi + +} + +prompt_vcs_status() { + # status symbols + if prompt_git; then + local vcs_status="" + [[ "$GIT_PS1_STATUS" == *h* ]] && vcs_status+="${NONE}↰" + [[ "$GIT_PS1_STATUS" == *t* ]] && vcs_status+="${R}!" + [[ "$GIT_PS1_STATUS" == *u* ]] && vcs_status+="${Y}≠" + [[ "$GIT_PS1_STATUS" == *s* ]] && vcs_status+="${R}±" + [[ "$GIT_PS1_STATUS" == *n* ]] && vcs_status+="${BB}∅" + [[ -n "$vcs_status" ]] && prompt_segment black white "${vcs_status}" + fi +} + +prompt_vcs_action() { + # action info + if prompt_git; then + local action="" + [[ "$GIT_PS1_STATUS" == *R* ]] && action+=" rebase" + [[ "$GIT_PS1_STATUS" == *i* ]] && action+="-i" + [[ "$GIT_PS1_STATUS" == *A* ]] && action+=" apply" + [[ "$GIT_PS1_STATUS" == *M* ]] && action+=" merge" + [[ "$GIT_PS1_STATUS" == *B* ]] && action+=" bisect" + [[ -n "$action" ]] && prompt_segment red white "$action" + fi +} + +# vim: ft=sh: diff --git a/zsh/prompt b/zsh/prompt index e98a685..9c2fd80 100644 --- a/zsh/prompt +++ b/zsh/prompt @@ -1,85 +1,26 @@ source "$DOTFILES_SHELL_DIR/prompt_segments" source "$DOTFILES_ZSH_DIR/prompt_segments" +source "$DOTFILES_SHELL_DIR/prompt_vcs" prompt_host() { + local bg='black' + local fg='white' + if [[ $UID -eq 0 ]]; then - prompt_segment red white '%n@%m' - else - prompt_segment black white '%n@%m' + bg='red' fi + + if [[ -n $SSH_CLIENT ]]; then + fg='yellow' + fi + + prompt_segment $bg $fg '%n@%m' } prompt_dir() { prompt_segment green white '%~' } -prompt_git() { - if [[ -n $GIT_PS1_STATUS ]]; then - PROMPT_VCS_TYPE='git' - PROMPT_VCS_REF="$GIT_PS1_BRANCH" - PROMPT_VCS_WPATH="$GIT_PS1_TOPLEVEL" - PROMPT_VCS_WNAME="$GIT_PS1_NAME" - PROMPT_VCS_WPWD="$GIT_PS1_PREFIX" - [[ "$GIT_PS1_STATUS" == *t* ]] && PROMPT_VCS_DIRTY=1 - [[ "$GIT_PS1_STATUS" == *u* ]] && PROMPT_VCS_DIRTY=1 - [[ "$GIT_PS1_STATUS" == *s* ]] && PROMPT_VCS_DIRTY=1 - return 0 - else - unset PROMPT_VCS_TYPE - return 1 - fi -} - -prompt_vcs_repo() { - if prompt_git; then # TODO: || prompt_hg - local branch_icon repo_color - if prompt_is_fancy; then - branch_icon=" $POWERLINE_BRANCH " - else - branch_icon=" ⎇ " - fi - - if [[ $PROMPT_VCS_DIRTY -eq 1 ]]; then - repo_color=red - else - repo_color=blue - fi - - prompt_segment $repo_color white "$PROMPT_VCS_WNAME$branch_icon$PROMPT_VCS_REF" - [[ -n $PROMPT_VCS_WPWD ]] && prompt_segment green white "$PROMPT_VCS_WPWD" - - return 0 - else - return 1 - fi - -} - -prompt_vcs_status() { - # status symbols - if prompt_git; then - local vcs_status="" - [[ "$GIT_PS1_STATUS" == *h* ]] && vcs_status+="${NONE}↰" - [[ "$GIT_PS1_STATUS" == *t* ]] && vcs_status+="${R}!" - [[ "$GIT_PS1_STATUS" == *u* ]] && vcs_status+="${Y}≠" - [[ "$GIT_PS1_STATUS" == *s* ]] && vcs_status+="${R}±" - [[ "$GIT_PS1_STATUS" == *n* ]] && vcs_status+="${BB}∅" - [[ -n "$vcs_status" ]] && prompt_segment black white "${vcs_status}" - fi -} - -prompt_vcs_action() { - # action info - if prompt_git; then - local action="" - [[ "$GIT_PS1_STATUS" == *R* ]] && action+=" rebase" - [[ "$GIT_PS1_STATUS" == *i* ]] && action+="-i" - [[ "$GIT_PS1_STATUS" == *A* ]] && action+=" apply" - [[ "$GIT_PS1_STATUS" == *M* ]] && action+=" merge" - [[ "$GIT_PS1_STATUS" == *B* ]] && action+=" bisect" - [[ -n "$action" ]] && prompt_segment red white "$action" - fi -} prompt_segment_test() { prompt_segment red white