diff --git a/themes/powerline/README.md b/themes/powerline/README.md new file mode 100644 index 00000000..8a094719 --- /dev/null +++ b/themes/powerline/README.md @@ -0,0 +1,58 @@ +# Powerline Theme + +A colorful theme, where shows a lot information about your shell session. + +**IMPORTANT:** This theme requires that [a font with the Powerline symbols](https://github.com/powerline/fonts) needs to be used in your terminal emulator, otherwise the prompt won't be displayed correctly, i.e. some of the additional icons and characters will be missing. Please follow your operating system's instructions to install one of the fonts from the above link and select it in your terminal emulator. + +## Provided Information + +* Current path +* Current username and hostname +* Current time +* 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 [../../plugins/available/battery.plugin.bash](battery plugin)) +* SCM Repository status (e.g. Git, SVN) +* The current Python environment (Virtualenv, venv, and Conda are supported) in use +* The current Ruby environment (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, but you can change this behavior by setting the value of the following variable: + + POWERLINE_PROMPT_USER_INFO_MODE="sudo" + +For now, the only supported value is `sudo`, which hides the username and hostname, and shows an indicator when `sudo` has the credentials cached. Other values have no effect at this time. + +### Clock Format + +You can change the format using the following variable: + + THEME_CLOCK_FORMAT="%H:%M:%S" + +The time/date is printed by the `date` command, so refer to its man page to change the format. + +### Segment Order + +The contents of the prompt can be "reordered", all the "segments" (every piece of information) can take any place. The currently available segments are: + +* battery +* clock +* cwd +* in_vim +* python_venv +* rvm +* scm +* user_info + +A variables can be defined to set the order of the prompt segments: + + POWERLINE_PROMPT="user_info scm python_venv rvm cwd" + +The example values above are the current default values, but if you want to remove anything from the prompt, simply remove the "string" that represents the segment from the variable. diff --git a/themes/powerline/powerline.base.bash b/themes/powerline/powerline.base.bash new file mode 100644 index 00000000..3abeda8d --- /dev/null +++ b/themes/powerline/powerline.base.bash @@ -0,0 +1,158 @@ +function set_color { + if [[ "${1}" != "-" ]]; then + fg="38;5;${1}" + fi + if [[ "${2}" != "-" ]]; then + bg="48;5;${2}" + [[ -n "${fg}" ]] && bg=";${bg}" + fi + echo -e "\[\033[${fg}${bg}m\]" +} + +function __powerline_user_info_prompt { + local user_info="" + local color=${USER_INFO_THEME_PROMPT_COLOR} + + if sudo -n uptime 2>&1 | grep -q "load"; then + color=${USER_INFO_THEME_PROMPT_COLOR_SUDO} + fi + case "${POWERLINE_PROMPT_USER_INFO_MODE}" in + "sudo") + if [[ "${color}" == "${USER_INFO_THEME_PROMPT_COLOR_SUDO}" ]]; then + user_info="!" + fi + ;; + *) + if [[ -n "${SSH_CLIENT}" ]]; then + user_info="${USER_INFO_SSH_CHAR}${USER}@${HOSTNAME}" + else + user_info="${USER}" + fi + ;; + esac + [[ -n "${user_info}" ]] && echo "${user_info}|${color}" +} + +function __powerline_ruby_prompt { + local ruby_version="" + + if command_exists rvm; then + ruby_version="$(rvm_version_prompt)" + elif command_exists rbenv; then + ruby_version=$(rbenv_version_prompt) + fi + + [[ -n "${ruby_version}" ]] && echo "${RUBY_CHAR}${ruby_version}|${RUBY_THEME_PROMPT_COLOR}" +} + +function __powerline_python_venv_prompt { + local python_venv="" + + if [[ -n "${CONDA_DEFAULT_ENV}" ]]; then + python_venv="${CONDA_DEFAULT_ENV}" + PYTHON_VENV_CHAR=${CONDA_PYTHON_VENV_CHAR} + elif [[ -n "${VIRTUAL_ENV}" ]]; then + python_venv=$(basename "${VIRTUAL_ENV}") + fi + + [[ -n "${python_venv}" ]] && echo "${PYTHON_VENV_CHAR}${python_venv}|${PYTHON_VENV_THEME_PROMPT_COLOR}" +} + +function __powerline_scm_prompt { + local color="" + local scm_prompt="" + + scm_prompt_vars + + if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then + if [[ "${SCM_DIRTY}" -eq 3 ]]; then + color=${SCM_THEME_PROMPT_STAGED_COLOR} + elif [[ "${SCM_DIRTY}" -eq 2 ]]; then + color=${SCM_THEME_PROMPT_UNSTAGED_COLOR} + elif [[ "${SCM_DIRTY}" -eq 1 ]]; then + color=${SCM_THEME_PROMPT_DIRTY_COLOR} + else + color=${SCM_THEME_PROMPT_CLEAN_COLOR} + fi + if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then + scm_prompt+="${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" + fi + echo "${scm_prompt}${scm}|${color}" + fi +} + +function __powerline_cwd_prompt { + echo "$(pwd | sed "s|^${HOME}|~|")|${CWD_THEME_PROMPT_COLOR}" +} + +function __powerline_clock_prompt { + echo "$(date +"${THEME_CLOCK_FORMAT}")|${CLOCK_THEME_PROMPT_COLOR}" +} + +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 + 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 +} + +function __powerline_in_vim_prompt { + if [ -n "$VIMRUNTIME" ]; then + echo "${IN_VIM_THEME_PROMPT_TEXT}|${IN_VIM_THEME_PROMPT_COLOR}" + fi +} + +function __powerline_left_segment { + local OLD_IFS="${IFS}"; IFS="|" + local params=( $1 ) + IFS="${OLD_IFS}" + local separator_char="${POWERLINE_LEFT_SEPARATOR}" + local separator="" + + if [[ "${SEGMENTS_AT_LEFT}" -gt 0 ]]; then + separator="$(set_color ${LAST_SEGMENT_COLOR} ${params[1]})${separator_char}${normal}" + fi + LEFT_PROMPT+="${separator}$(set_color - ${params[1]}) ${params[0]} ${normal}" + LAST_SEGMENT_COLOR=${params[1]} + (( SEGMENTS_AT_LEFT += 1 )) +} + +function __powerline_last_status_prompt { + [[ "$1" -ne 0 ]] && echo "${1}|${LAST_STATUS_THEME_PROMPT_COLOR}" +} + +function __powerline_prompt_command { + local last_status="$?" ## always the first + local separator_char="${POWERLINE_PROMPT_CHAR}" + + LEFT_PROMPT="" + SEGMENTS_AT_LEFT=0 + LAST_SEGMENT_COLOR="" + + ## left prompt ## + for segment in $POWERLINE_PROMPT; do + local info="$(__powerline_${segment}_prompt)" + [[ -n "${info}" ]] && __powerline_left_segment "${info}" + done + [[ "${last_status}" -ne 0 ]] && __powerline_left_segment $(__powerline_last_status_prompt ${last_status}) + [[ -n "${LEFT_PROMPT}" ]] && LEFT_PROMPT+="$(set_color ${LAST_SEGMENT_COLOR} -)${separator_char}${normal}" + + PS1="${LEFT_PROMPT} " + + ## cleanup ## + unset LAST_SEGMENT_COLOR \ + LEFT_PROMPT \ + SEGMENTS_AT_LEFT +} diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index 967a412c..12de9cbe 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -1,133 +1,51 @@ #!/usr/bin/env bash -THEME_PROMPT_SEPARATOR="" +. "$BASH_IT/themes/powerline/powerline.base.bash" -SHELL_SSH_CHAR=" " -SHELL_THEME_PROMPT_COLOR=32 -SHELL_THEME_PROMPT_COLOR_SUDO=202 +PROMPT_CHAR=${POWERLINE_PROMPT_CHAR:=""} +POWERLINE_LEFT_SEPARATOR=${POWERLINE_LEFT_SEPARATOR:=""} -VIRTUALENV_CHAR="ⓔ " -VIRTUALENV_THEME_PROMPT_COLOR=35 +USER_INFO_SSH_CHAR=${POWERLINE_USER_INFO_SSH_CHAR:=" "} +USER_INFO_THEME_PROMPT_COLOR=32 +USER_INFO_THEME_PROMPT_COLOR_SUDO=202 + +PYTHON_VENV_CHAR=${POWERLINE_PYTHON_VENV_CHAR:="❲p❳ "} +CONDA_PYTHON_VENV_CHAR=${POWERLINE_CONDA_PYTHON_VENV_CHAR:="❲c❳ "} +PYTHON_VENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" -SCM_GIT_CHAR=" " - +SCM_GIT_CHAR=${POWERLINE_SCM_GIT_CHAR:=" "} SCM_THEME_PROMPT_CLEAN="" SCM_THEME_PROMPT_DIRTY="" +SCM_THEME_PROMPT_CLEAN_COLOR=25 +SCM_THEME_PROMPT_DIRTY_COLOR=88 +SCM_THEME_PROMPT_STAGED_COLOR=30 +SCM_THEME_PROMPT_UNSTAGED_COLOR=92 +SCM_THEME_PROMPT_COLOR=${SCM_THEME_PROMPT_CLEAN_COLOR} -SCM_THEME_PROMPT_COLOR=238 -SCM_THEME_PROMPT_CLEAN_COLOR=231 -SCM_THEME_PROMPT_DIRTY_COLOR=196 -SCM_THEME_PROMPT_STAGED_COLOR=220 -SCM_THEME_PROMPT_UNSTAGED_COLOR=166 +RVM_THEME_PROMPT_PREFIX="" +RVM_THEME_PROMPT_SUFFIX="" +RBENV_THEME_PROMPT_PREFIX="" +RBENV_THEME_PROMPT_SUFFIX="" +RUBY_THEME_PROMPT_COLOR=161 +RUBY_CHAR=${POWERLINE_RUBY_CHAR:="❲r❳ "} CWD_THEME_PROMPT_COLOR=240 LAST_STATUS_THEME_PROMPT_COLOR=52 -IN_VIM_PROMPT_COLOR=35 -IN_VIM_PROMPT_TEXT="vim" +CLOCK_THEME_PROMPT_COLOR=240 +BATTERY_AC_CHAR=${BATTERY_AC_CHAR:="⚡"} +BATTERY_STATUS_THEME_PROMPT_GOOD_COLOR=70 +BATTERY_STATUS_THEME_PROMPT_LOW_COLOR=208 +BATTERY_STATUS_THEME_PROMPT_CRITICAL_COLOR=160 -function set_rgb_color { - if [[ "${1}" != "-" ]]; then - fg="38;5;${1}" - fi - if [[ "${2}" != "-" ]]; then - bg="48;5;${2}" - [[ -n "${fg}" ]] && bg=";${bg}" - fi - echo -e "\[\033[${fg}${bg}m\]" -} +THEME_CLOCK_FORMAT=${THEME_CLOCK_FORMAT:="%H:%M:%S"} -function powerline_shell_prompt { - SHELL_PROMPT_COLOR=${SHELL_THEME_PROMPT_COLOR} - if sudo -n uptime 2>&1 | grep -q "load"; then - SHELL_PROMPT_COLOR=${SHELL_THEME_PROMPT_COLOR_SUDO} - fi - if [[ -n "${SSH_CLIENT}" ]]; then - SHELL_PROMPT="${SHELL_SSH_CHAR}\u@\h" - else - SHELL_PROMPT="\u" - fi - SHELL_PROMPT="${bold_white}$(set_rgb_color - ${SHELL_PROMPT_COLOR}) ${SHELL_PROMPT} ${normal}" - LAST_THEME_COLOR=${SHELL_PROMPT_COLOR} -} +IN_VIM_THEME_PROMPT_COLOR=245 +IN_VIM_THEME_PROMPT_TEXT="vim" -function powerline_virtualenv_prompt { - local environ="" - - if [[ -n "$CONDA_DEFAULT_ENV" ]]; then - environ="conda: $CONDA_DEFAULT_ENV" - elif [[ -n "$VIRTUAL_ENV" ]]; then - environ=$(basename "$VIRTUAL_ENV") - fi - - if [[ -n "$environ" ]]; then - VIRTUALENV_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${VIRTUALENV_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${VIRTUALENV_THEME_PROMPT_COLOR}) ${VIRTUALENV_CHAR}$environ ${normal}" - LAST_THEME_COLOR=${VIRTUALENV_THEME_PROMPT_COLOR} - else - VIRTUALENV_PROMPT="" - fi -} - -function powerline_scm_prompt { - scm_prompt_vars - - if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then - if [[ "${SCM_DIRTY}" -eq 3 ]]; then - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_STAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" - elif [[ "${SCM_DIRTY}" -eq 2 ]]; then - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_UNSTAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" - elif [[ "${SCM_DIRTY}" -eq 1 ]]; then - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_DIRTY_COLOR} ${SCM_THEME_PROMPT_COLOR})" - else - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_CLEAN_COLOR} ${SCM_THEME_PROMPT_COLOR})" - fi - if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then - SCM_PROMPT+=" ${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" - fi - SCM_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${SCM_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${SCM_PROMPT} ${normal}" - LAST_THEME_COLOR=${SCM_THEME_PROMPT_COLOR} - else - SCM_PROMPT="" - fi -} - -function powerline_cwd_prompt { - CWD_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${CWD_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${CWD_THEME_PROMPT_COLOR}) \w ${normal}$(set_rgb_color ${CWD_THEME_PROMPT_COLOR} -)${normal}" - LAST_THEME_COLOR=${CWD_THEME_PROMPT_COLOR} -} - -function powerline_last_status_prompt { - if [[ "$1" -eq 0 ]]; then - LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" - else - LAST_STATUS_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${LAST_STATUS_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${LAST_STATUS_THEME_PROMPT_COLOR}) ${LAST_STATUS} ${normal}$(set_rgb_color ${LAST_STATUS_THEME_PROMPT_COLOR} -)${THEME_PROMPT_SEPARATOR}${normal}" - fi -} - -function powerline_in_vim_prompt { - if [ -z "$VIMRUNTIME" ]; then - IN_VIM_PROMPT="" - else - IN_VIM_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${IN_VIM_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}$(set_rgb_color - ${IN_VIM_PROMPT_COLOR}) ${IN_VIM_PROMPT_TEXT} ${normal}$(set_rgb_color ${IN_VIM_PROMPT_COLOR} -)${normal}" - LAST_THEME_COLOR=${IN_VIM_PROMPT_COLOR} - fi -} - -function powerline_prompt_command() { - local LAST_STATUS="$?" - - powerline_shell_prompt - powerline_in_vim_prompt - powerline_virtualenv_prompt - powerline_scm_prompt - powerline_cwd_prompt - powerline_last_status_prompt LAST_STATUS - - PS1="${SHELL_PROMPT}${IN_VIM_PROMPT}${VIRTUALENV_PROMPT}${SCM_PROMPT}${CWD_PROMPT}${LAST_STATUS_PROMPT} " -} - -safe_append_prompt_command powerline_prompt_command +POWERLINE_PROMPT=${POWERLINE_PROMPT:="user_info scm python_venv ruby cwd"} +safe_append_prompt_command __powerline_prompt_command