Skip to content

refactor(engine): leave the menu accept rule in one place - #1210

Open
shreeve wants to merge 1 commit into
nushell:mainfrom
shreeve:menu-accept-is-the-one-rule
Open

refactor(engine): leave the menu accept rule in one place#1210
shreeve wants to merge 1 commit into
nushell:mainfrom
shreeve:menu-accept-is-the-one-rule

Conversation

@shreeve

@shreeve shreeve commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Summary

The follow-up from #1175, as suggested there.

Enter grew a guard that accepts an open menu's selection, and #1203 landed
MenuAccept carrying the same rule a second time. They are not even spelled the
same way: the guard filters on is_active() && !get_values().is_empty(), while
MenuAccept finds the first active menu and checks emptiness afterwards. Those
disagree when the first active menu is the empty one — unreachable today, since
ReedlineEvent::Menu refuses to activate while active_menu() is Some, but it is
the drift worth removing rather than documenting.

Enter, Submit and SubmitOrNewline now try MenuAccept first and carry on to
the submit path when it declines, which is what the guard was arranging for. The
guarded arm goes away, the rule lives in the MenuAccept arm, and each submit arm
says plainly that a menu gets first refusal.

Behavior

Unchanged. MenuAccept reports Inapplicable for exactly the cases the guard
excluded — no menu open, or an open menu with nothing to accept — and the
delegation sits at the top of each arm, ahead of the bashisms and abbreviation
expansion, so the ordering is what it was.

Worth noting the guard covered Submit and SubmitOrNewline as well as Enter,
and nothing tested that. It does now.

One thing this surfaced, not fixed here

MenuAccept does not check results_are_provisional(), so accepting over stale
suggestions splices nothing — the span belongs to another line and is refused
downstream — while Deactivate still runs and the arm still reports Handled. A
dead key, reachable with an async completer. decide_menu_completion and MenuNext
both guard this explicitly and their comments say exactly why.

This is not a regression: the deleted guard had no provisional check either, so
Enter behaved this way already. But this PR is what makes MenuAccept the single
path, and the rule it now owns is missing a check its two siblings have. Happy to fix
it in a follow-up, or fold it in here if you would rather it not land as-is.

Tests

Two rstest cases over all three events:

  • every_submit_event_accepts_an_open_menu — the menu takes the keypress, closes,
    and its selection reaches the buffer
  • every_submit_event_passes_an_empty_menu — once the menu has nothing to offer,
    the line runs

Both pass on the two-rule version as well, which is the point: they pin the
behavior, and this does not move it.

cargo fmt --check and cargo clippy --all-targets --all-features -- -D warnings
are clean; the suite passes with default and with all features.

`Enter` grew a guard that accepts an open menu's selection, and `MenuAccept`
landed with the same rule written a second way: the guard filters on
`is_active() && !get_values().is_empty()`, `MenuAccept` finds the first
active menu and checks emptiness after. Nothing can tell them apart today,
since `ReedlineEvent::Menu` will not activate a second menu while one is
open, but the two are already spelled differently and only one of them is
the one anybody reads.

`Enter`, `Submit` and `SubmitOrNewline` now offer an open menu first refusal
and carry on to the submit path when it declines, which is what the guard
was arranging for. The rule lives in the `MenuAccept` arm, and the reasoning
that used to sit above `Enter` describing the guard sits with it.

The behavior is unchanged, and the new cases pin it from both sides: all
three events accept an open menu, and all three run the line once the menu
has nothing to offer. They pass on the two-rule version too.
@shreeve
shreeve force-pushed the menu-accept-is-the-one-rule branch from 93a7c2e to 2a043ad Compare September 9, 2026 12:42
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