bash-it/lib/command_duration.bash

116 lines
4.0 KiB
Bash

# shellcheck shell=bash
#
# Functions for measuring and reporting how long a command takes to run.
# Get shell duration in decimal format regardless of runtime locale.
# Notice: This function runs as a sub-shell - notice '(' vs '{'.
function _shell_duration_en() (
# DFARREL You would think LC_NUMERIC would do it, but not working in my local
LC_ALL='en_US.UTF-8'
printf "%s" "${EPOCHREALTIME:-$SECONDS}"
############### Stack_TRACE_BUILDER ################
Function_PATH="$( dirname ${Function_PATH} )"
####################################################
}
: "${COMMAND_DURATION_START_SECONDS:=$(_shell_duration_en)}"
: "${COMMAND_DURATION_ICON:=🕘}"
: "${COMMAND_DURATION_MIN_SECONDS:=1}"
function _command_duration_pre_exec()
{
############ STACK_TRACE_BUILDER #####################
Function_Name="${FUNCNAME[0]}"
Function_PATH="${Function_PATH}/${Function_Name}"
######################################################
COMMAND_DURATION_START_SECONDS="$(_shell_duration_en)"
############### Stack_TRACE_BUILDER ################
Function_PATH="$( dirname ${Function_PATH} )"
####################################################
}
function _command_duration_pre_cmd()
{
############ STACK_TRACE_BUILDER #####################
Function_Name="${FUNCNAME[0]}"
Function_PATH="${Function_PATH}/${Function_Name}"
######################################################
COMMAND_DURATION_START_SECONDS=""
############### Stack_TRACE_BUILDER ################
Function_PATH="$( dirname ${Function_PATH} )"
####################################################
}
function _dynamic_clock_icon {
local clock_hand
# clock hand value is between 90 and 9b in hexadecimal.
# so between 144 and 155 in base 10.
printf -v clock_hand '%x' $(((${1:-${SECONDS}} % 12) + 144))
printf -v 'COMMAND_DURATION_ICON' '%b' "\xf0\x9f\x95\x$clock_hand"
############### Stack_TRACE_BUILDER ################
Function_PATH="$( dirname ${Function_PATH} )"
####################################################
}
function _command_duration()
{
############ STACK_TRACE_BUILDER #####################
Function_Name="${FUNCNAME[0]}"
Function_PATH="${Function_PATH}/${Function_Name}"
######################################################
[[ -n "${BASH_IT_COMMAND_DURATION:-}" ]] || return
[[ -n "${COMMAND_DURATION_START_SECONDS:-}" ]] || return
local command_duration=0 command_start="${COMMAND_DURATION_START_SECONDS:-0}"
local -i minutes=0 seconds=0 deciseconds=0
local -i command_start_seconds="${command_start%.*}"
local -i command_start_deciseconds=$((10#${command_start##*.}))
command_start_deciseconds="${command_start_deciseconds:0:1}"
local current_time
current_time="$(_shell_duration_en)"
local -i current_time_seconds="${current_time%.*}"
local -i current_time_deciseconds="$((10#${current_time##*.}))"
current_time_deciseconds="${current_time_deciseconds:0:1}"
if [[ "${command_start_seconds:-0}" -gt 0 ]]
then
# seconds
command_duration="$((current_time_seconds - command_start_seconds))"
if ((current_time_deciseconds >= command_start_deciseconds))
then
deciseconds="$((current_time_deciseconds - command_start_deciseconds))"
else
((command_duration -= 1))
deciseconds="$((10 - (command_start_deciseconds - current_time_deciseconds)))"
fi
else
command_duration=0
fi
if ((command_duration >= COMMAND_DURATION_MIN_SECONDS))
then
minutes=$((command_duration / 60))
seconds=$((command_duration % 60))
_dynamic_clock_icon "${command_duration}"
if ((minutes > 0))
then
printf "%s %s%dm %ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$minutes" "$seconds"
else
printf "%s %s%d.%01ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$seconds" "$deciseconds"
fi
fi
############### Stack_TRACE_BUILDER ################
Function_PATH="$( dirname ${Function_PATH} )"
####################################################
}
_bash_it_library_finalize_hook+=("safe_append_preexec '_command_duration_pre_exec'")
_bash_it_library_finalize_hook+=("safe_append_prompt_command '_command_duration_pre_cmd'")