Make tmux alert parsing and focus more robust
Session names can contain pipes but never colons, so split fields on colons instead. Remember refreshes that arrive while the indicator is already polling, and jump to the most recently used tmux client rather than an arbitrary one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a382be2645
commit
5b130c1063
+14
-9
@@ -6,8 +6,9 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Window names can contain the separator, so they always come last when parsed.
|
||||
WINDOW_FORMAT='#{window_bell_flag}#{window_activity_flag}#{window_silence_flag}|#{session_name}|#{window_index}|#{window_name}'
|
||||
# Session names cannot contain colons, and window names can, so they always
|
||||
# come last when parsed.
|
||||
WINDOW_FORMAT='#{window_bell_flag}#{window_activity_flag}#{window_silence_flag}:#{session_name}:#{window_index}:#{window_name}'
|
||||
|
||||
usage() {
|
||||
echo "Usage: omarchy-tmux-alert <show [--json]|focus>" >&2
|
||||
@@ -20,9 +21,9 @@ alerted_windows() {
|
||||
local flags session index name
|
||||
|
||||
tmux list-windows -a -F "$WINDOW_FORMAT" 2>/dev/null |
|
||||
while IFS='|' read -r flags session index name; do
|
||||
while IFS=':' read -r flags session index name; do
|
||||
if [[ $flags == *1* ]]; then
|
||||
printf '%s|%s|%s\n' "$session" "$index" "$name"
|
||||
printf '%s:%s:%s\n' "$session" "$index" "$name"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -33,7 +34,7 @@ show() {
|
||||
readarray -t windows < <(alerted_windows)
|
||||
|
||||
for window in "${windows[@]}"; do
|
||||
IFS='|' read -r session index name <<<"$window"
|
||||
IFS=':' read -r session index name <<<"$window"
|
||||
[[ -n $description ]] && description+=", "
|
||||
description+="$name ($session:$index)"
|
||||
done
|
||||
@@ -68,23 +69,27 @@ focus_terminal_window() {
|
||||
hyprctl dispatch focuswindow "address:$address" >/dev/null
|
||||
}
|
||||
|
||||
most_recent_client() {
|
||||
tmux list-clients "$@" -F '#{client_activity}:#{client_tty}:#{client_pid}' 2>/dev/null | sort -rn | head -n1
|
||||
}
|
||||
|
||||
focus() {
|
||||
local target session index client tty pid
|
||||
|
||||
target=$(alerted_windows | head -n1)
|
||||
[[ -n $target ]] || return 0
|
||||
|
||||
IFS='|' read -r session index _ <<<"$target"
|
||||
IFS=':' read -r session index _ <<<"$target"
|
||||
|
||||
client=$(tmux list-clients -t "$session" -F '#{client_tty}|#{client_pid}' 2>/dev/null | head -n1)
|
||||
[[ -n $client ]] || client=$(tmux list-clients -F '#{client_tty}|#{client_pid}' 2>/dev/null | head -n1)
|
||||
client=$(most_recent_client -t "$session")
|
||||
[[ -n $client ]] || client=$(most_recent_client)
|
||||
|
||||
if [[ -z $client ]]; then
|
||||
tmux select-window -t "$session:$index"
|
||||
exec omarchy-launch-terminal tmux attach -t "$session"
|
||||
fi
|
||||
|
||||
IFS='|' read -r tty pid <<<"$client"
|
||||
IFS=':' read -r _ tty pid <<<"$client"
|
||||
tmux switch-client -c "$tty" -t "$session:$index"
|
||||
omarchy-shell -q omarchy.indicators refresh
|
||||
focus_terminal_window "$pid"
|
||||
|
||||
@@ -8,6 +8,7 @@ BarIndicator {
|
||||
|
||||
property int waitingCount: 0
|
||||
property string tooltip: ""
|
||||
property bool refreshPending: false
|
||||
|
||||
active: waitingCount > 0
|
||||
activeText: ""
|
||||
@@ -16,7 +17,8 @@ BarIndicator {
|
||||
inactiveTooltipText: "No terminal is waiting"
|
||||
|
||||
function refresh() {
|
||||
if (!statusProc.running) statusProc.running = true
|
||||
if (statusProc.running) refreshPending = true
|
||||
else statusProc.running = true
|
||||
}
|
||||
|
||||
function update(raw) {
|
||||
@@ -54,6 +56,11 @@ BarIndicator {
|
||||
root.waitingCount = 0
|
||||
root.tooltip = ""
|
||||
}
|
||||
|
||||
if (root.refreshPending) {
|
||||
root.refreshPending = false
|
||||
root.refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,22 +22,22 @@ export TMUX_STUB_WINDOWS="$test_dir/windows"
|
||||
export PATH="$test_dir:$PATH"
|
||||
|
||||
cat >"$TMUX_STUB_WINDOWS" <<'WINDOWS'
|
||||
000|Work|1|editor
|
||||
100|Work|2|claude
|
||||
001|Side|1|server|with|pipes
|
||||
000:Work:1:editor
|
||||
100:Work:2:claude
|
||||
001:Side|Gig:1:server: still going
|
||||
WINDOWS
|
||||
|
||||
output=$("$ROOT/bin/omarchy-tmux-alert" show --json)
|
||||
expected='{"count":2,"tooltip":"claude (Work:2), server|with|pipes (Side:1)"}'
|
||||
expected='{"count":2,"tooltip":"claude (Work:2), server: still going (Side|Gig:1)"}'
|
||||
[[ $output == "$expected" ]] || fail "tmux alert reports alerted windows" "expected: $expected"$'\n'"actual: $output"
|
||||
pass "tmux alert reports alerted windows"
|
||||
|
||||
output=$("$ROOT/bin/omarchy-tmux-alert" show)
|
||||
[[ $output == "claude (Work:2), server|with|pipes (Side:1)" ]] || fail "tmux alert describes alerted windows" "$output"
|
||||
[[ $output == "claude (Work:2), server: still going (Side|Gig:1)" ]] || fail "tmux alert describes alerted windows" "$output"
|
||||
pass "tmux alert describes alerted windows"
|
||||
|
||||
cat >"$TMUX_STUB_WINDOWS" <<'WINDOWS'
|
||||
000|Work|1|editor
|
||||
000:Work:1:editor
|
||||
WINDOWS
|
||||
|
||||
output=$("$ROOT/bin/omarchy-tmux-alert" show --json)
|
||||
|
||||
Reference in New Issue
Block a user