detached 27d6799

docs: correct notices comments on paint order and toast field matching

render_pipeline.go's modal paint order draws notices over the picker,
while HandleInput's keyboard priority gives the picker precedence over
notices; document that the mismatch is intentional-by-omission and
currently unreachable rather than leaving it unexplained.

model.go's rowMessage comment claimed its "×N" formatting matched the
toast overlay's own count formatting; the format string matches, but
the toast appends ×N to Title while this appends to Message. Correct
the comment to say so.
commit
27d6799b590609e9acc386cba47a07be522dec1a
author
brice · · 2026-07-20 13:41 UTC
parent
ca92619
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +12 -2
M internal/usecase/daemon/render_pipeline.go +8 -0
@@ -274,6 +274,14 @@ func composeCapturedOverlays(state capturedRenderState, frame renderer.Frame, da
274274 if o.paletteActive && !state.floating.visible {
275275 (overlayBackdrop{DimPaneContents: true}).apply(frame, content, layoutSnapshot, state.theme)
276276 }
277+ // This paint order intentionally differs from HandleInput's keyboard
278+ // priority (prompt > palette > picker > notices > copy, see
279+ // overlay_runtime.go), which paints the picker under notices instead of
280+ // over it. Currently unreachable: notices only opens via the palette, and
281+ // HandleInput short-circuits to the first active overlay, so picker and
282+ // notices are never simultaneously active. If that ever changes, this
283+ // mismatch would let the picker own the keyboard while notices visually
284+ // covers it.
277285 for _, modal := range []capturedModal{o.copySearch, o.picker, o.noticesOverlay, o.palette, o.prompt} {
278286 if modal.inner.Width == 0 && modal.inner.Height == 0 {
279287 continue
@@ -274,6 +274,14 @@ func composeCapturedOverlays(state capturedRenderState, frame renderer.Frame, da
274 if o.paletteActive && !state.floating.visible {274 if o.paletteActive && !state.floating.visible {
275 (overlayBackdrop{DimPaneContents: true}).apply(frame, content, layoutSnapshot, state.theme)275 (overlayBackdrop{DimPaneContents: true}).apply(frame, content, layoutSnapshot, state.theme)
276 }276 }
277+ // This paint order intentionally differs from HandleInput's keyboard
278+ // priority (prompt > palette > picker > notices > copy, see
279+ // overlay_runtime.go), which paints the picker under notices instead of
280+ // over it. Currently unreachable: notices only opens via the palette, and
281+ // HandleInput short-circuits to the first active overlay, so picker and
282+ // notices are never simultaneously active. If that ever changes, this
283+ // mismatch would let the picker own the keyboard while notices visually
284+ // covers it.
277 for _, modal := range []capturedModal{o.copySearch, o.picker, o.noticesOverlay, o.palette, o.prompt} {285 for _, modal := range []capturedModal{o.copySearch, o.picker, o.noticesOverlay, o.palette, o.prompt} {
278 if modal.inner.Width == 0 && modal.inner.Height == 0 {286 if modal.inner.Width == 0 && modal.inner.Height == 0 {
279 continue287 continue
M internal/usecase/notices/model.go +4 -2
@@ -121,8 +121,10 @@ func (m *Model) Render(inner domain.Size, styles RenderStyles) renderer.Frame {
121121 return frame
122122 }
123123
124-// rowMessage appends a "×N" coalesce count suffix, matching the toast
125-// overlay's own count formatting.
124+// rowMessage appends a "×N" coalesce count suffix. The format string matches
125+// the toast overlay's own count formatting (internal/usecase/ui.ComposeNotices),
126+// but the field it is appended to differs: the toast appends to Title, while
127+// this row appends to Message, matching this overlay's row layout.
126128 func rowMessage(n domain.Notification) string {
127129 if n.Count > 1 {
128130 return fmt.Sprintf("%s ×%d", n.Message, n.Count)
@@ -121,8 +121,10 @@ func (m *Model) Render(inner domain.Size, styles RenderStyles) renderer.Frame {
121 return frame121 return frame
122 }122 }
123 123
124-// rowMessage appends a "×N" coalesce count suffix, matching the toast124+// rowMessage appends a "×N" coalesce count suffix. The format string matches
125-// overlay's own count formatting.125+// the toast overlay's own count formatting (internal/usecase/ui.ComposeNotices),
126+// but the field it is appended to differs: the toast appends to Title, while
127+// this row appends to Message, matching this overlay's row layout.
126 func rowMessage(n domain.Notification) string {128 func rowMessage(n domain.Notification) string {
127 if n.Count > 1 {129 if n.Count > 1 {
128 return fmt.Sprintf("%s ×%d", n.Message, n.Count)130 return fmt.Sprintf("%s ×%d", n.Message, n.Count)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close