Merge pull request #605 from edubxb/powerline-multiline-segmentorder

Add support to change the order of the prompt info in the Powerline Multiline theme
pull/257/merge
Nils Winkler 2016-01-31 20:14:26 +01:00
commit 9a72ab8de1
2 changed files with 248 additions and 215 deletions

View File

@ -0,0 +1,60 @@
# Powerline Multiline Theme
Colorfull multiline theme, the first line shows information about your shell session (divided into two parts, left and right), the second one is where the shell commands are introduced.
**IMPORTANT:** This theme has a requirement, [a font with the Powerline symbols](https://github.com/powerline/fonts) need tu be used in your terminal emulator, otherwise, the prompt won't be displayed correctly.
## Information provided
* Current path
* Current username and hostname
* An indicator when connected by SSH
* An indicator when sudo has the credentials cached (see the sudo manpage for more info about this)
* An indicator when the current shell is inside the Vim editor
* Battery charging status (depends on the battery plugin)
* Repository status
* The current Python enviroment (Virtualenv, venv, and Conda are supported) in use
* The current Ruby enviroment (RVM) in use
* Last command exit code (only shown when the exit code is greater than 0)
## Configuration
This theme is pretty configurable, all the configuration is done by setting environment variables.
### User information
By default, the username and hostname are shown at the right side, but you can change this behavior setting the value of the following variable:
POWERLINE_PROMPT_USER_INFO_MODE
for now, the only supported value is `sudo`, that hides the username and hostname, and shows an indicator when the sudo has the credentials cached. Any other value has no effect.
### Clock format
By default, the current time is shown at the right side, you can change the format with the variable:
POWERLINE_PROMPT_CLOCK_FORMAT="%H:%M:%S"
the date is printed by the `date` command, so refer to its man page to change the format.
### Segment order
Both prompt sides can be "reordered", all the "segments" (every piece of information) can take any place, the current available segments are:
* battery
* clock
* cwd
* in_vim
* python_venv
* rvm
* scm
* user_info
Two variables can be defined to set the order of the prompt segments:
POWERLINE_LEFT_PROMPT="scm python_venv rvm cwd"
POWERLINE_RIGHT_PROMPT="in_vim clock battery user_info"
the example values are the defaults, but if you want to remove something else from the prompt, simply remove the "string" that represents the segment from the corresponding variable.

View File

@ -1,15 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
THEME_PROMPT_SEPARATOR="" USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "}
THEME_PROMPT_LEFT_SEPARATOR="" USER_INFO_THEME_PROMPT_COLOR=32
USER_INFO_THEME_PROMPT_COLOR_SUDO=202
SHELL_SSH_CHAR=${SHELL_SSH_CHAR:=" "} PYTHON_VENV_CHAR=${POWERLINE_PYTHON_VENV_CHAR:="p "}
SHELL_THEME_PROMPT_COLOR=32 CONDA_PYTHON_VENV_CHAR=${POWERLINE_CONDA_PYTHON_VENV_CHAR:="c "}
SHELL_THEME_PROMPT_COLOR_SUDO=202 PYTHON_VENV_THEME_PROMPT_COLOR=35
VIRTUALENV_CHAR=${POWERLINE_VIRTUALENV_CHAR:="p "}
CONDA_VIRTUALENV_CHAR=${POWERLINE_CONDA_VIRTUALENV_CHAR:="c "}
VIRTUALENV_THEME_PROMPT_COLOR=35
SCM_NONE_CHAR="" SCM_NONE_CHAR=""
SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:=" "} SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:=" "}
@ -40,12 +37,13 @@ BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR=70
BATTERY_STATUS_THEME_PROMPT_LOW_COLOR=208 BATTERY_STATUS_THEME_PROMPT_LOW_COLOR=208
BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR=160 BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR=160
THEME_PROMPT_CLOCK_FORMAT=${THEME_PROMPT_CLOCK_FORMAT:="%H:%M:%S"} THEME_PROMPT_CLOCK_FORMAT=${POWERLINE_PROMPT_CLOCK_FORMAT:="%H:%M:%S"}
THEME_PROMPT_USERINFO_MODE=${THEME_PROMPT_USERINFO_MODE:="default"} IN_VIM_THEME_PROMPT_COLOR=245
IN_VIM_THEME_PROMPT_TEXT="vim"
IN_VIM_PROMPT_COLOR=35 POWERLINE_LEFT_PROMPT="scm python_venv rvm cwd"
IN_VIM_PROMPT_TEXT="vim" POWERLINE_RIGHT_PROMPT="in_vim clock battery user_info"
function set_rgb_color { function set_rgb_color {
@ -59,207 +57,182 @@ function set_rgb_color {
echo -e "\[\033[${fg}${bg}m\]" echo -e "\[\033[${fg}${bg}m\]"
} }
function powerline_shell_prompt { function __powerline_user_info_prompt {
SHELL_PROMPT="" local user_info=""
SHELL_PROMPT_COLOR=${SHELL_THEME_PROMPT_COLOR} local color=${USER_INFO_THEME_PROMPT_COLOR}
if sudo -n uptime 2>&1 | grep -q "load"; then if sudo -n uptime 2>&1 | grep -q "load"; then
SHELL_PROMPT_COLOR=${SHELL_THEME_PROMPT_COLOR_SUDO} color=${USER_INFO_THEME_PROMPT_COLOR_SUDO}
fi fi
case "${THEME_PROMPT_USERINFO_MODE}" in case "${POWERLINE_PROMPT_USER_INFO_MODE}" in
"default")
if [[ -n "${SSH_CLIENT}" ]]; then
SHELL_PROMPT="${SHELL_SSH_CHAR}${USER}@${HOSTNAME}"
else
SHELL_PROMPT="${USER}"
fi
RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#SHELL_PROMPT} + 2 ))
SHELL_PROMPT="$(set_rgb_color - ${SHELL_PROMPT_COLOR}) ${SHELL_PROMPT} ${normal}"
LAST_THEME_COLOR=${SHELL_PROMPT_COLOR}
(( SEGMENT_AT_RIGHT += 1 ))
;;
"sudo") "sudo")
if [[ "${SHELL_PROMPT_COLOR}" == "${SHELL_THEME_PROMPT_COLOR_SUDO}" ]]; then if [[ "${color}" == "${USER_INFO_THEME_PROMPT_COLOR_SUDO}" ]]; then
SHELL_PROMPT="!" user_info="!"
RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#SHELL_PROMPT} + 2 )) fi
SHELL_PROMPT="$(set_rgb_color - ${SHELL_PROMPT_COLOR}) ${SHELL_PROMPT} ${normal}" ;;
LAST_THEME_COLOR=${SHELL_PROMPT_COLOR} *)
(( SEGMENT_AT_RIGHT += 1 )) if [[ -n "${SSH_CLIENT}" ]]; then
user_info="${USER_INFO_SSH_CHAR}${USER}@${HOSTNAME}"
else
user_info="${USER}"
fi fi
;; ;;
esac esac
[[ -n "${user_info}" ]] && echo "${user_info}|${color}"
} }
function powerline_rvm_prompt { function __powerline_rvm_prompt {
local environ="" local rvm=""
if command_exists rvm; then if command_exists rvm; then
rvm_prompt=$(rvm_version_prompt) rvm="$(rvm_version_prompt)"
if [[ "${rvm_prompt}" != $(rvm strings default) ]]; then [[ -n "${rvm}" ]] && echo "${RVM_CHAR}${rvm}|${RVM_THEME_PROMPT_COLOR}"
RVM_PROMPT="$(set_rgb_color - ${RVM_THEME_PROMPT_COLOR}) ${RVM_CHAR}${rvm_prompt} ${normal}"
if [[ "${SEGMENT_AT_LEFT}" -gt 0 ]]; then
RVM_PROMPT=$(set_rgb_color ${LAST_THEME_COLOR} ${RVM_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${RVM_PROMPT}
fi
LAST_THEME_COLOR=${RVM_THEME_PROMPT_COLOR}
(( SEGMENT_AT_LEFT += 1 ))
else
RVM_PROMPT=""
fi
fi fi
} }
function powerline_virtualenv_prompt { function __powerline_python_venv_prompt {
local environ="" local python_venv=""
if [[ -n "$CONDA_DEFAULT_ENV" ]]; then if [[ -n "${CONDA_DEFAULT_ENV}" ]]; then
environ="$CONDA_DEFAULT_ENV" python_venv="${CONDA_DEFAULT_ENV}"
VIRTUALENV_CHAR=${CONDA_VIRTUALENV_CHAR} PYTHON_VENV_CHAR=${CONDA_PYTHON_VENV_CHAR}
elif [[ -n "$VIRTUAL_ENV" ]]; then elif [[ -n "${VIRTUAL_ENV}" ]]; then
environ=$(basename "$VIRTUAL_ENV") python_venv=$(basename "${VIRTUAL_ENV}")
fi fi
if [[ -n "$environ" ]]; then [[ -n "${python_venv}" ]] && echo "${PYTHON_VENV_CHAR}${python_venv}|${PYTHON_VENV_THEME_PROMPT_COLOR}"
VIRTUALENV_PROMPT="$(set_rgb_color - ${VIRTUALENV_THEME_PROMPT_COLOR}) ${VIRTUALENV_CHAR}$environ ${normal}"
if [[ "${SEGMENT_AT_LEFT}" -gt 0 ]]; then
VIRTUALENV_PROMPT=$(set_rgb_color ${LAST_THEME_COLOR} ${VIRTUALENV_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${VIRTUALENV_PROMPT}
fi
LAST_THEME_COLOR=${VIRTUALENV_THEME_PROMPT_COLOR}
(( SEGMENT_AT_LEFT += 1 ))
else
VIRTUALENV_PROMPT=""
fi
} }
function powerline_scm_prompt { function __powerline_scm_prompt {
local color=""
local scm_prompt=""
scm_prompt_vars scm_prompt_vars
if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then
if [[ "${SCM_DIRTY}" -eq 3 ]]; then if [[ "${SCM_DIRTY}" -eq 3 ]]; then
SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_STAGED_COLOR} color=${SCM_THEME_PROMPT_STAGED_COLOR}
elif [[ "${SCM_DIRTY}" -eq 2 ]]; then elif [[ "${SCM_DIRTY}" -eq 2 ]]; then
SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_UNSTAGED_COLOR} color=${SCM_THEME_PROMPT_UNSTAGED_COLOR}
elif [[ "${SCM_DIRTY}" -eq 1 ]]; then elif [[ "${SCM_DIRTY}" -eq 1 ]]; then
SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_DIRTY_COLOR} color=${SCM_THEME_PROMPT_DIRTY_COLOR}
else else
SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_CLEAN_COLOR} color=${SCM_THEME_PROMPT_CLEAN_COLOR}
fi fi
if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then
SCM_PROMPT=" ${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}"
fi fi
SCM_PROMPT="$(set_rgb_color - ${SCM_THEME_PROMPT_COLOR})${SCM_PROMPT} ${normal}" echo "${scm_prompt}|${color}"
LAST_THEME_COLOR=${SCM_THEME_PROMPT_COLOR}
(( SEGMENT_AT_LEFT += 1 ))
else
SCM_PROMPT=""
fi fi
} }
function powerline_cwd_prompt { function __powerline_cwd_prompt {
CWD_PROMPT="$(set_rgb_color - ${CWD_THEME_PROMPT_COLOR}) \w ${normal}$(set_rgb_color ${CWD_THEME_PROMPT_COLOR} -)${normal}$(set_rgb_color ${CWD_THEME_PROMPT_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" echo "$(pwd | sed "s|^${HOME}|~|")|${CWD_THEME_PROMPT_COLOR}"
if [[ "${SEGMENT_AT_LEFT}" -gt 0 ]]; then
CWD_PROMPT=$(set_rgb_color ${LAST_THEME_COLOR} ${CWD_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${CWD_PROMPT}
SEGMENT_AT_LEFT=0
fi
LAST_THEME_COLOR=${CWD_THEME_PROMPT_COLOR}
} }
function powerline_last_status_prompt { function __powerline_clock_prompt {
if [[ "$1" -eq 0 ]]; then echo "$(date +"${THEME_PROMPT_CLOCK_FORMAT}")|${CLOCK_THEME_PROMPT_COLOR}"
LAST_STATUS_PROMPT="" }
function __powerline_battery_prompt {
local color=""
local battery_status="$(battery_percentage 2> /dev/null)"
if [[ -z "${battery_status}" ]] || [[ "${battery_status}" = "-1" ]] || [[ "${battery_status}" = "no" ]]; then
true
else else
LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_STATUS_THEME_PROMPT_COLOR} -) ${LAST_STATUS} ${normal}" if [[ "$((10#${battery_status}))" -le 5 ]]; then
color="${BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR}"
elif [[ "$((10#${battery_status}))" -le 25 ]]; then
color="${BATTERY_STATUS_THEME_PROMPT_LOW_COLOR}"
else
color="${BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR}"
fi
[[ "$(ac_adapter_connected)" ]] && battery_status="${BATTERY_AC_CHAR}${battery_status}"
echo "${battery_status}%|${color}"
fi fi
} }
function powerline_clock_prompt { function __powerline_in_vim_prompt {
if [[ -z "${THEME_PROMPT_CLOCK_FORMAT}" ]]; then if [ -n "$VIMRUNTIME" ]; then
CLOCK_PROMPT="" echo "${IN_VIM_THEME_PROMPT_TEXT}|${IN_VIM_THEME_PROMPT_COLOR}"
else
local CLOCK=" $(date +"${THEME_PROMPT_CLOCK_FORMAT}") "
CLOCK_PROMPT=$(set_rgb_color - ${CLOCK_THEME_PROMPT_COLOR})${CLOCK}${normal}
if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then
CLOCK_PROMPT+=$(set_rgb_color ${LAST_THEME_COLOR} ${CLOCK_THEME_PROMPT_COLOR})${THEME_PROMPT_LEFT_SEPARATOR}${normal}
(( RIGHT_PROMPT_LENGTH += SEGMENT_AT_RIGHT - 1 ))
fi
RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#CLOCK} ))
LAST_THEME_COLOR=${CLOCK_THEME_PROMPT_COLOR}
(( SEGMENT_AT_RIGHT += 1 ))
fi fi
} }
function powerline_battery_status_prompt { function __powerline_last_status_prompt {
BATTERY_STATUS="$(battery_percentage 2> /dev/null)" [[ "$1" -ne 0 ]] && echo "$(set_rgb_color ${LAST_STATUS_THEME_PROMPT_COLOR} -) ${1} ${normal}"
if [[ -z "${BATTERY_STATUS}" ]] || [[ "${BATTERY_STATUS}" = "-1" ]] || [[ "${BATTERY_STATUS}" = "no" ]]; then
BATTERY_PROMPT=""
else
if [[ "$((10#${BATTERY_STATUS}))" -le 5 ]]; then
BATTERY_STATUS_THEME_PROMPT_COLOR="${BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR}"
elif [[ "$((10#${BATTERY_STATUS}))" -le 25 ]]; then
BATTERY_STATUS_THEME_PROMPT_COLOR="${BATTERY_STATUS_THEME_PROMPT_LOW_COLOR}"
else
BATTERY_STATUS_THEME_PROMPT_COLOR="${BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR}"
fi
[[ "$(ac_adapter_connected)" ]] && BATTERY_STATUS="${BATTERY_AC_CHAR}${BATTERY_STATUS}"
BATTERY_PROMPT="$(set_rgb_color - ${BATTERY_STATUS_THEME_PROMPT_COLOR}) ${BATTERY_STATUS}% "
if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then
BATTERY_PROMPT+=$(set_rgb_color ${LAST_THEME_COLOR} ${BATTERY_STATUS_THEME_PROMPT_COLOR})${THEME_PROMPT_LEFT_SEPARATOR}${normal}
(( RIGHT_PROMPT_LENGTH += SEGMENT_AT_RIGHT ))
else
BATTERY_STATUS+=" "
fi
RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#BATTERY_STATUS} + 2 ))
LAST_THEME_COLOR=${BATTERY_STATUS_THEME_PROMPT_COLOR}
(( SEGMENT_AT_RIGHT += 1 ))
fi
} }
function powerline_in_vim_prompt { function __powerline_left_segment {
if [ -z "$VIMRUNTIME" ]; then local OLD_IFS="${IFS}"; IFS="|"
IN_VIM_PROMPT="" local params=( $1 )
else IFS="${OLD_IFS}"
IN_VIM_PROMPT="$(set_rgb_color - ${IN_VIM_PROMPT_COLOR}) ${IN_VIM_PROMPT_TEXT} " local separator_char=""
if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then local separator=""
IN_VIM_PROMPT+=$(set_rgb_color ${LAST_THEME_COLOR} ${IN_VIM_PROMPT_COLOR})${THEME_PROMPT_LEFT_SEPARATOR}${normal}
(( RIGHT_PROMPT_LENGTH += SEGMENT_AT_RIGHT )) if [[ "${SEGMENTS_AT_LEFT}" -gt 0 ]]; then
fi separator="$(set_rgb_color ${LAST_SEGMENT_COLOR} ${params[1]})${separator_char}${normal}${normal}"
RIGHT_PROMPT_LENGTH=$(( ${RIGHT_PROMPT_LENGTH} + ${#IN_VIM_PROMPT_TEXT} ))
LAST_THEME_COLOR=${IN_VIM_PROMPT_COLOR}
(( SEGMENT_AT_RIGHT += 1 ))
fi fi
LEFT_PROMPT+="${separator}$(set_rgb_color - ${params[1]}) ${params[0]} ${normal}"
LAST_SEGMENT_COLOR=${params[1]}
(( SEGMENTS_AT_LEFT += 1 ))
} }
function __powerline_right_segment {
local OLD_IFS="${IFS}"; IFS="|"
local params=( $1 )
IFS="${OLD_IFS}"
local separator_char=""
local padding=2
local separator_color=""
function powerline_prompt_command() { if [[ "${SEGMENTS_AT_RIGHT}" -eq 0 ]]; then
local LAST_STATUS="$?" separator_color="$(set_rgb_color ${params[1]} -)"
local MOVE_CURSOR_RIGHTMOST='\033[500C' else
SEGMENT_AT_LEFT=0 separator_color="$(set_rgb_color ${params[1]} ${LAST_SEGMENT_COLOR})"
SEGMENT_AT_RIGHT=0 (( padding += 1 ))
RIGHT_PROMPT_LENGTH=1 fi
RIGHT_PROMPT+="${separator_color}${separator_char}${normal}$(set_rgb_color - ${params[1]}) ${params[0]} ${normal}$(set_rgb_color - ${COLOR})${normal}"
RIGHT_PROMPT_LENGTH=$(( ${#params[0]} + RIGHT_PROMPT_LENGTH + padding ))
LAST_SEGMENT_COLOR="${params[1]}"
(( SEGMENTS_AT_RIGHT += 1 ))
}
function __powerline_prompt_command {
local last_status="$?" ## always the first
local separator_char=""
local move_cursor_rightmost='\033[500C'
LEFT_PROMPT=""
RIGHT_PROMPT="" RIGHT_PROMPT=""
RIGHT_PROMPT_LENGTH=0
SEGMENTS_AT_LEFT=0
SEGMENTS_AT_RIGHT=0
LAST_SEGMENT_COLOR=""
## left prompt ## ## left prompt ##
powerline_scm_prompt for segment in $POWERLINE_LEFT_PROMPT; do
powerline_virtualenv_prompt local info="$(__powerline_${segment}_prompt)"
powerline_rvm_prompt [[ -n "${info}" ]] && __powerline_left_segment "${info}"
powerline_cwd_prompt done
powerline_last_status_prompt LAST_STATUS [[ -n "${LEFT_PROMPT}" ]] && LEFT_PROMPT+="$(set_rgb_color ${LAST_SEGMENT_COLOR} -)${separator_char}${normal}"
LEFT_PROMPT="${SCM_PROMPT}${VIRTUALENV_PROMPT}${RVM_PROMPT}${CWD_PROMPT}${MOVE_CURSOR_RIGHTMOST}"
## right prompt ## ## right prompt ##
LAST_THEME_COLOR="-" if [[ -n "${POWERLINE_RIGHT_PROMPT}" ]]; then
powerline_shell_prompt LEFT_PROMPT+="${move_cursor_rightmost}"
powerline_battery_status_prompt for segment in $POWERLINE_RIGHT_PROMPT; do
powerline_clock_prompt local info="$(__powerline_${segment}_prompt)"
powerline_in_vim_prompt [[ -n "${info}" ]] && __powerline_right_segment "${info}"
done
if [[ "${SEGMENT_AT_RIGHT}" -gt 0 ]]; then LEFT_PROMPT+="\033[${RIGHT_PROMPT_LENGTH}D"
LEFT_PROMPT+="${MOVE_CURSOR_RIGHTMOST}"
[[ "${SEGMENT_AT_RIGHT}" -eq 1 ]] && (( RIGHT_PROMPT_LENGTH-=1 ))
RIGHT_PROMPT="\033[${RIGHT_PROMPT_LENGTH}D$(set_rgb_color ${LAST_THEME_COLOR} -)${THEME_PROMPT_LEFT_SEPARATOR}${normal}"
RIGHT_PROMPT+="${IN_VIM_PROMPT}${CLOCK_PROMPT}${BATTERY_PROMPT}${SHELL_PROMPT}${normal}"
fi fi
PS1="${LEFT_PROMPT}${RIGHT_PROMPT}\n${LAST_STATUS_PROMPT}${PROMPT_CHAR} " PS1="${LEFT_PROMPT}${RIGHT_PROMPT}\n$(__powerline_last_status_prompt ${last_status})${PROMPT_CHAR} "
## cleanup ##
unset LAST_SEGMENT_COLOR \
LEFT_PROMPT RIGHT_PROMPT RIGHT_PROMPT_LENGTH \
SEGMENTS_AT_LEFT SEGMENTS_AT_RIGHT
} }
PROMPT_COMMAND=powerline_prompt_command PROMPT_COMMAND=__powerline_prompt_command