aboutsummaryrefslogtreecommitdiff
path: root/packaging/tmux
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-23 13:59:59 +0300
committerIgor Soarez <igor@soarez.org>2026-10-23 13:59:59 +0300
commit9c9c9dad93b16781ec2fc40bd7582db62240171c (patch)
treecf85f3a53f8441eae36982d06244041cfe0ff6f3 /packaging/tmux
parentc082f5044eedd2294d72f920d1018e40d73aab33 (diff)
restore, step 3: offer it in the panel, menu, and status line
when tmux stops (and its sessions are missing from the running server, or no server runs), the daemon publishes the restore offer: offer.json for the menu bar app and @dingger_restore for the status line, withdrawn once restored or dismissed. - panel: a first row "↺ Restore 9 sessions · 22 agents" with when it was saved and how many agents were mid-turn; clicking restores, "Not now" dismisses. an offer shows the panel like a waiting agent; off stays off. - menu: the offer on top; restore all, one session, or not now. - status line: a clickable blue ↺N before the clock. - restore runs through the user's login shell, as a terminal starts tmux, so restored panes get a real environment, not launchd's; --report writes restore.log and notifies a summary. restore --dismiss. - commands log only warnings by default; SIGPIPE ends them quietly. e2e: the offer through the real menu bar binary, the summary notification, the offer clearing, a restore with no tmux running, and not now staying dismissed when a terminal starts tmux. the second test daemon is started directly (it leaked through a function's $! before, and dozens of leaked daemons fought over the test socket and loaded the machine); each run uses its own socket and checks its daemons stop.
Diffstat (limited to 'packaging/tmux')
-rw-r--r--packaging/tmux/dingger.tmux10
1 files changed, 8 insertions, 2 deletions
diff --git a/packaging/tmux/dingger.tmux b/packaging/tmux/dingger.tmux
index 64c5bff..f1529f1 100644
--- a/packaging/tmux/dingger.tmux
+++ b/packaging/tmux/dingger.tmux
@@ -4,9 +4,15 @@
# of the menu bar: blocked first, then the longest-done (FIFO), skipping the
# window you are already looking at.
#
+# After tmux restarts, `↺N` (blue) offers to restore N saved sessions:
+# clicking it runs `dingger restore`; a notification summarizes, the full
+# report is in ~/.local/state/dingger/restore.log.
+#
# Source this from your tmux config: source-file /path/to/dingger.tmux
-set -g status-right '%d-%b %H:%M#{?#{e|>:#{@dingger_blocked},0}, #[fg=#f38ba8#,bold]×#{@dingger_blocked}#[default],}#{?#{e|>:#{@dingger_done},0}, #[fg=#94e2d5]✓#{@dingger_done}#[default],}#{?#{e|>:#{@dingger_working},0}, #[fg=#f9e2af]◐#{@dingger_working}#[default],}'
-bind -n MouseDown1StatusRight run-shell "$HOME/.local/bin/dingger focus --client '#{client_name}'"
+set -g status-right '#{?@dingger_restore,#[range=user|restore]#[fg=#89b4fa#,bold]↺#{@dingger_restore}#[norange default] ,}%d-%b %H:%M#{?#{e|>:#{@dingger_blocked},0}, #[fg=#f38ba8#,bold]×#{@dingger_blocked}#[default],}#{?#{e|>:#{@dingger_done},0}, #[fg=#94e2d5]✓#{@dingger_done}#[default],}#{?#{e|>:#{@dingger_working},0}, #[fg=#f9e2af]◐#{@dingger_working}#[default],}'
+bind -n MouseDown1StatusRight if -F '#{==:#{mouse_status_range},restore}' \
+ 'run-shell -b "$HOME/.local/bin/dingger restore --report"' \
+ "run-shell \"$HOME/.local/bin/dingger focus --client '#{client_name}'\""
# Tell dingger the moment you look somewhere else (it marks what you see as
# attended). Index 77 keeps your own hooks and makes reloading idempotent.
set-hook -g 'client-session-changed[77]' 'run-shell -b "$HOME/.local/bin/dingger poke"'