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:="#"}