From ed4d206bf6d383e526140099980d292493ab7634 Mon Sep 17 00:00:00 2001 From: Cristian Lupascu Date: Tue, 18 Aug 2020 16:50:16 +0300 Subject: [PATCH] Powerline prompt section to display last command duration Human display of the last command duration, if threshold exceeded Add configurable threshold for prompt duration display (5s) Nicer format for the time --- lib/utilities.bash | 17 ++++++++ plugins/available/cmd-duration.plugin.bash | 8 ++++ test/lib/utilities.bats | 41 +++++++++++++++++++ .../powerline-multiline.theme.bash | 3 ++ .../powerline-naked.theme.bash | 3 ++ .../powerline-plain.theme.bash | 3 ++ themes/powerline/powerline.base.bash | 17 ++++++++ themes/powerline/powerline.theme.bash | 3 ++ 8 files changed, 95 insertions(+) create mode 100644 plugins/available/cmd-duration.plugin.bash diff --git a/lib/utilities.bash b/lib/utilities.bash index db63956d..52427d3d 100644 --- a/lib/utilities.bash +++ b/lib/utilities.bash @@ -162,3 +162,20 @@ _bash-it-component-item-is-disabled() { local item="$2" _bash-it-component-help "${component}" | $(_bash-it-grep) -E -v '\[x\]' | $(_bash-it-grep) -E -q -- "^${item}\s" } + +# Given a number of seconds, transforms it into a human readable duration +_bash-it-human-duration() { + local T=$1 + if [ "$T" -lt 60 ]; then + printf '%ds' "$T" + return + fi + local D=$(( T / 60 / 60 / 24 )) + local H=$(( T / 60 / 60 % 24 )) + local M=$(( T / 60 % 60 )) + local S=$(( T % 60 )) + (( $D > 0 )) && printf '%d day(s), ' $D + (( $D > 0 || $H > 0 )) && printf '%02dh:' $H + (( $D > 0 || $H > 0 || $M > 0 )) && printf '%02dm:' $M + printf '%02ds' $S +} diff --git a/plugins/available/cmd-duration.plugin.bash b/plugins/available/cmd-duration.plugin.bash new file mode 100644 index 00000000..97f6b2ad --- /dev/null +++ b/plugins/available/cmd-duration.plugin.bash @@ -0,0 +1,8 @@ +cite about-plugin +about-plugin 'keep track of the moment when the last command started, to be able to compute its duration' + +preexec () { + export BASH_IT_LAST_COMMAND_STARTED=${EPOCHSECONDS:-$(perl -e 'print time()')} +} + +preexec_install; diff --git a/test/lib/utilities.bats b/test/lib/utilities.bats index 6e0f4ac7..e83e0be3 100644 --- a/test/lib/utilities.bats +++ b/test/lib/utilities.bats @@ -91,3 +91,44 @@ function item_disabled() { run has_match xyz "${fruits[@]}" assert_line -n 0 '' } + +@test "_bash-it-human-duration() - under a minute only displays second count" { + run _bash-it-human-duration 2 + [ "$output" = "2s" ] + + run _bash-it-human-duration 30 + [ "$output" = "30s" ] + + run _bash-it-human-duration 59 + [ "$output" = "59s" ] +} + +@test "_bash-it-human-duration() - over a minute, but under an hour displays mm:ss" { + run _bash-it-human-duration 60 + [ "$output" = "01m:00s" ] + + run _bash-it-human-duration 83 + [ "$output" = "01m:23s" ] + + run _bash-it-human-duration 3599 + [ "$output" = "59m:59s" ] +} + +@test "_bash-it-human-duration() - over an hour, displays in the hh:mm:ss format" { + run _bash-it-human-duration 3600 + [ "$output" = "01h:00m:00s" ] + + run _bash-it-human-duration 3700 + [ "$output" = "01h:01m:40s" ] + + run _bash-it-human-duration $(( 3600 * 24 - 1 )) + [ "$output" = "23h:59m:59s" ] +} + +@test "_bash-it-human-duration() - duration over 1 day - starts displaying number of days as well" { + run _bash-it-human-duration 86400 + [ "$output" = "1 day(s), 00h:00m:00s" ] + + run _bash-it-human-duration $(( 3600 * 24 * 3 + 3600 * 5 + 60 * 7 + 23 )) + [ "$output" = "3 day(s), 05h:07m:23s" ] +} diff --git a/themes/powerline-multiline/powerline-multiline.theme.bash b/themes/powerline-multiline/powerline-multiline.theme.bash index 54651cb6..75c58848 100644 --- a/themes/powerline-multiline/powerline-multiline.theme.bash +++ b/themes/powerline-multiline/powerline-multiline.theme.bash @@ -82,6 +82,9 @@ SHLVL_THEME_PROMPT_CHAR=${POWERLINE_SHLVL_CHAR:="§"} DIRSTACK_THEME_PROMPT_COLOR=${POWERLINE_DIRSTACK_COLOR:=${CWD_THEME_PROMPT_COLOR}} DIRSTACK_THEME_PROMPT_CHAR=${POWERLINE_DIRSTACK_CHAR:="←"} +DURATION_THEME_PROMPT_COLOR=${POWERLINE_DURATION_COLOR:=124} +DURATION_THRESHOLD=${POWERLINE_DURATION_THRESHOLD:=5} + HISTORY_NUMBER_THEME_PROMPT_COLOR=${POWERLINE_HISTORY_NUMBER_COLOR:=0} HISTORY_NUMBER_THEME_PROMPT_CHAR=${POWERLINE_HISTORY_NUMBER_CHAR:="#"} diff --git a/themes/powerline-naked/powerline-naked.theme.bash b/themes/powerline-naked/powerline-naked.theme.bash index 5c5fed26..644feb21 100644 --- a/themes/powerline-naked/powerline-naked.theme.bash +++ b/themes/powerline-naked/powerline-naked.theme.bash @@ -77,6 +77,9 @@ SHLVL_THEME_PROMPT_CHAR=${POWERLINE_SHLVL_CHAR:="§"} DIRSTACK_THEME_PROMPT_COLOR=${POWERLINE_DIRSTACK_COLOR:=${CWD_THEME_PROMPT_COLOR}} DIRSTACK_THEME_PROMPT_CHAR=${POWERLINE_DIRSTACK_CHAR:="←"} +DURATION_THEME_PROMPT_COLOR=${POWERLINE_DURATION_COLOR:=124} +DURATION_THRESHOLD=${POWERLINE_DURATION_THRESHOLD:=5} + HISTORY_NUMBER_THEME_PROMPT_COLOR=${POWERLINE_HISTORY_NUMBER_COLOR:=254} HISTORY_NUMBER_THEME_PROMPT_CHAR=${POWERLINE_HISTORY_NUMBER_CHAR:="#"} diff --git a/themes/powerline-plain/powerline-plain.theme.bash b/themes/powerline-plain/powerline-plain.theme.bash index 6ae81a56..db576305 100644 --- a/themes/powerline-plain/powerline-plain.theme.bash +++ b/themes/powerline-plain/powerline-plain.theme.bash @@ -74,6 +74,9 @@ SHLVL_THEME_PROMPT_CHAR=${POWERLINE_SHLVL_CHAR:="§"} DIRSTACK_THEME_PROMPT_COLOR=${POWERLINE_DIRSTACK_COLOR:=${CWD_THEME_PROMPT_COLOR}} DIRSTACK_THEME_PROMPT_CHAR=${POWERLINE_DIRSTACK_CHAR:="←"} +DURATION_THEME_PROMPT_COLOR=${POWERLINE_DURATION_COLOR:=124} +DURATION_THRESHOLD=${POWERLINE_DURATION_THRESHOLD:=5} + HISTORY_NUMBER_THEME_PROMPT_COLOR=${POWERLINE_HISTORY_NUMBER_COLOR:=0} HISTORY_NUMBER_THEME_PROMPT_CHAR=${POWERLINE_HISTORY_NUMBER_CHAR:="#"} diff --git a/themes/powerline/powerline.base.bash b/themes/powerline/powerline.base.bash index 8c983a7b..620f256f 100644 --- a/themes/powerline/powerline.base.bash +++ b/themes/powerline/powerline.base.bash @@ -188,6 +188,23 @@ function __powerline_dirstack_prompt { fi } +function __powerline_duration_prompt { + if [ -z $BASH_IT_LAST_COMMAND_STARTED ]; then + # either the duration plugin was not started, + # or this is the first time the prompt is displayed, + # therefore no command has run yet + return + fi + + local cmd_end=${EPOCHSECONDS:-$(perl -e 'print time()')} + (( duration_seconds = cmd_end - BASH_IT_LAST_COMMAND_STARTED )) + + if [ $duration_seconds -ge $DURATION_THRESHOLD ]; then + local human_duration=$(_bash-it-human-duration "$duration_seconds") + echo "${human_duration}|${DURATION_THEME_PROMPT_COLOR}" + fi +} + function __powerline_history_number_prompt { echo "${HISTORY_NUMBER_THEME_PROMPT_CHAR}\!|${HISTORY_NUMBER_THEME_PROMPT_COLOR}" } diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index d897c7c8..c1491eba 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -78,6 +78,9 @@ SHLVL_THEME_PROMPT_CHAR=${POWERLINE_SHLVL_CHAR:="§"} DIRSTACK_THEME_PROMPT_COLOR=${POWERLINE_DIRSTACK_COLOR:=${CWD_THEME_PROMPT_COLOR}} DIRSTACK_THEME_PROMPT_CHAR=${POWERLINE_DIRSTACK_CHAR:="←"} +DURATION_THEME_PROMPT_COLOR=${POWERLINE_DURATION_COLOR:=124} +DURATION_THRESHOLD=${POWERLINE_DURATION_THRESHOLD:=5} + HISTORY_NUMBER_THEME_PROMPT_COLOR=${POWERLINE_HISTORY_NUMBER_COLOR:=0} HISTORY_NUMBER_THEME_PROMPT_CHAR=${POWERLINE_HISTORY_NUMBER_CHAR:="#"}