Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0119368
Delete preexec vendor
BarbUk Feb 3, 2026
027b7ae
Squashed 'vendor/github.com/rcaloras/bash-preexec/' content from comm…
BarbUk Feb 3, 2026
b509d72
Add "preexec" from "https://github.com/rcaloras/bash-preexec@0.6.0"
BarbUk Feb 3, 2026
7ab0074
Update precommit
BarbUk Feb 3, 2026
ee821b3
Rework command duration plugin to handle locale with . or , and remov…
BarbUk Feb 3, 2026
f630441
Sh format
BarbUk Feb 3, 2026
b42c3ac
Revert "Update precommit"
BarbUk Feb 3, 2026
1857412
Fix cmd-returned-notify.plugin.bash
BarbUk Feb 3, 2026
83f11a8
Fix _shell_duration_en function call, restore original variable names
BarbUk Feb 3, 2026
64ec7e7
With recent version of bash preexec set PROMPT_COMMAND as an array
BarbUk Feb 3, 2026
4c60358
But leave test for old macos version of bash
BarbUk Feb 3, 2026
5ae5522
New version of preexec add a :
BarbUk Feb 3, 2026
f689001
Fix preexec bats tests shellcheck errors
BarbUk Feb 3, 2026
d65288f
, and . are not the only possibilities of decimal_point
BarbUk Feb 3, 2026
2339683
Ignore warning for vendors bats test files
BarbUk Feb 3, 2026
3e3ddf3
Add default for COMMAND_DURATION_START_SECONDS
BarbUk Feb 3, 2026
7373708
Fix shellcheck SC1091 for vendor bats tests
BarbUk Feb 3, 2026
9e88c2a
Ignore last shellcheck error in vendor bats tests
BarbUk Feb 3, 2026
1fb6e65
Add more information about the reason of this change
BarbUk Feb 10, 2026
f775bbd
Get the current time from command_duration lib function
BarbUk Feb 10, 2026
53de05d
Work with microseconds, truncate the output to display
BarbUk Feb 10, 2026
4d86661
Only calculate and display microseconds if precision > 0
BarbUk Feb 10, 2026
ee1c783
Add documentation about COMMAND_DURATION_PRECISION
BarbUk Feb 10, 2026
42b8086
Handle case with leading 0 in microseconds
BarbUk Feb 10, 2026
5ef3b70
Handle case with leading 0 in microseconds
BarbUk Feb 10, 2026
9e5f7ce
No quote for integer local var
BarbUk Feb 10, 2026
c0f2a5d
Add tests
BarbUk Feb 10, 2026
964e9bc
Disable shellcheck false positive for bats tests
BarbUk Feb 10, 2026
67cb1b2
local -> locale
BarbUk Feb 11, 2026
3c39331
Rephrase
BarbUk Feb 11, 2026
275c8d3
overide -> override
BarbUk Feb 11, 2026
910dbed
Fix phrasing
BarbUk Feb 11, 2026
43f1bd4
Add tests when EPOCHREALTIME is not available
BarbUk Feb 11, 2026
b848e5b
Uses string instead of int
BarbUk Feb 11, 2026
71a8a71
Reintroduce paste documentation to keep context about this change
BarbUk Feb 11, 2026
dd80054
Remove unused code branch
BarbUk Feb 12, 2026
ed314d5
Add test with precision 0 and microseconds time
BarbUk Feb 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 45 additions & 30 deletions lib/command_duration.bash
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,79 @@
# 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.
# Note: LC_ALL='en_US.UTF-8' has been used to enforce the decimal point to be
# a period, but the specific locale 'en_US.UTF-8' is not ensured to exist in
# the system. One should instead use the locale 'C', which is ensured by the
# C and POSIX standards.
Comment thread
BarbUk marked this conversation as resolved.
local LC_ALL=C
printf "%s" "${EPOCHREALTIME:-$SECONDS}"
)

: "${COMMAND_DURATION_START_SECONDS:=$(_shell_duration_en)}"
function _command_duration_current_time() {
local current_time
if [[ -n "${EPOCHREALTIME:-}" ]]; then
current_time="${EPOCHREALTIME//[!0-9]/.}"
else
current_time="$SECONDS"
fi

echo "$current_time"
}

: "${COMMAND_DURATION_START_SECONDS:=$(_command_duration_current_time)}"
: "${COMMAND_DURATION_ICON:=🕘}"
: "${COMMAND_DURATION_MIN_SECONDS:=1}"

function _command_duration_pre_exec() {
COMMAND_DURATION_START_SECONDS="$(_shell_duration_en)"
COMMAND_DURATION_START_SECONDS="$(_command_duration_current_time)"
}

function _command_duration_pre_cmd() {
COMMAND_DURATION_START_SECONDS=""
}

function _dynamic_clock_icon {
local clock_hand
local clock_hand duration="$1"

# Clock only work for time >= 1s
if ((duration < 1)); then
duration=1
fi

# 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}} - 1) % 12) + 144))
printf -v clock_hand '%x' $((((${duration:-${SECONDS}} - 1) % 12) + 144))
printf -v 'COMMAND_DURATION_ICON' '%b' "\xf0\x9f\x95\x$clock_hand"
}

function _command_duration() {
[[ -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}"
current_time="$(_command_duration_current_time)"

local -i command_duration=0
local -i minutes=0 seconds=0 deciseconds=0

local -i command_start_seconds=${COMMAND_DURATION_START_SECONDS%.*}
local -i current_time_seconds=${current_time%.*}

# Calculate seconds difference
command_duration=$((current_time_seconds - command_start_seconds))

if [[ "${command_start_seconds:-0}" -gt 0 ]]; then
# seconds
command_duration="$((current_time_seconds - command_start_seconds))"
# Calculate deciseconds if both timestamps have fractional parts
if [[ "$COMMAND_DURATION_START_SECONDS" == *.* ]] && [[ "$current_time" == *.* ]]; then
local -i command_start_deciseconds=$((10#${COMMAND_DURATION_START_SECONDS##*.}))
local -i current_time_deciseconds="$((10#${current_time##*.}))"

# Take first digit for deciseconds
command_start_deciseconds="${command_start_deciseconds:0:1}"
current_time_deciseconds="${current_time_deciseconds:0:1}"
Comment thread
BarbUk marked this conversation as resolved.
Outdated

if ((current_time_deciseconds >= command_start_deciseconds)); then
deciseconds="$((current_time_deciseconds - command_start_deciseconds))"
deciseconds=$((current_time_deciseconds - command_start_deciseconds))
else
((command_duration -= 1))
deciseconds="$((10 - (command_start_deciseconds - current_time_deciseconds)))"
deciseconds=$((10 + current_time_deciseconds - command_start_deciseconds))
fi
else
fi

if ((command_duration < 0)); then
command_duration=0
deciseconds=0
fi

if ((command_duration >= COMMAND_DURATION_MIN_SECONDS)); then
Expand Down
6 changes: 5 additions & 1 deletion plugins/available/cmd-returned-notify.plugin.bash
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ url "https://github.com/Bash-it/bash-it"
function precmd_return_notification() {
local command_start="${COMMAND_DURATION_START_SECONDS:=0}"
local current_time
current_time="$(_shell_duration_en)"
if [[ -n "${EPOCHREALTIME:-}" ]]; then
current_time="${EPOCHREALTIME//,/.}"
Comment thread
BarbUk marked this conversation as resolved.
Outdated
else
current_time="$SECONDS"
fi
local -i command_duration="$((${current_time%.*} - ${command_start%.*}))"
if [[ "${command_duration}" -gt "${NOTIFY_IF_COMMAND_RETURNS_AFTER:-5}" ]]; then
printf '\a'
Expand Down
12 changes: 10 additions & 2 deletions test/lib/preexec.bats
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ function local_setup {
assert_success

__bp_install
assert_equal "${PROMPT_COMMAND}" $'__bp_precmd_invoke_cmd\n__bp_interactive_mode'
if ((BASH_VERSINFO[0] > 5 || (BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 1))); then
assert_equal "${PROMPT_COMMAND[*]}" $'__bp_precmd_invoke_cmd __bp_interactive_mode'
else
assert_equal "${PROMPT_COMMAND}" $'__bp_precmd_invoke_cmd\n__bp_interactive_mode'
fi
}

@test "vendor preexec: __bp_install() with existing" {
Expand All @@ -75,7 +79,11 @@ function local_setup {
assert_success

__bp_install
assert_equal "${PROMPT_COMMAND}" $'__bp_precmd_invoke_cmd\n'"$test_prompt_string"$'\n__bp_interactive_mode'
if ((BASH_VERSINFO[0] > 5 || (BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 1))); then
assert_equal "${PROMPT_COMMAND[*]}" $'__bp_precmd_invoke_cmd\n'"$test_prompt_string"$'\n: __bp_interactive_mode'
else
assert_equal "${PROMPT_COMMAND}" $'__bp_precmd_invoke_cmd\n'"$test_prompt_string"$'\n:\n__bp_interactive_mode'
fi
}

@test "lib preexec: __bp_require_not_readonly()" {
Expand Down
6 changes: 3 additions & 3 deletions test/plugins/cmd-returned-notify.plugin.bats
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function local_setup_file() {

@test "plugins cmd-returned-notify: notify after elapsed time" {
NOTIFY_IF_COMMAND_RETURNS_AFTER=0
COMMAND_DURATION_START_SECONDS="$(_shell_duration_en)"
COMMAND_DURATION_START_SECONDS="$(_command_duration_current_time)"
export COMMAND_DURATION_START_SECONDS NOTIFY_IF_COMMAND_RETURNS_AFTER
sleep 1
run precmd_return_notification
Expand All @@ -20,7 +20,7 @@ function local_setup_file() {

@test "plugins cmd-returned-notify: do not notify before elapsed time" {
NOTIFY_IF_COMMAND_RETURNS_AFTER=10
COMMAND_DURATION_START_SECONDS="$(_shell_duration_en)"
COMMAND_DURATION_START_SECONDS="$(_command_duration_current_time)"
export COMMAND_DURATION_START_SECONDS NOTIFY_IF_COMMAND_RETURNS_AFTER
sleep 1
run precmd_return_notification
Expand All @@ -37,7 +37,7 @@ function local_setup_file() {
@test "lib command_duration: preexec set COMMAND_DURATION_START_SECONDS" {
COMMAND_DURATION_START_SECONDS=
assert_equal "${COMMAND_DURATION_START_SECONDS}" ""
NOW="$(_shell_duration_en)"
NOW="$(_command_duration_current_time)"
_command_duration_pre_exec
# We need to make sure to account for nanoseconds...
assert_equal "${COMMAND_DURATION_START_SECONDS%.*}" "${NOW%.*}"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 0 additions & 20 deletions vendor/github.com/rcaloras/bash-preexec/.travis.yml

This file was deleted.

19 changes: 14 additions & 5 deletions vendor/github.com/rcaloras/bash-preexec/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading