Skip to content

feat(ui): define the global keys, and give the status bar three zones - #49

Merged
stanlyzoolo merged 1 commit into
mainfrom
feat/hotkeys-global-layout
Jul 29, 2026
Merged

feat(ui): define the global keys, and give the status bar three zones#49
stanlyzoolo merged 1 commit into
mainfrom
feat/hotkeys-global-layout

Conversation

@stanlyzoolo

Copy link
Copy Markdown
Owner

A key is global when it does the same thing in every focus. Six do, and the status bar now carries exactly those:

keepkit v0.1.0          t track  u untrack  m rename  a api  ? keys  q quit          api ▮▮▮░░░░░░░░░ 15/60

enter and / used to lead that list and are the two that failed the definition — enter runs a tool in [1], installs a release in [2] and is unbound in [3]; / filters the list in [1] but searches [3]'s text from [2]. The bar could only ever advertise one of their meanings and be wrong in the other panels. Both moved to [1]'s footer beside space group.

The bar is three zones

Version pinned left, keys centered, gauge pinned right (renderHintsBar, render.go). Centering is measured against the whole bar and then clamped into the band the two edges leave, so a narrow terminal pushes the block up against the version cell instead of overlapping it. The collapsed self-update cell rides with the version: it carries its action alone (U update) and the version cell is the subject naming what is being updated.

Drop order under width pressure: trailing hints, then the gauge, then the version, then the self cell. The leading cell is truncated, never wrapped — a wrapped bar makes View() return height+1 rows and scrolls the top border off the alt screen.

Two key collisions had to be settled

m takes rename, so [3]'s man source becomes M — and the whole trio goes capital: R readme, H help, M man. That retires the worst of the old overlaps: the [3] title advertised r readme regardless of focus, so pressing r from [2] silently spent three API requests on a refresh instead. All three now fire from [2] as well as [3]; lowercase r means refresh and nothing else.

API overlay: La.

Fixed on the way

  • panelFooter reserved 2 cells for the gap to a right cell that does not exist. [1] and [2] pass "" there, so [1] lost its last footer cell one step earlier than the width required.
  • The tag-grouping refusal still said press [t]. t has been the track verb since the tag editor moved to #.

Known limit

[1] is 20% of the width, so the three footer cells (34 columns with separators) only all fit on a wide terminal:

terminal [1] inner footer
200 36 / filter · enter run · space group
120–160 20–28 / filter · enter run
≤100 (incl. the 80-col baseline) 12–16 / filter

Cells drop from the right in priority order. Shortening the labels or widening [1]'s share would buy the third cell back; neither is in this PR.

Testing

  • TestRunHintLivesInToolsFooter, TestToolsFooterCellOrderenter is in [1]'s footer and out of the bar; cell order and drop order.
  • TestRenderHintsBarAlignment — three zones: version at the left edge, hint block centered on the bar within ±1 cell, gauge at the right edge, plus the clamped narrow case.
  • TestReadmeKeyBranchesR fires from both [2] and [3], r no longer switches the source, m renames.
  • TestModeEnterAndEsc — each global verb opens its mode from a panel other than [1].
  • Existing bar/gauge/placeholder tests rewritten to the new invariant rather than relaxed.

Every new assertion was mutation-checked: reverting the production edit turns it red (7/7 killed). Rendered output read at 80 and 120 columns.

CLAUDE.md, ARCHITECTURE.md and README.md updated in the same commit.

Preflight green: go build / go vet / go test -race ./... / golangci-lint run.

Not in scope

Four findings from the same review are left alone: ctrl+c is dead in 11 of 13 input modes, / is a silent no-op in readme mode, l (focus right) is bound but undocumented, and [3]'s footer says ctrl+d/u page where the [?] overlay says half page.

The demo GIFs show the status bar and footers and are now stale.

A key is global when it does the same thing in every focus. Six do —
t track, u untrack, m rename, a api, ? keys, q quit — and the status bar
now carries exactly those. enter and / used to lead the list and are the
two that failed the definition: enter runs a tool in [1], installs a
release in [2] and is unbound in [3]; / filters the list in [1] but
searches [3]'s text from [2]. Both moved to [1]'s footer beside space
group, where their meaning is fixed.

The bar is three zones: the running version pinned left, the six keys
centered on the bar, the API gauge pinned right. Centering is measured
against the whole bar and then clamped into the band the edges leave, so
a narrow terminal pushes the block up against the version cell instead
of overlapping it. The collapsed self-update cell rides with the version
— it carries its action alone, and the version cell is the subject that
names what is being updated.

Two collisions had to be settled to free the letters. Rename takes m, so
panel [3]'s man source becomes M — and with it the whole trio goes
capital: R readme, H help, M man. That also retires the worst of the old
overlaps, where the [3] title advertised "r readme" while pressing r in
[2] silently spent three requests on a refresh. All three now fire from
[2] as well as [3]; lowercase r means refresh and nothing else. The API
overlay moves L -> a.

Also fixed on the way: an absent right cell in a panel footer reserved
two cells for the gap to a neighbour that does not exist, which dropped
[1]'s last footer cell one step earlier than the width required; and the
tag-grouping refusal still pointed at [t], which has been the track verb
since the tag editor moved to [#].

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@stanlyzoolo
stanlyzoolo merged commit 9ca6573 into main Jul 29, 2026
3 checks passed
@stanlyzoolo
stanlyzoolo deleted the feat/hotkeys-global-layout branch July 29, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant