aboutsummaryrefslogtreecommitdiff
path: root/tmuxrdr/ROADMAP.md
blob: e91477580e1c1065fa65936d6c3432d3b8971a87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# tmuxrdr roadmap: what only patching herdr can do

What is left of tmux's default prefix table, and of this machine's tmux.conf,
after `tmuxrdr/config/config.toml` and the tmux-mode plugin (`tmuxrdr/plugin`).
Each gap: what tmux does, why neither config nor plugin reaches it, and the
patch -- with touch points checked against the herdr v0.9.3 source, the base
this branch sits on. Each becomes one commit on the `tmuxrdr` branch, kept
small for rebasing (README.md, "Maintaining").

Applied so far: tmuxrdr's own directories -- `app_dir_name()` in
`src/config/io.rs` returns `tmuxrdr` -- so it runs beside stock herdr; and
tmux's status line as the tab row (`ui.tab_style = "tmux"`,
`src/client/shell/tabs_tmux.rs`). None of the patches below is applied yet.

## Coverage

tmux 3.7c's default prefix table has 88 bindings (`tmux -L x -f /dev/null
start-server \; list-keys -T prefix`). With this machine's tmux.conf on top:

- **67 bound** in config or plugin, each pressed in a tmuxrdr client (run in a
  throwaway tmux on its own socket) and its effect checked through the herdr
  CLI -- except `M-n`/`M-p`, seen only to do no harm with no agents running,
  and of `1`..`9` only 1 and 3. Approximate rather than exact: `w` `f` `q` (herdr's
  navigator), `/` (help, filtered), `C` (settings), `M-n` `M-p` (agents, not
  alerts), `E` (evens the whole tab, not just the current pane's
  neighbours), the C-/M-arrow step sizes (fractions of the area, not cells),
  and window indexes (positions -- see "Stable window indexes").
- **5 moot**: `S-Up` `S-Down` `S-Left` `S-Right` and `DC` pan or reset the view
  of a client smaller than its window. Herdr always sizes a tab to its client.
- **16 need a fork**: `Space`, `M-1`..`M-7`, `<`, `>`, `#`, `=`, `-`, `D`,
  `C-z`, `PPage` -- below, with the behaviours a binding cannot carry.

## Where patches go

Building, installing and rebasing are in README.md. For the patches below:
the keybinding layer is compact -- adding an action touches four files:
`src/config/keybinds.rs` (config field, parser), `src/input/keybindings.rs`
(`KeybindAction`, resolver table), `src/client/shell/input.rs` (mode
dispatch), `src/client/shell/actions.rs` (what it does). Put the logic in new
files where it can live apart, so the lines that touch upstream's stay few.

## Patches, smallest first

### 1. PageUp/PageDown/Home/End/Delete/Insert key names -- tmux `PPage`
- tmux: `prefix+PPage` is `copy-mode -u`, copy mode scrolled up a page.
- Gap: `parse_key_combo` (`src/config/keybinds.rs`, the `match lower.as_str()`
  near line 1303) knows no `pageup`, so nothing can bind it -- upstream
  issue #4892, "Keybinding will not accept PageUp", opened 2026-10-04. Copy
  mode is client-side and not in the CLI, so no plugin can enter it either.
- Patch: six arms in that match (`"pageup" | "ppage" => KeyCode::PageUp`, ...);
  a `copy_mode_page_up` action that enters copy mode and applies the page-up
  path `src/client/shell/copy_mode.rs` already has (`KeyCode::PageUp`, line
  161). Bind `prefix+pageup`. Small; the key names alone are a likely-accepted
  upstream PR.

### 2. Repeatable bindings -- tmux `-r`, repeat-time 500 ms
- tmux: arrows (select-pane), C-arrows and M-arrows (resize) repeat --
  prefix once, then the arrow as often as wanted within 500 ms of the last.
- Gap: `src/client/shell/input.rs`, the `ClientShellMode::Prefix` arm, sets
  `self.mode = return_mode` before running any binding: prefix mode is one
  key, always. herdr's resize mode (`prefix+ctrl+r` here) is the nearest.
- Patch: a `repeat` flag on bindings (config: a `keys.repeatable` list of
  action names, plus `repeat = true` on `[[keys.command]]` for the C-arrow
  commands) and `keys.repeat_time` (ms, default 500). After a repeatable
  binding, stay in Prefix with `prefix_repeat_deadline = now + repeat_time`;
  on the next key past the deadline, drop to terminal mode and route the key
  as typed -- tmux checks on the key too, so no timer is needed. Small to
  medium.

### 3. synchronize-panes -- tmux.conf's ``bind ` setw synchronize-panes``
- tmux: every pane of the window gets the keys typed into one.
- Gap: no API takes input once for many panes, and input routing is in the
  client. Upstream discussion "Hotkey / Toogle to Synchronize Input to All
  Panes in a Workspace" asks for exactly this.
- Patch: a per-tab `synchronized` flag and a `toggle_synchronize_panes`
  action; in `input.rs`'s Terminal arm, where keys go to
  `self.focused_pane_id().map(ClientInputTarget::Pane)` (line 577), fan out
  to every pane of the tab while the flag is set; mark it in the tab bar.
  Small to medium.

### 4. C-z suspend-client
- tmux: stops the client (SIGTSTP) and returns to the shell that started it;
  `fg` brings it back.
- Gap: client-only; nothing in the client handles it (no SIGTSTP in
  `src/client`).
- Patch: an action that leaves the alternate screen and raw mode, raises
  SIGTSTP, and on SIGCONT re-enters them and forces a full redraw. Small.
  (Under `exec herdr` from a terminal emulator there is no shell to return
  to -- tmux has the same problem -- so this matters only for herdr started
  by hand.)

### 5. Stable window indexes -- tmux's renumber-windows off
- tmux: closing window 2 of 3 leaves 1 and 3; prefix+3 still reaches the
  third.
- Gap: herdr shows an unnamed tab's place (`tab_display_name`,
  `src/workspace.rs` line 442: `tab_idx + 1`) and switch_tab counts places
  (`src/client/shell/actions.rs` line 955), so tabs renumber on every close
  -- tmux with renumber-windows on.
- Patch: a `ui.stable_tab_numbers` option showing each tab's public number
  (already kept: `next_public_tab_number`) and making switch_tab, `0` and `'`
  select by it. Small. Optional -- many tmux users set renumber-windows on.

### 6. `<` `>` window and pane menus
- tmux: prefix+< and prefix+> open the window and pane menus.
- Gap: herdr's menus are right-click only (`src/client/shell/context_menu.rs`);
  no action opens one from the keyboard.
- Patch: `open_tab_menu` and `open_pane_menu` actions opening the existing
  menus anchored on the focused tab and pane. Small to medium.

### 7. Marked-pane border
- tmux: the marked pane's border is highlighted.
- Gap: plugins cannot style borders; tmux-mode toasts "pane N marked"
  instead.
- Patch: a `marked` pane flag settable over the socket, drawn by the border
  rendering in `src/ui/panes.rs`; the plugin then sets it. Small.

### 8. Layouts -- `Space`, `M-1`..`M-7`
- tmux: next-layout and select-layout even-horizontal, even-vertical,
  main-horizontal, main-vertical, tiled, and the two mirrored mains, with
  main-pane-width 80 and main-pane-height 24.
- Gap: a tab is a BSP tree (`Node`, `src/layout.rs` line 73). The socket can
  set split ratios (`layout.set_split_ratio`, which tmux-mode's `E` uses) but
  not move a pane within its tab (`pane move` to the same tab reports
  `changed: false`), and `layout.apply` replaces the tab and kills its
  processes. A plugin could round-trip every pane through temporary tabs
  (`pane move` keeps a pane's process) and rebuild the tree -- it works on
  paper, flickers through tab creation in practice, and is not done here.
- Patch: `Layout::apply_preset(preset, ordered_panes)` in `src/layout.rs`
  rebuilding the tree from the pane order -- panes are ids in the tree, so
  their processes are untouched -- with the seven presets and tmux's
  main-pane sizes; `select_layout_*` and `next_layout` actions (per-tab index
  for the cycle). Medium.

### 9. display-panes -- `q`
- tmux: numbers on every pane for display-panes-time (1 s); a digit picks one.
- Gap: needs an overlay over the panes and a timed input mode. herdr's
  navigator stands in on `q`.
- Patch: a `DisplayPanes` client mode with a deadline, the numbers drawn by
  `src/client/shell/render.rs`, digits focusing the pane. Medium.

### 10. Paste buffers -- `#` `=` `-`
- tmux: a stack of copied buffers (buffer-limit 50); list-buffers,
  choose-buffer, delete-buffer.
- Gap: herdr writes copies straight to the system clipboard
  (`write_clipboard`, `src/platform/macos.rs` line 631), and plugins see no
  copy event, so nothing can keep a history. tmux-mode's `]` pastes the
  clipboard, which is tmux's newest buffer.
- Patch: push each copy onto a capped buffer list as it is written; a buffer
  view for `#`, a picker for `=` that pastes through the bracketed-paste path
  `pane send-text` already uses (`encode_api_text`,
  `src/app/api_helpers.rs`), delete for `-`. Medium.

### 11. `D` choose-client
- tmux: lists attached clients; pick one to detach.
- Gap: no client list in the CLI or UI.
- Patch: a client registry query on the server and a picker. Medium; low
  value on a single-user machine.