refactor(daemon): tidy palette helpers and review nitpicks
Move palette generation-guard helpers onto attachedClient since they never touch Daemon state, drop a redundant nil check and stray blank line, hoist an argument-command lookup out of the palette render loop, and clarify the JRS/BSK README wording.
- commit
- 9d03f4bb4662d015d8f88eca88dd1e37a3fa74f7
- author
- brice · · 2026-07-11 14:04 UTC
- parent
- 9d575ec
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
4 files · +6 -9
M README.md +1 -1
| @@ -180,7 +180,7 @@ Some terminals encode Alt+Space as a non-breaking space instead of `ESC Space`; | |||
| 180 | 180 | ||
| 181 | 181 | Open the palette with Alt+Space. Type a command code or fuzzy-match the label/description. Use Up/Down or Ctrl-N/Ctrl-P to move, Enter to run, and Esc/Ctrl-C to close. | |
| 182 | 182 | ||
| 183 | - | Successful commands are promoted near the top the next time the palette opens. `BSK` toggles only this client's previously active session. Type an exact `JRS` token to show the current interaction's immutable recent-session ranks; `JRS N` jumps to rank N. Invalid or stale ranks leave the palette open. | |
| 183 | + | Successful commands are promoted near the top the next time the palette opens. `BSK` toggles back to your previously active session. Typing `JRS` lists recent sessions by number in the status bar, and `JRS N` jumps to number N; the numbers are captured when you start typing, so a busy MRU list never shifts under you. An invalid or stale number leaves the palette open. | |
| 184 | 184 | ||
| 185 | 185 | | Code | Action | | |
| 186 | 186 | |---|---| | |
| @@ -180,7 +180,7 @@ Some terminals encode Alt+Space as a non-breaking space instead of `ESC Space`; | |||||
| 180 | 180 | ||||
| 181 | Open the palette with Alt+Space. Type a command code or fuzzy-match the label/description. Use Up/Down or Ctrl-N/Ctrl-P to move, Enter to run, and Esc/Ctrl-C to close. | 181 | Open the palette with Alt+Space. Type a command code or fuzzy-match the label/description. Use Up/Down or Ctrl-N/Ctrl-P to move, Enter to run, and Esc/Ctrl-C to close. | ||
| 182 | 182 | ||||
| 183 | - | Successful commands are promoted near the top the next time the palette opens. `BSK` toggles only this client's previously active session. Type an exact `JRS` token to show the current interaction's immutable recent-session ranks; `JRS N` jumps to rank N. Invalid or stale ranks leave the palette open. | 183 | + | Successful commands are promoted near the top the next time the palette opens. `BSK` toggles back to your previously active session. Typing `JRS` lists recent sessions by number in the status bar, and `JRS N` jumps to number N; the numbers are captured when you start typing, so a busy MRU list never shifts under you. An invalid or stale number leaves the palette open. |
| 184 | 184 | ||||
| 185 | | Code | Action | | 185 | | Code | Action | | ||
| 186 | |---|---| | 186 | |---|---| | ||
M internal/usecase/daemon/picker.go +0 -1
| @@ -378,7 +378,6 @@ func (d *Daemon) switchToTarget(sess *session, ac *attachedClient, target picker | |||
| 378 | 378 | return false | |
| 379 | 379 | } | |
| 380 | 380 | if old != nil && old != ac { | |
| 381 | - | ||
| 382 | 381 | d.unregisterPreview(old) | |
| 383 | 382 | old.clearPreviousSession() | |
| 384 | 383 | old.setSession(nil) | |
| @@ -378,7 +378,6 @@ func (d *Daemon) switchToTarget(sess *session, ac *attachedClient, target picker | |||||
| 378 | return false | 378 | return false | ||
| 379 | } | 379 | } | ||
| 380 | if old != nil && old != ac { | 380 | if old != nil && old != ac { | ||
| 381 | - | ||||
| 382 | d.unregisterPreview(old) | 381 | d.unregisterPreview(old) | ||
| 383 | old.clearPreviousSession() | 382 | old.clearPreviousSession() | ||
| 384 | old.setSession(nil) | 383 | old.setSession(nil) | ||
M internal/usecase/daemon/status.go +1 -3
| @@ -281,9 +281,7 @@ func (d *Daemon) barStateForContextual(cur *session, copyFeedback string, ranked | |||
| 281 | 281 | ||
| 282 | 282 | func (d *Daemon) barStateFor(cur *session, copyFeedback string) barState { | |
| 283 | 283 | state := d.barStateBase(cur, copyFeedback) | |
| 284 | - | if d != nil { | |
| 285 | - | state.mru = d.recentSessions(cur) | |
| 286 | - | } | |
| 284 | + | state.mru = d.recentSessions(cur) | |
| 287 | 285 | return state | |
| 288 | 286 | } | |
| 289 | 287 | ||
| @@ -281,9 +281,7 @@ func (d *Daemon) barStateForContextual(cur *session, copyFeedback string, ranked | |||||
| 281 | 281 | ||||
| 282 | func (d *Daemon) barStateFor(cur *session, copyFeedback string) barState { | 282 | func (d *Daemon) barStateFor(cur *session, copyFeedback string) barState { | ||
| 283 | state := d.barStateBase(cur, copyFeedback) | 283 | state := d.barStateBase(cur, copyFeedback) | ||
| 284 | - | if d != nil { | 284 | + | state.mru = d.recentSessions(cur) |
| 285 | - | state.mru = d.recentSessions(cur) | |||
| 286 | - | } | |||
| 287 | return state | 285 | return state | ||
| 288 | } | 286 | } | ||
| 289 | 287 | ||||
M internal/usecase/palette/model.go +4 -4
| @@ -93,6 +93,7 @@ func (m *Model) ArgumentCommand() (command.Command, bool) { | |||
| 93 | 93 | } | |
| 94 | 94 | return ArgumentCommand(m.commands, m.Query()) | |
| 95 | 95 | } | |
| 96 | + | ||
| 96 | 97 | func (m *Model) Matches() []Match { | |
| 97 | 98 | if m == nil { | |
| 98 | 99 | return nil | |
| @@ -178,6 +179,7 @@ func (m *Model) Render(inner domain.Size, opts RenderOptions) renderer.Frame { | |||
| 178 | 179 | codeWidth = len([]rune(match.Command.Code)) | |
| 179 | 180 | } | |
| 180 | 181 | } | |
| 182 | + | activeCmd, activeOK := m.ArgumentCommand() | |
| 181 | 183 | for y := range visible { | |
| 182 | 184 | idx := m.scroll + y | |
| 183 | 185 | if idx >= len(m.matches) { | |
| @@ -211,10 +213,8 @@ func (m *Model) Render(inner domain.Size, opts RenderOptions) renderer.Frame { | |||
| 211 | 213 | x++ | |
| 212 | 214 | } | |
| 213 | 215 | description := match.Command.Desc | |
| 214 | - | if opts.Guidance != "" && match.Command.ContextHint != command.ContextHintNone && m.Query() != "" { | |
| 215 | - | if active, ok := m.ArgumentCommand(); ok && active.Code == match.Command.Code { | |
| 216 | - | description = opts.Guidance | |
| 217 | - | } | |
| 216 | + | if opts.Guidance != "" && activeOK && match.Command.ContextHint != command.ContextHintNone && activeCmd.Code == match.Command.Code { | |
| 217 | + | description = opts.Guidance | |
| 218 | 218 | } | |
| 219 | 219 | ui.DrawText(frame, x, y+start, frame.Width, description, mergePaletteDescStyle(style, desc)) | |
| 220 | 220 | } | |
| @@ -93,6 +93,7 @@ func (m *Model) ArgumentCommand() (command.Command, bool) { | |||||
| 93 | } | 93 | } | ||
| 94 | return ArgumentCommand(m.commands, m.Query()) | 94 | return ArgumentCommand(m.commands, m.Query()) | ||
| 95 | } | 95 | } | ||
| 96 | + | ||||
| 96 | func (m *Model) Matches() []Match { | 97 | func (m *Model) Matches() []Match { | ||
| 97 | if m == nil { | 98 | if m == nil { | ||
| 98 | return nil | 99 | return nil | ||
| @@ -178,6 +179,7 @@ func (m *Model) Render(inner domain.Size, opts RenderOptions) renderer.Frame { | |||||
| 178 | codeWidth = len([]rune(match.Command.Code)) | 179 | codeWidth = len([]rune(match.Command.Code)) | ||
| 179 | } | 180 | } | ||
| 180 | } | 181 | } | ||
| 182 | + | activeCmd, activeOK := m.ArgumentCommand() | |||
| 181 | for y := range visible { | 183 | for y := range visible { | ||
| 182 | idx := m.scroll + y | 184 | idx := m.scroll + y | ||
| 183 | if idx >= len(m.matches) { | 185 | if idx >= len(m.matches) { | ||
| @@ -211,10 +213,8 @@ func (m *Model) Render(inner domain.Size, opts RenderOptions) renderer.Frame { | |||||
| 211 | x++ | 213 | x++ | ||
| 212 | } | 214 | } | ||
| 213 | description := match.Command.Desc | 215 | description := match.Command.Desc | ||
| 214 | - | if opts.Guidance != "" && match.Command.ContextHint != command.ContextHintNone && m.Query() != "" { | 216 | + | if opts.Guidance != "" && activeOK && match.Command.ContextHint != command.ContextHintNone && activeCmd.Code == match.Command.Code { |
| 215 | - | if active, ok := m.ArgumentCommand(); ok && active.Code == match.Command.Code { | 217 | + | description = opts.Guidance |
| 216 | - | description = opts.Guidance | |||
| 217 | - | } | |||
| 218 | } | 218 | } | ||
| 219 | ui.DrawText(frame, x, y+start, frame.Width, description, mergePaletteDescStyle(style, desc)) | 219 | ui.DrawText(frame, x, y+start, frame.Width, description, mergePaletteDescStyle(style, desc)) | ||
| 220 | } | 220 | } | ||