From 681e6f0714db36c69688ad3627f185695e6deba2 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 3 Apr 2017 22:10:59 +0200 Subject: [PATCH 001/107] Use zsh-async for asynchronous functionality --- .gitmodules | 3 +++ README.md | 10 ++++++++++ slimline.zsh | 48 ++++++++++++++++++++++-------------------------- zsh-async | 1 + 4 files changed, 36 insertions(+), 26 deletions(-) create mode 160000 zsh-async diff --git a/.gitmodules b/.gitmodules index e511ecc..906e225 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "gitline"] path = gitline url = https://github.com/mgee/gitline.git +[submodule "zsh-async"] + path = zsh-async + url = https://github.com/mafredri/zsh-async.git diff --git a/README.md b/README.md index b4d536b..5edece9 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ For a fish compatible version of this theme have a look at [slimfish](https://gi - [AWS Profile Info](#aws-profile-info) - [Auto Correction](#auto-correction) - [Python Virtualenv](#python-virtualenv) + - [Async Autoloading](#async-autoloading) - [Git Information](#git-information) - [Gitline](#gitline) - [Example](#example) @@ -202,6 +203,14 @@ Defines the color of the virtualenv name. Default is `cyan`. Defines the color of the parens surrounding the virtualenv name. Default is `white`. +### Async Autoloading + +##### `SLIMLINE_ENABLE_ASYNC_AUTOLOAD` + +Defines whether [zsh-async](https://github.com/mafredri/zsh-async) should be automatically +sourced if it was not already sourced. Disabling the automatic loading is useful if zsh-async +is installed globally and therefore already loaded (e.g. via antigen or zplugin). Default is `1`. + ### Git Information ##### `SLIMLINE_ENABLE_GIT` @@ -231,6 +240,7 @@ source "/slimline.plugin.zsh" ## Thanks +- [mafredri/zsh-async](https://github.com/mafredri/zsh-async) - [sindresorhus/pure](https://github.com/sindresorhus/pure) - [sorin-ionescu/prezto](https://github.com/sorin-ionescu/prezto.git) diff --git a/slimline.zsh b/slimline.zsh index fd1b456..fcd3878 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -160,46 +160,42 @@ prompt_slimline_preexec() { } prompt_slimline_async_git() { - local _prompt_slimline_git_output="" if (( ${SLIMLINE_ENABLE_GIT:-1} )); then - _prompt_slimline_git_output="$(python ${prompt_slimline_path}/gitline/gitline.py --shell=zsh)" + command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" fi - typeset -p _prompt_slimline_git_output >! "$_prompt_slimline_async_data" - - kill -WINCH $$ # Signal completion to parent process. } prompt_slimline_async_callback() { - if (( _prompt_slimline_async_pid == 0 )); then - return - fi + local job=${1} + local output=${3} + local has_next=${6} + + case "${job}" in + prompt_slimline_async_git) + _prompt_slimline_git_output="${output}" + prompt_slimline_set_prompt ${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white} + prompt_slimline_set_rprompt + ;; + esac - if [[ -s "$_prompt_slimline_async_data" ]]; then - alias typeset='typeset -g' - source "$_prompt_slimline_async_data" - unalias typeset + if (( ! ${has_next} )); then + zle && zle .reset-prompt fi - _prompt_slimline_async_pid=0 - prompt_slimline_set_prompt ${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white} - prompt_slimline_set_rprompt - zle && zle .reset-prompt } prompt_slimline_async_tasks() { _prompt_slimline_last_async_call=${EPOCHREALTIME} - # Kill the old process of slow commands if it is still running. - if (( __prompt_slimline_async_pid > 0 )); then - kill -KILL "$_prompt_slimline_async_pid" &>/dev/null - fi - - trap prompt_slimline_async_callback WINCH - prompt_slimline_async_git &! - _prompt_slimline_async_pid=$! + async_flush_jobs "prompt_slimline" + async_job "prompt_slimline" prompt_slimline_async_git "$(builtin pwd)" } prompt_slimline_async_init() { - _prompt_slimline_async_pid=0 - _prompt_slimline_async_data="${TMPPREFIX}-${prompt_slimline_default_user}-prompt_slimline_data" + if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} && !$+functions[async_init] && !$+functions[async_start_worker] )); then + source "${prompt_slimline_path}/zsh-async/async.zsh" + fi + async_init + async_start_worker "prompt_slimline" -u + async_register_callback "prompt_slimline" prompt_slimline_async_callback } prompt_slimline_setup() { diff --git a/zsh-async b/zsh-async new file mode 160000 index 0000000..001f40e --- /dev/null +++ b/zsh-async @@ -0,0 +1 @@ +Subproject commit 001f40e329bd04baebbe9008306246a01d015e2c From dffaf06c093f8920ed27f3713ca105db6439a97b Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 10:00:48 +0100 Subject: [PATCH 002/107] Pass calling function to symbol section --- slimline.zsh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index fcd3878..89072c8 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -75,7 +75,13 @@ prompt_slimline_cwd() { } prompt_slimline_symbol() { - local symbol_color=${1:-${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red}} + local stage=${1} + local symbol_color='' + if [[ "${stage}" == "async_callback" ]]; then + symbol_color=${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white} + else + symbol_color=${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red} + fi echo "%F{$symbol_color}${SLIMLINE_PROMPT_SYMBOL:-∙}%f " } @@ -148,8 +154,8 @@ prompt_slimline_precmd() { unset _prompt_slimline_git_output if (( ${EPOCHREALTIME} - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then - prompt_slimline_set_prompt - prompt_slimline_set_rprompt + prompt_slimline_set_prompt "precmd" + prompt_slimline_set_rprompt "precmd" prompt_slimline_async_tasks fi @@ -173,8 +179,8 @@ prompt_slimline_async_callback() { case "${job}" in prompt_slimline_async_git) _prompt_slimline_git_output="${output}" - prompt_slimline_set_prompt ${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white} - prompt_slimline_set_rprompt + prompt_slimline_set_prompt "async_callback" + prompt_slimline_set_rprompt "async_callback" ;; esac @@ -220,8 +226,8 @@ prompt_slimline_setup() { prompt_slimline_async_init - prompt_slimline_set_prompt - prompt_slimline_set_rprompt + prompt_slimline_set_prompt "setup" + prompt_slimline_set_rprompt "setup" prompt_slimline_set_sprompt } From cbfcf5256128276a686fb68a10155aaa32615314 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 10:05:19 +0100 Subject: [PATCH 003/107] Use one-line guards for section output --- slimline.zsh | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 89072c8..623866e 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -40,20 +40,13 @@ prompt_slimline_check_cmd_exec_time() { prompt_slimline_aws_profile() { # add AWS profile info - if (( ! ${SLIMLINE_DISPLAY_AWS_INFO:-0} )) || [[ -z "${AWS_PROFILE}" ]]; then - return - fi + if (( ! ${SLIMLINE_DISPLAY_AWS_INFO:-0} )) || [[ -z "${AWS_PROFILE}" ]]; then return; fi echo "%F{${SLIMLINE_AWS_COLOR:-blue}}${AWS_PROFILE}%f " } prompt_slimline_user_host_info() { - if (( ! ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then - return - fi - - if [[ -z "$SSH_TTY" && "${USER}" == "${prompt_slimline_default_user}" ]]; then - return - fi + if (( ! ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then return; fi + if [[ -z "$SSH_TTY" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi local user_color='' if [[ $UID -eq 0 ]]; then @@ -87,30 +80,22 @@ prompt_slimline_symbol() { prompt_slimline_execution_time() { # add elapsed time if threshold is exceeded - if (( ! ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )) || [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then - return - fi + if (( ! ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )) || [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi echo "%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}${_prompt_slimline_cmd_exec_time}%f " } prompt_slimline_exit_status() { - if (( ! ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then - return - fi + if (( ! ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then return; fi echo "%(?::%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}%? ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f) " } prompt_slimline_git() { - if [[ -z "${_prompt_slimline_git_output:-}" ]]; then - return - fi + if [[ -z "${_prompt_slimline_git_output:-}" ]]; then return; fi echo "${_prompt_slimline_git_output} " } prompt_slimline_virtualenv() { - if (( ! ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )) || [[ -z $VIRTUAL_ENV ]]; then - return - fi + if (( ! ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )) || [[ -z $VIRTUAL_ENV ]]; then return; fi local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" local virtualenv_color="${SLIMLINE_VIRTUALENV_COLOR:-cyan}" @@ -166,9 +151,8 @@ prompt_slimline_preexec() { } prompt_slimline_async_git() { - if (( ${SLIMLINE_ENABLE_GIT:-1} )); then - command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" - fi + if (( ! ${SLIMLINE_ENABLE_GIT:-1} )); then return; fi + command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" } prompt_slimline_async_callback() { From 67d73ac54a0e7b193da6bddff8667722bea046dd Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 10:15:11 +0100 Subject: [PATCH 004/107] Remove unneeded dollar from arithmetic variables --- slimline.zsh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 623866e..a40d078 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -23,9 +23,9 @@ prompt_slimline_human_time() { local hours=$(( tmp / 60 / 60 % 24 )) local minutes=$(( tmp / 60 % 60 )) local seconds=$(( tmp % 60 )) - (( $days > 0 )) && echo -n "${days}d " - (( $hours > 0 )) && echo -n "${hours}h " - (( $minutes > 0 )) && echo -n "${minutes}m " + (( days > 0 )) && echo -n "${days}d " + (( hours > 0 )) && echo -n "${hours}h " + (( minutes > 0 )) && echo -n "${minutes}m " echo "${seconds}s" } @@ -138,7 +138,7 @@ prompt_slimline_precmd() { unset _prompt_slimline_cmd_timestamp unset _prompt_slimline_git_output - if (( ${EPOCHREALTIME} - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then + if (( EPOCHREALTIME - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then prompt_slimline_set_prompt "precmd" prompt_slimline_set_rprompt "precmd" @@ -168,7 +168,7 @@ prompt_slimline_async_callback() { ;; esac - if (( ! ${has_next} )); then + if (( ! has_next )); then zle && zle .reset-prompt fi } From 4321f0f14d228787672eeebbe6802edcd11acbc6 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 10:19:29 +0100 Subject: [PATCH 005/107] Use double quoting were appropriate --- slimline.plugin.zsh | 2 +- slimline.zsh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/slimline.plugin.zsh b/slimline.plugin.zsh index bb0f06d..0e1df1b 100644 --- a/slimline.plugin.zsh +++ b/slimline.plugin.zsh @@ -1 +1 @@ -source ${0:A:h}/slimline.zsh +source "${0:A:h}/slimline.zsh" diff --git a/slimline.zsh b/slimline.zsh index a40d078..3f6f34a 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -11,7 +11,7 @@ # MIT License #------------------------------------------------------------------------------- -prompt_slimline_path="$(dirname $0:A:H)" +prompt_slimline_path="${0:A:h}" prompt_slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" # turns seconds into human readable time @@ -99,7 +99,7 @@ prompt_slimline_virtualenv() { local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" local virtualenv_color="${SLIMLINE_VIRTUALENV_COLOR:-cyan}" - echo "%F{$parens_color}(%f%F{$virtualenv_color}`basename $VIRTUAL_ENV`%f%F{$parens_color})%f " + echo "%F{$parens_color}(%f%F{$virtualenv_color}$(basename "${VIRTUAL_ENV}")%f%F{$parens_color})%f " } prompt_slimline_set_prompt() { @@ -109,7 +109,7 @@ prompt_slimline_set_prompt() { PROMPT+="$(prompt_slimline_user_host_info)" PROMPT+="$(prompt_slimline_cwd)" PROMPT+="$(prompt_slimline_aws_profile)" - PROMPT+="$(prompt_slimline_symbol $1)" + PROMPT+="$(prompt_slimline_symbol "$*")" } prompt_slimline_set_rprompt() { From c89eb5f2eed7b20a535ae9bc6593808925c05d3b Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 10:26:55 +0100 Subject: [PATCH 006/107] Mark section functions as such --- slimline.zsh | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 3f6f34a..33772b6 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -38,13 +38,13 @@ prompt_slimline_check_cmd_exec_time() { fi } -prompt_slimline_aws_profile() { +prompt_slimline_section_aws_profile() { # add AWS profile info if (( ! ${SLIMLINE_DISPLAY_AWS_INFO:-0} )) || [[ -z "${AWS_PROFILE}" ]]; then return; fi echo "%F{${SLIMLINE_AWS_COLOR:-blue}}${AWS_PROFILE}%f " } -prompt_slimline_user_host_info() { +prompt_slimline_section_user_host_info() { if (( ! ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then return; fi if [[ -z "$SSH_TTY" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi @@ -57,7 +57,7 @@ prompt_slimline_user_host_info() { echo "%F{${user_color}}%n%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}%m%f " } -prompt_slimline_cwd() { +prompt_slimline_section_cwd() { local cwd_color='' if [[ "$(builtin pwd)" == "/" ]]; then cwd_color="${SLIMLINE_CWD_ROOT_COLOR:-red}" @@ -67,7 +67,7 @@ prompt_slimline_cwd() { echo "%F{${cwd_color}}%3~%f " } -prompt_slimline_symbol() { +prompt_slimline_section_symbol() { local stage=${1} local symbol_color='' if [[ "${stage}" == "async_callback" ]]; then @@ -78,23 +78,23 @@ prompt_slimline_symbol() { echo "%F{$symbol_color}${SLIMLINE_PROMPT_SYMBOL:-∙}%f " } -prompt_slimline_execution_time() { +prompt_slimline_section_execution_time() { # add elapsed time if threshold is exceeded if (( ! ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )) || [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi echo "%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}${_prompt_slimline_cmd_exec_time}%f " } -prompt_slimline_exit_status() { +prompt_slimline_section_exit_status() { if (( ! ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then return; fi echo "%(?::%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}%? ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f) " } -prompt_slimline_git() { +prompt_slimline_section_git() { if [[ -z "${_prompt_slimline_git_output:-}" ]]; then return; fi echo "${_prompt_slimline_git_output} " } -prompt_slimline_virtualenv() { +prompt_slimline_section_virtualenv() { if (( ! ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )) || [[ -z $VIRTUAL_ENV ]]; then return; fi local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" @@ -106,20 +106,20 @@ prompt_slimline_set_prompt() { # clear prompt PROMPT="" - PROMPT+="$(prompt_slimline_user_host_info)" - PROMPT+="$(prompt_slimline_cwd)" - PROMPT+="$(prompt_slimline_aws_profile)" - PROMPT+="$(prompt_slimline_symbol "$*")" + PROMPT+="$(prompt_slimline_section_user_host_info)" + PROMPT+="$(prompt_slimline_section_cwd)" + PROMPT+="$(prompt_slimline_section_aws_profile)" + PROMPT+="$(prompt_slimline_section_symbol "$*")" } prompt_slimline_set_rprompt() { # clear prompt RPROMPT="" - RPROMPT+="$(prompt_slimline_execution_time)" - RPROMPT+="$(prompt_slimline_exit_status)" - RPROMPT+="$(prompt_slimline_git)" - RPROMPT+="$(prompt_slimline_virtualenv)" + RPROMPT+="$(prompt_slimline_section_execution_time)" + RPROMPT+="$(prompt_slimline_section_exit_status)" + RPROMPT+="$(prompt_slimline_section_git)" + RPROMPT+="$(prompt_slimline_section_virtualenv)" # Trim trailing space RPROMPT="${${RPROMPT}%%[[:blank:]]#}" } From ca606d4aa610dd4a1acf91b15927791381aa7acf Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 10:43:03 +0100 Subject: [PATCH 007/107] Make prompt sections configurable --- slimline.zsh | 64 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 33772b6..34f43a8 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -41,7 +41,7 @@ prompt_slimline_check_cmd_exec_time() { prompt_slimline_section_aws_profile() { # add AWS profile info if (( ! ${SLIMLINE_DISPLAY_AWS_INFO:-0} )) || [[ -z "${AWS_PROFILE}" ]]; then return; fi - echo "%F{${SLIMLINE_AWS_COLOR:-blue}}${AWS_PROFILE}%f " + echo "%F{${SLIMLINE_AWS_COLOR:-blue}}${AWS_PROFILE}%f" } prompt_slimline_section_user_host_info() { @@ -54,7 +54,7 @@ prompt_slimline_section_user_host_info() { else user_color="${SLIMLINE_USER_COLOR:-green}" fi - echo "%F{${user_color}}%n%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}%m%f " + echo "%F{${user_color}}%n%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}%m%f" } prompt_slimline_section_cwd() { @@ -64,7 +64,7 @@ prompt_slimline_section_cwd() { else cwd_color="${SLIMLINE_CWD_COLOR:-cyan}" fi - echo "%F{${cwd_color}}%3~%f " + echo "%F{${cwd_color}}%3~%f" } prompt_slimline_section_symbol() { @@ -75,23 +75,23 @@ prompt_slimline_section_symbol() { else symbol_color=${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red} fi - echo "%F{$symbol_color}${SLIMLINE_PROMPT_SYMBOL:-∙}%f " + echo "%F{$symbol_color}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" } prompt_slimline_section_execution_time() { # add elapsed time if threshold is exceeded if (( ! ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )) || [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi - echo "%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}${_prompt_slimline_cmd_exec_time}%f " + echo "%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}${_prompt_slimline_cmd_exec_time}%f" } prompt_slimline_section_exit_status() { if (( ! ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then return; fi - echo "%(?::%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}%? ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f) " + echo "%(?::%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}%? ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f)" } prompt_slimline_section_git() { if [[ -z "${_prompt_slimline_git_output:-}" ]]; then return; fi - echo "${_prompt_slimline_git_output} " + echo "${_prompt_slimline_git_output}" } prompt_slimline_section_virtualenv() { @@ -99,29 +99,47 @@ prompt_slimline_section_virtualenv() { local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" local virtualenv_color="${SLIMLINE_VIRTUALENV_COLOR:-cyan}" - echo "%F{$parens_color}(%f%F{$virtualenv_color}$(basename "${VIRTUAL_ENV}")%f%F{$parens_color})%f " + echo "%F{$parens_color}(%f%F{$virtualenv_color}$(basename "${VIRTUAL_ENV}")%f%F{$parens_color})%f" +} + +prompt_slimline_get_sections() { + local var=${1} + local sections=${2} + local separator=${3} + shift 3 + + outputs=() + for section in ${=sections}; do + local function_name="prompt_slimline_section_${section}" + if (( ! $+functions[${function_name}] )); then + echo "'${section}' is not a valid section!" + continue + fi + local output="$(${function_name} "$*")" + if [[ -n ${output} ]]; then + outputs+=("${output}") + fi + done + + typeset -g "${var}"="${(epj:${separator}:)outputs}" } prompt_slimline_set_prompt() { - # clear prompt - PROMPT="" + local sections="${SLIMLINE_PROMPT_SECTIONS:-user_host_info cwd aws_profile symbol}" + local separator="${SLIMLINE_PROMPT_SECTION_SEPARATOR:- }" + prompt_slimline_get_sections "_prompt_slimline_prompt_sections_output" "${sections}" "${separator}" "$*" - PROMPT+="$(prompt_slimline_section_user_host_info)" - PROMPT+="$(prompt_slimline_section_cwd)" - PROMPT+="$(prompt_slimline_section_aws_profile)" - PROMPT+="$(prompt_slimline_section_symbol "$*")" + PROMPT="${_prompt_slimline_prompt_sections_output} " + unset _prompt_slimline_prompt_sections_output } prompt_slimline_set_rprompt() { - # clear prompt - RPROMPT="" + local sections=${SLIMLINE_RPROMPT_SECTIONS:-execution_time exit_status git virtualenv} + local separator="${SLIMLINE_RPROMPT_SECTION_SEPARATOR:- }" + prompt_slimline_get_sections "_prompt_slimline_rprompt_sections_output" "${sections}" "${separator}" "$*" - RPROMPT+="$(prompt_slimline_section_execution_time)" - RPROMPT+="$(prompt_slimline_section_exit_status)" - RPROMPT+="$(prompt_slimline_section_git)" - RPROMPT+="$(prompt_slimline_section_virtualenv)" - # Trim trailing space - RPROMPT="${${RPROMPT}%%[[:blank:]]#}" + RPROMPT="${_prompt_slimline_rprompt_sections_output}" + unset _prompt_slimline_rprompt_sections_output } prompt_slimline_set_sprompt() { @@ -195,8 +213,6 @@ prompt_slimline_setup() { SLIMLINE_ENABLE_GIT=0 fi - setopt extended_glob - prompt_opts=(cr percent subst) zmodload zsh/datetime From e4504df4873b4be6fa6b5d306eb1a04264fba8f2 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 10:48:58 +0100 Subject: [PATCH 008/107] Use alternative way of displaying exit status This way the exit status section output is empty and correctly ignored if the exit status is zero. --- slimline.zsh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/slimline.zsh b/slimline.zsh index 34f43a8..f92de6e 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -86,7 +86,8 @@ prompt_slimline_section_execution_time() { prompt_slimline_section_exit_status() { if (( ! ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then return; fi - echo "%(?::%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}%? ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f)" + if (( _prompt_slimline_last_exit_status == 0 )); then return; fi + echo "%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}${_prompt_slimline_last_exit_status} ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f" } prompt_slimline_section_git() { @@ -168,6 +169,10 @@ prompt_slimline_preexec() { _prompt_slimline_cmd_timestamp=$EPOCHSECONDS } +prompt_slimline_exit_status() { + _prompt_slimline_last_exit_status=$? +} + prompt_slimline_async_git() { if (( ! ${SLIMLINE_ENABLE_GIT:-1} )); then return; fi command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" @@ -224,6 +229,8 @@ prompt_slimline_setup() { add-zsh-hook precmd prompt_slimline_precmd add-zsh-hook preexec prompt_slimline_preexec + precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) + prompt_slimline_async_init prompt_slimline_set_prompt "setup" From 41cf5889ab0ed49706f27b99b9dffd4fc54064b8 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 13:43:58 +0100 Subject: [PATCH 009/107] Disable git task if git section is not in prompt --- slimline.zsh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index f92de6e..63af105 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -91,7 +91,7 @@ prompt_slimline_section_exit_status() { } prompt_slimline_section_git() { - if [[ -z "${_prompt_slimline_git_output:-}" ]]; then return; fi + if [[ -z "${_prompt_slimline_git_output}" ]]; then return; fi echo "${_prompt_slimline_git_output}" } @@ -126,18 +126,16 @@ prompt_slimline_get_sections() { } prompt_slimline_set_prompt() { - local sections="${SLIMLINE_PROMPT_SECTIONS:-user_host_info cwd aws_profile symbol}" local separator="${SLIMLINE_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_prompt_sections_output" "${sections}" "${separator}" "$*" + prompt_slimline_get_sections "_prompt_slimline_prompt_sections_output" "${_prompt_slimline_prompt_sections}" "${separator}" "$*" PROMPT="${_prompt_slimline_prompt_sections_output} " unset _prompt_slimline_prompt_sections_output } prompt_slimline_set_rprompt() { - local sections=${SLIMLINE_RPROMPT_SECTIONS:-execution_time exit_status git virtualenv} local separator="${SLIMLINE_RPROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_rprompt_sections_output" "${sections}" "${separator}" "$*" + prompt_slimline_get_sections "_prompt_slimline_rprompt_sections_output" "${_prompt_slimline_rprompt_sections}" "${separator}" "$*" RPROMPT="${_prompt_slimline_rprompt_sections_output}" unset _prompt_slimline_rprompt_sections_output @@ -174,7 +172,7 @@ prompt_slimline_exit_status() { } prompt_slimline_async_git() { - if (( ! ${SLIMLINE_ENABLE_GIT:-1} )); then return; fi + if (( ! _prompt_slimline_task_git_enabled )); then return; fi command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" } @@ -218,6 +216,14 @@ prompt_slimline_setup() { SLIMLINE_ENABLE_GIT=0 fi + _prompt_slimline_prompt_sections="${SLIMLINE_PROMPT_SECTIONS-user_host_info cwd aws_profile symbol}" + _prompt_slimline_rprompt_sections="${SLIMLINE_RPROMPT_SECTIONS-execution_time exit_status git virtualenv}" + if (( ${=_prompt_slimline_prompt_sections[(I)git]} || ${=_prompt_slimline_rprompt_sections[(I)git]} )); then + _prompt_slimline_task_git_enabled=1 + else + _prompt_slimline_task_git_enabled=0 + fi + prompt_opts=(cr percent subst) zmodload zsh/datetime From e30e609b1b3b0a7f92f2af455fb1f316186a9446 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 18:46:32 +0100 Subject: [PATCH 010/107] Verify section names eagerly --- slimline.zsh | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 63af105..a332282 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -111,12 +111,7 @@ prompt_slimline_get_sections() { outputs=() for section in ${=sections}; do - local function_name="prompt_slimline_section_${section}" - if (( ! $+functions[${function_name}] )); then - echo "'${section}' is not a valid section!" - continue - fi - local output="$(${function_name} "$*")" + local output="$(${section} "$*")" if [[ -n ${output} ]]; then outputs+=("${output}") fi @@ -209,6 +204,21 @@ prompt_slimline_async_init() { async_register_callback "prompt_slimline" prompt_slimline_async_callback } +prompt_slimline_expand_sections() { + local var=${1} + local expanded_sections=() + for section in ${=${(P)var}}; do + local function_name="prompt_slimline_section_${section}" + if (( ! $+functions[${function_name}] )); then + print -P "%F{red}slimline%f: '${section}' is not a valid section!" + continue + fi + expanded_sections+=("${function_name}") + done + + typeset -g "${var}"="${(j: :)expanded_sections}" +} + prompt_slimline_setup() { # If python or git are not installed, disable the git functionality. if ! (( $+commands[python] && $+commands[git] )); then @@ -223,6 +233,8 @@ prompt_slimline_setup() { else _prompt_slimline_task_git_enabled=0 fi + prompt_slimline_expand_sections "_prompt_slimline_prompt_sections" + prompt_slimline_expand_sections "_prompt_slimline_rprompt_sections" prompt_opts=(cr percent subst) From b79196722483ae15809d85a5432da3229f746b2a Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 18:47:34 +0100 Subject: [PATCH 011/107] Move git check to separate function --- slimline.zsh | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index a332282..427ed0b 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -167,7 +167,7 @@ prompt_slimline_exit_status() { } prompt_slimline_async_git() { - if (( ! _prompt_slimline_task_git_enabled )); then return; fi + if (( ! _prompt_slimline_enable_git_task )); then return; fi command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" } @@ -204,6 +204,20 @@ prompt_slimline_async_init() { async_register_callback "prompt_slimline" prompt_slimline_async_callback } +prompt_slimline_check_git_support() { + if (( ${=_prompt_slimline_prompt_sections[(I)git]} || ${=_prompt_slimline_rprompt_sections[(I)git]} )); then + # If python or git are not installed, disable the git functionality. + if (( $+commands[python] && $+commands[git] )); then + _prompt_slimline_enable_git_task=1 + else + print -P "%F{red}slimline%f: python and/or git not installed or not in PATH, disabling git information" + _prompt_slimline_enable_git_task=0 + fi + else + _prompt_slimline_enable_git_task=0 + fi +} + prompt_slimline_expand_sections() { local var=${1} local expanded_sections=() @@ -220,19 +234,10 @@ prompt_slimline_expand_sections() { } prompt_slimline_setup() { - # If python or git are not installed, disable the git functionality. - if ! (( $+commands[python] && $+commands[git] )); then - echo "slimline: python and/or git not installed or not in PATH, disabling git information" - SLIMLINE_ENABLE_GIT=0 - fi _prompt_slimline_prompt_sections="${SLIMLINE_PROMPT_SECTIONS-user_host_info cwd aws_profile symbol}" _prompt_slimline_rprompt_sections="${SLIMLINE_RPROMPT_SECTIONS-execution_time exit_status git virtualenv}" - if (( ${=_prompt_slimline_prompt_sections[(I)git]} || ${=_prompt_slimline_rprompt_sections[(I)git]} )); then - _prompt_slimline_task_git_enabled=1 - else - _prompt_slimline_task_git_enabled=0 - fi + prompt_slimline_check_git_support prompt_slimline_expand_sections "_prompt_slimline_prompt_sections" prompt_slimline_expand_sections "_prompt_slimline_rprompt_sections" From 27f364125ce216cb7ce59fac87017534203c5269 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 18:53:35 +0100 Subject: [PATCH 012/107] Add initial noop function to parse legacy options --- slimline.zsh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/slimline.zsh b/slimline.zsh index 427ed0b..c7c0baa 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -204,6 +204,13 @@ prompt_slimline_async_init() { async_register_callback "prompt_slimline" prompt_slimline_async_callback } +prompt_slimline_evaluate_legacy_options() { + local prompt_sections=(user_host_info cwd aws_profile symbol) + local rprompt_sections=(execution_time exit_status git virtualenv) + SLIMLINE_PROMPT_SECTIONS="${(j: :)prompt_sections}" + SLIMLINE_RPROMPT_SECTIONS="${(j: :)rprompt_sections}" +} + prompt_slimline_check_git_support() { if (( ${=_prompt_slimline_prompt_sections[(I)git]} || ${=_prompt_slimline_rprompt_sections[(I)git]} )); then # If python or git are not installed, disable the git functionality. @@ -234,6 +241,9 @@ prompt_slimline_expand_sections() { } prompt_slimline_setup() { + if (( ${SLIMLINE_PROMPT_VERSION:-1} < 2 )); then + prompt_slimline_evaluate_legacy_options + fi _prompt_slimline_prompt_sections="${SLIMLINE_PROMPT_SECTIONS-user_host_info cwd aws_profile symbol}" _prompt_slimline_rprompt_sections="${SLIMLINE_RPROMPT_SECTIONS-execution_time exit_status git virtualenv}" From b919c90dc8c161ffd7f88aeee4ead62a0880a9a8 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 19:05:29 +0100 Subject: [PATCH 013/107] Add support for a custom prompt format --- slimline.zsh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index c7c0baa..cee60e1 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -124,7 +124,8 @@ prompt_slimline_set_prompt() { local separator="${SLIMLINE_PROMPT_SECTION_SEPARATOR:- }" prompt_slimline_get_sections "_prompt_slimline_prompt_sections_output" "${_prompt_slimline_prompt_sections}" "${separator}" "$*" - PROMPT="${_prompt_slimline_prompt_sections_output} " + local format="${SLIMLINE_PROMPT_FORMAT:-|sections| }" + PROMPT="${format/|sections|/${_prompt_slimline_prompt_sections_output}}" unset _prompt_slimline_prompt_sections_output } @@ -132,7 +133,8 @@ prompt_slimline_set_rprompt() { local separator="${SLIMLINE_RPROMPT_SECTION_SEPARATOR:- }" prompt_slimline_get_sections "_prompt_slimline_rprompt_sections_output" "${_prompt_slimline_rprompt_sections}" "${separator}" "$*" - RPROMPT="${_prompt_slimline_rprompt_sections_output}" + local format="${SLIMLINE_RPROMPT_FORMAT:-|sections|}" + RPROMPT="${format/|sections|/${_prompt_slimline_rprompt_sections_output}}" unset _prompt_slimline_rprompt_sections_output } From 77f76f4535b54ea7149f4448d5c74026278562ef Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 21:54:21 +0100 Subject: [PATCH 014/107] Add new option format for more customization --- slimline.zsh | 118 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 31 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index cee60e1..a3e80e0 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -39,55 +39,65 @@ prompt_slimline_check_cmd_exec_time() { } prompt_slimline_section_aws_profile() { - # add AWS profile info - if (( ! ${SLIMLINE_DISPLAY_AWS_INFO:-0} )) || [[ -z "${AWS_PROFILE}" ]]; then return; fi - echo "%F{${SLIMLINE_AWS_COLOR:-blue}}${AWS_PROFILE}%f" + if [[ -z "${AWS_PROFILE}" ]]; then return; fi + local profile="${AWS_PROFILE}" + local format="%F{white}(%f%F{blue}|profile|%f%F{white})%f" + echo "${${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}/|profile|/${profile}}" } prompt_slimline_section_user_host_info() { - if (( ! ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then return; fi if [[ -z "$SSH_TTY" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi - local user_color='' + local user="%n" + local host="%m" + local format_root="%F{red}|user|%f@%F{yellow}|host|%f" + local format="%F{green}|user|%f@%F{yellow}|host|%f" + local selected='' if [[ $UID -eq 0 ]]; then - user_color="${SLIMLINE_USER_ROOT_COLOR:-red}" + selected="${SLIMLINE_USER_HOST_INFO_ROOT_FORMAT:-${format_root}}" else - user_color="${SLIMLINE_USER_COLOR:-green}" + selected="${SLIMLINE_USER_HOST_INFO_FORMAT:-${format}}" fi - echo "%F{${user_color}}%n%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}%m%f" + echo "${${selected/|user|/${user}}/|host|/${host}}" } prompt_slimline_section_cwd() { - local cwd_color='' + local path="%3~" + local format_root="%F{red}|path|%f" + local format="%F{cyan}|path|%f" + local selected='' if [[ "$(builtin pwd)" == "/" ]]; then - cwd_color="${SLIMLINE_CWD_ROOT_COLOR:-red}" + selected="${SLIMLINE_CWD_ROOT_FORMAT:-${format_root}}" else - cwd_color="${SLIMLINE_CWD_COLOR:-cyan}" + selected="${SLIMLINE_CWD_FORMAT:-${format}}" fi - echo "%F{${cwd_color}}%3~%f" + echo "${selected/|path|/${path}}" } prompt_slimline_section_symbol() { local stage=${1} - local symbol_color='' + local format_working="%F{red}∙%f" + local format_ready="%F{white}∙%f" if [[ "${stage}" == "async_callback" ]]; then - symbol_color=${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white} + echo "${SLIMLINE_SYMBOL_READY_FORMAT:-${format_ready}}" else - symbol_color=${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red} + echo "${SLIMLINE_SYMBOL_WORKING_FORMAT:-${format_working}}" fi - echo "%F{$symbol_color}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" } prompt_slimline_section_execution_time() { # add elapsed time if threshold is exceeded - if (( ! ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )) || [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi - echo "%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}${_prompt_slimline_cmd_exec_time}%f" + if [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi + local exec_time="${_prompt_slimline_cmd_exec_time}" + local format="%F{yellow}|exec_time|%f" + echo "${${SLIMLINE_EXECUTION_TIME_FORMAT:-${format}}/|exec_time|/${exec_time}}" } prompt_slimline_section_exit_status() { - if (( ! ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then return; fi if (( _prompt_slimline_last_exit_status == 0 )); then return; fi - echo "%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}${_prompt_slimline_last_exit_status} ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f" + local exit_status=${_prompt_slimline_last_exit_status} + local format="%F{red}|exit_status| ↵%f" + echo "${${SLIMLINE_EXIT_STATUS_FORMAT:-${format}}/|exit_status|/${exit_status}}" } prompt_slimline_section_git() { @@ -96,11 +106,11 @@ prompt_slimline_section_git() { } prompt_slimline_section_virtualenv() { - if (( ! ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )) || [[ -z $VIRTUAL_ENV ]]; then return; fi + if [[ -z $VIRTUAL_ENV ]]; then return; fi - local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" - local virtualenv_color="${SLIMLINE_VIRTUALENV_COLOR:-cyan}" - echo "%F{$parens_color}(%f%F{$virtualenv_color}$(basename "${VIRTUAL_ENV}")%f%F{$parens_color})%f" + local virtualenv="$(basename "${VIRTUAL_ENV}")" + local format="%F{white}(%f%F{cyan}|virtualenv|%f%F{white})%f" + echo "${${SLIMLINE_VIRTUALENV_FORMAT:-${format}}/|virtualenv|/${virtualenv}}" } prompt_slimline_get_sections() { @@ -124,8 +134,8 @@ prompt_slimline_set_prompt() { local separator="${SLIMLINE_PROMPT_SECTION_SEPARATOR:- }" prompt_slimline_get_sections "_prompt_slimline_prompt_sections_output" "${_prompt_slimline_prompt_sections}" "${separator}" "$*" - local format="${SLIMLINE_PROMPT_FORMAT:-|sections| }" - PROMPT="${format/|sections|/${_prompt_slimline_prompt_sections_output}}" + local format="|sections| " + PROMPT="${${SLIMLINE_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_prompt_sections_output}}" unset _prompt_slimline_prompt_sections_output } @@ -133,13 +143,17 @@ prompt_slimline_set_rprompt() { local separator="${SLIMLINE_RPROMPT_SECTION_SEPARATOR:- }" prompt_slimline_get_sections "_prompt_slimline_rprompt_sections_output" "${_prompt_slimline_rprompt_sections}" "${separator}" "$*" - local format="${SLIMLINE_RPROMPT_FORMAT:-|sections|}" - RPROMPT="${format/|sections|/${_prompt_slimline_rprompt_sections_output}}" + local format="|sections|" + RPROMPT="${${SLIMLINE_RPROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_rprompt_sections_output}}" unset _prompt_slimline_rprompt_sections_output } prompt_slimline_set_sprompt() { - SPROMPT="zsh: correct %F{${SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR:-red}}%R%f to %F{${SLIMLINE_AUTOCORRECT_PROPOSED_COLOR:-green}}%r%f [nyae]? " + local from="%R" + local to="%r" + local format="zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? " + local selected="${SLIMLINE_AUTOCORRECT_FORMAT:-${format}}" + SPROMPT="${${selected/|from|/${from}}/|to|/${to}}" } prompt_slimline_chpwd() { @@ -207,8 +221,50 @@ prompt_slimline_async_init() { } prompt_slimline_evaluate_legacy_options() { - local prompt_sections=(user_host_info cwd aws_profile symbol) - local rprompt_sections=(execution_time exit_status git virtualenv) + local prompt_sections=() + local rprompt_sections=() + + if (( ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then + SLIMLINE_USER_HOST_INFO_ROOT_FORMAT="%F{${SLIMLINE_USER_ROOT_COLOR:-red}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" + SLIMLINE_USER_HOST_INFO_FORMAT="%F{${SLIMLINE_USER_COLOR:-green}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" + prompt_sections+=("user_host_info") + fi + + SLIMLINE_CWD_ROOT_FORMAT="%F{${SLIMLINE_CWD_ROOT_COLOR:-red}}|path|%f" + SLIMLINE_CWD_FORMAT="%F{${SLIMLINE_CWD_COLOR:-cyan}}|path|%f" + prompt_sections+=("cwd") + + if (( ${SLIMLINE_DISPLAY_AWS_INFO:-0} )); then + SLIMLINE_AWS_PROFILE_FORMAT="%F{${SLIMLINE_AWS_COLOR:-blue}}|profile|%f" + prompt_sections+=("aws_profile"); + fi + + SLIMLINE_SYMBOL_READY_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" + SLIMLINE_SYMBOL_WORKING_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" + prompt_sections+=("symbol") + + if (( ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )); then + SLIMLINE_EXECUTION_TIME_FORMAT="%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}|exec_time|%f" + rprompt_sections+=("execution_time") + fi + + if (( ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then + SLIMLINE_EXIT_STATUS_FORMAT="%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}|exit_status| ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f" + rprompt_sections+=("exit_status") + fi + + if (( ${SLIMLINE_ENABLE_GIT:-1} )); then + rprompt_sections+=("git") + fi + + if (( ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )); then + local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" + SLIMLINE_VIRTUALENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|virtualenv|%f%F{$parens_color})%f" + rprompt_sections+=("virtualenv") + fi + + SLIMLINE_AUTOCORRECT_FORMAT="zsh: correct %F{${SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR:-red}}|from|%f to %F{${SLIMLINE_AUTOCORRECT_PROPOSED_COLOR:-green}}|to|%f [nyae]? " + SLIMLINE_PROMPT_SECTIONS="${(j: :)prompt_sections}" SLIMLINE_RPROMPT_SECTIONS="${(j: :)rprompt_sections}" } From 21ef8cb19bf4d46bcbd18e62ce8c8f56467ca072 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 22:14:01 +0100 Subject: [PATCH 015/107] Use braces for variables --- slimline.zsh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index a3e80e0..3bcffc6 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -46,14 +46,14 @@ prompt_slimline_section_aws_profile() { } prompt_slimline_section_user_host_info() { - if [[ -z "$SSH_TTY" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi + if [[ -z "${SSH_TTY}" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi local user="%n" local host="%m" local format_root="%F{red}|user|%f@%F{yellow}|host|%f" local format="%F{green}|user|%f@%F{yellow}|host|%f" local selected='' - if [[ $UID -eq 0 ]]; then + if [[ ${UID} -eq 0 ]]; then selected="${SLIMLINE_USER_HOST_INFO_ROOT_FORMAT:-${format_root}}" else selected="${SLIMLINE_USER_HOST_INFO_FORMAT:-${format}}" @@ -106,7 +106,7 @@ prompt_slimline_section_git() { } prompt_slimline_section_virtualenv() { - if [[ -z $VIRTUAL_ENV ]]; then return; fi + if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi local virtualenv="$(basename "${VIRTUAL_ENV}")" local format="%F{white}(%f%F{cyan}|virtualenv|%f%F{white})%f" From ae74b22f4b39a91ad8d4427e2ed5c2004ed2bd06 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sat, 3 Mar 2018 22:20:12 +0100 Subject: [PATCH 016/107] Update copyright year --- LICENSE | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 606c15a..f14e3ef 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2017 Markus Engelbrecht +Copyright (c) 2015-2018 Markus Engelbrecht Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - From 4f2830c2d62b3eb382caedb9f647105ae03dcd94 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 06:31:07 +0100 Subject: [PATCH 017/107] Calculate prompt in async callback right before refreshing it --- slimline.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 3bcffc6..5ce4f17 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -195,12 +195,12 @@ prompt_slimline_async_callback() { case "${job}" in prompt_slimline_async_git) _prompt_slimline_git_output="${output}" - prompt_slimline_set_prompt "async_callback" - prompt_slimline_set_rprompt "async_callback" ;; esac if (( ! has_next )); then + prompt_slimline_set_prompt "async_callback" + prompt_slimline_set_rprompt "async_callback" zle && zle .reset-prompt fi } From 7b601d87e7970c1616687146967d4d8340e45b64 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 06:32:02 +0100 Subject: [PATCH 018/107] Rename variables to follow left_prompt and right_prompt --- slimline.zsh | 70 ++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 5ce4f17..9dbd33f 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -130,25 +130,25 @@ prompt_slimline_get_sections() { typeset -g "${var}"="${(epj:${separator}:)outputs}" } -prompt_slimline_set_prompt() { - local separator="${SLIMLINE_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_prompt_sections_output" "${_prompt_slimline_prompt_sections}" "${separator}" "$*" +prompt_slimline_set_left_prompt() { + local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" + prompt_slimline_get_sections "_prompt_slimline_left_prompt_sections_output" "${_prompt_slimline_left_prompt_sections}" "${separator}" "$*" local format="|sections| " - PROMPT="${${SLIMLINE_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_prompt_sections_output}}" - unset _prompt_slimline_prompt_sections_output + PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_left_prompt_sections_output}}" + unset _prompt_slimline_left_prompt_sections_output } -prompt_slimline_set_rprompt() { - local separator="${SLIMLINE_RPROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_rprompt_sections_output" "${_prompt_slimline_rprompt_sections}" "${separator}" "$*" +prompt_slimline_set_right_prompt() { + local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" + prompt_slimline_get_sections "_prompt_slimline_right_prompt_sections_output" "${_prompt_slimline_right_prompt_sections}" "${separator}" "$*" local format="|sections|" - RPROMPT="${${SLIMLINE_RPROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_rprompt_sections_output}}" - unset _prompt_slimline_rprompt_sections_output + RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_right_prompt_sections_output}}" + unset _prompt_slimline_right_prompt_sections_output } -prompt_slimline_set_sprompt() { +prompt_slimline_set_spelling_prompt() { local from="%R" local to="%r" local format="zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? " @@ -167,8 +167,8 @@ prompt_slimline_precmd() { unset _prompt_slimline_git_output if (( EPOCHREALTIME - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then - prompt_slimline_set_prompt "precmd" - prompt_slimline_set_rprompt "precmd" + prompt_slimline_set_left_prompt "precmd" + prompt_slimline_set_right_prompt "precmd" prompt_slimline_async_tasks fi @@ -199,8 +199,8 @@ prompt_slimline_async_callback() { esac if (( ! has_next )); then - prompt_slimline_set_prompt "async_callback" - prompt_slimline_set_rprompt "async_callback" + prompt_slimline_set_left_prompt "async_callback" + prompt_slimline_set_right_prompt "async_callback" zle && zle .reset-prompt fi } @@ -221,56 +221,56 @@ prompt_slimline_async_init() { } prompt_slimline_evaluate_legacy_options() { - local prompt_sections=() - local rprompt_sections=() + local left_prompt_sections=() + local right_prompt_sections=() if (( ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then SLIMLINE_USER_HOST_INFO_ROOT_FORMAT="%F{${SLIMLINE_USER_ROOT_COLOR:-red}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" SLIMLINE_USER_HOST_INFO_FORMAT="%F{${SLIMLINE_USER_COLOR:-green}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" - prompt_sections+=("user_host_info") + left_prompt_sections+=("user_host_info") fi SLIMLINE_CWD_ROOT_FORMAT="%F{${SLIMLINE_CWD_ROOT_COLOR:-red}}|path|%f" SLIMLINE_CWD_FORMAT="%F{${SLIMLINE_CWD_COLOR:-cyan}}|path|%f" - prompt_sections+=("cwd") + left_prompt_sections+=("cwd") if (( ${SLIMLINE_DISPLAY_AWS_INFO:-0} )); then SLIMLINE_AWS_PROFILE_FORMAT="%F{${SLIMLINE_AWS_COLOR:-blue}}|profile|%f" - prompt_sections+=("aws_profile"); + left_prompt_sections+=("aws_profile"); fi SLIMLINE_SYMBOL_READY_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" SLIMLINE_SYMBOL_WORKING_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" - prompt_sections+=("symbol") + left_prompt_sections+=("symbol") if (( ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )); then SLIMLINE_EXECUTION_TIME_FORMAT="%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}|exec_time|%f" - rprompt_sections+=("execution_time") + right_prompt_sections+=("execution_time") fi if (( ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then SLIMLINE_EXIT_STATUS_FORMAT="%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}|exit_status| ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f" - rprompt_sections+=("exit_status") + right_prompt_sections+=("exit_status") fi if (( ${SLIMLINE_ENABLE_GIT:-1} )); then - rprompt_sections+=("git") + right_prompt_sections+=("git") fi if (( ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )); then local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" SLIMLINE_VIRTUALENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|virtualenv|%f%F{$parens_color})%f" - rprompt_sections+=("virtualenv") + right_prompt_sections+=("virtualenv") fi SLIMLINE_AUTOCORRECT_FORMAT="zsh: correct %F{${SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR:-red}}|from|%f to %F{${SLIMLINE_AUTOCORRECT_PROPOSED_COLOR:-green}}|to|%f [nyae]? " - SLIMLINE_PROMPT_SECTIONS="${(j: :)prompt_sections}" - SLIMLINE_RPROMPT_SECTIONS="${(j: :)rprompt_sections}" + SLIMLINE_LEFT_PROMPT_SECTIONS="${(j: :)left_prompt_sections}" + SLIMLINE_RIGHT_PROMPT_SECTIONS="${(j: :)right_prompt_sections}" } prompt_slimline_check_git_support() { - if (( ${=_prompt_slimline_prompt_sections[(I)git]} || ${=_prompt_slimline_rprompt_sections[(I)git]} )); then + if (( ${=_prompt_slimline_left_prompt_sections[(I)git]} || ${=_prompt_slimline_right_prompt_sections[(I)git]} )); then # If python or git are not installed, disable the git functionality. if (( $+commands[python] && $+commands[git] )); then _prompt_slimline_enable_git_task=1 @@ -303,11 +303,11 @@ prompt_slimline_setup() { prompt_slimline_evaluate_legacy_options fi - _prompt_slimline_prompt_sections="${SLIMLINE_PROMPT_SECTIONS-user_host_info cwd aws_profile symbol}" - _prompt_slimline_rprompt_sections="${SLIMLINE_RPROMPT_SECTIONS-execution_time exit_status git virtualenv}" + _prompt_slimline_left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd aws_profile symbol}" + _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git virtualenv}" prompt_slimline_check_git_support - prompt_slimline_expand_sections "_prompt_slimline_prompt_sections" - prompt_slimline_expand_sections "_prompt_slimline_rprompt_sections" + prompt_slimline_expand_sections "_prompt_slimline_left_prompt_sections" + prompt_slimline_expand_sections "_prompt_slimline_right_prompt_sections" prompt_opts=(cr percent subst) @@ -324,9 +324,9 @@ prompt_slimline_setup() { prompt_slimline_async_init - prompt_slimline_set_prompt "setup" - prompt_slimline_set_rprompt "setup" - prompt_slimline_set_sprompt + prompt_slimline_set_left_prompt "setup" + prompt_slimline_set_right_prompt "setup" + prompt_slimline_set_spelling_prompt } prompt_slimline_setup "$@" From a38787eb165940aad81f8d0738c226895db43479 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 06:51:40 +0100 Subject: [PATCH 019/107] Replace basename call with parameter expansion --- slimline.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slimline.zsh b/slimline.zsh index 9dbd33f..ca1607d 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -108,7 +108,7 @@ prompt_slimline_section_git() { prompt_slimline_section_virtualenv() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi - local virtualenv="$(basename "${VIRTUAL_ENV}")" + local virtualenv="${VIRTUAL_ENV##*/}" local format="%F{white}(%f%F{cyan}|virtualenv|%f%F{white})%f" echo "${${SLIMLINE_VIRTUALENV_FORMAT:-${format}}/|virtualenv|/${virtualenv}}" } From 4c2969eeb197f9ac2d92b2021bfc4380eea59991 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 06:53:30 +0100 Subject: [PATCH 020/107] Use underscore in virtual_env name This follows the environment variable name. --- slimline.zsh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index ca1607d..244bfb9 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -105,12 +105,12 @@ prompt_slimline_section_git() { echo "${_prompt_slimline_git_output}" } -prompt_slimline_section_virtualenv() { +prompt_slimline_section_virtual_env() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi - local virtualenv="${VIRTUAL_ENV##*/}" - local format="%F{white}(%f%F{cyan}|virtualenv|%f%F{white})%f" - echo "${${SLIMLINE_VIRTUALENV_FORMAT:-${format}}/|virtualenv|/${virtualenv}}" + local virtual_env="${VIRTUAL_ENV##*/}" + local format="%F{white}(%f%F{cyan}|virtual_env|%f%F{white})%f" + echo "${${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}/|virtual_env|/${virtual_env}}" } prompt_slimline_get_sections() { @@ -259,8 +259,8 @@ prompt_slimline_evaluate_legacy_options() { if (( ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )); then local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" - SLIMLINE_VIRTUALENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|virtualenv|%f%F{$parens_color})%f" - right_prompt_sections+=("virtualenv") + SLIMLINE_VIRTUAL_ENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|virtual_env|%f%F{$parens_color})%f" + right_prompt_sections+=("virtual_env") fi SLIMLINE_AUTOCORRECT_FORMAT="zsh: correct %F{${SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR:-red}}|from|%f to %F{${SLIMLINE_AUTOCORRECT_PROPOSED_COLOR:-green}}|to|%f [nyae]? " @@ -304,7 +304,7 @@ prompt_slimline_setup() { fi _prompt_slimline_left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd aws_profile symbol}" - _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git virtualenv}" + _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git virtual_env}" prompt_slimline_check_git_support prompt_slimline_expand_sections "_prompt_slimline_left_prompt_sections" prompt_slimline_expand_sections "_prompt_slimline_right_prompt_sections" From e4fb94f1a43d6036efe5dd624162c9214069e1db Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:29:38 +0100 Subject: [PATCH 021/107] Use brackets for virtual_env and aws_profile sections --- slimline.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 244bfb9..534b116 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -41,7 +41,7 @@ prompt_slimline_check_cmd_exec_time() { prompt_slimline_section_aws_profile() { if [[ -z "${AWS_PROFILE}" ]]; then return; fi local profile="${AWS_PROFILE}" - local format="%F{white}(%f%F{blue}|profile|%f%F{white})%f" + local format="%F{white}[%F{blue}|profile|%F{white}]%f" echo "${${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}/|profile|/${profile}}" } @@ -109,7 +109,7 @@ prompt_slimline_section_virtual_env() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi local virtual_env="${VIRTUAL_ENV##*/}" - local format="%F{white}(%f%F{cyan}|virtual_env|%f%F{white})%f" + local format="%F{white}[%F{cyan}|virtual_env|%F{white}]%f" echo "${${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}/|virtual_env|/${virtual_env}}" } From 24aa500123904b119027acac91db143a57573a68 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:30:22 +0100 Subject: [PATCH 022/107] Use white as color for the @ symbol in user_host_info --- slimline.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 534b116..9ad08bd 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -50,8 +50,8 @@ prompt_slimline_section_user_host_info() { local user="%n" local host="%m" - local format_root="%F{red}|user|%f@%F{yellow}|host|%f" - local format="%F{green}|user|%f@%F{yellow}|host|%f" + local format_root="%F{red}|user|%F{white}@%F{yellow}|host|%f" + local format="%F{green}|user|%F{white}@%F{yellow}|host|%f" local selected='' if [[ ${UID} -eq 0 ]]; then selected="${SLIMLINE_USER_HOST_INFO_ROOT_FORMAT:-${format_root}}" From eb5c902bf772576fc2e39555908bae32fc7d1b5e Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:30:43 +0100 Subject: [PATCH 023/107] Add option to always show user_host_info --- slimline.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slimline.zsh b/slimline.zsh index 9ad08bd..7659612 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -46,7 +46,7 @@ prompt_slimline_section_aws_profile() { } prompt_slimline_section_user_host_info() { - if [[ -z "${SSH_TTY}" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi + if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi local user="%n" local host="%m" From 8e81669086aa743dd9e773d04bd28e6fe100987b Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:39:38 +0100 Subject: [PATCH 024/107] Add prefixes to virtual_env and aws_profile This way they can be distinguished if they are on the same prompt. --- slimline.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 7659612..73e8e6f 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -41,7 +41,7 @@ prompt_slimline_check_cmd_exec_time() { prompt_slimline_section_aws_profile() { if [[ -z "${AWS_PROFILE}" ]]; then return; fi local profile="${AWS_PROFILE}" - local format="%F{white}[%F{blue}|profile|%F{white}]%f" + local format="%F{white}[AWS:%F{blue}|profile|%F{white}]%f" echo "${${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}/|profile|/${profile}}" } @@ -109,7 +109,7 @@ prompt_slimline_section_virtual_env() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi local virtual_env="${VIRTUAL_ENV##*/}" - local format="%F{white}[%F{cyan}|virtual_env|%F{white}]%f" + local format="%F{white}[VENV:%F{cyan}|virtual_env|%F{white}]%f" echo "${${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}/|virtual_env|/${virtual_env}}" } From df6d144f63c4ce7a1204885b47e507515fead0c1 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:39:45 +0100 Subject: [PATCH 025/107] Move aws_profile to the right prompt --- slimline.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 73e8e6f..1b2ec20 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -303,8 +303,8 @@ prompt_slimline_setup() { prompt_slimline_evaluate_legacy_options fi - _prompt_slimline_left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd aws_profile symbol}" - _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git virtual_env}" + _prompt_slimline_left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd symbol}" + _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtual_env}" prompt_slimline_check_git_support prompt_slimline_expand_sections "_prompt_slimline_left_prompt_sections" prompt_slimline_expand_sections "_prompt_slimline_right_prompt_sections" From 1f080f4113d219ff9a0c918ef6ab4e40005eccfa Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:42:24 +0100 Subject: [PATCH 026/107] Add nodejs section --- slimline.zsh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/slimline.zsh b/slimline.zsh index 1b2ec20..285c0fe 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -113,6 +113,13 @@ prompt_slimline_section_virtual_env() { echo "${${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}/|virtual_env|/${virtual_env}}" } +prompt_slimline_section_nodejs() { + if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi + local version="$(node -v 2>/dev/null)" + local format="%F{white}[%F{green}⬢ |version|%F{white}]%f" + echo "${${SLIMLINE_NODE_FORMAT:-${format}}/|version|/${version}}" +} + prompt_slimline_get_sections() { local var=${1} local sections=${2} @@ -304,7 +311,7 @@ prompt_slimline_setup() { fi _prompt_slimline_left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd symbol}" - _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtual_env}" + _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtual_env nodejs}" prompt_slimline_check_git_support prompt_slimline_expand_sections "_prompt_slimline_left_prompt_sections" prompt_slimline_expand_sections "_prompt_slimline_right_prompt_sections" From 09b77b49257291f39b8d77685392b8637ac5d05b Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:52:58 +0100 Subject: [PATCH 027/107] Add support for custom git section format --- slimline.zsh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/slimline.zsh b/slimline.zsh index 285c0fe..2362b54 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -102,7 +102,9 @@ prompt_slimline_section_exit_status() { prompt_slimline_section_git() { if [[ -z "${_prompt_slimline_git_output}" ]]; then return; fi - echo "${_prompt_slimline_git_output}" + local status="${_prompt_slimline_git_output}" + local format="|status|" + echo "${${SLIMLINE_GIT_FORMAT:-${format}}/|status|/${status}}" } prompt_slimline_section_virtual_env() { @@ -261,6 +263,7 @@ prompt_slimline_evaluate_legacy_options() { fi if (( ${SLIMLINE_ENABLE_GIT:-1} )); then + SLIMLINE_GIT_FORMAT="|status|" right_prompt_sections+=("git") fi From cbe87df3796275bdd0af32a87a17efa7a9d141a1 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 12:56:30 +0100 Subject: [PATCH 028/107] Rename variable --- slimline.zsh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 2362b54..5d4d691 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -102,9 +102,9 @@ prompt_slimline_section_exit_status() { prompt_slimline_section_git() { if [[ -z "${_prompt_slimline_git_output}" ]]; then return; fi - local status="${_prompt_slimline_git_output}" - local format="|status|" - echo "${${SLIMLINE_GIT_FORMAT:-${format}}/|status|/${status}}" + local output="${_prompt_slimline_git_output}" + local format="|output|" + echo "${${SLIMLINE_GIT_FORMAT:-${format}}/|output|/${output}}" } prompt_slimline_section_virtual_env() { @@ -263,7 +263,7 @@ prompt_slimline_evaluate_legacy_options() { fi if (( ${SLIMLINE_ENABLE_GIT:-1} )); then - SLIMLINE_GIT_FORMAT="|status|" + SLIMLINE_GIT_FORMAT="|output|" right_prompt_sections+=("git") fi From b1bc7ac17517663edd28a831251cec2659a074c6 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 19:06:00 +0100 Subject: [PATCH 029/107] Refactor sections into separate files This includes the following functionality for sections: * Automatic async task handling * Automatic enable/disable depending upon check function * Automatic precmd and preexec handling --- lib/legacy_options.zsh | 49 +++++++ sections/aws_profile.zsh | 6 + sections/cwd.zsh | 12 ++ sections/execution_time.zsh | 37 +++++ sections/exit_status.zsh | 6 + sections/git.zsh | 29 ++++ sections/nodejs.zsh | 6 + sections/symbol.zsh | 10 ++ sections/user_host_info.zsh | 15 ++ sections/virtual_env.zsh | 7 + slimline.zsh | 272 ++++++++---------------------------- 11 files changed, 236 insertions(+), 213 deletions(-) create mode 100644 lib/legacy_options.zsh create mode 100644 sections/aws_profile.zsh create mode 100644 sections/cwd.zsh create mode 100644 sections/execution_time.zsh create mode 100644 sections/exit_status.zsh create mode 100644 sections/git.zsh create mode 100644 sections/nodejs.zsh create mode 100644 sections/symbol.zsh create mode 100644 sections/user_host_info.zsh create mode 100644 sections/virtual_env.zsh diff --git a/lib/legacy_options.zsh b/lib/legacy_options.zsh new file mode 100644 index 0000000..9e28549 --- /dev/null +++ b/lib/legacy_options.zsh @@ -0,0 +1,49 @@ +prompt_slimline_evaluate_legacy_options() { + local left_prompt_sections=() + local right_prompt_sections=() + + if (( ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then + SLIMLINE_USER_HOST_INFO_ROOT_FORMAT="%F{${SLIMLINE_USER_ROOT_COLOR:-red}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" + SLIMLINE_USER_HOST_INFO_FORMAT="%F{${SLIMLINE_USER_COLOR:-green}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" + left_prompt_sections+=("user_host_info") + fi + + SLIMLINE_CWD_ROOT_FORMAT="%F{${SLIMLINE_CWD_ROOT_COLOR:-red}}|path|%f" + SLIMLINE_CWD_FORMAT="%F{${SLIMLINE_CWD_COLOR:-cyan}}|path|%f" + left_prompt_sections+=("cwd") + + if (( ${SLIMLINE_DISPLAY_AWS_INFO:-0} )); then + SLIMLINE_AWS_PROFILE_FORMAT="%F{${SLIMLINE_AWS_COLOR:-blue}}|profile|%f" + left_prompt_sections+=("aws_profile"); + fi + + SLIMLINE_SYMBOL_READY_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" + SLIMLINE_SYMBOL_WORKING_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" + left_prompt_sections+=("symbol") + + if (( ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )); then + SLIMLINE_EXECUTION_TIME_FORMAT="%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}|exec_time|%f" + right_prompt_sections+=("execution_time") + fi + + if (( ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then + SLIMLINE_EXIT_STATUS_FORMAT="%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}|exit_status| ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f" + right_prompt_sections+=("exit_status") + fi + + if (( ${SLIMLINE_ENABLE_GIT:-1} )); then + SLIMLINE_GIT_FORMAT="|output|" + right_prompt_sections+=("git") + fi + + if (( ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )); then + local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" + SLIMLINE_VIRTUAL_ENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|virtual_env|%f%F{$parens_color})%f" + right_prompt_sections+=("virtual_env") + fi + + SLIMLINE_AUTOCORRECT_FORMAT="zsh: correct %F{${SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR:-red}}|from|%f to %F{${SLIMLINE_AUTOCORRECT_PROPOSED_COLOR:-green}}|to|%f [nyae]? " + + SLIMLINE_LEFT_PROMPT_SECTIONS="${(j: :)left_prompt_sections}" + SLIMLINE_RIGHT_PROMPT_SECTIONS="${(j: :)right_prompt_sections}" +} diff --git a/sections/aws_profile.zsh b/sections/aws_profile.zsh new file mode 100644 index 0000000..5122c7b --- /dev/null +++ b/sections/aws_profile.zsh @@ -0,0 +1,6 @@ +prompt_slimline_section_aws_profile() { + if [[ -z "${AWS_PROFILE}" ]]; then return; fi + local profile="${AWS_PROFILE}" + local format="%F{white}[AWS:%F{blue}|profile|%F{white}]%f" + echo "${${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}/|profile|/${profile}}" +} diff --git a/sections/cwd.zsh b/sections/cwd.zsh new file mode 100644 index 0000000..ede8f4c --- /dev/null +++ b/sections/cwd.zsh @@ -0,0 +1,12 @@ +prompt_slimline_section_cwd() { + local path="%3~" + local format_root="%F{red}|path|%f" + local format="%F{cyan}|path|%f" + local selected='' + if [[ "$(builtin pwd)" == "/" ]]; then + selected="${SLIMLINE_CWD_ROOT_FORMAT:-${format_root}}" + else + selected="${SLIMLINE_CWD_FORMAT:-${format}}" + fi + echo "${selected/|path|/${path}}" +} diff --git a/sections/execution_time.zsh b/sections/execution_time.zsh new file mode 100644 index 0000000..a08d936 --- /dev/null +++ b/sections/execution_time.zsh @@ -0,0 +1,37 @@ +# turns seconds into human readable time +# 165392 => 1d 21h 56m 32s +# https://github.com/sindresorhus/pretty-time-zsh +prompt_slimline_human_time() { + local tmp=$1 + local days=$(( tmp / 60 / 60 / 24 )) + local hours=$(( tmp / 60 / 60 % 24 )) + local minutes=$(( tmp / 60 % 60 )) + local seconds=$(( tmp % 60 )) + (( days > 0 )) && echo -n "${days}d " + (( hours > 0 )) && echo -n "${hours}h " + (( minutes > 0 )) && echo -n "${minutes}m " + echo "${seconds}s" +} + +prompt_slimline_section_execution_time_preexec() { + _prompt_slimline_cmd_timestamp=$EPOCHSECONDS +} + +prompt_slimline_section_execution_time_precmd() { + local integer elapsed + (( elapsed = EPOCHSECONDS - ${_prompt_slimline_cmd_timestamp:-$EPOCHSECONDS} )) + _prompt_slimline_cmd_exec_time= + if (( elapsed > ${SLIMLINE_MAX_EXEC_TIME:-5} )); then + _prompt_slimline_cmd_exec_time="$(prompt_slimline_human_time $elapsed)" + fi + + unset _prompt_slimline_cmd_timestamp +} + +prompt_slimline_section_execution_time() { + # add elapsed time if threshold is exceeded + if [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi + local exec_time="${_prompt_slimline_cmd_exec_time}" + local format="%F{yellow}|exec_time|%f" + echo "${${SLIMLINE_EXECUTION_TIME_FORMAT:-${format}}/|exec_time|/${exec_time}}" +} diff --git a/sections/exit_status.zsh b/sections/exit_status.zsh new file mode 100644 index 0000000..7afd857 --- /dev/null +++ b/sections/exit_status.zsh @@ -0,0 +1,6 @@ +prompt_slimline_section_exit_status() { + if (( prompt_slimline_last_exit_status == 0 )); then return; fi + local exit_status=${prompt_slimline_last_exit_status} + local format="%F{red}|exit_status| ↵%f" + echo "${${SLIMLINE_EXIT_STATUS_FORMAT:-${format}}/|exit_status|/${exit_status}}" +} diff --git a/sections/git.zsh b/sections/git.zsh new file mode 100644 index 0000000..2e3577c --- /dev/null +++ b/sections/git.zsh @@ -0,0 +1,29 @@ +prompt_slimline_section_git_precmd() { + unset _prompt_slimline_git_output +} + +prompt_slimline_section_git_async_task() { + command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" +} + +prompt_slimline_section_git_async_task_complete() { + local output=${3} + _prompt_slimline_git_output="${output}" +} + +prompt_slimline_section_git_check() { + # If python or git are not installed, disable the git functionality. + if (( ${+commands[python]} && ${+commands[git]} )); then + return 0 + fi + + print -P "%F{red}slimline%f: python and/or git not installed or not in PATH, disabling git information" + return 1 +} + +prompt_slimline_section_git() { + if [[ -z "${_prompt_slimline_git_output}" ]]; then return; fi + local output="${_prompt_slimline_git_output}" + local format="|output|" + echo "${${SLIMLINE_GIT_FORMAT:-${format}}/|output|/${output}}" +} diff --git a/sections/nodejs.zsh b/sections/nodejs.zsh new file mode 100644 index 0000000..447a293 --- /dev/null +++ b/sections/nodejs.zsh @@ -0,0 +1,6 @@ +prompt_slimline_section_nodejs() { + if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi + local version="$(node -v 2>/dev/null)" + local format="%F{white}[%F{green}⬢ |version|%F{white}]%f" + echo "${${SLIMLINE_NODE_FORMAT:-${format}}/|version|/${version}}" +} diff --git a/sections/symbol.zsh b/sections/symbol.zsh new file mode 100644 index 0000000..3ff9c9e --- /dev/null +++ b/sections/symbol.zsh @@ -0,0 +1,10 @@ +prompt_slimline_section_symbol() { + local stage=${1} + local format_working="%F{red}∙%f" + local format_ready="%F{white}∙%f" + if [[ "${stage}" == "tasks_complete" ]]; then + echo "${SLIMLINE_SYMBOL_READY_FORMAT:-${format_ready}}" + else + echo "${SLIMLINE_SYMBOL_WORKING_FORMAT:-${format_working}}" + fi +} diff --git a/sections/user_host_info.zsh b/sections/user_host_info.zsh new file mode 100644 index 0000000..316d218 --- /dev/null +++ b/sections/user_host_info.zsh @@ -0,0 +1,15 @@ +prompt_slimline_section_user_host_info() { + if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi + + local user="%n" + local host="%m" + local format_root="%F{red}|user|%F{white}@%F{yellow}|host|%f" + local format="%F{green}|user|%F{white}@%F{yellow}|host|%f" + local selected='' + if [[ ${UID} -eq 0 ]]; then + selected="${SLIMLINE_USER_HOST_INFO_ROOT_FORMAT:-${format_root}}" + else + selected="${SLIMLINE_USER_HOST_INFO_FORMAT:-${format}}" + fi + echo "${${selected/|user|/${user}}/|host|/${host}}" +} diff --git a/sections/virtual_env.zsh b/sections/virtual_env.zsh new file mode 100644 index 0000000..bbd6c4a --- /dev/null +++ b/sections/virtual_env.zsh @@ -0,0 +1,7 @@ +prompt_slimline_section_virtual_env() { + if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi + + local virtual_env="${VIRTUAL_ENV##*/}" + local format="%F{white}[VENV:%F{cyan}|virtual_env|%F{white}]%f" + echo "${${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}/|virtual_env|/${virtual_env}}" +} diff --git a/slimline.zsh b/slimline.zsh index 5d4d691..174f6bf 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -14,114 +14,6 @@ prompt_slimline_path="${0:A:h}" prompt_slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" -# turns seconds into human readable time -# 165392 => 1d 21h 56m 32s -# https://github.com/sindresorhus/pretty-time-zsh -prompt_slimline_human_time() { - local tmp=$1 - local days=$(( tmp / 60 / 60 / 24 )) - local hours=$(( tmp / 60 / 60 % 24 )) - local minutes=$(( tmp / 60 % 60 )) - local seconds=$(( tmp % 60 )) - (( days > 0 )) && echo -n "${days}d " - (( hours > 0 )) && echo -n "${hours}h " - (( minutes > 0 )) && echo -n "${minutes}m " - echo "${seconds}s" -} - -prompt_slimline_check_cmd_exec_time() { - local integer elapsed - (( elapsed = EPOCHSECONDS - ${_prompt_slimline_cmd_timestamp:-$EPOCHSECONDS} )) - _prompt_slimline_cmd_exec_time= - if (( elapsed > ${SLIMLINE_MAX_EXEC_TIME:-5} )); then - _prompt_slimline_cmd_exec_time="$(prompt_slimline_human_time $elapsed)" - fi -} - -prompt_slimline_section_aws_profile() { - if [[ -z "${AWS_PROFILE}" ]]; then return; fi - local profile="${AWS_PROFILE}" - local format="%F{white}[AWS:%F{blue}|profile|%F{white}]%f" - echo "${${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}/|profile|/${profile}}" -} - -prompt_slimline_section_user_host_info() { - if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi - - local user="%n" - local host="%m" - local format_root="%F{red}|user|%F{white}@%F{yellow}|host|%f" - local format="%F{green}|user|%F{white}@%F{yellow}|host|%f" - local selected='' - if [[ ${UID} -eq 0 ]]; then - selected="${SLIMLINE_USER_HOST_INFO_ROOT_FORMAT:-${format_root}}" - else - selected="${SLIMLINE_USER_HOST_INFO_FORMAT:-${format}}" - fi - echo "${${selected/|user|/${user}}/|host|/${host}}" -} - -prompt_slimline_section_cwd() { - local path="%3~" - local format_root="%F{red}|path|%f" - local format="%F{cyan}|path|%f" - local selected='' - if [[ "$(builtin pwd)" == "/" ]]; then - selected="${SLIMLINE_CWD_ROOT_FORMAT:-${format_root}}" - else - selected="${SLIMLINE_CWD_FORMAT:-${format}}" - fi - echo "${selected/|path|/${path}}" -} - -prompt_slimline_section_symbol() { - local stage=${1} - local format_working="%F{red}∙%f" - local format_ready="%F{white}∙%f" - if [[ "${stage}" == "async_callback" ]]; then - echo "${SLIMLINE_SYMBOL_READY_FORMAT:-${format_ready}}" - else - echo "${SLIMLINE_SYMBOL_WORKING_FORMAT:-${format_working}}" - fi -} - -prompt_slimline_section_execution_time() { - # add elapsed time if threshold is exceeded - if [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi - local exec_time="${_prompt_slimline_cmd_exec_time}" - local format="%F{yellow}|exec_time|%f" - echo "${${SLIMLINE_EXECUTION_TIME_FORMAT:-${format}}/|exec_time|/${exec_time}}" -} - -prompt_slimline_section_exit_status() { - if (( _prompt_slimline_last_exit_status == 0 )); then return; fi - local exit_status=${_prompt_slimline_last_exit_status} - local format="%F{red}|exit_status| ↵%f" - echo "${${SLIMLINE_EXIT_STATUS_FORMAT:-${format}}/|exit_status|/${exit_status}}" -} - -prompt_slimline_section_git() { - if [[ -z "${_prompt_slimline_git_output}" ]]; then return; fi - local output="${_prompt_slimline_git_output}" - local format="|output|" - echo "${${SLIMLINE_GIT_FORMAT:-${format}}/|output|/${output}}" -} - -prompt_slimline_section_virtual_env() { - if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi - - local virtual_env="${VIRTUAL_ENV##*/}" - local format="%F{white}[VENV:%F{cyan}|virtual_env|%F{white}]%f" - echo "${${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}/|virtual_env|/${virtual_env}}" -} - -prompt_slimline_section_nodejs() { - if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi - local version="$(node -v 2>/dev/null)" - local format="%F{white}[%F{green}⬢ |version|%F{white}]%f" - echo "${${SLIMLINE_NODE_FORMAT:-${format}}/|version|/${version}}" -} - prompt_slimline_get_sections() { local var=${1} local sections=${2} @@ -165,51 +57,43 @@ prompt_slimline_set_spelling_prompt() { SPROMPT="${${selected/|from|/${from}}/|to|/${to}}" } -prompt_slimline_chpwd() { - prompt_slimline_async_tasks +prompt_slimline_set_prompts() { + local stage="${1}" + prompt_slimline_set_left_prompt "${stage}" + prompt_slimline_set_right_prompt "${stage}" } -prompt_slimline_precmd() { - prompt_slimline_check_cmd_exec_time - - unset _prompt_slimline_cmd_timestamp - unset _prompt_slimline_git_output - - if (( EPOCHREALTIME - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then - prompt_slimline_set_left_prompt "precmd" - prompt_slimline_set_right_prompt "precmd" - +prompt_slimline_chpwd() { + if (( ${#_prompt_slimline_async_tasks[@]} )); then prompt_slimline_async_tasks fi } -prompt_slimline_preexec() { - _prompt_slimline_cmd_timestamp=$EPOCHSECONDS +prompt_slimline_precmd() { + if (( EPOCHREALTIME - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then + # In case no tasks need to be executed signal the sections that all tasks are finished. + if (( ${#_prompt_slimline_async_tasks[@]} )); then + prompt_slimline_set_prompts "precmd" + prompt_slimline_async_tasks + else + prompt_slimline_set_prompts "tasks_complete" + fi + fi } prompt_slimline_exit_status() { - _prompt_slimline_last_exit_status=$? -} - -prompt_slimline_async_git() { - if (( ! _prompt_slimline_enable_git_task )); then return; fi - command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" + prompt_slimline_last_exit_status=$? } prompt_slimline_async_callback() { local job=${1} - local output=${3} local has_next=${6} - case "${job}" in - prompt_slimline_async_git) - _prompt_slimline_git_output="${output}" - ;; - esac + local complete_function="${job}_complete" + ${complete_function} $* if (( ! has_next )); then - prompt_slimline_set_left_prompt "async_callback" - prompt_slimline_set_right_prompt "async_callback" + prompt_slimline_set_prompts "tasks_complete" zle && zle .reset-prompt fi } @@ -217,11 +101,13 @@ prompt_slimline_async_callback() { prompt_slimline_async_tasks() { _prompt_slimline_last_async_call=${EPOCHREALTIME} async_flush_jobs "prompt_slimline" - async_job "prompt_slimline" prompt_slimline_async_git "$(builtin pwd)" + for task in ${_prompt_slimline_async_tasks}; do + async_job "prompt_slimline" "${task}" "$(builtin pwd)" + done } prompt_slimline_async_init() { - if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} && !$+functions[async_init] && !$+functions[async_start_worker] )); then + if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} && ! ${+functions[async_init]} && ! ${+functions[async_start_worker]} )); then source "${prompt_slimline_path}/zsh-async/async.zsh" fi async_init @@ -229,80 +115,42 @@ prompt_slimline_async_init() { async_register_callback "prompt_slimline" prompt_slimline_async_callback } -prompt_slimline_evaluate_legacy_options() { - local left_prompt_sections=() - local right_prompt_sections=() - - if (( ${SLIMLINE_DISPLAY_USER_HOST_INFO:-1} )); then - SLIMLINE_USER_HOST_INFO_ROOT_FORMAT="%F{${SLIMLINE_USER_ROOT_COLOR:-red}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" - SLIMLINE_USER_HOST_INFO_FORMAT="%F{${SLIMLINE_USER_COLOR:-green}}|user|%f@%F{${SLIMLINE_HOST_COLOR:-yellow}}|host|%f" - left_prompt_sections+=("user_host_info") - fi - - SLIMLINE_CWD_ROOT_FORMAT="%F{${SLIMLINE_CWD_ROOT_COLOR:-red}}|path|%f" - SLIMLINE_CWD_FORMAT="%F{${SLIMLINE_CWD_COLOR:-cyan}}|path|%f" - left_prompt_sections+=("cwd") - - if (( ${SLIMLINE_DISPLAY_AWS_INFO:-0} )); then - SLIMLINE_AWS_PROFILE_FORMAT="%F{${SLIMLINE_AWS_COLOR:-blue}}|profile|%f" - left_prompt_sections+=("aws_profile"); - fi - - SLIMLINE_SYMBOL_READY_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_READY:-white}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" - SLIMLINE_SYMBOL_WORKING_FORMAT="%F{${SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING:-red}}${SLIMLINE_PROMPT_SYMBOL:-∙}%f" - left_prompt_sections+=("symbol") - - if (( ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )); then - SLIMLINE_EXECUTION_TIME_FORMAT="%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}|exec_time|%f" - right_prompt_sections+=("execution_time") - fi - - if (( ${SLIMLINE_DISPLAY_EXIT_STATUS:-1} )); then - SLIMLINE_EXIT_STATUS_FORMAT="%F{${SLIMLINE_EXIT_STATUS_COLOR:-red}}|exit_status| ${SLIMLINE_EXIT_STATUS_SYMBOL:-↵}%f" - right_prompt_sections+=("exit_status") - fi - - if (( ${SLIMLINE_ENABLE_GIT:-1} )); then - SLIMLINE_GIT_FORMAT="|output|" - right_prompt_sections+=("git") - fi +prompt_slimline_load_sections() { + local var=${1} + local expanded_sections=() + for section in ${=${(P)var}}; do + local section_file="${prompt_slimline_path}/sections/${section}.zsh" + if [[ -f "${section_file}" ]]; then + source "${section_file}" + fi - if (( ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )); then - local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" - SLIMLINE_VIRTUAL_ENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|virtual_env|%f%F{$parens_color})%f" - right_prompt_sections+=("virtual_env") - fi + local section_function="prompt_slimline_section_${section}" + if (( ! $+functions[${section_function}] )); then + print -P "%F{red}slimline%f: '${section}' is not a valid section!" + continue + fi - SLIMLINE_AUTOCORRECT_FORMAT="zsh: correct %F{${SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR:-red}}|from|%f to %F{${SLIMLINE_AUTOCORRECT_PROPOSED_COLOR:-green}}|to|%f [nyae]? " + local section_check_function="${section_function}_check" + if (( $+functions[${section_check_function}] )); then + if ! ${section_check_function}; then continue; fi + fi - SLIMLINE_LEFT_PROMPT_SECTIONS="${(j: :)left_prompt_sections}" - SLIMLINE_RIGHT_PROMPT_SECTIONS="${(j: :)right_prompt_sections}" -} + local section_preexec_function="${section_function}_preexec" + if (( $+functions[${section_preexec_function}] )); then + add-zsh-hook preexec "${section_preexec_function}" + fi -prompt_slimline_check_git_support() { - if (( ${=_prompt_slimline_left_prompt_sections[(I)git]} || ${=_prompt_slimline_right_prompt_sections[(I)git]} )); then - # If python or git are not installed, disable the git functionality. - if (( $+commands[python] && $+commands[git] )); then - _prompt_slimline_enable_git_task=1 - else - print -P "%F{red}slimline%f: python and/or git not installed or not in PATH, disabling git information" - _prompt_slimline_enable_git_task=0 + local section_precmd_function="${section_function}_precmd" + if (( $+functions[${section_precmd_function}] )); then + add-zsh-hook precmd "${section_precmd_function}" fi - else - _prompt_slimline_enable_git_task=0 - fi -} -prompt_slimline_expand_sections() { - local var=${1} - local expanded_sections=() - for section in ${=${(P)var}}; do - local function_name="prompt_slimline_section_${section}" - if (( ! $+functions[${function_name}] )); then - print -P "%F{red}slimline%f: '${section}' is not a valid section!" - continue + local section_async_task_function="${section_function}_async_task" + if (( $+functions[${section_async_task_function}] )); then + _prompt_slimline_async_tasks+=("${section_async_task_function}") fi - expanded_sections+=("${function_name}") + + expanded_sections+=("${section_function}") done typeset -g "${var}"="${(j: :)expanded_sections}" @@ -310,32 +158,30 @@ prompt_slimline_expand_sections() { prompt_slimline_setup() { if (( ${SLIMLINE_PROMPT_VERSION:-1} < 2 )); then + source "${prompt_slimline_path}/lib/legacy_options.zsh" prompt_slimline_evaluate_legacy_options fi _prompt_slimline_left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd symbol}" _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtual_env nodejs}" - prompt_slimline_check_git_support - prompt_slimline_expand_sections "_prompt_slimline_left_prompt_sections" - prompt_slimline_expand_sections "_prompt_slimline_right_prompt_sections" prompt_opts=(cr percent subst) - zmodload zsh/datetime zmodload zsh/zle autoload -Uz add-zsh-hook - add-zsh-hook chpwd prompt_slimline_chpwd add-zsh-hook precmd prompt_slimline_precmd - add-zsh-hook preexec prompt_slimline_preexec + + _prompt_slimline_async_tasks=() + prompt_slimline_load_sections "_prompt_slimline_left_prompt_sections" + prompt_slimline_load_sections "_prompt_slimline_right_prompt_sections" precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) prompt_slimline_async_init - prompt_slimline_set_left_prompt "setup" - prompt_slimline_set_right_prompt "setup" + prompt_slimline_set_prompts "setup" prompt_slimline_set_spelling_prompt } From c0a8c56078285678109648f3eecdbee63705778f Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 20:01:54 +0100 Subject: [PATCH 030/107] Initialize async worker lazily --- slimline.zsh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 174f6bf..ec460a5 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -99,6 +99,9 @@ prompt_slimline_async_callback() { } prompt_slimline_async_tasks() { + if (( ! ${_prompt_slimline_async_init_done:-0} )); then + prompt_slimline_async_init + fi _prompt_slimline_last_async_call=${EPOCHREALTIME} async_flush_jobs "prompt_slimline" for task in ${_prompt_slimline_async_tasks}; do @@ -113,6 +116,7 @@ prompt_slimline_async_init() { async_init async_start_worker "prompt_slimline" -u async_register_callback "prompt_slimline" prompt_slimline_async_callback + _prompt_slimline_async_init_done=1 } prompt_slimline_load_sections() { @@ -179,8 +183,6 @@ prompt_slimline_setup() { precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) - prompt_slimline_async_init - prompt_slimline_set_prompts "setup" prompt_slimline_set_spelling_prompt } From 7b332a7059f9e9b10483eb5696be34f1ffdfecde Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 20:23:43 +0100 Subject: [PATCH 031/107] Track number of finished tasks and turn symbol white if all are finished --- sections/symbol.zsh | 2 +- slimline.zsh | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/sections/symbol.zsh b/sections/symbol.zsh index 3ff9c9e..fa6c1ba 100644 --- a/sections/symbol.zsh +++ b/sections/symbol.zsh @@ -2,7 +2,7 @@ prompt_slimline_section_symbol() { local stage=${1} local format_working="%F{red}∙%f" local format_ready="%F{white}∙%f" - if [[ "${stage}" == "tasks_complete" ]]; then + if [[ "${stage}" == "all_tasks_complete" ]]; then echo "${SLIMLINE_SYMBOL_READY_FORMAT:-${format_ready}}" else echo "${SLIMLINE_SYMBOL_WORKING_FORMAT:-${format_working}}" diff --git a/slimline.zsh b/slimline.zsh index ec460a5..3dbd4c8 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -76,7 +76,7 @@ prompt_slimline_precmd() { prompt_slimline_set_prompts "precmd" prompt_slimline_async_tasks else - prompt_slimline_set_prompts "tasks_complete" + prompt_slimline_set_prompts "all_tasks_complete" fi fi } @@ -92,8 +92,16 @@ prompt_slimline_async_callback() { local complete_function="${job}_complete" ${complete_function} $* + _prompt_slimline_async_tasks_complete=$(( _prompt_slimline_async_tasks_complete + 1 )) + if (( ! has_next )); then - prompt_slimline_set_prompts "tasks_complete" + local stage='' + if (( _prompt_slimline_async_tasks_complete == ${#_prompt_slimline_async_tasks} )); then + stage="all_tasks_complete" + else + stage="task_complete" + fi + prompt_slimline_set_prompts "${stage}" zle && zle .reset-prompt fi } @@ -102,8 +110,9 @@ prompt_slimline_async_tasks() { if (( ! ${_prompt_slimline_async_init_done:-0} )); then prompt_slimline_async_init fi - _prompt_slimline_last_async_call=${EPOCHREALTIME} async_flush_jobs "prompt_slimline" + _prompt_slimline_last_async_call=${EPOCHREALTIME} + _prompt_slimline_async_tasks_complete=0 for task in ${_prompt_slimline_async_tasks}; do async_job "prompt_slimline" "${task}" "$(builtin pwd)" done From 8be8fd0bf223ba72020e91bedd72bf8a9ca0dc05 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 20:26:31 +0100 Subject: [PATCH 032/107] Fix section function arguments quoting --- slimline.zsh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 3dbd4c8..b9d58f0 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -22,7 +22,7 @@ prompt_slimline_get_sections() { outputs=() for section in ${=sections}; do - local output="$(${section} "$*")" + local output="$(${section} $*)" if [[ -n ${output} ]]; then outputs+=("${output}") fi @@ -33,7 +33,7 @@ prompt_slimline_get_sections() { prompt_slimline_set_left_prompt() { local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_left_prompt_sections_output" "${_prompt_slimline_left_prompt_sections}" "${separator}" "$*" + prompt_slimline_get_sections "_prompt_slimline_left_prompt_sections_output" "${_prompt_slimline_left_prompt_sections}" "${separator}" $* local format="|sections| " PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_left_prompt_sections_output}}" @@ -42,7 +42,7 @@ prompt_slimline_set_left_prompt() { prompt_slimline_set_right_prompt() { local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_right_prompt_sections_output" "${_prompt_slimline_right_prompt_sections}" "${separator}" "$*" + prompt_slimline_get_sections "_prompt_slimline_right_prompt_sections_output" "${_prompt_slimline_right_prompt_sections}" "${separator}" $* local format="|sections|" RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_right_prompt_sections_output}}" From f7c15718eede0d1c38b180c0049f11865477def3 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 20:45:51 +0100 Subject: [PATCH 033/107] Check for async task complete function Ignore the section if no complete function is present. --- slimline.zsh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index b9d58f0..10d77d0 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -148,6 +148,16 @@ prompt_slimline_load_sections() { if ! ${section_check_function}; then continue; fi fi + local section_async_task_function="${section_function}_async_task" + if (( $+functions[${section_async_task_function}] )); then + local section_async_task_complete_function="${section_async_task_function}_complete" + if (( ! $+functions[${section_async_task_complete_function}] )); then + print -P "%F{red}slimline%f: The async task of section '${section}' has no complete function!" + continue + fi + _prompt_slimline_async_tasks+=("${section_async_task_function}") + fi + local section_preexec_function="${section_function}_preexec" if (( $+functions[${section_preexec_function}] )); then add-zsh-hook preexec "${section_preexec_function}" @@ -158,11 +168,6 @@ prompt_slimline_load_sections() { add-zsh-hook precmd "${section_precmd_function}" fi - local section_async_task_function="${section_function}_async_task" - if (( $+functions[${section_async_task_function}] )); then - _prompt_slimline_async_tasks+=("${section_async_task_function}") - fi - expanded_sections+=("${section_function}") done From 056036947ed387a76844bfc784d916ff61c66999 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 20:48:27 +0100 Subject: [PATCH 034/107] Use braces for parameter expansion --- slimline.zsh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 10d77d0..1dd28b7 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -138,20 +138,20 @@ prompt_slimline_load_sections() { fi local section_function="prompt_slimline_section_${section}" - if (( ! $+functions[${section_function}] )); then + if (( ! ${+functions[${section_function}]} )); then print -P "%F{red}slimline%f: '${section}' is not a valid section!" continue fi local section_check_function="${section_function}_check" - if (( $+functions[${section_check_function}] )); then + if (( ${+functions[${section_check_function}]} )); then if ! ${section_check_function}; then continue; fi fi local section_async_task_function="${section_function}_async_task" - if (( $+functions[${section_async_task_function}] )); then + if (( ${+functions[${section_async_task_function}]} )); then local section_async_task_complete_function="${section_async_task_function}_complete" - if (( ! $+functions[${section_async_task_complete_function}] )); then + if (( ! ${+functions[${section_async_task_complete_function}]} )); then print -P "%F{red}slimline%f: The async task of section '${section}' has no complete function!" continue fi @@ -159,12 +159,12 @@ prompt_slimline_load_sections() { fi local section_preexec_function="${section_function}_preexec" - if (( $+functions[${section_preexec_function}] )); then + if (( ${+functions[${section_preexec_function}]} )); then add-zsh-hook preexec "${section_preexec_function}" fi local section_precmd_function="${section_function}_precmd" - if (( $+functions[${section_precmd_function}] )); then + if (( ${+functions[${section_precmd_function}]} )); then add-zsh-hook precmd "${section_precmd_function}" fi From 7c0cf5d457ddd6f90dc8cd6fddc741a8803bdc26 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 20:55:49 +0100 Subject: [PATCH 035/107] Add time section --- sections/time.zsh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 sections/time.zsh diff --git a/sections/time.zsh b/sections/time.zsh new file mode 100644 index 0000000..29eda7a --- /dev/null +++ b/sections/time.zsh @@ -0,0 +1,5 @@ +prompt_slimline_section_time() { + local time_str="%D{%T}" + local format="%F{white}|time_str|%f" + echo "${${SLIMLINE_TIME_FORMAT:-${format}}/|time_str|/${time_str}}" +} From 40516cb42cddd9eccc515567f606cf7d29609144 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 21:01:40 +0100 Subject: [PATCH 036/107] Rename section check to init function --- sections/git.zsh | 2 +- slimline.zsh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sections/git.zsh b/sections/git.zsh index 2e3577c..29389c0 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -11,7 +11,7 @@ prompt_slimline_section_git_async_task_complete() { _prompt_slimline_git_output="${output}" } -prompt_slimline_section_git_check() { +prompt_slimline_section_git_init() { # If python or git are not installed, disable the git functionality. if (( ${+commands[python]} && ${+commands[git]} )); then return 0 diff --git a/slimline.zsh b/slimline.zsh index 1dd28b7..e4b7506 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -143,9 +143,9 @@ prompt_slimline_load_sections() { continue fi - local section_check_function="${section_function}_check" - if (( ${+functions[${section_check_function}]} )); then - if ! ${section_check_function}; then continue; fi + local section_init_function="${section_function}_init" + if (( ${+functions[${section_init_function}]} )); then + if ! ${section_init_function}; then continue; fi fi local section_async_task_function="${section_function}_async_task" From 3c5304a2c6b06bd3d849f4dd9665d44fc726facf Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 21:01:49 +0100 Subject: [PATCH 037/107] Use local variable for section outputs --- slimline.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slimline.zsh b/slimline.zsh index e4b7506..9450c60 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -20,7 +20,7 @@ prompt_slimline_get_sections() { local separator=${3} shift 3 - outputs=() + local outputs=() for section in ${=sections}; do local output="$(${section} $*)" if [[ -n ${output} ]]; then From 9ff034247ffb45f50692026b6d05396516896ea4 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 21:11:16 +0100 Subject: [PATCH 038/107] Rename stage to event --- sections/symbol.zsh | 4 ++-- slimline.zsh | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sections/symbol.zsh b/sections/symbol.zsh index fa6c1ba..40be9e8 100644 --- a/sections/symbol.zsh +++ b/sections/symbol.zsh @@ -1,8 +1,8 @@ prompt_slimline_section_symbol() { - local stage=${1} + local event=${1} local format_working="%F{red}∙%f" local format_ready="%F{white}∙%f" - if [[ "${stage}" == "all_tasks_complete" ]]; then + if [[ "${event}" == "all_tasks_complete" ]]; then echo "${SLIMLINE_SYMBOL_READY_FORMAT:-${format_ready}}" else echo "${SLIMLINE_SYMBOL_WORKING_FORMAT:-${format_working}}" diff --git a/slimline.zsh b/slimline.zsh index 9450c60..1e60eee 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -58,9 +58,9 @@ prompt_slimline_set_spelling_prompt() { } prompt_slimline_set_prompts() { - local stage="${1}" - prompt_slimline_set_left_prompt "${stage}" - prompt_slimline_set_right_prompt "${stage}" + local event="${1}" + prompt_slimline_set_left_prompt "${event}" + prompt_slimline_set_right_prompt "${event}" } prompt_slimline_chpwd() { @@ -95,13 +95,13 @@ prompt_slimline_async_callback() { _prompt_slimline_async_tasks_complete=$(( _prompt_slimline_async_tasks_complete + 1 )) if (( ! has_next )); then - local stage='' + local event='' if (( _prompt_slimline_async_tasks_complete == ${#_prompt_slimline_async_tasks} )); then - stage="all_tasks_complete" + event="all_tasks_complete" else - stage="task_complete" + event="task_complete" fi - prompt_slimline_set_prompts "${stage}" + prompt_slimline_set_prompts "${event}" zle && zle .reset-prompt fi } From 3659a1094d0d53d21004545bb4e54fbcb92e9db8 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 21:19:40 +0100 Subject: [PATCH 039/107] Move slimline hooks after the section hooks This way the section hooks can clean up data before the prompt is rendered in precmd. --- slimline.zsh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 1e60eee..dcb67e4 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -188,13 +188,14 @@ prompt_slimline_setup() { zmodload zsh/zle autoload -Uz add-zsh-hook - add-zsh-hook chpwd prompt_slimline_chpwd - add-zsh-hook precmd prompt_slimline_precmd _prompt_slimline_async_tasks=() prompt_slimline_load_sections "_prompt_slimline_left_prompt_sections" prompt_slimline_load_sections "_prompt_slimline_right_prompt_sections" + add-zsh-hook chpwd prompt_slimline_chpwd + add-zsh-hook precmd prompt_slimline_precmd + precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) prompt_slimline_set_prompts "setup" From f140ade46bf39b7da45150e2c99dcc15d926c109 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 21:28:47 +0100 Subject: [PATCH 040/107] Fix parameter passing --- slimline.zsh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index dcb67e4..85ce969 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -22,7 +22,7 @@ prompt_slimline_get_sections() { local outputs=() for section in ${=sections}; do - local output="$(${section} $*)" + local output="$(${section} "$@")" if [[ -n ${output} ]]; then outputs+=("${output}") fi @@ -33,7 +33,7 @@ prompt_slimline_get_sections() { prompt_slimline_set_left_prompt() { local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_left_prompt_sections_output" "${_prompt_slimline_left_prompt_sections}" "${separator}" $* + prompt_slimline_get_sections "_prompt_slimline_left_prompt_sections_output" "${_prompt_slimline_left_prompt_sections}" "${separator}" "$@" local format="|sections| " PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_left_prompt_sections_output}}" @@ -42,7 +42,7 @@ prompt_slimline_set_left_prompt() { prompt_slimline_set_right_prompt() { local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_right_prompt_sections_output" "${_prompt_slimline_right_prompt_sections}" "${separator}" $* + prompt_slimline_get_sections "_prompt_slimline_right_prompt_sections_output" "${_prompt_slimline_right_prompt_sections}" "${separator}" "$@" local format="|sections|" RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_right_prompt_sections_output}}" @@ -90,7 +90,7 @@ prompt_slimline_async_callback() { local has_next=${6} local complete_function="${job}_complete" - ${complete_function} $* + ${complete_function} "$@" _prompt_slimline_async_tasks_complete=$(( _prompt_slimline_async_tasks_complete + 1 )) From 2b7ec1871a09107b0a11eb0ff9148fe2c6b785ba Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Sun, 4 Mar 2018 21:31:15 +0100 Subject: [PATCH 041/107] Revert "Initialize async worker lazily" This reverts commit c0a8c56078285678109648f3eecdbee63705778f. # Conflicts: # slimline.zsh --- slimline.zsh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 85ce969..43f5cae 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -107,9 +107,6 @@ prompt_slimline_async_callback() { } prompt_slimline_async_tasks() { - if (( ! ${_prompt_slimline_async_init_done:-0} )); then - prompt_slimline_async_init - fi async_flush_jobs "prompt_slimline" _prompt_slimline_last_async_call=${EPOCHREALTIME} _prompt_slimline_async_tasks_complete=0 @@ -125,7 +122,6 @@ prompt_slimline_async_init() { async_init async_start_worker "prompt_slimline" -u async_register_callback "prompt_slimline" prompt_slimline_async_callback - _prompt_slimline_async_init_done=1 } prompt_slimline_load_sections() { @@ -198,6 +194,8 @@ prompt_slimline_setup() { precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) + prompt_slimline_async_init + prompt_slimline_set_prompts "setup" prompt_slimline_set_spelling_prompt } From 4ae8bf4cae992469fe3781fc15034ac475129d8a Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 21:57:20 +0100 Subject: [PATCH 042/107] Make section loading not depend upon implicit globals --- slimline.zsh | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 43f5cae..ed349ca 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -24,7 +24,7 @@ prompt_slimline_get_sections() { for section in ${=sections}; do local output="$(${section} "$@")" if [[ -n ${output} ]]; then - outputs+=("${output}") + outputs+="${output}" fi done @@ -125,9 +125,13 @@ prompt_slimline_async_init() { } prompt_slimline_load_sections() { - local var=${1} + local sections="${1}" + local section_var="${2}" + local async_tasks_var="${3}" + local expanded_sections=() - for section in ${=${(P)var}}; do + local async_tasks=() + for section in ${=sections}; do local section_file="${prompt_slimline_path}/sections/${section}.zsh" if [[ -f "${section_file}" ]]; then source "${section_file}" @@ -151,7 +155,7 @@ prompt_slimline_load_sections() { print -P "%F{red}slimline%f: The async task of section '${section}' has no complete function!" continue fi - _prompt_slimline_async_tasks+=("${section_async_task_function}") + async_tasks+="${section_async_task_function}" fi local section_preexec_function="${section_function}_preexec" @@ -164,10 +168,11 @@ prompt_slimline_load_sections() { add-zsh-hook precmd "${section_precmd_function}" fi - expanded_sections+=("${section_function}") + expanded_sections+="${section_function}" done - typeset -g "${var}"="${(j: :)expanded_sections}" + typeset -g "${section_var}"="${(j: :)expanded_sections}" + : ${(PA)=async_tasks_var::=${(P)async_tasks_var} ${async_tasks}} } prompt_slimline_setup() { @@ -176,8 +181,8 @@ prompt_slimline_setup() { prompt_slimline_evaluate_legacy_options fi - _prompt_slimline_left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd symbol}" - _prompt_slimline_right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtual_env nodejs}" + local left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd symbol}" + local right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtual_env nodejs}" prompt_opts=(cr percent subst) zmodload zsh/datetime @@ -186,8 +191,8 @@ prompt_slimline_setup() { autoload -Uz add-zsh-hook _prompt_slimline_async_tasks=() - prompt_slimline_load_sections "_prompt_slimline_left_prompt_sections" - prompt_slimline_load_sections "_prompt_slimline_right_prompt_sections" + prompt_slimline_load_sections "${left_prompt_sections}" "_prompt_slimline_left_prompt_sections" "_prompt_slimline_async_tasks" + prompt_slimline_load_sections "${right_prompt_sections}" "_prompt_slimline_right_prompt_sections" "_prompt_slimline_async_tasks" add-zsh-hook chpwd prompt_slimline_chpwd add-zsh-hook precmd prompt_slimline_precmd From 1a5930317f24b1b408f6cb7c741316fc53b3b8d5 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 21:59:47 +0100 Subject: [PATCH 043/107] Reorder section output function parameters --- slimline.zsh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index ed349ca..6545829 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -14,10 +14,10 @@ prompt_slimline_path="${0:A:h}" prompt_slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" -prompt_slimline_get_sections() { - local var=${1} - local sections=${2} - local separator=${3} +prompt_slimline_get_section_output() { + local sections="${1}" + local separator="${2}" + local var="${3}" shift 3 local outputs=() @@ -33,7 +33,7 @@ prompt_slimline_get_sections() { prompt_slimline_set_left_prompt() { local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_left_prompt_sections_output" "${_prompt_slimline_left_prompt_sections}" "${separator}" "$@" + prompt_slimline_get_section_output "${_prompt_slimline_left_prompt_sections}" "${separator}" "_prompt_slimline_left_prompt_sections_output" "$@" local format="|sections| " PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_left_prompt_sections_output}}" @@ -42,7 +42,7 @@ prompt_slimline_set_left_prompt() { prompt_slimline_set_right_prompt() { local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_sections "_prompt_slimline_right_prompt_sections_output" "${_prompt_slimline_right_prompt_sections}" "${separator}" "$@" + prompt_slimline_get_section_output "${_prompt_slimline_right_prompt_sections}" "${separator}" "_prompt_slimline_right_prompt_sections_output" "$@" local format="|sections|" RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_right_prompt_sections_output}}" From 182e205c6396cbaa6f1a05b65e9e159edc64b69d Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 22:04:03 +0100 Subject: [PATCH 044/107] Move section handling functions into separate file --- lib/section.zsh | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ slimline.zsh | 68 +------------------------------------------------ 2 files changed, 68 insertions(+), 67 deletions(-) create mode 100644 lib/section.zsh diff --git a/lib/section.zsh b/lib/section.zsh new file mode 100644 index 0000000..ca5bbc3 --- /dev/null +++ b/lib/section.zsh @@ -0,0 +1,67 @@ +prompt_slimline_get_section_output() { + local sections="${1}" + local separator="${2}" + local var="${3}" + shift 3 + + local outputs=() + for section in ${=sections}; do + local output="$(${section} "$@")" + if [[ -n ${output} ]]; then + outputs+="${output}" + fi + done + + typeset -g "${var}"="${(epj:${separator}:)outputs}" +} + +prompt_slimline_load_sections() { + local sections="${1}" + local section_var="${2}" + local async_tasks_var="${3}" + + local expanded_sections=() + local async_tasks=() + for section in ${=sections}; do + local section_file="${prompt_slimline_path}/sections/${section}.zsh" + if [[ -f "${section_file}" ]]; then + source "${section_file}" + fi + + local section_function="prompt_slimline_section_${section}" + if (( ! ${+functions[${section_function}]} )); then + print -P "%F{red}slimline%f: '${section}' is not a valid section!" + continue + fi + + local section_init_function="${section_function}_init" + if (( ${+functions[${section_init_function}]} )); then + if ! ${section_init_function}; then continue; fi + fi + + local section_async_task_function="${section_function}_async_task" + if (( ${+functions[${section_async_task_function}]} )); then + local section_async_task_complete_function="${section_async_task_function}_complete" + if (( ! ${+functions[${section_async_task_complete_function}]} )); then + print -P "%F{red}slimline%f: The async task of section '${section}' has no complete function!" + continue + fi + async_tasks+="${section_async_task_function}" + fi + + local section_preexec_function="${section_function}_preexec" + if (( ${+functions[${section_preexec_function}]} )); then + add-zsh-hook preexec "${section_preexec_function}" + fi + + local section_precmd_function="${section_function}_precmd" + if (( ${+functions[${section_precmd_function}]} )); then + add-zsh-hook precmd "${section_precmd_function}" + fi + + expanded_sections+="${section_function}" + done + + typeset -g "${section_var}"="${(j: :)expanded_sections}" + : ${(PA)=async_tasks_var::=${(P)async_tasks_var} ${async_tasks}} +} diff --git a/slimline.zsh b/slimline.zsh index 6545829..5d496a9 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -14,22 +14,7 @@ prompt_slimline_path="${0:A:h}" prompt_slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" -prompt_slimline_get_section_output() { - local sections="${1}" - local separator="${2}" - local var="${3}" - shift 3 - - local outputs=() - for section in ${=sections}; do - local output="$(${section} "$@")" - if [[ -n ${output} ]]; then - outputs+="${output}" - fi - done - - typeset -g "${var}"="${(epj:${separator}:)outputs}" -} +source "${prompt_slimline_path}/lib/section.zsh" prompt_slimline_set_left_prompt() { local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" @@ -124,57 +109,6 @@ prompt_slimline_async_init() { async_register_callback "prompt_slimline" prompt_slimline_async_callback } -prompt_slimline_load_sections() { - local sections="${1}" - local section_var="${2}" - local async_tasks_var="${3}" - - local expanded_sections=() - local async_tasks=() - for section in ${=sections}; do - local section_file="${prompt_slimline_path}/sections/${section}.zsh" - if [[ -f "${section_file}" ]]; then - source "${section_file}" - fi - - local section_function="prompt_slimline_section_${section}" - if (( ! ${+functions[${section_function}]} )); then - print -P "%F{red}slimline%f: '${section}' is not a valid section!" - continue - fi - - local section_init_function="${section_function}_init" - if (( ${+functions[${section_init_function}]} )); then - if ! ${section_init_function}; then continue; fi - fi - - local section_async_task_function="${section_function}_async_task" - if (( ${+functions[${section_async_task_function}]} )); then - local section_async_task_complete_function="${section_async_task_function}_complete" - if (( ! ${+functions[${section_async_task_complete_function}]} )); then - print -P "%F{red}slimline%f: The async task of section '${section}' has no complete function!" - continue - fi - async_tasks+="${section_async_task_function}" - fi - - local section_preexec_function="${section_function}_preexec" - if (( ${+functions[${section_preexec_function}]} )); then - add-zsh-hook preexec "${section_preexec_function}" - fi - - local section_precmd_function="${section_function}_precmd" - if (( ${+functions[${section_precmd_function}]} )); then - add-zsh-hook precmd "${section_precmd_function}" - fi - - expanded_sections+="${section_function}" - done - - typeset -g "${section_var}"="${(j: :)expanded_sections}" - : ${(PA)=async_tasks_var::=${(P)async_tasks_var} ${async_tasks}} -} - prompt_slimline_setup() { if (( ${SLIMLINE_PROMPT_VERSION:-1} < 2 )); then source "${prompt_slimline_path}/lib/legacy_options.zsh" From d14bcc75604b9800b76535ec1757bb4f3274d29c Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 22:11:09 +0100 Subject: [PATCH 045/107] Rename some functions to follow common google shell style guide --- lib/{legacy_options.zsh => legacy.zsh} | 2 +- lib/section.zsh | 4 ++-- slimline.zsh | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) rename lib/{legacy_options.zsh => legacy.zsh} (98%) diff --git a/lib/legacy_options.zsh b/lib/legacy.zsh similarity index 98% rename from lib/legacy_options.zsh rename to lib/legacy.zsh index 9e28549..fbf7707 100644 --- a/lib/legacy_options.zsh +++ b/lib/legacy.zsh @@ -1,4 +1,4 @@ -prompt_slimline_evaluate_legacy_options() { +slimline::legacy::evaluate_options() { local left_prompt_sections=() local right_prompt_sections=() diff --git a/lib/section.zsh b/lib/section.zsh index ca5bbc3..b87e522 100644 --- a/lib/section.zsh +++ b/lib/section.zsh @@ -1,4 +1,4 @@ -prompt_slimline_get_section_output() { +slimline::section::get_output() { local sections="${1}" local separator="${2}" local var="${3}" @@ -15,7 +15,7 @@ prompt_slimline_get_section_output() { typeset -g "${var}"="${(epj:${separator}:)outputs}" } -prompt_slimline_load_sections() { +slimline::section::load() { local sections="${1}" local section_var="${2}" local async_tasks_var="${3}" diff --git a/slimline.zsh b/slimline.zsh index 5d496a9..2558468 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -18,7 +18,7 @@ source "${prompt_slimline_path}/lib/section.zsh" prompt_slimline_set_left_prompt() { local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_section_output "${_prompt_slimline_left_prompt_sections}" "${separator}" "_prompt_slimline_left_prompt_sections_output" "$@" + slimline::section::get_output "${_prompt_slimline_left_prompt_sections}" "${separator}" "_prompt_slimline_left_prompt_sections_output" "$@" local format="|sections| " PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_left_prompt_sections_output}}" @@ -27,7 +27,7 @@ prompt_slimline_set_left_prompt() { prompt_slimline_set_right_prompt() { local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" - prompt_slimline_get_section_output "${_prompt_slimline_right_prompt_sections}" "${separator}" "_prompt_slimline_right_prompt_sections_output" "$@" + slimline::section::get_output "${_prompt_slimline_right_prompt_sections}" "${separator}" "_prompt_slimline_right_prompt_sections_output" "$@" local format="|sections|" RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_right_prompt_sections_output}}" @@ -111,8 +111,8 @@ prompt_slimline_async_init() { prompt_slimline_setup() { if (( ${SLIMLINE_PROMPT_VERSION:-1} < 2 )); then - source "${prompt_slimline_path}/lib/legacy_options.zsh" - prompt_slimline_evaluate_legacy_options + source "${prompt_slimline_path}/lib/legacy.zsh" + slimline::legacy::evaluate_options fi local left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd symbol}" @@ -125,8 +125,8 @@ prompt_slimline_setup() { autoload -Uz add-zsh-hook _prompt_slimline_async_tasks=() - prompt_slimline_load_sections "${left_prompt_sections}" "_prompt_slimline_left_prompt_sections" "_prompt_slimline_async_tasks" - prompt_slimline_load_sections "${right_prompt_sections}" "_prompt_slimline_right_prompt_sections" "_prompt_slimline_async_tasks" + slimline::section::load "${left_prompt_sections}" "_prompt_slimline_left_prompt_sections" "_prompt_slimline_async_tasks" + slimline::section::load "${right_prompt_sections}" "_prompt_slimline_right_prompt_sections" "_prompt_slimline_async_tasks" add-zsh-hook chpwd prompt_slimline_chpwd add-zsh-hook precmd prompt_slimline_precmd From b906bb2503b5f1e27c3b3c7694f0c343106997ea Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 22:58:00 +0100 Subject: [PATCH 046/107] Only add async task array if it is not empty --- lib/section.zsh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/section.zsh b/lib/section.zsh index b87e522..d69bca8 100644 --- a/lib/section.zsh +++ b/lib/section.zsh @@ -63,5 +63,7 @@ slimline::section::load() { done typeset -g "${section_var}"="${(j: :)expanded_sections}" - : ${(PA)=async_tasks_var::=${(P)async_tasks_var} ${async_tasks}} + if (( ${#async_tasks[@]} )); then + : ${(PA)=async_tasks_var::=${(P)async_tasks_var} ${async_tasks}} + fi } From 6ae127324b1f49d99a3bd7cc2ec142335e5f780a Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 23:08:39 +0100 Subject: [PATCH 047/107] Remove chpwd hook since fzf-marks is working without it (see #9) --- slimline.zsh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 2558468..68be50b 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -48,12 +48,6 @@ prompt_slimline_set_prompts() { prompt_slimline_set_right_prompt "${event}" } -prompt_slimline_chpwd() { - if (( ${#_prompt_slimline_async_tasks[@]} )); then - prompt_slimline_async_tasks - fi -} - prompt_slimline_precmd() { if (( EPOCHREALTIME - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then # In case no tasks need to be executed signal the sections that all tasks are finished. @@ -128,7 +122,6 @@ prompt_slimline_setup() { slimline::section::load "${left_prompt_sections}" "_prompt_slimline_left_prompt_sections" "_prompt_slimline_async_tasks" slimline::section::load "${right_prompt_sections}" "_prompt_slimline_right_prompt_sections" "_prompt_slimline_async_tasks" - add-zsh-hook chpwd prompt_slimline_chpwd add-zsh-hook precmd prompt_slimline_precmd precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) From b925fe9b1f3d152def7b9ae48bca7eadbb68f39f Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 23:13:48 +0100 Subject: [PATCH 048/107] Refactor async handling and move it into separate file --- lib/async.zsh | 51 +++++++++++++++++++++++++++++++++++++++++++++++ slimline.zsh | 55 ++++++++------------------------------------------- 2 files changed, 59 insertions(+), 47 deletions(-) create mode 100644 lib/async.zsh diff --git a/lib/async.zsh b/lib/async.zsh new file mode 100644 index 0000000..7c71b47 --- /dev/null +++ b/lib/async.zsh @@ -0,0 +1,51 @@ +slimline::async::init() { + if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} && ! ${+functions[async_init]} && ! ${+functions[async_start_worker]} )); then + source "${prompt_slimline_path}/zsh-async/async.zsh" + fi + + slimline_async_tasks="${1}" + slimline_async_callback_complete="${2}" + slimline_async_worker_name="prompt_slimline" + + async_init + async_start_worker "${slimline_async_worker_name}" -u + async_register_callback "${slimline_async_worker_name}" slimline::async::callback +} + +slimline::async::callback() { + local job=${1} + local has_next=${6} + + local complete_function="${job}_complete" + ${complete_function} "$@" + + slimline_async_tasks_complete=$(( slimline_async_tasks_complete + 1 )) + + if (( ! has_next )); then + if (( slimline_async_tasks_complete == ${#${=slimline_async_tasks}} )); then + ${slimline_async_callback_complete} "all_tasks_complete" + else + ${slimline_async_callback_complete} "task_complete" + fi + fi +} + +slimline::async::start_tasks() { + if (( ! ${#${=slimline_async_tasks}} )); then + ${slimline_async_callback_complete} "all_tasks_complete" + return + fi + + local event="${1}" + if [[ "${event}" == "precmd" ]]; then + if (( EPOCHREALTIME - ${slimline_async_last_call:-0} <= 0.5 )); then return; fi + ${slimline_async_callback_complete} "precmd" + fi + + async_flush_jobs "${slimline_async_worker_name}" + slimline_async_last_call=${EPOCHREALTIME} + slimline_async_tasks_complete=0 + for task in ${=slimline_async_tasks}; do + async_job "${slimline_async_worker_name}" "${task}" "$(builtin pwd)" + done +} diff --git a/slimline.zsh b/slimline.zsh index 68be50b..c514c6e 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -14,6 +14,7 @@ prompt_slimline_path="${0:A:h}" prompt_slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" +source "${prompt_slimline_path}/lib/async.zsh" source "${prompt_slimline_path}/lib/section.zsh" prompt_slimline_set_left_prompt() { @@ -49,58 +50,17 @@ prompt_slimline_set_prompts() { } prompt_slimline_precmd() { - if (( EPOCHREALTIME - ${_prompt_slimline_last_async_call:-0} > 0.5 )); then - # In case no tasks need to be executed signal the sections that all tasks are finished. - if (( ${#_prompt_slimline_async_tasks[@]} )); then - prompt_slimline_set_prompts "precmd" - prompt_slimline_async_tasks - else - prompt_slimline_set_prompts "all_tasks_complete" - fi - fi + slimline::async::start_tasks "precmd" } prompt_slimline_exit_status() { prompt_slimline_last_exit_status=$? } -prompt_slimline_async_callback() { - local job=${1} - local has_next=${6} - - local complete_function="${job}_complete" - ${complete_function} "$@" - - _prompt_slimline_async_tasks_complete=$(( _prompt_slimline_async_tasks_complete + 1 )) - - if (( ! has_next )); then - local event='' - if (( _prompt_slimline_async_tasks_complete == ${#_prompt_slimline_async_tasks} )); then - event="all_tasks_complete" - else - event="task_complete" - fi - prompt_slimline_set_prompts "${event}" - zle && zle .reset-prompt - fi -} - -prompt_slimline_async_tasks() { - async_flush_jobs "prompt_slimline" - _prompt_slimline_last_async_call=${EPOCHREALTIME} - _prompt_slimline_async_tasks_complete=0 - for task in ${_prompt_slimline_async_tasks}; do - async_job "prompt_slimline" "${task}" "$(builtin pwd)" - done -} - -prompt_slimline_async_init() { - if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} && ! ${+functions[async_init]} && ! ${+functions[async_start_worker]} )); then - source "${prompt_slimline_path}/zsh-async/async.zsh" - fi - async_init - async_start_worker "prompt_slimline" -u - async_register_callback "prompt_slimline" prompt_slimline_async_callback +prompt_slimline_async_task_complete() { + local event="${1}" + prompt_slimline_set_prompts "${event}" + zle && zle .reset-prompt } prompt_slimline_setup() { @@ -126,7 +86,8 @@ prompt_slimline_setup() { precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) - prompt_slimline_async_init + slimline::async::init "${_prompt_slimline_async_tasks}" "prompt_slimline_async_task_complete" + unset _prompt_slimline_async_tasks prompt_slimline_set_prompts "setup" prompt_slimline_set_spelling_prompt From 352ec5df638427995c58d62498a1db6ac49a4235 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 23:35:52 +0100 Subject: [PATCH 049/107] Move prompt functions into separate file --- lib/prompt.zsh | 37 +++++++++++++++++++++++++++++++++++++ slimline.zsh | 49 +++++++++---------------------------------------- 2 files changed, 46 insertions(+), 40 deletions(-) create mode 100644 lib/prompt.zsh diff --git a/lib/prompt.zsh b/lib/prompt.zsh new file mode 100644 index 0000000..af979e2 --- /dev/null +++ b/lib/prompt.zsh @@ -0,0 +1,37 @@ +slimline::prompt::set_left() { + local sections="${1}" + local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" + shift 1 + slimline::section::get_output "${sections}" "${separator}" "slimline_left_prompt_sections_output" "$@" + + local format="|sections| " + PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${slimline_left_prompt_sections_output}}" + unset slimline_left_prompt_sections_output +} + +slimline::prompt::set_right() { + local sections="${1}" + local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" + shift 1 + slimline::section::get_output "${sections}" "${separator}" "slimline_right_prompt_sections_output" "$@" + + local format="|sections|" + RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${slimline_right_prompt_sections_output}}" + unset slimline_right_prompt_sections_output +} + +slimline::prompt::set_spelling() { + local from="%R" + local to="%r" + local format="zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? " + local selected="${SLIMLINE_AUTOCORRECT_FORMAT:-${format}}" + SPROMPT="${${selected/|from|/${from}}/|to|/${to}}" +} + +slimline::prompt::set() { + local event="${1}" + local sections_left="${2}" + local sections_right="${3}" + slimline::prompt::set_left "${sections_left}" "${event}" + slimline::prompt::set_right "${sections_right}" "${event}" +} diff --git a/slimline.zsh b/slimline.zsh index c514c6e..0f10461 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -15,40 +15,9 @@ prompt_slimline_path="${0:A:h}" prompt_slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" source "${prompt_slimline_path}/lib/async.zsh" +source "${prompt_slimline_path}/lib/prompt.zsh" source "${prompt_slimline_path}/lib/section.zsh" -prompt_slimline_set_left_prompt() { - local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" - slimline::section::get_output "${_prompt_slimline_left_prompt_sections}" "${separator}" "_prompt_slimline_left_prompt_sections_output" "$@" - - local format="|sections| " - PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_left_prompt_sections_output}}" - unset _prompt_slimline_left_prompt_sections_output -} - -prompt_slimline_set_right_prompt() { - local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" - slimline::section::get_output "${_prompt_slimline_right_prompt_sections}" "${separator}" "_prompt_slimline_right_prompt_sections_output" "$@" - - local format="|sections|" - RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${_prompt_slimline_right_prompt_sections_output}}" - unset _prompt_slimline_right_prompt_sections_output -} - -prompt_slimline_set_spelling_prompt() { - local from="%R" - local to="%r" - local format="zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? " - local selected="${SLIMLINE_AUTOCORRECT_FORMAT:-${format}}" - SPROMPT="${${selected/|from|/${from}}/|to|/${to}}" -} - -prompt_slimline_set_prompts() { - local event="${1}" - prompt_slimline_set_left_prompt "${event}" - prompt_slimline_set_right_prompt "${event}" -} - prompt_slimline_precmd() { slimline::async::start_tasks "precmd" } @@ -59,7 +28,7 @@ prompt_slimline_exit_status() { prompt_slimline_async_task_complete() { local event="${1}" - prompt_slimline_set_prompts "${event}" + slimline::prompt::set "${event}" "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" zle && zle .reset-prompt } @@ -78,19 +47,19 @@ prompt_slimline_setup() { autoload -Uz add-zsh-hook - _prompt_slimline_async_tasks=() - slimline::section::load "${left_prompt_sections}" "_prompt_slimline_left_prompt_sections" "_prompt_slimline_async_tasks" - slimline::section::load "${right_prompt_sections}" "_prompt_slimline_right_prompt_sections" "_prompt_slimline_async_tasks" + slimline_async_tasks_functions=() + slimline::section::load "${left_prompt_sections}" "slimline_left_prompt_sections" "slimline_async_tasks_functions" + slimline::section::load "${right_prompt_sections}" "slimline_right_prompt_sections" "slimline_async_tasks_functions" add-zsh-hook precmd prompt_slimline_precmd precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) - slimline::async::init "${_prompt_slimline_async_tasks}" "prompt_slimline_async_task_complete" - unset _prompt_slimline_async_tasks + slimline::async::init "${slimline_async_tasks_functions}" "prompt_slimline_async_task_complete" + unset slimline_async_tasks_functions - prompt_slimline_set_prompts "setup" - prompt_slimline_set_spelling_prompt + slimline::prompt::set "setup" "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" + slimline::prompt::set_spelling } prompt_slimline_setup "$@" From 9f74df00f951ed7890d60676958849e919cc145d Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 23:38:42 +0100 Subject: [PATCH 050/107] Simplify collecting async tasks --- lib/section.zsh | 4 +--- slimline.zsh | 8 +++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/section.zsh b/lib/section.zsh index d69bca8..bc3a212 100644 --- a/lib/section.zsh +++ b/lib/section.zsh @@ -63,7 +63,5 @@ slimline::section::load() { done typeset -g "${section_var}"="${(j: :)expanded_sections}" - if (( ${#async_tasks[@]} )); then - : ${(PA)=async_tasks_var::=${(P)async_tasks_var} ${async_tasks}} - fi + typeset -g "${async_tasks_var}"="${(j: :)async_tasks}" } diff --git a/slimline.zsh b/slimline.zsh index 0f10461..629edaa 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -47,16 +47,14 @@ prompt_slimline_setup() { autoload -Uz add-zsh-hook - slimline_async_tasks_functions=() - slimline::section::load "${left_prompt_sections}" "slimline_left_prompt_sections" "slimline_async_tasks_functions" - slimline::section::load "${right_prompt_sections}" "slimline_right_prompt_sections" "slimline_async_tasks_functions" + slimline::section::load "${left_prompt_sections}" "slimline_left_prompt_sections" "slimline_left_prompt_async_tasks" + slimline::section::load "${right_prompt_sections}" "slimline_right_prompt_sections" "slimline_right_prompt_async_tasks" add-zsh-hook precmd prompt_slimline_precmd precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) - slimline::async::init "${slimline_async_tasks_functions}" "prompt_slimline_async_task_complete" - unset slimline_async_tasks_functions + slimline::async::init "${slimline_left_prompt_async_tasks} ${slimline_right_prompt_async_tasks}" "prompt_slimline_async_task_complete" slimline::prompt::set "setup" "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" slimline::prompt::set_spelling From 66bb84b21bc7bcde4a9b2830b4c7ca6c7f4320bb Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Mon, 5 Mar 2018 23:43:22 +0100 Subject: [PATCH 051/107] Rename functions for more clarity --- slimline.zsh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slimline.zsh b/slimline.zsh index 629edaa..60f3dbc 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -18,11 +18,11 @@ source "${prompt_slimline_path}/lib/async.zsh" source "${prompt_slimline_path}/lib/prompt.zsh" source "${prompt_slimline_path}/lib/section.zsh" -prompt_slimline_precmd() { +prompt_slimline_precmd_async_tasks() { slimline::async::start_tasks "precmd" } -prompt_slimline_exit_status() { +prompt_slimline_precmd_exit_status() { prompt_slimline_last_exit_status=$? } @@ -50,9 +50,9 @@ prompt_slimline_setup() { slimline::section::load "${left_prompt_sections}" "slimline_left_prompt_sections" "slimline_left_prompt_async_tasks" slimline::section::load "${right_prompt_sections}" "slimline_right_prompt_sections" "slimline_right_prompt_async_tasks" - add-zsh-hook precmd prompt_slimline_precmd + add-zsh-hook precmd prompt_slimline_precmd_async_tasks - precmd_functions=("prompt_slimline_exit_status" ${precmd_functions[@]}) + precmd_functions=("prompt_slimline_precmd_exit_status" ${precmd_functions[@]}) slimline::async::init "${slimline_left_prompt_async_tasks} ${slimline_right_prompt_async_tasks}" "prompt_slimline_async_task_complete" From 83c6f43c25bde32d6a8d717a0aead8c01eefda5d Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 20:36:55 +0100 Subject: [PATCH 052/107] Rework most identifiers and make nodejs section asynchronous --- lib/async.zsh | 2 +- lib/prompt.zsh | 6 +++--- lib/section.zsh | 4 ++-- lib/utils.zsh | 20 ++++++++++++++++++++ sections/aws_profile.zsh | 2 +- sections/cwd.zsh | 2 +- sections/execution_time.zsh | 35 ++++++++++------------------------- sections/exit_status.zsh | 6 +++--- sections/git.zsh | 20 ++++++++++---------- sections/nodejs.zsh | 18 ++++++++++++++++-- sections/symbol.zsh | 2 +- sections/time.zsh | 2 +- sections/user_host_info.zsh | 4 ++-- sections/virtual_env.zsh | 2 +- slimline.zsh | 35 ++++++++++++++++++----------------- 15 files changed, 90 insertions(+), 70 deletions(-) create mode 100644 lib/utils.zsh diff --git a/lib/async.zsh b/lib/async.zsh index 7c71b47..33ea8c7 100644 --- a/lib/async.zsh +++ b/lib/async.zsh @@ -1,6 +1,6 @@ slimline::async::init() { if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} && ! ${+functions[async_init]} && ! ${+functions[async_start_worker]} )); then - source "${prompt_slimline_path}/zsh-async/async.zsh" + source "${slimline_path}/zsh-async/async.zsh" fi slimline_async_tasks="${1}" diff --git a/lib/prompt.zsh b/lib/prompt.zsh index af979e2..cce2339 100644 --- a/lib/prompt.zsh +++ b/lib/prompt.zsh @@ -29,9 +29,9 @@ slimline::prompt::set_spelling() { } slimline::prompt::set() { - local event="${1}" - local sections_left="${2}" - local sections_right="${3}" + local sections_left="${1}" + local sections_right="${2}" + local event="${3}" slimline::prompt::set_left "${sections_left}" "${event}" slimline::prompt::set_right "${sections_right}" "${event}" } diff --git a/lib/section.zsh b/lib/section.zsh index bc3a212..350f863 100644 --- a/lib/section.zsh +++ b/lib/section.zsh @@ -23,12 +23,12 @@ slimline::section::load() { local expanded_sections=() local async_tasks=() for section in ${=sections}; do - local section_file="${prompt_slimline_path}/sections/${section}.zsh" + local section_file="${slimline_path}/sections/${section}.zsh" if [[ -f "${section_file}" ]]; then source "${section_file}" fi - local section_function="prompt_slimline_section_${section}" + local section_function="slimline_section_${section}" if (( ! ${+functions[${section_function}]} )); then print -P "%F{red}slimline%f: '${section}' is not a valid section!" continue diff --git a/lib/utils.zsh b/lib/utils.zsh new file mode 100644 index 0000000..6081de6 --- /dev/null +++ b/lib/utils.zsh @@ -0,0 +1,20 @@ +# turns seconds into human readable time +# 165392 => 1d 21h 56m 32s +# https://github.com/sindresorhus/pretty-time-zsh +# Copyright (c) Sindre Sorhus (sindresorhus.com) +# MIT License +# See https://github.com/sindresorhus/pretty-time-zsh/blob/1176d39364c584134e1532309c43fae44c6f4069/license +slimline::utils::pretty_time() { + local human total_seconds=$1 + local days=$(( total_seconds / 60 / 60 / 24 )) + local hours=$(( total_seconds / 60 / 60 % 24 )) + local minutes=$(( total_seconds / 60 % 60 )) + local seconds=$(( total_seconds % 60 )) + + (( days > 0 )) && human+="${days}d " + (( hours > 0 )) && human+="${hours}h " + (( minutes > 0 )) && human+="${minutes}m " + human+="${seconds}s" + + echo "$human" +} diff --git a/sections/aws_profile.zsh b/sections/aws_profile.zsh index 5122c7b..94f4fbe 100644 --- a/sections/aws_profile.zsh +++ b/sections/aws_profile.zsh @@ -1,4 +1,4 @@ -prompt_slimline_section_aws_profile() { +slimline_section_aws_profile() { if [[ -z "${AWS_PROFILE}" ]]; then return; fi local profile="${AWS_PROFILE}" local format="%F{white}[AWS:%F{blue}|profile|%F{white}]%f" diff --git a/sections/cwd.zsh b/sections/cwd.zsh index ede8f4c..94cf409 100644 --- a/sections/cwd.zsh +++ b/sections/cwd.zsh @@ -1,4 +1,4 @@ -prompt_slimline_section_cwd() { +slimline_section_cwd() { local path="%3~" local format_root="%F{red}|path|%f" local format="%F{cyan}|path|%f" diff --git a/sections/execution_time.zsh b/sections/execution_time.zsh index a08d936..9b08b9e 100644 --- a/sections/execution_time.zsh +++ b/sections/execution_time.zsh @@ -1,37 +1,22 @@ -# turns seconds into human readable time -# 165392 => 1d 21h 56m 32s -# https://github.com/sindresorhus/pretty-time-zsh -prompt_slimline_human_time() { - local tmp=$1 - local days=$(( tmp / 60 / 60 / 24 )) - local hours=$(( tmp / 60 / 60 % 24 )) - local minutes=$(( tmp / 60 % 60 )) - local seconds=$(( tmp % 60 )) - (( days > 0 )) && echo -n "${days}d " - (( hours > 0 )) && echo -n "${hours}h " - (( minutes > 0 )) && echo -n "${minutes}m " - echo "${seconds}s" +slimline_section_execution_time_preexec() { + slimline_section_execution_time_cmd_timestamp=$EPOCHSECONDS } -prompt_slimline_section_execution_time_preexec() { - _prompt_slimline_cmd_timestamp=$EPOCHSECONDS -} - -prompt_slimline_section_execution_time_precmd() { +slimline_section_execution_time_precmd() { local integer elapsed - (( elapsed = EPOCHSECONDS - ${_prompt_slimline_cmd_timestamp:-$EPOCHSECONDS} )) - _prompt_slimline_cmd_exec_time= + (( elapsed = EPOCHSECONDS - ${slimline_section_execution_time_cmd_timestamp:-$EPOCHSECONDS} )) + slimline_section_execution_time_output= if (( elapsed > ${SLIMLINE_MAX_EXEC_TIME:-5} )); then - _prompt_slimline_cmd_exec_time="$(prompt_slimline_human_time $elapsed)" + slimline_section_execution_time_output="$(slimline::utils::pretty_time $elapsed)" fi - unset _prompt_slimline_cmd_timestamp + unset slimline_section_execution_time_cmd_timestamp } -prompt_slimline_section_execution_time() { +slimline_section_execution_time() { # add elapsed time if threshold is exceeded - if [[ -z "${_prompt_slimline_cmd_exec_time}" ]]; then return; fi - local exec_time="${_prompt_slimline_cmd_exec_time}" + if [[ -z "${slimline_section_execution_time_output}" ]]; then return; fi + local exec_time="${slimline_section_execution_time_output}" local format="%F{yellow}|exec_time|%f" echo "${${SLIMLINE_EXECUTION_TIME_FORMAT:-${format}}/|exec_time|/${exec_time}}" } diff --git a/sections/exit_status.zsh b/sections/exit_status.zsh index 7afd857..82a2e8c 100644 --- a/sections/exit_status.zsh +++ b/sections/exit_status.zsh @@ -1,6 +1,6 @@ -prompt_slimline_section_exit_status() { - if (( prompt_slimline_last_exit_status == 0 )); then return; fi - local exit_status=${prompt_slimline_last_exit_status} +slimline_section_exit_status() { + if (( slimline_last_exit_status == 0 )); then return; fi + local exit_status=${slimline_last_exit_status} local format="%F{red}|exit_status| ↵%f" echo "${${SLIMLINE_EXIT_STATUS_FORMAT:-${format}}/|exit_status|/${exit_status}}" } diff --git a/sections/git.zsh b/sections/git.zsh index 29389c0..6b9272a 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -1,17 +1,17 @@ -prompt_slimline_section_git_precmd() { - unset _prompt_slimline_git_output +slimline_section_git_precmd() { + unset slimline_section_git_output } -prompt_slimline_section_git_async_task() { - command python "${prompt_slimline_path}/gitline/gitline.py" --shell=zsh "$*" +slimline_section_git_async_task() { + command python "${slimline_path}/gitline/gitline.py" --shell=zsh "$*" } -prompt_slimline_section_git_async_task_complete() { +slimline_section_git_async_task_complete() { local output=${3} - _prompt_slimline_git_output="${output}" + slimline_section_git_output="${output}" } -prompt_slimline_section_git_init() { +slimline_section_git_init() { # If python or git are not installed, disable the git functionality. if (( ${+commands[python]} && ${+commands[git]} )); then return 0 @@ -21,9 +21,9 @@ prompt_slimline_section_git_init() { return 1 } -prompt_slimline_section_git() { - if [[ -z "${_prompt_slimline_git_output}" ]]; then return; fi - local output="${_prompt_slimline_git_output}" +slimline_section_git() { + if [[ -z "${slimline_section_git_output}" ]]; then return; fi + local output="${slimline_section_git_output}" local format="|output|" echo "${${SLIMLINE_GIT_FORMAT:-${format}}/|output|/${output}}" } diff --git a/sections/nodejs.zsh b/sections/nodejs.zsh index 447a293..3f9a4d5 100644 --- a/sections/nodejs.zsh +++ b/sections/nodejs.zsh @@ -1,6 +1,20 @@ -prompt_slimline_section_nodejs() { +slimline_section_nodejs_precmd() { + unset slimline_section_nodejs_output +} + +slimline_section_nodejs_async_task() { + echo "$(node -v 2>/dev/null)" +} + +slimline_section_nodejs_async_task_complete() { + local output="${3}" + slimline_section_nodejs_output="${output}" +} + +slimline_section_nodejs() { if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi - local version="$(node -v 2>/dev/null)" + if [[ -z "${slimline_section_nodejs_output}" ]]; then return; fi + local version="${slimline_section_nodejs_output}" local format="%F{white}[%F{green}⬢ |version|%F{white}]%f" echo "${${SLIMLINE_NODE_FORMAT:-${format}}/|version|/${version}}" } diff --git a/sections/symbol.zsh b/sections/symbol.zsh index 40be9e8..e852c9b 100644 --- a/sections/symbol.zsh +++ b/sections/symbol.zsh @@ -1,4 +1,4 @@ -prompt_slimline_section_symbol() { +slimline_section_symbol() { local event=${1} local format_working="%F{red}∙%f" local format_ready="%F{white}∙%f" diff --git a/sections/time.zsh b/sections/time.zsh index 29eda7a..2133dbe 100644 --- a/sections/time.zsh +++ b/sections/time.zsh @@ -1,4 +1,4 @@ -prompt_slimline_section_time() { +slimline_section_time() { local time_str="%D{%T}" local format="%F{white}|time_str|%f" echo "${${SLIMLINE_TIME_FORMAT:-${format}}/|time_str|/${time_str}}" diff --git a/sections/user_host_info.zsh b/sections/user_host_info.zsh index 316d218..432bb49 100644 --- a/sections/user_host_info.zsh +++ b/sections/user_host_info.zsh @@ -1,5 +1,5 @@ -prompt_slimline_section_user_host_info() { - if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${prompt_slimline_default_user}" ]]; then return; fi +slimline_section_user_host_info() { + if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_default_user}" ]]; then return; fi local user="%n" local host="%m" diff --git a/sections/virtual_env.zsh b/sections/virtual_env.zsh index bbd6c4a..effb5c8 100644 --- a/sections/virtual_env.zsh +++ b/sections/virtual_env.zsh @@ -1,4 +1,4 @@ -prompt_slimline_section_virtual_env() { +slimline_section_virtual_env() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi local virtual_env="${VIRTUAL_ENV##*/}" diff --git a/slimline.zsh b/slimline.zsh index 60f3dbc..122e34e 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -11,30 +11,31 @@ # MIT License #------------------------------------------------------------------------------- -prompt_slimline_path="${0:A:h}" -prompt_slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" +slimline_path="${0:A:h}" +slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" -source "${prompt_slimline_path}/lib/async.zsh" -source "${prompt_slimline_path}/lib/prompt.zsh" -source "${prompt_slimline_path}/lib/section.zsh" +source "${slimline_path}/lib/async.zsh" +source "${slimline_path}/lib/prompt.zsh" +source "${slimline_path}/lib/section.zsh" +source "${slimline_path}/lib/utils.zsh" -prompt_slimline_precmd_async_tasks() { +slimline_precmd_async_tasks() { slimline::async::start_tasks "precmd" } -prompt_slimline_precmd_exit_status() { - prompt_slimline_last_exit_status=$? +slimline_precmd_exit_status() { + slimline_last_exit_status=$? } -prompt_slimline_async_task_complete() { +slimline_async_task_complete() { local event="${1}" - slimline::prompt::set "${event}" "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" + slimline::prompt::set "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" "${event}" zle && zle .reset-prompt } -prompt_slimline_setup() { +slimline_setup() { if (( ${SLIMLINE_PROMPT_VERSION:-1} < 2 )); then - source "${prompt_slimline_path}/lib/legacy.zsh" + source "${slimline_path}/lib/legacy.zsh" slimline::legacy::evaluate_options fi @@ -50,14 +51,14 @@ prompt_slimline_setup() { slimline::section::load "${left_prompt_sections}" "slimline_left_prompt_sections" "slimline_left_prompt_async_tasks" slimline::section::load "${right_prompt_sections}" "slimline_right_prompt_sections" "slimline_right_prompt_async_tasks" - add-zsh-hook precmd prompt_slimline_precmd_async_tasks + add-zsh-hook precmd slimline_precmd_async_tasks - precmd_functions=("prompt_slimline_precmd_exit_status" ${precmd_functions[@]}) + precmd_functions=("slimline_precmd_exit_status" ${precmd_functions[@]}) - slimline::async::init "${slimline_left_prompt_async_tasks} ${slimline_right_prompt_async_tasks}" "prompt_slimline_async_task_complete" + slimline::async::init "${slimline_left_prompt_async_tasks} ${slimline_right_prompt_async_tasks}" "slimline_async_task_complete" - slimline::prompt::set "setup" "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" + slimline::prompt::set "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" "setup" slimline::prompt::set_spelling } -prompt_slimline_setup "$@" +slimline_setup "$@" From 511b6edcec27d75fc71bbc5fdbd185912fa62fbe Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 20:38:37 +0100 Subject: [PATCH 053/107] Rename section package to sections --- lib/prompt.zsh | 4 ++-- lib/{section.zsh => sections.zsh} | 4 ++-- slimline.zsh | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) rename lib/{section.zsh => sections.zsh} (96%) diff --git a/lib/prompt.zsh b/lib/prompt.zsh index cce2339..db80f1d 100644 --- a/lib/prompt.zsh +++ b/lib/prompt.zsh @@ -2,7 +2,7 @@ slimline::prompt::set_left() { local sections="${1}" local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" shift 1 - slimline::section::get_output "${sections}" "${separator}" "slimline_left_prompt_sections_output" "$@" + slimline::sections::get_output "${sections}" "${separator}" "slimline_left_prompt_sections_output" "$@" local format="|sections| " PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${slimline_left_prompt_sections_output}}" @@ -13,7 +13,7 @@ slimline::prompt::set_right() { local sections="${1}" local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" shift 1 - slimline::section::get_output "${sections}" "${separator}" "slimline_right_prompt_sections_output" "$@" + slimline::sections::get_output "${sections}" "${separator}" "slimline_right_prompt_sections_output" "$@" local format="|sections|" RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${slimline_right_prompt_sections_output}}" diff --git a/lib/section.zsh b/lib/sections.zsh similarity index 96% rename from lib/section.zsh rename to lib/sections.zsh index 350f863..4039e7e 100644 --- a/lib/section.zsh +++ b/lib/sections.zsh @@ -1,4 +1,4 @@ -slimline::section::get_output() { +slimline::sections::get_output() { local sections="${1}" local separator="${2}" local var="${3}" @@ -15,7 +15,7 @@ slimline::section::get_output() { typeset -g "${var}"="${(epj:${separator}:)outputs}" } -slimline::section::load() { +slimline::sections::load() { local sections="${1}" local section_var="${2}" local async_tasks_var="${3}" diff --git a/slimline.zsh b/slimline.zsh index 122e34e..9fb6d4c 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -16,7 +16,7 @@ slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" source "${slimline_path}/lib/async.zsh" source "${slimline_path}/lib/prompt.zsh" -source "${slimline_path}/lib/section.zsh" +source "${slimline_path}/lib/sections.zsh" source "${slimline_path}/lib/utils.zsh" slimline_precmd_async_tasks() { @@ -48,8 +48,8 @@ slimline_setup() { autoload -Uz add-zsh-hook - slimline::section::load "${left_prompt_sections}" "slimline_left_prompt_sections" "slimline_left_prompt_async_tasks" - slimline::section::load "${right_prompt_sections}" "slimline_right_prompt_sections" "slimline_right_prompt_async_tasks" + slimline::sections::load "${left_prompt_sections}" "slimline_left_prompt_sections" "slimline_left_prompt_async_tasks" + slimline::sections::load "${right_prompt_sections}" "slimline_right_prompt_sections" "slimline_right_prompt_async_tasks" add-zsh-hook precmd slimline_precmd_async_tasks From 81784d266b750c15c4648aacd75baeaa956f508a Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 20:42:49 +0100 Subject: [PATCH 054/107] Use new naming scheme for sections --- lib/sections.zsh | 10 +++++----- sections/aws_profile.zsh | 2 +- sections/cwd.zsh | 2 +- sections/execution_time.zsh | 6 +++--- sections/exit_status.zsh | 2 +- sections/git.zsh | 10 +++++----- sections/nodejs.zsh | 8 ++++---- sections/symbol.zsh | 2 +- sections/time.zsh | 2 +- sections/user_host_info.zsh | 2 +- sections/virtual_env.zsh | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/sections.zsh b/lib/sections.zsh index 4039e7e..51e6224 100644 --- a/lib/sections.zsh +++ b/lib/sections.zsh @@ -28,18 +28,18 @@ slimline::sections::load() { source "${section_file}" fi - local section_function="slimline_section_${section}" + local section_function="slimline::section::${section}" if (( ! ${+functions[${section_function}]} )); then print -P "%F{red}slimline%f: '${section}' is not a valid section!" continue fi - local section_init_function="${section_function}_init" + local section_init_function="${section_function}::init" if (( ${+functions[${section_init_function}]} )); then if ! ${section_init_function}; then continue; fi fi - local section_async_task_function="${section_function}_async_task" + local section_async_task_function="${section_function}::async_task" if (( ${+functions[${section_async_task_function}]} )); then local section_async_task_complete_function="${section_async_task_function}_complete" if (( ! ${+functions[${section_async_task_complete_function}]} )); then @@ -49,12 +49,12 @@ slimline::sections::load() { async_tasks+="${section_async_task_function}" fi - local section_preexec_function="${section_function}_preexec" + local section_preexec_function="${section_function}::preexec" if (( ${+functions[${section_preexec_function}]} )); then add-zsh-hook preexec "${section_preexec_function}" fi - local section_precmd_function="${section_function}_precmd" + local section_precmd_function="${section_function}::precmd" if (( ${+functions[${section_precmd_function}]} )); then add-zsh-hook precmd "${section_precmd_function}" fi diff --git a/sections/aws_profile.zsh b/sections/aws_profile.zsh index 94f4fbe..ef2769d 100644 --- a/sections/aws_profile.zsh +++ b/sections/aws_profile.zsh @@ -1,4 +1,4 @@ -slimline_section_aws_profile() { +slimline::section::aws_profile() { if [[ -z "${AWS_PROFILE}" ]]; then return; fi local profile="${AWS_PROFILE}" local format="%F{white}[AWS:%F{blue}|profile|%F{white}]%f" diff --git a/sections/cwd.zsh b/sections/cwd.zsh index 94cf409..8b1471a 100644 --- a/sections/cwd.zsh +++ b/sections/cwd.zsh @@ -1,4 +1,4 @@ -slimline_section_cwd() { +slimline::section::cwd() { local path="%3~" local format_root="%F{red}|path|%f" local format="%F{cyan}|path|%f" diff --git a/sections/execution_time.zsh b/sections/execution_time.zsh index 9b08b9e..207b2a4 100644 --- a/sections/execution_time.zsh +++ b/sections/execution_time.zsh @@ -1,8 +1,8 @@ -slimline_section_execution_time_preexec() { +slimline::section::execution_time::preexec() { slimline_section_execution_time_cmd_timestamp=$EPOCHSECONDS } -slimline_section_execution_time_precmd() { +slimline::section::execution_time::precmd() { local integer elapsed (( elapsed = EPOCHSECONDS - ${slimline_section_execution_time_cmd_timestamp:-$EPOCHSECONDS} )) slimline_section_execution_time_output= @@ -13,7 +13,7 @@ slimline_section_execution_time_precmd() { unset slimline_section_execution_time_cmd_timestamp } -slimline_section_execution_time() { +slimline::section::execution_time() { # add elapsed time if threshold is exceeded if [[ -z "${slimline_section_execution_time_output}" ]]; then return; fi local exec_time="${slimline_section_execution_time_output}" diff --git a/sections/exit_status.zsh b/sections/exit_status.zsh index 82a2e8c..8bb4724 100644 --- a/sections/exit_status.zsh +++ b/sections/exit_status.zsh @@ -1,4 +1,4 @@ -slimline_section_exit_status() { +slimline::section::exit_status() { if (( slimline_last_exit_status == 0 )); then return; fi local exit_status=${slimline_last_exit_status} local format="%F{red}|exit_status| ↵%f" diff --git a/sections/git.zsh b/sections/git.zsh index 6b9272a..ea0596f 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -1,17 +1,17 @@ -slimline_section_git_precmd() { +slimline::section::git::precmd() { unset slimline_section_git_output } -slimline_section_git_async_task() { +slimline::section::git::async_task() { command python "${slimline_path}/gitline/gitline.py" --shell=zsh "$*" } -slimline_section_git_async_task_complete() { +slimline::section::git::async_task_complete() { local output=${3} slimline_section_git_output="${output}" } -slimline_section_git_init() { +slimline::section::git::init() { # If python or git are not installed, disable the git functionality. if (( ${+commands[python]} && ${+commands[git]} )); then return 0 @@ -21,7 +21,7 @@ slimline_section_git_init() { return 1 } -slimline_section_git() { +slimline::section::git() { if [[ -z "${slimline_section_git_output}" ]]; then return; fi local output="${slimline_section_git_output}" local format="|output|" diff --git a/sections/nodejs.zsh b/sections/nodejs.zsh index 3f9a4d5..1c10f44 100644 --- a/sections/nodejs.zsh +++ b/sections/nodejs.zsh @@ -1,17 +1,17 @@ -slimline_section_nodejs_precmd() { +slimline::section::nodejs::precmd() { unset slimline_section_nodejs_output } -slimline_section_nodejs_async_task() { +slimline::section::nodejs::async_task() { echo "$(node -v 2>/dev/null)" } -slimline_section_nodejs_async_task_complete() { +slimline::section::nodejs::async_task_complete() { local output="${3}" slimline_section_nodejs_output="${output}" } -slimline_section_nodejs() { +slimline::section::nodejs() { if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi if [[ -z "${slimline_section_nodejs_output}" ]]; then return; fi local version="${slimline_section_nodejs_output}" diff --git a/sections/symbol.zsh b/sections/symbol.zsh index e852c9b..74a5a06 100644 --- a/sections/symbol.zsh +++ b/sections/symbol.zsh @@ -1,4 +1,4 @@ -slimline_section_symbol() { +slimline::section::symbol() { local event=${1} local format_working="%F{red}∙%f" local format_ready="%F{white}∙%f" diff --git a/sections/time.zsh b/sections/time.zsh index 2133dbe..ec5d477 100644 --- a/sections/time.zsh +++ b/sections/time.zsh @@ -1,4 +1,4 @@ -slimline_section_time() { +slimline::section::time() { local time_str="%D{%T}" local format="%F{white}|time_str|%f" echo "${${SLIMLINE_TIME_FORMAT:-${format}}/|time_str|/${time_str}}" diff --git a/sections/user_host_info.zsh b/sections/user_host_info.zsh index 432bb49..67bf1b5 100644 --- a/sections/user_host_info.zsh +++ b/sections/user_host_info.zsh @@ -1,4 +1,4 @@ -slimline_section_user_host_info() { +slimline::section::user_host_info() { if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_default_user}" ]]; then return; fi local user="%n" diff --git a/sections/virtual_env.zsh b/sections/virtual_env.zsh index effb5c8..2e4d2e6 100644 --- a/sections/virtual_env.zsh +++ b/sections/virtual_env.zsh @@ -1,4 +1,4 @@ -slimline_section_virtual_env() { +slimline::section::virtual_env() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi local virtual_env="${VIRTUAL_ENV##*/}" From 3f776b066bee8a7f3556517d56ec34d0c5540639 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 22:11:38 +0100 Subject: [PATCH 055/107] Add convenience function for expanding a template string --- lib/legacy.zsh | 4 ++-- lib/utils.zsh | 8 ++++++++ sections/aws_profile.zsh | 3 +-- sections/cwd.zsh | 3 +-- sections/execution_time.zsh | 5 ++--- sections/exit_status.zsh | 3 +-- sections/git.zsh | 3 +-- sections/nodejs.zsh | 3 +-- sections/time.zsh | 5 ++--- sections/user_host_info.zsh | 4 +--- sections/virtual_env.zsh | 6 ++---- 11 files changed, 22 insertions(+), 25 deletions(-) diff --git a/lib/legacy.zsh b/lib/legacy.zsh index fbf7707..5144133 100644 --- a/lib/legacy.zsh +++ b/lib/legacy.zsh @@ -22,7 +22,7 @@ slimline::legacy::evaluate_options() { left_prompt_sections+=("symbol") if (( ${SLIMLINE_DISPLAY_EXEC_TIME:-1} )); then - SLIMLINE_EXECUTION_TIME_FORMAT="%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}|exec_time|%f" + SLIMLINE_EXECUTION_TIME_FORMAT="%F{${SLIMLINE_EXEC_TIME_COLOR:-yellow}}|time|%f" right_prompt_sections+=("execution_time") fi @@ -38,7 +38,7 @@ slimline::legacy::evaluate_options() { if (( ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )); then local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" - SLIMLINE_VIRTUAL_ENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|virtual_env|%f%F{$parens_color})%f" + SLIMLINE_VIRTUAL_ENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|basename|%f%F{$parens_color})%f" right_prompt_sections+=("virtual_env") fi diff --git a/lib/utils.zsh b/lib/utils.zsh index 6081de6..e8f6036 100644 --- a/lib/utils.zsh +++ b/lib/utils.zsh @@ -18,3 +18,11 @@ slimline::utils::pretty_time() { echo "$human" } + +slimline::utils::expand() { + local template="${1}" + for (( i=2; i < $# ; i+=2 )) ; do + template="${template/|${@[i]}|/${@[i + 1]}}" + done + echo "${template}" +} diff --git a/sections/aws_profile.zsh b/sections/aws_profile.zsh index ef2769d..1a0513f 100644 --- a/sections/aws_profile.zsh +++ b/sections/aws_profile.zsh @@ -1,6 +1,5 @@ slimline::section::aws_profile() { if [[ -z "${AWS_PROFILE}" ]]; then return; fi - local profile="${AWS_PROFILE}" local format="%F{white}[AWS:%F{blue}|profile|%F{white}]%f" - echo "${${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}/|profile|/${profile}}" + slimline::utils::expand "${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}" "profile" "${AWS_PROFILE}" } diff --git a/sections/cwd.zsh b/sections/cwd.zsh index 8b1471a..90c7528 100644 --- a/sections/cwd.zsh +++ b/sections/cwd.zsh @@ -1,5 +1,4 @@ slimline::section::cwd() { - local path="%3~" local format_root="%F{red}|path|%f" local format="%F{cyan}|path|%f" local selected='' @@ -8,5 +7,5 @@ slimline::section::cwd() { else selected="${SLIMLINE_CWD_FORMAT:-${format}}" fi - echo "${selected/|path|/${path}}" + slimline::utils::expand "${selected}" "path" "%3~" } diff --git a/sections/execution_time.zsh b/sections/execution_time.zsh index 207b2a4..b781766 100644 --- a/sections/execution_time.zsh +++ b/sections/execution_time.zsh @@ -16,7 +16,6 @@ slimline::section::execution_time::precmd() { slimline::section::execution_time() { # add elapsed time if threshold is exceeded if [[ -z "${slimline_section_execution_time_output}" ]]; then return; fi - local exec_time="${slimline_section_execution_time_output}" - local format="%F{yellow}|exec_time|%f" - echo "${${SLIMLINE_EXECUTION_TIME_FORMAT:-${format}}/|exec_time|/${exec_time}}" + local format="%F{yellow}|time|%f" + slimline::utils::expand "${SLIMLINE_EXECUTION_TIME_FORMAT:-${format}}" "time" "${slimline_section_execution_time_output}" } diff --git a/sections/exit_status.zsh b/sections/exit_status.zsh index 8bb4724..6c1690a 100644 --- a/sections/exit_status.zsh +++ b/sections/exit_status.zsh @@ -1,6 +1,5 @@ slimline::section::exit_status() { if (( slimline_last_exit_status == 0 )); then return; fi - local exit_status=${slimline_last_exit_status} local format="%F{red}|exit_status| ↵%f" - echo "${${SLIMLINE_EXIT_STATUS_FORMAT:-${format}}/|exit_status|/${exit_status}}" + slimline::utils::expand "${SLIMLINE_EXIT_STATUS_FORMAT:-${format}}" "exit_status" "${slimline_last_exit_status}" } diff --git a/sections/git.zsh b/sections/git.zsh index ea0596f..f406db7 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -23,7 +23,6 @@ slimline::section::git::init() { slimline::section::git() { if [[ -z "${slimline_section_git_output}" ]]; then return; fi - local output="${slimline_section_git_output}" local format="|output|" - echo "${${SLIMLINE_GIT_FORMAT:-${format}}/|output|/${output}}" + slimline::utils::expand "${SLIMLINE_GIT_FORMAT:-${format}}" "output" "${slimline_section_git_output}" } diff --git a/sections/nodejs.zsh b/sections/nodejs.zsh index 1c10f44..454cd2f 100644 --- a/sections/nodejs.zsh +++ b/sections/nodejs.zsh @@ -14,7 +14,6 @@ slimline::section::nodejs::async_task_complete() { slimline::section::nodejs() { if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi if [[ -z "${slimline_section_nodejs_output}" ]]; then return; fi - local version="${slimline_section_nodejs_output}" local format="%F{white}[%F{green}⬢ |version|%F{white}]%f" - echo "${${SLIMLINE_NODE_FORMAT:-${format}}/|version|/${version}}" + slimline::utils::expand "${SLIMLINE_NODEJS_FORMAT:-${format}}" "version" "${slimline_section_nodejs_output}" } diff --git a/sections/time.zsh b/sections/time.zsh index ec5d477..57824f3 100644 --- a/sections/time.zsh +++ b/sections/time.zsh @@ -1,5 +1,4 @@ slimline::section::time() { - local time_str="%D{%T}" - local format="%F{white}|time_str|%f" - echo "${${SLIMLINE_TIME_FORMAT:-${format}}/|time_str|/${time_str}}" + local format="%F{white}|time|%f" + slimline::utils::expand "${SLIMLINE_TIME_FORMAT:-${format}}" "time" "%D{%T}" } diff --git a/sections/user_host_info.zsh b/sections/user_host_info.zsh index 67bf1b5..7032279 100644 --- a/sections/user_host_info.zsh +++ b/sections/user_host_info.zsh @@ -1,8 +1,6 @@ slimline::section::user_host_info() { if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_default_user}" ]]; then return; fi - local user="%n" - local host="%m" local format_root="%F{red}|user|%F{white}@%F{yellow}|host|%f" local format="%F{green}|user|%F{white}@%F{yellow}|host|%f" local selected='' @@ -11,5 +9,5 @@ slimline::section::user_host_info() { else selected="${SLIMLINE_USER_HOST_INFO_FORMAT:-${format}}" fi - echo "${${selected/|user|/${user}}/|host|/${host}}" + slimline::utils::expand "${selected}" "user" "%n" "host" "%m" } diff --git a/sections/virtual_env.zsh b/sections/virtual_env.zsh index 2e4d2e6..91edb0e 100644 --- a/sections/virtual_env.zsh +++ b/sections/virtual_env.zsh @@ -1,7 +1,5 @@ slimline::section::virtual_env() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi - - local virtual_env="${VIRTUAL_ENV##*/}" - local format="%F{white}[VENV:%F{cyan}|virtual_env|%F{white}]%f" - echo "${${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}/|virtual_env|/${virtual_env}}" + local format="%F{white}[VENV:%F{cyan}|basename|%F{white}]%f" + slimline::utils::expand "${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}" "basename" "${VIRTUAL_ENV##*/}" } From e1ca329351826948abc5f3ad333cd70fb90ff59b Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 22:12:04 +0100 Subject: [PATCH 056/107] Reduce the scope of some global variables --- slimline.zsh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/slimline.zsh b/slimline.zsh index 9fb6d4c..ca77ddb 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -56,6 +56,8 @@ slimline_setup() { precmd_functions=("slimline_precmd_exit_status" ${precmd_functions[@]}) slimline::async::init "${slimline_left_prompt_async_tasks} ${slimline_right_prompt_async_tasks}" "slimline_async_task_complete" + unset slimline_left_prompt_async_tasks + unset slimline_right_prompt_async_tasks slimline::prompt::set "${slimline_left_prompt_sections}" "${slimline_right_prompt_sections}" "setup" slimline::prompt::set_spelling From ff8fc3864ee73d7f9e427740ef5b20222121f80f Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 22:49:05 +0100 Subject: [PATCH 057/107] Remove more repeated code --- lib/utils.zsh | 6 ++++-- sections/aws_profile.zsh | 4 ++-- sections/cwd.zsh | 9 +++------ sections/execution_time.zsh | 4 ++-- sections/exit_status.zsh | 4 ++-- sections/git.zsh | 5 ++--- sections/nodejs.zsh | 4 ++-- sections/symbol.zsh | 8 +++----- sections/time.zsh | 3 +-- sections/user_host_info.zsh | 14 +++++++------- sections/virtual_env.zsh | 4 ++-- 11 files changed, 30 insertions(+), 35 deletions(-) diff --git a/lib/utils.zsh b/lib/utils.zsh index e8f6036..9c374c5 100644 --- a/lib/utils.zsh +++ b/lib/utils.zsh @@ -20,8 +20,10 @@ slimline::utils::pretty_time() { } slimline::utils::expand() { - local template="${1}" - for (( i=2; i < $# ; i+=2 )) ; do + local format_name="SLIMLINE_${1:u}_FORMAT" + local default_format="${2}" + local template="${(P)format_name:-${default_format}}" + for (( i=3; i < $# ; i+=2 )) ; do template="${template/|${@[i]}|/${@[i + 1]}}" done echo "${template}" diff --git a/sections/aws_profile.zsh b/sections/aws_profile.zsh index 1a0513f..a0a80ed 100644 --- a/sections/aws_profile.zsh +++ b/sections/aws_profile.zsh @@ -1,5 +1,5 @@ slimline::section::aws_profile() { if [[ -z "${AWS_PROFILE}" ]]; then return; fi - local format="%F{white}[AWS:%F{blue}|profile|%F{white}]%f" - slimline::utils::expand "${SLIMLINE_AWS_PROFILE_FORMAT:-${format}}" "profile" "${AWS_PROFILE}" + slimline::utils::expand "aws_profile" "%F{white}[AWS:%F{blue}|profile|%F{white}]%f" \ + "profile" "${AWS_PROFILE}" } diff --git a/sections/cwd.zsh b/sections/cwd.zsh index 90c7528..d4fcc70 100644 --- a/sections/cwd.zsh +++ b/sections/cwd.zsh @@ -1,11 +1,8 @@ slimline::section::cwd() { - local format_root="%F{red}|path|%f" - local format="%F{cyan}|path|%f" - local selected='' + local -A variables=("path" "%3~") if [[ "$(builtin pwd)" == "/" ]]; then - selected="${SLIMLINE_CWD_ROOT_FORMAT:-${format_root}}" + slimline::utils::expand "cwd_root" "%F{red}|path|%f" ${(kv)variables} else - selected="${SLIMLINE_CWD_FORMAT:-${format}}" + slimline::utils::expand "cwd" "%F{cyan}|path|%f" ${(kv)variables} fi - slimline::utils::expand "${selected}" "path" "%3~" } diff --git a/sections/execution_time.zsh b/sections/execution_time.zsh index b781766..1768d7c 100644 --- a/sections/execution_time.zsh +++ b/sections/execution_time.zsh @@ -16,6 +16,6 @@ slimline::section::execution_time::precmd() { slimline::section::execution_time() { # add elapsed time if threshold is exceeded if [[ -z "${slimline_section_execution_time_output}" ]]; then return; fi - local format="%F{yellow}|time|%f" - slimline::utils::expand "${SLIMLINE_EXECUTION_TIME_FORMAT:-${format}}" "time" "${slimline_section_execution_time_output}" + slimline::utils::expand "execution_time" "%F{yellow}|time|%f" \ + "time" "${slimline_section_execution_time_output}" } diff --git a/sections/exit_status.zsh b/sections/exit_status.zsh index 6c1690a..c882072 100644 --- a/sections/exit_status.zsh +++ b/sections/exit_status.zsh @@ -1,5 +1,5 @@ slimline::section::exit_status() { if (( slimline_last_exit_status == 0 )); then return; fi - local format="%F{red}|exit_status| ↵%f" - slimline::utils::expand "${SLIMLINE_EXIT_STATUS_FORMAT:-${format}}" "exit_status" "${slimline_last_exit_status}" + slimline::utils::expand "exit_status" "%F{red}|exit_status| ↵%f" \ + "exit_status" "${slimline_last_exit_status}" } diff --git a/sections/git.zsh b/sections/git.zsh index f406db7..147498e 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -14,7 +14,7 @@ slimline::section::git::async_task_complete() { slimline::section::git::init() { # If python or git are not installed, disable the git functionality. if (( ${+commands[python]} && ${+commands[git]} )); then - return 0 + return 0 fi print -P "%F{red}slimline%f: python and/or git not installed or not in PATH, disabling git information" @@ -23,6 +23,5 @@ slimline::section::git::init() { slimline::section::git() { if [[ -z "${slimline_section_git_output}" ]]; then return; fi - local format="|output|" - slimline::utils::expand "${SLIMLINE_GIT_FORMAT:-${format}}" "output" "${slimline_section_git_output}" + slimline::utils::expand "git" "|output|" "output" "${slimline_section_git_output}" } diff --git a/sections/nodejs.zsh b/sections/nodejs.zsh index 454cd2f..f2bae21 100644 --- a/sections/nodejs.zsh +++ b/sections/nodejs.zsh @@ -14,6 +14,6 @@ slimline::section::nodejs::async_task_complete() { slimline::section::nodejs() { if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi if [[ -z "${slimline_section_nodejs_output}" ]]; then return; fi - local format="%F{white}[%F{green}⬢ |version|%F{white}]%f" - slimline::utils::expand "${SLIMLINE_NODEJS_FORMAT:-${format}}" "version" "${slimline_section_nodejs_output}" + slimline::utils::expand "nodejs" "%F{white}[%F{green}⬢ |version|%F{white}]%f" \ + "version" "${slimline_section_nodejs_output}" } diff --git a/sections/symbol.zsh b/sections/symbol.zsh index 74a5a06..ca23b8b 100644 --- a/sections/symbol.zsh +++ b/sections/symbol.zsh @@ -1,10 +1,8 @@ slimline::section::symbol() { - local event=${1} - local format_working="%F{red}∙%f" - local format_ready="%F{white}∙%f" + local event="${1}" if [[ "${event}" == "all_tasks_complete" ]]; then - echo "${SLIMLINE_SYMBOL_READY_FORMAT:-${format_ready}}" + slimline::utils::expand "symbol_ready" "%F{white}∙%f" else - echo "${SLIMLINE_SYMBOL_WORKING_FORMAT:-${format_working}}" + slimline::utils::expand "symbol_working" "%F{red}∙%f" fi } diff --git a/sections/time.zsh b/sections/time.zsh index 57824f3..628b20b 100644 --- a/sections/time.zsh +++ b/sections/time.zsh @@ -1,4 +1,3 @@ slimline::section::time() { - local format="%F{white}|time|%f" - slimline::utils::expand "${SLIMLINE_TIME_FORMAT:-${format}}" "time" "%D{%T}" + slimline::utils::expand "time" "%F{white}|time|%f" "time" "%D{%T}" } diff --git a/sections/user_host_info.zsh b/sections/user_host_info.zsh index 7032279..227e5fc 100644 --- a/sections/user_host_info.zsh +++ b/sections/user_host_info.zsh @@ -1,13 +1,13 @@ slimline::section::user_host_info() { - if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_default_user}" ]]; then return; fi + if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && \ + [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_default_user}" ]]; then + return; + fi - local format_root="%F{red}|user|%F{white}@%F{yellow}|host|%f" - local format="%F{green}|user|%F{white}@%F{yellow}|host|%f" - local selected='' + local -A variables=("user" "%n" "host" "%m") if [[ ${UID} -eq 0 ]]; then - selected="${SLIMLINE_USER_HOST_INFO_ROOT_FORMAT:-${format_root}}" + slimline::utils::expand "user_host_info_root" "%F{red}|user|%F{white}@%F{yellow}|host|%f" ${(kv)variables} else - selected="${SLIMLINE_USER_HOST_INFO_FORMAT:-${format}}" + slimline::utils::expand "user_host_info" "%F{green}|user|%F{white}@%F{yellow}|host|%f" ${(kv)variables} fi - slimline::utils::expand "${selected}" "user" "%n" "host" "%m" } diff --git a/sections/virtual_env.zsh b/sections/virtual_env.zsh index 91edb0e..44c8e88 100644 --- a/sections/virtual_env.zsh +++ b/sections/virtual_env.zsh @@ -1,5 +1,5 @@ slimline::section::virtual_env() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi - local format="%F{white}[VENV:%F{cyan}|basename|%F{white}]%f" - slimline::utils::expand "${SLIMLINE_VIRTUAL_ENV_FORMAT:-${format}}" "basename" "${VIRTUAL_ENV##*/}" + slimline::utils::expand "virtual_env" "%F{white}[VENV:%F{cyan}|basename|%F{white}]%f" \ + "basename" "${VIRTUAL_ENV##*/}" } From 1d1c783fcf1e7558487ff970239c3b01dbfd9d5f Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 22:53:28 +0100 Subject: [PATCH 058/107] Add util functions for logging messages --- lib/sections.zsh | 4 ++-- lib/utils.zsh | 12 ++++++++++++ sections/git.zsh | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/sections.zsh b/lib/sections.zsh index 51e6224..3ba2313 100644 --- a/lib/sections.zsh +++ b/lib/sections.zsh @@ -30,7 +30,7 @@ slimline::sections::load() { local section_function="slimline::section::${section}" if (( ! ${+functions[${section_function}]} )); then - print -P "%F{red}slimline%f: '${section}' is not a valid section!" + slimline::utils::error "'${section}' is not a valid section!" continue fi @@ -43,7 +43,7 @@ slimline::sections::load() { if (( ${+functions[${section_async_task_function}]} )); then local section_async_task_complete_function="${section_async_task_function}_complete" if (( ! ${+functions[${section_async_task_complete_function}]} )); then - print -P "%F{red}slimline%f: The async task of section '${section}' has no complete function!" + slimline::utils::error "The async task of section '${section}' has no complete function!" continue fi async_tasks+="${section_async_task_function}" diff --git a/lib/utils.zsh b/lib/utils.zsh index 9c374c5..21a27fb 100644 --- a/lib/utils.zsh +++ b/lib/utils.zsh @@ -28,3 +28,15 @@ slimline::utils::expand() { done echo "${template}" } + +slimline::utils::error() { + print -P "%F{red}slimline%f: ${1}" +} + +slimline::utils::warning() { + print -P "%F{yellow}slimline%f: ${1}" +} + +slimline::utils::info() { + print -P "%F{blue}slimline%f: ${1}" +} diff --git a/sections/git.zsh b/sections/git.zsh index 147498e..91bd99c 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -17,7 +17,7 @@ slimline::section::git::init() { return 0 fi - print -P "%F{red}slimline%f: python and/or git not installed or not in PATH, disabling git information" + slimline::utils::warning "python and/or git not installed or not in PATH, disabling git information" return 1 } From ba83f68bf2a0c1693140abfd0de0f41f3b204ebe Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 23:05:36 +0100 Subject: [PATCH 059/107] Use expand function for prompts --- lib/prompt.zsh | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/prompt.zsh b/lib/prompt.zsh index db80f1d..c06d0b5 100644 --- a/lib/prompt.zsh +++ b/lib/prompt.zsh @@ -2,10 +2,9 @@ slimline::prompt::set_left() { local sections="${1}" local separator="${SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR:- }" shift 1 - slimline::sections::get_output "${sections}" "${separator}" "slimline_left_prompt_sections_output" "$@" - local format="|sections| " - PROMPT="${${SLIMLINE_LEFT_PROMPT_FORMAT:-${format}}/|sections|/${slimline_left_prompt_sections_output}}" + slimline::sections::get_output "${sections}" "${separator}" "slimline_left_prompt_sections_output" "$@" + PROMPT="$(slimline::utils::expand "left_prompt" "|sections| " "sections" "${slimline_left_prompt_sections_output}")" unset slimline_left_prompt_sections_output } @@ -13,19 +12,16 @@ slimline::prompt::set_right() { local sections="${1}" local separator="${SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR:- }" shift 1 - slimline::sections::get_output "${sections}" "${separator}" "slimline_right_prompt_sections_output" "$@" - local format="|sections|" - RPROMPT="${${SLIMLINE_RIGHT_PROMPT_FORMAT:-${format}}/|sections|/${slimline_right_prompt_sections_output}}" + slimline::sections::get_output "${sections}" "${separator}" "slimline_right_prompt_sections_output" "$@" + RPROMPT="$(slimline::utils::expand "right_prompt" "|sections|" "sections" "${slimline_right_prompt_sections_output}")" unset slimline_right_prompt_sections_output } slimline::prompt::set_spelling() { - local from="%R" - local to="%r" - local format="zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? " - local selected="${SLIMLINE_AUTOCORRECT_FORMAT:-${format}}" - SPROMPT="${${selected/|from|/${from}}/|to|/${to}}" + SPROMPT="$(slimline::utils::expand "autocorrect" \ + "zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? " \ + "from" "%R" "to" "%r")" } slimline::prompt::set() { From 28d81bb2555d94e2d91ba5682434804acef07a23 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 23:17:46 +0100 Subject: [PATCH 060/107] Rename variable for better clarity --- lib/async.zsh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/async.zsh b/lib/async.zsh index 33ea8c7..0a6af40 100644 --- a/lib/async.zsh +++ b/lib/async.zsh @@ -4,7 +4,7 @@ slimline::async::init() { fi slimline_async_tasks="${1}" - slimline_async_callback_complete="${2}" + slimline_async_task_complete_callback="${2}" slimline_async_worker_name="prompt_slimline" async_init @@ -23,23 +23,23 @@ slimline::async::callback() { if (( ! has_next )); then if (( slimline_async_tasks_complete == ${#${=slimline_async_tasks}} )); then - ${slimline_async_callback_complete} "all_tasks_complete" + ${slimline_async_task_complete_callback} "all_tasks_complete" else - ${slimline_async_callback_complete} "task_complete" + ${slimline_async_task_complete_callback} "task_complete" fi fi } slimline::async::start_tasks() { if (( ! ${#${=slimline_async_tasks}} )); then - ${slimline_async_callback_complete} "all_tasks_complete" + ${slimline_async_task_complete_callback} "all_tasks_complete" return fi local event="${1}" if [[ "${event}" == "precmd" ]]; then if (( EPOCHREALTIME - ${slimline_async_last_call:-0} <= 0.5 )); then return; fi - ${slimline_async_callback_complete} "precmd" + ${slimline_async_task_complete_callback} "precmd" fi async_flush_jobs "${slimline_async_worker_name}" From 91157628e1040d3ee7f4c025220d5bea65298dcb Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Tue, 6 Mar 2018 23:26:30 +0100 Subject: [PATCH 061/107] Add helper function to check if a symbol is defined --- lib/async.zsh | 2 +- lib/sections.zsh | 12 ++++++------ lib/utils.zsh | 4 ++++ sections/git.zsh | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/async.zsh b/lib/async.zsh index 0a6af40..3caead7 100644 --- a/lib/async.zsh +++ b/lib/async.zsh @@ -1,5 +1,5 @@ slimline::async::init() { - if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} && ! ${+functions[async_init]} && ! ${+functions[async_start_worker]} )); then + if (( ${SLIMLINE_ENABLE_ASYNC_AUTOLOAD:-1} )) && ! slimline::utils::callable "async_init" && ! slimline::utils::callable "async_start_worker"; then source "${slimline_path}/zsh-async/async.zsh" fi diff --git a/lib/sections.zsh b/lib/sections.zsh index 3ba2313..aa8b829 100644 --- a/lib/sections.zsh +++ b/lib/sections.zsh @@ -29,20 +29,20 @@ slimline::sections::load() { fi local section_function="slimline::section::${section}" - if (( ! ${+functions[${section_function}]} )); then + if ! slimline::utils::callable "${section_function}"; then slimline::utils::error "'${section}' is not a valid section!" continue fi local section_init_function="${section_function}::init" - if (( ${+functions[${section_init_function}]} )); then + if slimline::utils::callable "${section_init_function}"; then if ! ${section_init_function}; then continue; fi fi local section_async_task_function="${section_function}::async_task" - if (( ${+functions[${section_async_task_function}]} )); then + if slimline::utils::callable "${section_async_task_function}"; then local section_async_task_complete_function="${section_async_task_function}_complete" - if (( ! ${+functions[${section_async_task_complete_function}]} )); then + if ! slimline::utils::callable "${section_async_task_complete_function}"; then slimline::utils::error "The async task of section '${section}' has no complete function!" continue fi @@ -50,12 +50,12 @@ slimline::sections::load() { fi local section_preexec_function="${section_function}::preexec" - if (( ${+functions[${section_preexec_function}]} )); then + if slimline::utils::callable "${section_preexec_function}"; then add-zsh-hook preexec "${section_preexec_function}" fi local section_precmd_function="${section_function}::precmd" - if (( ${+functions[${section_precmd_function}]} )); then + if slimline::utils::callable "${section_precmd_function}"; then add-zsh-hook precmd "${section_precmd_function}" fi diff --git a/lib/utils.zsh b/lib/utils.zsh index 21a27fb..fb2d15d 100644 --- a/lib/utils.zsh +++ b/lib/utils.zsh @@ -19,6 +19,10 @@ slimline::utils::pretty_time() { echo "$human" } +slimline::utils::callable() { + (( $+commands[$1] || $+functions[$1] )) +} + slimline::utils::expand() { local format_name="SLIMLINE_${1:u}_FORMAT" local default_format="${2}" diff --git a/sections/git.zsh b/sections/git.zsh index 91bd99c..9df750d 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -13,7 +13,7 @@ slimline::section::git::async_task_complete() { slimline::section::git::init() { # If python or git are not installed, disable the git functionality. - if (( ${+commands[python]} && ${+commands[git]} )); then + if slimline::utils::callable "python" && slimline::utils::callable "git"; then return 0 fi From 3208cdcb5dfb122bc4f44b20db803a68e4064f67 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Wed, 14 Mar 2018 18:23:01 +0100 Subject: [PATCH 062/107] Move default user variable into user host section --- sections/user_host_info.zsh | 6 +++++- slimline.zsh | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sections/user_host_info.zsh b/sections/user_host_info.zsh index 227e5fc..041dc4a 100644 --- a/sections/user_host_info.zsh +++ b/sections/user_host_info.zsh @@ -1,6 +1,10 @@ +slimline::section::user_host_info::init() { + slimline_section_user_host_info_default_user="${SLIMLINE_USER_HOST_INFO_DEFAULT_USER:-${USER}}" +} + slimline::section::user_host_info() { if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && \ - [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_default_user}" ]]; then + [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_section_user_host_info_default_user}" ]]; then return; fi diff --git a/slimline.zsh b/slimline.zsh index ca77ddb..4d45ba7 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -12,7 +12,6 @@ #------------------------------------------------------------------------------- slimline_path="${0:A:h}" -slimline_default_user="${SLIMLINE_DEFAULT_USER:-${USER}}" source "${slimline_path}/lib/async.zsh" source "${slimline_path}/lib/prompt.zsh" From 1b95509955e0d72857606c3a79d32baa48854e09 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Wed, 14 Mar 2018 18:23:20 +0100 Subject: [PATCH 063/107] Use new slimline options by default --- slimline.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slimline.zsh b/slimline.zsh index 4d45ba7..30a1794 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -33,7 +33,7 @@ slimline_async_task_complete() { } slimline_setup() { - if (( ${SLIMLINE_PROMPT_VERSION:-1} < 2 )); then + if (( ${SLIMLINE_PROMPT_VERSION:-2} < 2 )); then source "${slimline_path}/lib/legacy.zsh" slimline::legacy::evaluate_options fi From c8a3a8cdf8ad58de6eaef37820bec9ed6fb7e5c4 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Wed, 14 Mar 2018 18:30:11 +0100 Subject: [PATCH 064/107] Add 24h and 12h time format placeholders --- sections/time.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/time.zsh b/sections/time.zsh index 628b20b..e2e2aae 100644 --- a/sections/time.zsh +++ b/sections/time.zsh @@ -1,3 +1,3 @@ slimline::section::time() { - slimline::utils::expand "time" "%F{white}|time|%f" "time" "%D{%T}" + slimline::utils::expand "time" "%F{white}|time24|%f" "time24" "%T" "time12" "%t" } From e24c759aaa98f192d0898c93ab9585e6bdfb9bda Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Wed, 14 Mar 2018 18:45:04 +0100 Subject: [PATCH 065/107] Adjust text for git section in case it is disabled --- sections/git.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/git.zsh b/sections/git.zsh index 9df750d..22faf71 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -17,7 +17,7 @@ slimline::section::git::init() { return 0 fi - slimline::utils::warning "python and/or git not installed or not in PATH, disabling git information" + slimline::utils::warning "python and/or git not installed or not in PATH, disabling git section" return 1 } From 6855f6d09229d3b315584814ed95b4b0a4e12c7c Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Wed, 14 Mar 2018 22:03:12 +0100 Subject: [PATCH 066/107] Rename spelling prompt --- lib/prompt.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/prompt.zsh b/lib/prompt.zsh index c06d0b5..b09b7f0 100644 --- a/lib/prompt.zsh +++ b/lib/prompt.zsh @@ -19,7 +19,7 @@ slimline::prompt::set_right() { } slimline::prompt::set_spelling() { - SPROMPT="$(slimline::utils::expand "autocorrect" \ + SPROMPT="$(slimline::utils::expand "spelling_prompt" \ "zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? " \ "from" "%R" "to" "%r")" } From e772b13a314b19500bd98d00ef21508258709bd8 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Wed, 14 Mar 2018 23:04:36 +0100 Subject: [PATCH 067/107] Use render function for prompts and rename some local variables --- lib/sections.zsh | 35 ++++++++++++++++++----------------- sections/aws_profile.zsh | 2 +- sections/cwd.zsh | 2 +- sections/execution_time.zsh | 2 +- sections/exit_status.zsh | 2 +- sections/git.zsh | 2 +- sections/nodejs.zsh | 2 +- sections/symbol.zsh | 2 +- sections/time.zsh | 2 +- sections/user_host_info.zsh | 2 +- sections/virtual_env.zsh | 2 +- 11 files changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/sections.zsh b/lib/sections.zsh index aa8b829..7adb3f2 100644 --- a/lib/sections.zsh +++ b/lib/sections.zsh @@ -28,38 +28,39 @@ slimline::sections::load() { source "${section_file}" fi - local section_function="slimline::section::${section}" - if ! slimline::utils::callable "${section_function}"; then + local section_namespace="slimline::section::${section}" + local render_function="${section_namespace}::render" + if ! slimline::utils::callable "${render_function}"; then slimline::utils::error "'${section}' is not a valid section!" continue fi - local section_init_function="${section_function}::init" - if slimline::utils::callable "${section_init_function}"; then - if ! ${section_init_function}; then continue; fi + local init_function="${section_namespace}::init" + if slimline::utils::callable "${init_function}"; then + if ! ${init_function}; then continue; fi fi - local section_async_task_function="${section_function}::async_task" - if slimline::utils::callable "${section_async_task_function}"; then - local section_async_task_complete_function="${section_async_task_function}_complete" - if ! slimline::utils::callable "${section_async_task_complete_function}"; then + local async_task_function="${section_namespace}::async_task" + if slimline::utils::callable "${async_task_function}"; then + local async_task_complete_function="${async_task_function}_complete" + if ! slimline::utils::callable "${async_task_complete_function}"; then slimline::utils::error "The async task of section '${section}' has no complete function!" continue fi - async_tasks+="${section_async_task_function}" + async_tasks+="${async_task_function}" fi - local section_preexec_function="${section_function}::preexec" - if slimline::utils::callable "${section_preexec_function}"; then - add-zsh-hook preexec "${section_preexec_function}" + local preexec_function="${section_namespace}::preexec" + if slimline::utils::callable "${preexec_function}"; then + add-zsh-hook preexec "${preexec_function}" fi - local section_precmd_function="${section_function}::precmd" - if slimline::utils::callable "${section_precmd_function}"; then - add-zsh-hook precmd "${section_precmd_function}" + local precmd_function="${section_namespace}::precmd" + if slimline::utils::callable "${precmd_function}"; then + add-zsh-hook precmd "${precmd_function}" fi - expanded_sections+="${section_function}" + expanded_sections+="${render_function}" done typeset -g "${section_var}"="${(j: :)expanded_sections}" diff --git a/sections/aws_profile.zsh b/sections/aws_profile.zsh index a0a80ed..66f67a7 100644 --- a/sections/aws_profile.zsh +++ b/sections/aws_profile.zsh @@ -1,4 +1,4 @@ -slimline::section::aws_profile() { +slimline::section::aws_profile::render() { if [[ -z "${AWS_PROFILE}" ]]; then return; fi slimline::utils::expand "aws_profile" "%F{white}[AWS:%F{blue}|profile|%F{white}]%f" \ "profile" "${AWS_PROFILE}" diff --git a/sections/cwd.zsh b/sections/cwd.zsh index d4fcc70..ee89f99 100644 --- a/sections/cwd.zsh +++ b/sections/cwd.zsh @@ -1,4 +1,4 @@ -slimline::section::cwd() { +slimline::section::cwd::render() { local -A variables=("path" "%3~") if [[ "$(builtin pwd)" == "/" ]]; then slimline::utils::expand "cwd_root" "%F{red}|path|%f" ${(kv)variables} diff --git a/sections/execution_time.zsh b/sections/execution_time.zsh index 1768d7c..3adc70e 100644 --- a/sections/execution_time.zsh +++ b/sections/execution_time.zsh @@ -13,7 +13,7 @@ slimline::section::execution_time::precmd() { unset slimline_section_execution_time_cmd_timestamp } -slimline::section::execution_time() { +slimline::section::execution_time::render() { # add elapsed time if threshold is exceeded if [[ -z "${slimline_section_execution_time_output}" ]]; then return; fi slimline::utils::expand "execution_time" "%F{yellow}|time|%f" \ diff --git a/sections/exit_status.zsh b/sections/exit_status.zsh index c882072..d2c1e0b 100644 --- a/sections/exit_status.zsh +++ b/sections/exit_status.zsh @@ -1,4 +1,4 @@ -slimline::section::exit_status() { +slimline::section::exit_status::render() { if (( slimline_last_exit_status == 0 )); then return; fi slimline::utils::expand "exit_status" "%F{red}|exit_status| ↵%f" \ "exit_status" "${slimline_last_exit_status}" diff --git a/sections/git.zsh b/sections/git.zsh index 22faf71..25339cc 100644 --- a/sections/git.zsh +++ b/sections/git.zsh @@ -21,7 +21,7 @@ slimline::section::git::init() { return 1 } -slimline::section::git() { +slimline::section::git::render() { if [[ -z "${slimline_section_git_output}" ]]; then return; fi slimline::utils::expand "git" "|output|" "output" "${slimline_section_git_output}" } diff --git a/sections/nodejs.zsh b/sections/nodejs.zsh index f2bae21..c1603be 100644 --- a/sections/nodejs.zsh +++ b/sections/nodejs.zsh @@ -11,7 +11,7 @@ slimline::section::nodejs::async_task_complete() { slimline_section_nodejs_output="${output}" } -slimline::section::nodejs() { +slimline::section::nodejs::render() { if [[ ! -f "package.json" && ! -d "node_modules" ]]; then return; fi if [[ -z "${slimline_section_nodejs_output}" ]]; then return; fi slimline::utils::expand "nodejs" "%F{white}[%F{green}⬢ |version|%F{white}]%f" \ diff --git a/sections/symbol.zsh b/sections/symbol.zsh index ca23b8b..bfe2e5b 100644 --- a/sections/symbol.zsh +++ b/sections/symbol.zsh @@ -1,4 +1,4 @@ -slimline::section::symbol() { +slimline::section::symbol::render() { local event="${1}" if [[ "${event}" == "all_tasks_complete" ]]; then slimline::utils::expand "symbol_ready" "%F{white}∙%f" diff --git a/sections/time.zsh b/sections/time.zsh index e2e2aae..e09516b 100644 --- a/sections/time.zsh +++ b/sections/time.zsh @@ -1,3 +1,3 @@ -slimline::section::time() { +slimline::section::time::render() { slimline::utils::expand "time" "%F{white}|time24|%f" "time24" "%T" "time12" "%t" } diff --git a/sections/user_host_info.zsh b/sections/user_host_info.zsh index 041dc4a..d39b80c 100644 --- a/sections/user_host_info.zsh +++ b/sections/user_host_info.zsh @@ -2,7 +2,7 @@ slimline::section::user_host_info::init() { slimline_section_user_host_info_default_user="${SLIMLINE_USER_HOST_INFO_DEFAULT_USER:-${USER}}" } -slimline::section::user_host_info() { +slimline::section::user_host_info::render() { if (( ! ${SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO:-0} )) && \ [[ -z "${SSH_TTY}" && "${USER}" == "${slimline_section_user_host_info_default_user}" ]]; then return; diff --git a/sections/virtual_env.zsh b/sections/virtual_env.zsh index 44c8e88..0260f51 100644 --- a/sections/virtual_env.zsh +++ b/sections/virtual_env.zsh @@ -1,4 +1,4 @@ -slimline::section::virtual_env() { +slimline::section::virtual_env::render() { if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi slimline::utils::expand "virtual_env" "%F{white}[VENV:%F{cyan}|basename|%F{white}]%f" \ "basename" "${VIRTUAL_ENV##*/}" From 1c810b43a579b2e9ab44bac7edfa4a8c93d01f48 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Wed, 14 Mar 2018 23:05:43 +0100 Subject: [PATCH 068/107] Use command builtin instead of command substitution --- sections/nodejs.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/nodejs.zsh b/sections/nodejs.zsh index c1603be..9440f86 100644 --- a/sections/nodejs.zsh +++ b/sections/nodejs.zsh @@ -3,7 +3,7 @@ slimline::section::nodejs::precmd() { } slimline::section::nodejs::async_task() { - echo "$(node -v 2>/dev/null)" + command node -v 2>/dev/null } slimline::section::nodejs::async_task_complete() { From ba1357d3e09cb0cd10b51ad5c871d3b4a66245a3 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Thu, 15 Mar 2018 11:07:12 +0100 Subject: [PATCH 069/107] Rename virtual_env section back to virtualenv --- sections/virtual_env.zsh | 5 ----- sections/virtualenv.zsh | 5 +++++ slimline.zsh | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 sections/virtual_env.zsh create mode 100644 sections/virtualenv.zsh diff --git a/sections/virtual_env.zsh b/sections/virtual_env.zsh deleted file mode 100644 index 0260f51..0000000 --- a/sections/virtual_env.zsh +++ /dev/null @@ -1,5 +0,0 @@ -slimline::section::virtual_env::render() { - if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi - slimline::utils::expand "virtual_env" "%F{white}[VENV:%F{cyan}|basename|%F{white}]%f" \ - "basename" "${VIRTUAL_ENV##*/}" -} diff --git a/sections/virtualenv.zsh b/sections/virtualenv.zsh new file mode 100644 index 0000000..c52d397 --- /dev/null +++ b/sections/virtualenv.zsh @@ -0,0 +1,5 @@ +slimline::section::virtualenv::render() { + if [[ -z "${VIRTUAL_ENV}" ]]; then return; fi + slimline::utils::expand "virtualenv" "%F{white}[VENV:%F{cyan}|basename|%F{white}]%f" \ + "basename" "${VIRTUAL_ENV##*/}" +} diff --git a/slimline.zsh b/slimline.zsh index 30a1794..36a0518 100644 --- a/slimline.zsh +++ b/slimline.zsh @@ -39,7 +39,7 @@ slimline_setup() { fi local left_prompt_sections="${SLIMLINE_LEFT_PROMPT_SECTIONS-user_host_info cwd symbol}" - local right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtual_env nodejs}" + local right_prompt_sections="${SLIMLINE_RIGHT_PROMPT_SECTIONS-execution_time exit_status git aws_profile virtualenv nodejs}" prompt_opts=(cr percent subst) zmodload zsh/datetime From 146e94d0aef454e41d63c383b66634bd96fa16b2 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Thu, 15 Mar 2018 11:12:23 +0100 Subject: [PATCH 070/107] Fix references to virtual_env --- lib/legacy.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/legacy.zsh b/lib/legacy.zsh index 5144133..4534dbf 100644 --- a/lib/legacy.zsh +++ b/lib/legacy.zsh @@ -38,8 +38,8 @@ slimline::legacy::evaluate_options() { if (( ${SLIMLINE_DISPLAY_VIRTUALENV:-1} )); then local parens_color="${SLIMLINE_VIRTUALENV_PARENS_COLOR:-white}" - SLIMLINE_VIRTUAL_ENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|basename|%f%F{$parens_color})%f" - right_prompt_sections+=("virtual_env") + SLIMLINE_VIRTUALENV_FORMAT="%F{$parens_color}(%f%F{${SLIMLINE_VIRTUALENV_COLOR:-cyan}}|basename|%f%F{$parens_color})%f" + right_prompt_sections+=("virtualenv") fi SLIMLINE_AUTOCORRECT_FORMAT="zsh: correct %F{${SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR:-red}}|from|%f to %F{${SLIMLINE_AUTOCORRECT_PROPOSED_COLOR:-green}}|to|%f [nyae]? " From 502b72e6553bbaff51cf88579edf3f4ce3e8fd41 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Thu, 15 Mar 2018 11:13:26 +0100 Subject: [PATCH 071/107] Adapt readme for new slimline (not finished) --- README.md | 331 ++++++++++++++++++++++++++++++++-------------- legacy_options.md | 145 ++++++++++++++++++++ 2 files changed, 380 insertions(+), 96 deletions(-) create mode 100644 legacy_options.md diff --git a/README.md b/README.md index 5edece9..5d28428 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,25 @@ -# slimline +## slimline -Minimal, fast and elegant ZSH prompt. Displays the right information at the right time. +Modular, fast and elegant ZSH prompt. Displays the right information at the right time. Features: - sleek look -- customizable non-blocking git information display -- prompt symbol indicates if prompt background tasks are running +- modular layout using configurable sections in the left and right prompt +- the appearance of each section can be customized using format strings +- easily extensible using custom sections (which can be optionally asynchronous) +- fast non-blocking prompt using asynchronous information display + +Sections: +- prompt symbol which indicates if asynchronous tasks are running +- current working directory which highlights if it is the root `/` directory - exit code of last command if the exit code is not zero - runtime of executed command if it exceeds a threshold -- username and host name if connected to a ssh server -- very customizable +- username and hostname if connected to a ssh server or optionally always +- current time of day in 24h or 12h format +- current aws profile +- current python virtualenv +- nodejs version configured for the current directory +- customizable git information display @@ -17,10 +27,9 @@ With most information (connected to ssh server, runtime and exit status from las -For a fish compatible version of this theme have a look at [slimfish](https://github.com/mgee/slimfish). - -## Table Of Contents + +- [slimline](#slimline) - [Requirements](#requirements) - [Optional](#optional) - [Installation](#installation) @@ -28,22 +37,44 @@ For a fish compatible version of this theme have a look at [slimfish](https://gi - [zplugin](#zplugin) - [zgen](#zgen) - [Manually](#manually) -- [Options](#options) - - [Prompt Symbol](#prompt-symbol) - - [Current Working Directory](#current-working-directory) - - [Exit Status](#exit-status) - - [Execution Time](#execution-time) - - [User and Host Info](#user-and-host-info) - - [AWS Profile Info](#aws-profile-info) - - [Auto Correction](#auto-correction) - - [Python Virtualenv](#python-virtualenv) - - [Async Autoloading](#async-autoloading) - - [Git Information](#git-information) - - [Gitline](#gitline) +- [Sections and Formats](#sections-and-formats) +- [Legacy Options](#legacy-options) +- [Global Options](#global-options) + - [Left Prompt](#left-prompt) + - [Right Prompt](#right-prompt) + - [Spelling Prompt](#spelling-prompt) +- [Built-in Sections](#built-in-sections) + - [Prompt Symbol (`symbol`)](#prompt-symbol-symbol) + - [Current Working Directory (`cwd`)](#current-working-directory-cwd) + - [Exit Status (`exit_status`)](#exit-status-exit_status) + - [Execution Time (`execution_time`)](#execution-time-execution_time) + - [User and Host Info (`user_host_info`)](#user-and-host-info-user_host_info) + - [Time (`time`)](#time-time) + - [AWS Profile (`aws_profile`)](#aws-profile-aws_profile) + - [Python Virtualenv (`virtualenv`)](#python-virtualenv-virtualenv) + - [Node.js (`nodejs`) *async*](#nodejs-nodejs-async) + - [Git (`git`) *async*](#git-git-async) +- [Custom Sections](#custom-sections) + - [Functions](#functions) + - [Render](#render) + - [Init](#init) + - [Preexec](#preexec) + - [Precmd](#precmd) + - [Async Task](#async-task) + - [Utility Functions](#utility-functions) + - [Section Format Expansion](#section-format-expansion) + - [Logging](#logging) + - [Callable Check](#callable-check) + - [Examples](#examples) + - [Minimal Section](#minimal-section) + - [Section with init function](#section-with-init-function) + - [Section with asynchronous task](#section-with-asynchronous-task) - [Example](#example) - [Thanks](#thanks) - [License](#license) + + ## Requirements * zsh @@ -56,19 +87,19 @@ For a fish compatible version of this theme have a look at [slimfish](https://gi Choose one of the methods below. -### [antigen](https://github.com/zsh-users/antigen) +### antigen ``` antigen bundle mgee/slimline ``` -### [zplugin](https://github.com/zdharma/zplugin) +### zplugin ``` zplugin load mgee/slimline ``` -### [zgen](https://github.com/tarjoilija/zgen) +### zgen ``` zgen load mgee/slimline @@ -88,139 +119,244 @@ Source the prompt in your `.zshrc` (or other appropriate) file: source /slimline.zsh ``` -## Options +## Sections and Formats -Slimline can be customized using a variety of environment variables. -For an example on how to do so see the [example](#example). +Slimline has two prompts. The left and right prompt. In each prompt sections can be placed and +ordered. The appearance of each section can be completely customized. -### Prompt Symbol +A section displays information like the current directory or the git status. Slimline provides +a number of sections by default but can also be extended with [custom sections](#custom-sections). +Each sections has a format string which can be customized to change the color or text +inside the section. -##### `SLIMLINE_PROMPT_SYMBOL` +Inside the format of the section placeholders can be used which will be replaced with information +specific to this section. Placeholders are enclosed in pipes `|`, eg. the placeholder `|path|` +in the [`cwd` section](#current-working-directory-cwd). -Defines the symbol of the prompt. Default is `∙`. +## Legacy Options -##### `SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING` +Slimline uses a new option format but supports the previous options as fallback by setting +`SLIMLINE_PROMPT_VERSION` to `1`: +```shell +export SLIMLINE_PROMPT_VERSION=1 # Activate legacy option format +``` -Defines the color of the prompt when asynchronous tasks are running. Default is `red`. +The legacy options are described [here](legacy_options.md). -##### `SLIMLINE_PROMPT_SYMBOL_COLOR_READY` +## Global Options -Defines the color of the prompt when all asynchronous tasks are finished. Default is `white`. +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_PROMPT_VERSION` | `2` | The version of the prompt options. To use the legacy options described [here](legacy_options.md) set it to `1`. | +| `SLIMLINE_ENABLE_ASYNC_AUTOLOAD` | `1` | Defines whether [zsh-async](https://github.com/mafredri/zsh-async) should be automatically sourced if it was not already sourced. Disabling the automatic loading is useful if zsh-async is installed globally and therefore already loaded (e.g. via antigen or zplugin). | -### Current Working Directory +### Left Prompt -##### `SLIMLINE_CWD_COLOR` +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_LEFT_PROMPT_SECTIONS` | `user_host_info cwd symbol` | The sections to use in the left prompt. | +| `SLIMLINE_LEFT_PROMPT_SECTION_SEPARATOR` | ` ` | The separator between each section. | +| `SLIMLINE_LEFT_PROMPT_FORMAT` | `|sections| ` | The format string for the left prompt (notice the space at the end). The `|sections|` placeholder will be replaced with the section output. | -Defines the color of the current working directory. Default is `cyan`. +### Right Prompt -##### `SLIMLINE_CWD_ROOT_COLOR` +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_RIGHT_PROMPT_SECTIONS` | `execution_time exit_status git aws_profile virtual_env nodejs` | The sections to use in the right prompt. | +| `SLIMLINE_RIGHT_PROMPT_SECTION_SEPARATOR` | ` ` | The separator between each section. | +| `SLIMLINE_RIGHT_PROMPT_FORMAT` | `|sections|` | The format string for the right prompt. The `|sections|` placeholder will be replaced with the section output. | -Defines the color of the current working directory if it equals the root directory `/`. Default is `red`. +### Spelling Prompt -### Exit Status +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_SPELLING_PROMPT_FORMAT` | `zsh: correct %F{red}|from|%f to %F{green}|to|%f [nyae]? ` | The format string for spelling prompt which is shown for auto correction. The `|from|` placeholder will be replaced with the incorrect command and `|to|` with the correction. | -##### `SLIMLINE_DISPLAY_EXIT_STATUS` +## Built-in Sections -Defines whether the exit status is displayed if the exit code is not zero. Default is `1`. +### Prompt Symbol (`symbol`) -##### `SLIMLINE_EXIT_STATUS_SYMBOL` +The section displayes the prompt symbol. It supports two formats. The *working* format is used when asynchronous tasks are +pending and the *ready format for when all tasks are completed. -Defines the symbol of the exit status glyph. Default is `↵`. +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_SYMBOL_WORKING_FORMAT` | `%F{red}∙%f` | The format to use for the symbol when there are asynchronous tasks pending. | +| `SLIMLINE_SYMBOL_READY_FORMAT` | `%F{white}∙%f` | The format to use for the symbol when all asynchronous tasks have completed. | -##### `SLIMLINE_EXIT_STATUS_COLOR` +### Current Working Directory (`cwd`) -Defines the color of the exit status information. Default is `red`. +This section displays the current working directory. It supports two formats. +The *root* format is used when the cwd is the root path and the other format when it is not. -### Execution Time +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_CWD_FORMAT` | `%F{cyan}|path|%f` | The format to use when the current working directory is in a normal directory (not the root path `/`). The placeholder for the path is `|path|`. | +| `SLIMLINE_CWD_ROOT_FORMAT` | `%F{red}|path|%f` | The format to use when the current working directory is in the root path `/`. The placeholder for the path is `|path|`. | -##### `SLIMLINE_DISPLAY_EXEC_TIME` +### Exit Status (`exit_status`) -Defines whether the runtime of a process is displayed if it exceeds the maximum execution time -specified by the option below. Default is `1`. +The section displays the exit status of the last command if it is != 0. -##### `SLIMLINE_MAX_EXEC_TIME` +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_EXIT_STATUS_FORMAT` | `%F{red}|exit_status| ↵%f` | The format to use when the exit status of the last command is != 0. The placeholder for the exit status value is `|exit_status|`. | -Defines the maximum execution time of a process until its run time is displayed on exit. -Default is `5` seconds. +### Execution Time (`execution_time`) -##### `SLIMLINE_EXEC_TIME_COLOR` +The execution time of the last command if it exceeds the configurable threshold. -Defines the color of the execution time. Default is `yellow`. +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_MAX_EXEC_TIME` | `5` | The maximum execution time of a process in seconds until its run time is displayed on exit. | +| `SLIMLINE_EXECUTION_TIME_FORMAT` | `%F{yellow}|time|%f` | The format of the execution time display. The placeholder for the execution time in seconds is `|time|`. | -### User and Host Info +### User and Host Info (`user_host_info`) -##### `SLIMLINE_DISPLAY_USER_HOST_INFO` +This section displays user and host information and supports two formats. +The *root* format is used if the current user is root. +By default the user and host information is only displayed if the user is different than the +default user or if there is an active ssh session. -Defines whether the `user@host` part is displayed if the user differs from the default user or if connected to a ssh server. Default is `1`. +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_ALWAYS_SHOW_USER_HOST_INFO` | `0` | Defines whether the user and host information should always be displayed. | +| `SLIMLINE_USER_HOST_INFO_DEFAULT_USER` | `$USER` | The default user for this prompt. This is used to hide the user and host name if the current user is the same as the default user. | +| `SLIMLINE_USER_HOST_INFO_FORMAT` | `%F{green}|user|%F{white}@%F{yellow}|host|%f` | The format of user and host info if the user is **not** root. The placeholder for the username is `|user|` and for the hostname is `|host|`. | +| `SLIMLINE_USER_HOST_INFO_ROOT_FORMAT` | `%F{red}|user|%F{white}@%F{yellow}|host|%f` | The format of user and host info if the user **is** root. The placeholder for the username is `|user|` and for the hostname is `|host|`. | -##### `SLIMLINE_USER_COLOR` +### Time (`time`) -Defines the color of the user. Default is `green`. +This section displays the current time in 24h format and is disabled by default. +To use it add it to your left or right prompt manually. To use the 12h time format use the `|time12|` placeholder. -##### `SLIMLINE_USER_ROOT_COLOR` +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_TIME_FORMAT` | `%F{white}|time24|%f` | The format to use for displaying the time of day. The placeholder for the time in 24h format is `|time24|`. The placeholder for the time in 12h format is `|time12|`. | -Defines the color of the user if the user is root. Default is `red`. +### AWS Profile (`aws_profile`) -##### `SLIMLINE_HOST_COLOR` +This section displays the current aws profile detected via the `$AWS_PROFILE` environment variable. -Defines the color of the host. Default is `yellow`. +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_AWS_PROFILE_FORMAT` | `%F{white}[AWS:%F{blue}|profile|%F{white}]%f` | The format to use for displaying the aws profile. The placeholder for the profile is `|profile|`. | -##### `SLIMLINE_DEFAULT_USER` +### Python Virtualenv (`virtualenv`) -Username to consider as the default user. By default this is the current effective user (i.e. the output of `whoami`) +This section displays the current python virtual env detected via the `$VIRTUAL_ENV` environment variable. -### AWS Profile Info +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_VIRTUALENV_FORMAT` | `%F{white}[VENV:%F{cyan}|basename|%F{white}]%f` | The format to use for displaying the virtual env information. The placeholder for the basename of the virtual env is `|basename|`. | -##### `SLIMLINE_DISPLAY_AWS_INFO` +### Node.js (`nodejs`) *async* -Defines whether value of `AWS_PROFILE` environment variable should be displayed. Default is `0`. +This section displays the nodejs version if the current directory contains a `package.json` file or `node_modules` directory. -##### `SLIMLINE_AWS_COLOR` +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_NODEJS_FORMAT` | `%F{white}[%F{green}⬢ |version|%F{white}]%f` | The format to use for displaying the nodejs information. The placeholder for the configured version of nodejs is `|version|`. | -Defines the color of aws profile info. Default is `blue`. +### Git (`git`) *async* -### Auto Correction +This section displays various git status information. +It uses [gitline](https://github.com/mgee/gitline) to acquire and format the git information. +gitline can be extensively customized. Have a look at the [gitline options](https://github.com/mgee/gitline#options). -##### `SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR` +Additionally this section has the following options: -Defines the color of the misspelled string for which is correction is proposed. Default is `red`. +| Variable | Default | Meaning | +| :------- | :-----: | ------- | +| `SLIMLINE_GIT_FORMAT` | `|output|` | The format to use for the git status information. The placeholder `|output|` is +replaced with the output from gitline. -##### `SLIMLINE_AUTOCORRECT_PROPOSED_COLOR` +## Custom Sections -Defines the color of the proposed correction of a misspelled string. Default is `green`. +Custom sections can be easily written by following the slimline section naming scheme. +This way sections are automatically discovered and can execute asynchronous tasks easily. -### Python Virtualenv +Sections use the namespace `slimline::section::` where name is replaced by the +section name. Each section needs at least a `render` function. +For a section with the name `foo` the render function is named `slimline::section::foo::render`. -##### `SLIMLINE_DISPLAY_VIRTUALENV` +A section can have the following functions: +| Function | Required | Meaning | +| :------- | :-----: | ------- | +| `slimline::section::::render` | **yes** | This function is used to display information in the prompt. | +| `slimline::section::::init` | **no** | This function can initialize data and check for requirements for the section. If the function returns `0` the section will be loaded. In case the section shall be deactivated return `1` instead. | +| `slimline::section::::preexec` | **no** | If the function is defined it will be executed right before a new command in zsh is executed. | +| `slimline::section::::precmd` | **no** | If the function is defined it will be executed before the prompt render functions. | +| `slimline::section::::async_task` | **no** | This function will be executed asynchronously by zsh-async and its output will be available in the `async_task_complete` function. +| `slimline::section::::async_task_complete` | **no** | This function is not required except when the `async_task` function is defined. This function will receive the output of the `async_task` function and other information. | -Defines whether active python virtualenv shall be displayed. Default is `1`. +### Functions -##### `SLIMLINE_VIRTUALENV_COLOR` +#### Render -Defines the color of the virtualenv name. Default is `cyan`. +#### Init -##### `SLIMLINE_VIRTUALENV_PARENS_COLOR` +#### Preexec -Defines the color of the parens surrounding the virtualenv name. Default is `white`. +#### Precmd -### Async Autoloading +#### Async Task -##### `SLIMLINE_ENABLE_ASYNC_AUTOLOAD` +### Utility Functions -Defines whether [zsh-async](https://github.com/mafredri/zsh-async) should be automatically -sourced if it was not already sourced. Disabling the automatic loading is useful if zsh-async -is installed globally and therefore already loaded (e.g. via antigen or zplugin). Default is `1`. +#### Section Format Expansion -### Git Information +#### Logging -##### `SLIMLINE_ENABLE_GIT` +#### Callable Check -Defines whether git information shall be displayed (requires python). Default is `1`. +### Examples -#### Gitline +#### Minimal Section -slimline uses [gitline](https://github.com/mgee/gitline) to display git information. -gitline can be extensively customized. Have a look at the [gitline options](https://github.com/mgee/gitline#options). +#### Section with init function + +```shell +slimline::section::foo::init() { + if slimline::utils::callable "ruby"; then + return 0 # Ok, section can be loaded + fi + + slimline::utils::warning "ruby not installed or not in PATH, disabling foo section" + return 1 # Disable the section +} + +slimline::section::foo::render() { + echo "%F{blue}bar%f" +} + +# Add it to the right prompt +export SLIMLINE_RIGHT_PROMPT_SECTIONS="foo execution_time exit_status git aws_profile virtual_env nodejs" +``` + +#### Section with asynchronous task + +```shell +slimline::section::foo::precmd() { + unset slimline_section_foo_output +} + +slimline::section::foo::async_task() { + sleep 2 + echo "bar" +} + +slimline::section::foo::async_task_complete() { + slimline_section_foo_output=$3 +} + +slimline::section::foo::render() { + echo "${slimline_section_foo_output}" +} + +# Add it to the right prompt +export SLIMLINE_RIGHT_PROMPT_SECTIONS="foo execution_time exit_status git aws_profile virtual_env nodejs" +``` ## Example @@ -228,12 +364,14 @@ Here is an example for customizing the prompt symbol as well as the git reposito branch format: ```shell -export SLIMLINE_PROMPT_SYMBOL='$' +export SLIMLINE_SYMBOL_READY_FORMAT="%F{white}\$%f" +export SLIMLINE_SYMBOL_WORKING_FORMAT="%F{red}\$%f" + # If you have a powerline compatible font you can also use the alternative repo indicator ''. export GITLINE_REPO_INDICATOR='${reset}git' export GITLINE_BRANCH='[${blue}${branch}${reset}]' -source "/slimline.plugin.zsh" +source "/slimline.zsh" ``` @@ -242,6 +380,7 @@ source "/slimline.plugin.zsh" - [mafredri/zsh-async](https://github.com/mafredri/zsh-async) - [sindresorhus/pure](https://github.com/sindresorhus/pure) +- [denysdovhan/spaceship-prompt](https://github.com/denysdovhan/spaceship-prompt) - [sorin-ionescu/prezto](https://github.com/sorin-ionescu/prezto.git) ## License diff --git a/legacy_options.md b/legacy_options.md new file mode 100644 index 0000000..2da7882 --- /dev/null +++ b/legacy_options.md @@ -0,0 +1,145 @@ +## Legacy Options + +Slimline can be customized using a variety of environment variables. +For an example on how to do so see the [example](#example). + +- [Prompt Symbol](#prompt-symbol) +- [Current Working Directory](#current-working-directory) +- [Exit Status](#exit-status) +- [Execution Time](#execution-time) +- [User and Host Info](#user-and-host-info) +- [AWS Profile Info](#aws-profile-info) +- [Auto Correction](#auto-correction) +- [Python Virtualenv](#python-virtualenv) + +### Prompt Symbol + +##### `SLIMLINE_PROMPT_SYMBOL` + +Defines the symbol of the prompt. Default is `∙`. + +##### `SLIMLINE_PROMPT_SYMBOL_COLOR_WORKING` + +Defines the color of the prompt when asynchronous tasks are running. Default is `red`. + +##### `SLIMLINE_PROMPT_SYMBOL_COLOR_READY` + +Defines the color of the prompt when all asynchronous tasks are finished. Default is `white`. + +### Current Working Directory + +##### `SLIMLINE_CWD_COLOR` + +Defines the color of the current working directory. Default is `cyan`. + +##### `SLIMLINE_CWD_ROOT_COLOR` + +Defines the color of the current working directory if it equals the root directory `/`. Default is `red`. + +### Exit Status + +##### `SLIMLINE_DISPLAY_EXIT_STATUS` + +Defines whether the exit status is displayed if the exit code is not zero. Default is `1`. + +##### `SLIMLINE_EXIT_STATUS_SYMBOL` + +Defines the symbol of the exit status glyph. Default is `↵`. + +##### `SLIMLINE_EXIT_STATUS_COLOR` + +Defines the color of the exit status information. Default is `red`. + +### Execution Time + +##### `SLIMLINE_DISPLAY_EXEC_TIME` + +Defines whether the runtime of a process is displayed if it exceeds the maximum execution time +specified by the option below. Default is `1`. + +##### `SLIMLINE_MAX_EXEC_TIME` + +Defines the maximum execution time of a process until its run time is displayed on exit. +Default is `5` seconds. + +##### `SLIMLINE_EXEC_TIME_COLOR` + +Defines the color of the execution time. Default is `yellow`. + +### User and Host Info + +##### `SLIMLINE_DISPLAY_USER_HOST_INFO` + +Defines whether the `user@host` part is displayed if the user differs from the default user or if connected to a ssh server. Default is `1`. + +##### `SLIMLINE_USER_COLOR` + +Defines the color of the user. Default is `green`. + +##### `SLIMLINE_USER_ROOT_COLOR` + +Defines the color of the user if the user is root. Default is `red`. + +##### `SLIMLINE_HOST_COLOR` + +Defines the color of the host. Default is `yellow`. + +##### `SLIMLINE_DEFAULT_USER` + +Username to consider as the default user. By default this is the current effective user (i.e. the output of `whoami`) + +### AWS Profile Info + +##### `SLIMLINE_DISPLAY_AWS_INFO` + +Defines whether value of `AWS_PROFILE` environment variable should be displayed. Default is `0`. + +##### `SLIMLINE_AWS_COLOR` + +Defines the color of aws profile info. Default is `blue`. + +### Auto Correction + +##### `SLIMLINE_AUTOCORRECT_MISSPELLED_COLOR` + +Defines the color of the misspelled string for which is correction is proposed. Default is `red`. + +##### `SLIMLINE_AUTOCORRECT_PROPOSED_COLOR` + +Defines the color of the proposed correction of a misspelled string. Default is `green`. + +### Python Virtualenv + +##### `SLIMLINE_DISPLAY_VIRTUALENV` + +Defines whether active python virtualenv shall be displayed. Default is `1`. + +##### `SLIMLINE_VIRTUALENV_COLOR` + +Defines the color of the virtualenv name. Default is `cyan`. + +##### `SLIMLINE_VIRTUALENV_PARENS_COLOR` + +Defines the color of the parens surrounding the virtualenv name. Default is `white`. + +### Git Information + +##### `SLIMLINE_ENABLE_GIT` + +Defines whether git information shall be displayed (requires python). Default is `1`. + +## Example + +Here is an example for customizing the prompt symbol as well as the git repository indicator and +branch format: + +```shell +export SLIMLINE_PROMPT_VERSION=1 # Activate legacy option format +export SLIMLINE_PROMPT_SYMBOL='$' + +# If you have a powerline compatible font you can also use the alternative repo indicator ''. +export GITLINE_REPO_INDICATOR='${reset}git' +export GITLINE_BRANCH='[${blue}${branch}${reset}]' + +source "/slimline.zsh" +``` From b7ae85dc9b3a796e15a790675007503a5539c405 Mon Sep 17 00:00:00 2001 From: Markus Engelbrecht Date: Thu, 15 Mar 2018 11:35:59 +0100 Subject: [PATCH 072/107] Update screenshots --- README.md | 10 +++++----- screenshot.png | Bin 59624 -> 23424 bytes screenshot_example.png | Bin 62117 -> 24833 bytes screenshot_full.png | Bin 66569 -> 35243 bytes 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5d28428..b0db8cd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Modular, fast and elegant ZSH prompt. Displays the right information at the right time. + + Features: - sleek look - modular layout using configurable sections in the left and right prompt @@ -21,11 +23,9 @@ Sections: - nodejs version configured for the current directory - customizable git information display - - -With most information (connected to ssh server, runtime and exit status from last command): +With more information (connected to ssh server, runtime and exit status from last command, aws profile and nodejs version): - + @@ -374,7 +374,7 @@ export GITLINE_BRANCH='[${blue}${branch}${reset}]' source "/slimline.zsh" ``` - + ## Thanks diff --git a/screenshot.png b/screenshot.png index 4af70052dae85b7aa50e362e25e888d0a52d4364..47219c270f9ca9aa655964d03273f3577268c041 100644 GIT binary patch literal 23424 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 literal 59624 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