Files
PodTui/tasks/yazi-remake/06-rewire-keybinds.md
2026-07-31 09:27:57 -04:00

57 lines
3.2 KiB
Markdown

# 06. Rewire keybinds — h/l drill+pop, digits switch tabs, focus starts on current
meta:
id: yazi-remake-06
feature: yazi-remake
priority: P1
depends_on: [yazi-remake-01, yazi-remake-05]
tags: [implementation, keybinds, tests-required]
objective:
- Rewire the Shell dispatch so the sidebar's special-cased j/k branch is gone, h/l drill/pop on depth-tabs and swipe on fixed tabs, digit keys + `[ ]` are the sole tab switcher, and app focus starts on the current pane.
deliverables:
- `src/components/Shell.tsx` (dispatch) — `SIDEBAR_ACTIONS` set + the `if (nav.activePane() === SIDEBAR_PANE)` branch deleted
- `h`/`l` unified: depth-tabs `l`=current-drills (`open` emit), `h`=current-pops (noop at depth 0); fixed-pane tabs `h/l`=`swipe(∓1, count)`
- `1`-`6` / `tab-goto-*`, `tab-next`/`tab-prev` (`[`/`]`) — the only tab switchers
- Initial focus + tab-enter land on `DEPTH_CENTER_PANE`
- `keybinds.jsonc` reviewed (update labels/help only if needed)
steps:
- Read the current `dispatch()` (post task 01 it references a deleted `SIDEBAR_PANE` — fix the compile here)
- Remove the `SIDEBAR_ACTIONS` constant and its branch
- In the `default` case, implement: digit/tab-goto → `setActiveTab`; `swipe-prev` → (depth-tab & current & depth>0) `popDepth` else (depth-tab & current & depth==0) noop else `swipe(-1, count)`; `swipe-next` → (depth-tab & current) emit `open` else `swipe(1, count)`
- Move/list actions (`move-down/up`, `jump-*`, `page-*`, `goto-top/bottom`) flow to `PAGE_ACTIONS``emit("nav.action")` for the current pane only
- Confirm `escape`/`command`/`visual-mode`/`toggle-select`/audio/global branches unchanged
- Verify the app boot path sets focus to current (task 01 set the signal; confirm dispatch doesn't override)
- Run diagnostics + harness key sequence
tests:
- Unit: `dispatch("move-down")` on a depth-tab current pane emits `nav.action {action:"move-down"}` (Arrange current pane, Act, Assert emit)
- Integration: `dispatch("swipe-next")` on a depth-tab at depth 0 emits `open` (drill); `dispatch("swipe-prev")` at depth 1 pops to depth 0; at depth 0 `swipe-prev` is a noop
- e2e (harness): `l` drills (depth 0→1, parent populates), `h` pops (1→0, parent blanks), `1`/`2`/`3` switch tabs, `j`/`k` move the current list cursor without changing depth
acceptance_criteria:
- No `SIDEBAR_PANE` or `SIDEBAR_ACTIONS` references in `Shell.tsx`
- `h` at depth 0 is a noop (does not error, does not change pane)
- `l` at current on a depth-tab drills (depth+1)
- Digit keys switch tabs; focus lands on current pane
- `j`/`k` move within current only
validation:
- `grep -n "SIDEBAR" src/components/Shell.tsx` returns nothing
- `lens_diagnostics` paths=[`src/components/Shell.tsx`] severity=error → 0 findings
- Harness: `init` (focus on current) → `l` (depth 1, parent filled) → `l` (depth 2) → `h` (depth 1) → `h` (depth 0, parent blank) → `3` (Discover tab, focus on current) → `j`/`k` move
notes:
- Depends on 01 (pane model: `swipe` bounds, no SIDEBAR) and 05 (dispatch lives in the rebuilt Shell)
- If `keybinds.jsonc` has a `tab-next`/`tab-prev` mapping conflict, resolve here
- The noop `h` at depth 0 should feel inert (yazi: at root, `h` does nothing)