mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-09 13:21:42 +00:00
opentui(v6): arrows + enter navigate every completion menu (paths, args)
This commit is contained in:
parent
72118b049f
commit
e1edbb0e89
3 changed files with 18 additions and 7 deletions
|
|
@ -47,12 +47,17 @@ function clampSelected(ctx: MenuKeyContext): number {
|
|||
* Route one key press against the open menu. `modified` is Ctrl/Alt/Option —
|
||||
* modified arrows/Enter never belong to the menu (Tab/Esc keep their
|
||||
* pre-existing modifier-blind accept/dismiss semantics).
|
||||
*
|
||||
* ANY open menu owns plain arrows/Enter (glitch, 2026-06-10): @-path and
|
||||
* arg menus navigate exactly like the slash menu — standard editor-
|
||||
* autocomplete behavior; Esc dismisses to hand the cursor keys back.
|
||||
* (`ctx.slashMenu` still feeds the hint text + suggestion rows.)
|
||||
*/
|
||||
export function routeMenuKey(name: string, modified: boolean, ctx: MenuKeyContext): MenuKeyAction {
|
||||
if (ctx.count <= 0) return PASS
|
||||
if (name === 'tab') return { index: clampSelected(ctx), kind: 'accept' }
|
||||
if (name === 'escape') return { kind: 'dismiss' }
|
||||
if (modified || !ctx.slashMenu) return PASS
|
||||
if (modified) return PASS
|
||||
const sel = clampSelected(ctx)
|
||||
if (name === 'up') return { kind: 'move', selected: (sel - 1 + ctx.count) % ctx.count }
|
||||
if (name === 'down') return { kind: 'move', selected: (sel + 1) % ctx.count }
|
||||
|
|
|
|||
|
|
@ -47,9 +47,17 @@ describe('routeMenuKey — key-routing precedence table', () => {
|
|||
['Esc dismisses', 'escape', false, ctx({ selected: 2 }), { kind: 'dismiss' }],
|
||||
// NOT the slash menu (path/@-mention dropdown): arrows + Enter keep their
|
||||
// existing meanings (history / cursor / textarea submit) …
|
||||
['Down on a path menu passes', 'down', false, ctx({ slashMenu: false }), { kind: 'pass' }],
|
||||
['Up on a path menu passes', 'up', false, ctx({ slashMenu: false }), { kind: 'pass' }],
|
||||
['Enter on a path menu passes (submits as today)', 'return', false, ctx({ slashMenu: false }), { kind: 'pass' }],
|
||||
// glitch 2026-06-10: ANY open menu owns plain arrows/Enter (path/arg menus
|
||||
// navigate like the slash menu; Esc hands the cursor keys back).
|
||||
['Down on a path menu moves', 'down', false, ctx({ slashMenu: false }), { kind: 'move', selected: 1 }],
|
||||
['Up on a path menu moves (wraps)', 'up', false, ctx({ slashMenu: false }), { kind: 'move', selected: 2 }],
|
||||
[
|
||||
'Enter on a path menu accepts the highlighted item',
|
||||
'return',
|
||||
false,
|
||||
ctx({ slashMenu: false }),
|
||||
{ index: 0, kind: 'accept' }
|
||||
],
|
||||
// … but Tab/Esc keep working on ANY menu (pre-Epic-8 semantics)
|
||||
['Tab on a path menu still accepts', 'tab', false, ctx({ slashMenu: false }), { index: 0, kind: 'accept' }],
|
||||
['Esc on a path menu still dismisses', 'escape', false, ctx({ slashMenu: false }), { kind: 'dismiss' }],
|
||||
|
|
|
|||
|
|
@ -234,7 +234,6 @@ export function Composer(props: {
|
|||
// Whether the composer text starts with `/` (slash menu vs path menu) — a
|
||||
// signal so the dropdown hint stays reactive; the key handler re-checks
|
||||
// `ta.plainText` directly.
|
||||
const [slashText, setSlashText] = createSignal(false)
|
||||
|
||||
/** Replace the textarea content and park the cursor at the end (history recall). */
|
||||
const setBuffer = (text: string) => {
|
||||
|
|
@ -416,7 +415,7 @@ export function Composer(props: {
|
|||
)}
|
||||
</For>
|
||||
<text selectable={false} fg={theme().color.muted}>
|
||||
{slashText() ? '↑/↓ select · Enter/Tab accept · Esc dismiss' : 'Tab complete · Esc dismiss'}
|
||||
{'↑/↓ select · Enter/Tab accept · Esc dismiss'}
|
||||
</text>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -460,7 +459,6 @@ export function Composer(props: {
|
|||
}}
|
||||
onContentChange={() => {
|
||||
const text = ta?.plainText ?? ''
|
||||
setSlashText(text.startsWith('/'))
|
||||
setBufText(text) // drives the token analysis (highlight + suggestion)
|
||||
props.onType?.(text)
|
||||
}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue