From bbd976f56971150de7b6dd6356dbb63a5efe364b Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Thu, 20 Apr 2023 15:29:49 +0200 Subject: [PATCH] Attempt aligning bash with zsh - support PROMPT - support RPROMPT (buggy if on same line) - support zsh color codes in PROMPT and RPROMPT - refactor set_prompt to use PROMPT and RPROMPT - add duration and rc to RPROMPT --- bash/ext | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ bash/prompt | 53 ++++++++++++++++++++++++++++++++--------------------- bash/rc | 16 +++++++++++++++- 3 files changed, 95 insertions(+), 22 deletions(-) diff --git a/bash/ext b/bash/ext index 4df0923..fa5c492 100644 --- a/bash/ext +++ b/bash/ext @@ -56,4 +56,52 @@ clear_incomplete_line() { fi } +function sub_prompt_colors_unsized() { + sed \ + -e 's#%F{black}#\\033[30m#g' \ + -e 's#%F{red}#\\033[31m#g' \ + -e 's#%F{green}#\\033[32m#g' \ + -e 's#%F{yellow}#\\033[33m#g' \ + -e 's#%F{blue}#\\033[34m#g' \ + -e 's#%F{magenta}#\\033[35m#g' \ + -e 's#%F{cyan}#\\033[36m#g' \ + -e 's#%F{white}#\\033[37m#g' \ + -e 's#%f#\\033[00m#g' +} + +function sub_prompt_colors_sized() { + sed \ + -e 's#%F{black}#\\[\\033[30m\\]#g' \ + -e 's#%F{red}#\\[\\033[31m\\]#g' \ + -e 's#%F{green}#\\[\\033[32m\\]#g' \ + -e 's#%F{yellow}#\\[\\033[33m\\]#g' \ + -e 's#%F{blue}#\\[\\033[34m\\]#g' \ + -e 's#%F{magenta}#\\[\\033[35m\\]#g' \ + -e 's#%F{cyan}#\\[\\033[36m\\]#g' \ + -e 's#%F{white}#\\[\\033[37m\\]#g' \ + -e 's#%f#\\[\\033[00m\\]#g' +} + +function strip_prompt_colors() { + sed \ + -e 's#%F{black}##g' \ + -e 's#%F{red}##g' \ + -e 's#%F{green}##g' \ + -e 's#%F{yellow}##g' \ + -e 's#%F{blue}##g' \ + -e 's#%F{magenta}##g' \ + -e 's#%F{cyan}##g' \ + -e 's#%F{white}##g' \ + -e 's#%f##g' +} + +# right prompt support and PROMPT/RPROMPT vars +function apply_prompt_rprompt() { + local rprompt=$(echo "${RPROMPT}" | sub_prompt_colors_unsized) + local prompt=$(echo "${PROMPT}" | sub_prompt_colors_sized) + #local rprompt=$(echo "${RPROMPT}" | strip_prompt_colors) + #local prompt=$(echo "${PROMPT}" | strip_prompt_colors) + PS1="$(printf "\[%*s\r\]%s" "${COLUMNS}" "${rprompt:-}" "${prompt:-}")" +} + # vim: ft=bash diff --git a/bash/prompt b/bash/prompt index 3d45553..e635b36 100644 --- a/bash/prompt +++ b/bash/prompt @@ -52,30 +52,34 @@ function prompt_pwd() { fi } -prompt_build_simple() { +set_prompt() { __git_ps1_vars + local buffer="" + if [[ -n $SSH_CLIENT ]]; then - echo -n "${HOSTNAME%.local} " + buffer="${buffer}${HOST%.local} " fi if [[ -n $STY ]]; then buffer="${buffer}screen " fi - # add venv info - set_color -p yellow if [[ -n "$VIRTUAL_ENV" ]]; then - echo -n "${VIRTUAL_ENV##*/} " + buffer="${buffer}%F{yellow}${VIRTUAL_ENV##*/} " fi - set_color -p green - prompt_pwd + local pwd + if [[ $PWD == $HOME ]]; then + pwd="~" + else + pwd="${PWD##*/}" + fi + buffer="${buffer}%F{green}${pwd}" # add git prompt info if [[ -n "$GIT_PS1_STATUS" ]]; then - set_color -p blue - echo -n " $GIT_PS1_BRANCH" + buffer="${buffer} %F{blue}$GIT_PS1_BRANCH" vcs_status="" contains h "$GIT_PS1_STATUS" && vcs_status="$vcs_status""⇱" @@ -83,8 +87,7 @@ prompt_build_simple() { contains u "$GIT_PS1_STATUS" && vcs_status="$vcs_status""≠" contains s "$GIT_PS1_STATUS" && vcs_status="$vcs_status""±" contains n "$GIT_PS1_STATUS" && vcs_status="$vcs_status""∅" - set_color -p red - [[ -n "$vcs_status" ]] && echo -n " $vcs_status" + [[ -n "$vcs_status" ]] && buffer="${buffer} %F{red}$vcs_status" action="" contains R "$GIT_PS1_STATUS" && action="$action rebase" @@ -92,20 +95,28 @@ prompt_build_simple() { contains A "$GIT_PS1_STATUS" && action="$action apply" contains M "$GIT_PS1_STATUS" && action="$action merge" contains B "$GIT_PS1_STATUS" && action="$action bisect" - set_color -p yellow - [[ -n "$action" ]] && echo -n "$action" + [[ -n "$action" ]] && buffer="${buffer} %F{yellow}$action" fi - set_color -p yellow - [[ -n "${IN_NIX_SHELL}" ]] && echo -n " nix" + [[ -n "${IN_NIX_SHELL}" ]] && buffer="${buffer} %F{yellow}nix" - # close prompt - set_color -p none - echo -n '> ' -} + buffer="${buffer}%f> " + PROMPT="${buffer}" -set_prompt() { - PS1="$(prompt_build_simple)" + local rbuffer="" + + CMD_DURATION=${CMD_DURATION:-0} + local duration="${CMD_DURATION%.*}" + + if [[ ${duration:-0} -gt 0 ]]; then + printf -v formatted_duration "%.3f" "${CMD_DURATION}" + + rbuffer=" %F{yellow}${formatted_duration}s${rbuffer}" + fi + + [[ ${CMD_RC} -ne 0 ]] && rbuffer=" %F{red}${CMD_RC}${rbuffer}" + + RPROMPT="${rbuffer}%f" } # vim: ft=bash diff --git a/bash/rc b/bash/rc index 817567e..e10420b 100644 --- a/bash/rc +++ b/bash/rc @@ -19,14 +19,28 @@ GIT_PS1_SHOWSTASHSTATE=1 GIT_PS1_SHOWUNTRACKEDFILES=1 precmd() { - LAST_CMD_RC=$? + CMD_RC=$? + + if [[ -n ${CMD_START} ]]; then + CMD_END="${EPOCHREALTIME}" + CMD_DURATION=$(bc <<<"${CMD_END} - ${CMD_START}") + unset CMD_START + unset CMD_END + fi + _direnv_hook #clear_incomplete_line set_prompt + apply_prompt_rprompt update_terminal_cwd set_term_title } +preexec() { + set_term_title + CMD_START="${EPOCHREALTIME}" +} + chpwd() { __git_ps1_gitdir _gopath