-
Notifications
You must be signed in to change notification settings - Fork 0
refactor(tmux): flatten tmuxinator dir and improve tsh/tss #935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6cfffbe
395736c
378b7d8
2b3aac0
f87cb97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,7 @@ | ||
| { ... }: | ||
| { | ||
| xdg.configFile."tmuxinator".source = ./tmuxinator; | ||
| xdg.configFile."tmuxinator/primary.yml".source = ./primary.yml; | ||
| xdg.configFile."tmuxinator/mobile.yml".source = ./mobile.yml; | ||
| xdg.configFile."tmuxinator/work.yml".source = ./work.yml; | ||
| xdg.configFile."tmuxinator/desktop.yml".source = ./desktop.yml; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,72 +1,35 @@ | ||||||||||||||||||||||||||||||||
| function _tsh_function --description "Search tmux session history log or pane contents" | ||||||||||||||||||||||||||||||||
| set -l log ~/.local/share/tmux/session-history.log | ||||||||||||||||||||||||||||||||
| function _tsh_function --description "Search tmux pane contents (live + archived)" | ||||||||||||||||||||||||||||||||
| set -l pane_dir ~/.local/share/tmux/panes | ||||||||||||||||||||||||||||||||
| set -l archive_dir ~/.local/share/tmux/archive | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| # With argument(s): search stored pane content files (live + archived) | ||||||||||||||||||||||||||||||||
| if test (count $argv) -gt 0 | ||||||||||||||||||||||||||||||||
| if not test -d "$pane_dir" | ||||||||||||||||||||||||||||||||
| echo "No pane content store found at $pane_dir" | ||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| set -l query (string join ' ' $argv) | ||||||||||||||||||||||||||||||||
| set -l selected (rg -l -- "$query" "$pane_dir" "$archive_dir" 2>/dev/null \ | ||||||||||||||||||||||||||||||||
| | fzf --prompt="pane-search> " \ | ||||||||||||||||||||||||||||||||
| --height=40% \ | ||||||||||||||||||||||||||||||||
| --preview="rg -n -- '$query' {} 2>/dev/null | head -80" \ | ||||||||||||||||||||||||||||||||
| --preview-window=right:60%) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if test -z "$selected" | ||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| # work--0--0.txt or work--0--0--20260226-103000.txt → sess=work, widx=0 | ||||||||||||||||||||||||||||||||
| set -l fname (string replace -r '.*/' '' "$selected" \ | ||||||||||||||||||||||||||||||||
| | string replace -r '--\d{8}-\d{6}\.txt$' '' \ | ||||||||||||||||||||||||||||||||
| | string replace '.txt' '') | ||||||||||||||||||||||||||||||||
| set -l parts (string split -- '--' $fname) | ||||||||||||||||||||||||||||||||
| set -l sess $parts[1] | ||||||||||||||||||||||||||||||||
| set -l widx $parts[2] | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if not tmux has-session -t "$sess" 2>/dev/null | ||||||||||||||||||||||||||||||||
| echo "Session '$sess' no longer exists (archived pane — content shown above in preview)" | ||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if test -n "$TMUX" | ||||||||||||||||||||||||||||||||
| tmux switch-client -t "$sess" | ||||||||||||||||||||||||||||||||
| tmux select-window -t "$sess:$widx" 2>/dev/null | ||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||
| tmux attach-session -t "$sess" \; select-window -t "$sess:$widx" | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| # No argument: fzf over the history log (session/window/path metadata) | ||||||||||||||||||||||||||||||||
| if not test -f "$log" | ||||||||||||||||||||||||||||||||
| echo "No session history found at $log" | ||||||||||||||||||||||||||||||||
| # Default: fzf over pane content files, optional query pre-fills search | ||||||||||||||||||||||||||||||||
| if not test -d "$pane_dir" | ||||||||||||||||||||||||||||||||
| echo "No pane content store found at $pane_dir" | ||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| set -l selected (cat "$log" | fzf \ | ||||||||||||||||||||||||||||||||
| --prompt="session-history> " \ | ||||||||||||||||||||||||||||||||
| --height=40% \ | ||||||||||||||||||||||||||||||||
| --tac \ | ||||||||||||||||||||||||||||||||
| --no-sort \ | ||||||||||||||||||||||||||||||||
| --preview='echo {}') | ||||||||||||||||||||||||||||||||
| set -l query (string join ' ' $argv) | ||||||||||||||||||||||||||||||||
| set -l selected (rg -l -- "$query" "$pane_dir" "$archive_dir" 2>/dev/null \ | ||||||||||||||||||||||||||||||||
| | fzf --prompt="pane-search> " \ | ||||||||||||||||||||||||||||||||
| --height=40% \ | ||||||||||||||||||||||||||||||||
| --query="$query" \ | ||||||||||||||||||||||||||||||||
| --preview="rg -n -- '$query' {} 2>/dev/null | head -80" \ | ||||||||||||||||||||||||||||||||
| --preview-window=right:60%) | ||||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+17
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: This preview command is vulnerable to command injection. If Escape single quotes in the query before passing it to the preview command. Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if test -z "$selected" | ||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| set -l target (string split ' ' $selected)[2] | ||||||||||||||||||||||||||||||||
| set -l parts (string split ':' $target) | ||||||||||||||||||||||||||||||||
| # work--0--0.txt or work--0--0--20260226-103000.txt → sess=work, widx=0 | ||||||||||||||||||||||||||||||||
| set -l fname (string replace -r '.*/' '' "$selected" \ | ||||||||||||||||||||||||||||||||
| | string replace -r '--\d{8}-\d{6}\.txt$' '' \ | ||||||||||||||||||||||||||||||||
| | string replace '.txt' '') | ||||||||||||||||||||||||||||||||
| set -l parts (string split -- '--' $fname) | ||||||||||||||||||||||||||||||||
| set -l sess $parts[1] | ||||||||||||||||||||||||||||||||
| set -l widx $parts[2] | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if not tmux has-session -t "$sess" 2>/dev/null | ||||||||||||||||||||||||||||||||
| echo "Session '$sess' no longer exists" | ||||||||||||||||||||||||||||||||
| bat --style=plain "$selected" 2>/dev/null; or less "$selected" | ||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| function _tsk_function --description "Kill tmux sessions or windows via fzf" | ||
| # Build list: sessions and windows | ||
| set -l items (begin | ||
| tmux list-sessions -F 'session #{session_name}' 2>/dev/null | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Using a double-space delimiter is fragile, as session or window names containing double spaces will break the parsing. Consider using a more robust delimiter like a tab character ( Prompt for AI agents |
||
| tmux list-windows -a -F 'window #{session_name}:#{window_index} #{window_name}' 2>/dev/null | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: The format string uses 3 spaces after 'window' (likely for alignment), but the parsing logic splits on 2 spaces ( Prompt for AI agents |
||
| end) | ||
|
|
||
| set -l selected (printf '%s\n' $items \ | ||
| | fzf --prompt="kill> " \ | ||
| --height=40% \ | ||
| --multi \ | ||
| --preview=' | ||
| set kind (string split " " {})[1] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: The Prompt for AI agents |
||
| set target (string split " " {})[2] | ||
| if test "$kind" = session | ||
| tmux list-windows -F "#I: #W #{pane_current_path}" -t $target 2>/dev/null | ||
| else | ||
| tmux list-panes -F "#P: #{pane_current_command} #{pane_current_path}" -t $target 2>/dev/null | ||
| end') | ||
|
|
||
| if test -z "$selected" | ||
| return | ||
| end | ||
|
|
||
| for line in $selected | ||
| set -l kind (string split ' ' $line)[1] | ||
| set -l target (string split ' ' $line)[2] | ||
| if test "$kind" = session | ||
| tmux kill-session -t "$target" 2>/dev/null | ||
| else | ||
| tmux kill-window -t "$target" 2>/dev/null | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,43 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| function _tss_function --description "Fuzzy-pick or create a tmux session" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| set -l log ~/.local/share/tmux/session-history.log | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # --log: browse session/window metadata log | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if test (count $argv) -gt 0 -a "$argv[1]" = --log | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if not test -f "$log" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "No session history found at $log" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| set -l selected (cat "$log" | fzf \ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| --prompt="session-history> " \ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| --height=40% \ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| --tac \ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| --no-sort \ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| --preview='echo {}') | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if test -z "$selected" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| set -l target (string split ' ' $selected)[2] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| set -l parts (string split ':' $target) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| set -l sess $parts[1] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| set -l widx $parts[2] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -type f -name "_tss_function.fish" | head -5Repository: shunkakinoki/dotfiles Length of output: 122 🏁 Script executed: cat -n ./home-manager/programs/fish/functions/_tss_function.fishRepository: shunkakinoki/dotfiles Length of output: 3250 🏁 Script executed: find . -name "*session-history*" -o -name "*tss*" | grep -E "(log|script|config)" | head -20Repository: shunkakinoki/dotfiles Length of output: 47 🏁 Script executed: rg "session-history" --type fish --type sh --type bashRepository: shunkakinoki/dotfiles Length of output: 93 🏁 Script executed: rg "session-history"Repository: shunkakinoki/dotfiles Length of output: 355 🏁 Script executed: cat -n ./home-manager/programs/tmux/session-logger.shRepository: shunkakinoki/dotfiles Length of output: 1809 Harden log-entry parsing before using tmux targets. Line 22 assumes a strict Proposed fix- set -l target (string split ' ' $selected)[2]
- set -l parts (string split ':' $target)
- set -l sess $parts[1]
- set -l widx $parts[2]
+ set -l target (string match -r '[^[:space:]]+:[0-9]+' -- $selected)
+ if test -z "$target"
+ echo "Could not parse session/window from: $selected"
+ return 1
+ end
+ set -l parts (string split ':' -- $target)
+ set -l sess $parts[1]
+ set -l widx $parts[2]📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Comment on lines
+22
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Validate the parsed log entry before using it to build tmux targets; otherwise malformed lines can lead to empty session/window values and broken tmux commands. Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if not tmux has-session -t "$sess" 2>/dev/null | ||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Session '$sess' no longer exists" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if test -n "$TMUX" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| tmux switch-client -t "$sess" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| tmux select-window -t "$sess:$widx" 2>/dev/null | ||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||
| tmux attach-session -t "$sess" \; select-window -t "$sess:$widx" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| set -l default_sessions primary mobile desktop work | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| # Build candidate list: default sessions first, then any extra existing sessions | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -145,6 +145,12 @@ bind Tab switch-client -l | |||||
| # Cross-session window picker | ||||||
| bind W run-shell "tmux new-window 'fish -c _tsw_function'" | ||||||
|
|
||||||
| # Pane content search (live + archived) | ||||||
| bind H run-shell "tmux new-window 'fish -c _tsh_function'" | ||||||
|
|
||||||
| # Kill sessions/windows via fzf | ||||||
| bind K run-shell "tmux new-window 'fish -c _tsk_function'" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: This rebinds the existing Prompt for AI agents
Suggested change
|
||||||
|
|
||||||
| # Extrakto (text extraction) | ||||||
| set -g @extrakto_key 'tab' | ||||||
|
|
||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Archive-only search is currently unreachable.
Line [6] returns when
pane_diris missing, even ifarchive_direxists. That breaks the intended “live + archived” behavior.Proposed fix
Also applies to: 12-13
🤖 Prompt for AI Agents