LLE: inline shadow ghost for the open completion menu's top candidate#357
Merged
Conversation
The move-or-accept-suggestion keys -- RIGHT, END, Ctrl-E, Ctrl-F, and the forward-word/partial-accept (Ctrl-Right, Meta-f) -- gate on has_autosuggestion(), which reported a suggestion whenever ctx->current_suggestion was non-empty. update_autosuggestion() fills that buffer regardless of whether a completion menu is visible, while the display suppresses the history ghost under a menu. The two disagreed: with a menu open, the keys spliced the invisible history suggestion into the command line underneath the menu, leaving the menu box drawn for the old word over a buffer that had changed. Only the RIGHT context action carried its own menu guard. Rather than copy that guard into every accept handler, report no autosuggestion from has_autosuggestion() while a completion menu is visible: the history ghost is suppressed then and the menu's candidate is committed through menu navigation, not the accept handlers. Every accept key falls through to its normal motion instead of splicing text under the menu; the menu's own navigation keys do not consult has_autosuggestion and are unaffected. No-menu acceptance is unchanged.
A completion menu opened in pre-navigation keeps the command line literal and lists candidates in the box below, but nothing previewed the candidate that a single Right/accept would take. Offer the highlighted candidate inline as a faint shadow ghost over the open menu -- the menu's companion to the history autosuggestion. The ghost and an open menu were mutually exclusive by design: three !completion_menu_visible guards (geometry, render, and the layer store) cleared the ghost whenever a menu was up. Relax the geometry and render guards for the single shadow case behind menu_shadow_active, set through a new display_controller_set_menu_shadow. The ghost wrap rows are now part of screen_buffer geometry, so a shadow drawn over a menu composes with the menu rows in one num_rows total -- the cursor math and prior-frame cleanup handle command + shadow + menu uniformly, with no second accounting path (an earlier attempt collapsed the cursor precisely because that path did not exist yet). The shadow is driven from one point in refresh_display: the menu's current selection is recomputed into the candidate's remainder (the splicer in accept phase, exactly as the completion-fallback autosuggestion) every refresh, so it tracks open, filter, the first navigation that leaves pre-navigation, and close with no per-keybinding wiring. set_menu_shadow only overrides the shared autosuggestion layer; it never clears it, so the history ghost survives on menu-less frames. It clears outside pre-navigation, off the buffer end, and with no menu. Gated by completion.menu_shadow_ghost, curated on in lush mode and off in bash/zsh/posix (which show the menu box alone, matching readline/zle); settable via lushrc.toml.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Completes the ghost-over-menu work begun in #356. When a completion menu opens in pre-navigation, its highlighted candidate is now shown inline after the command as a faint shadow ghost while the menu box lists the alternatives below -- the menu's companion to the history autosuggestion. A single Right (menu commit) takes it.
Built on #356's unified geometry: the ghost wrap rows live in
screen_buffer(num_rows), so a shadow drawn over a menu composes with the menu rows in one cursor-math total. The earlier shadow attempt collapsed the cursor precisely because that accounting path did not exist yet; it does now.Two commits:
Suppress autosuggestion acceptance while a completion menu is open. A pre-existing defect the shadow made visible: the move-or-accept-suggestion keys (RIGHT, END, Ctrl-E, Ctrl-F, Ctrl-Right/Meta-f partial-accept) gated on
has_autosuggestion(), which reported the (display-suppressed) history suggestion even under a menu, so they spliced it into the buffer underneath the menu. Fixed at the single shared predicate rather than per-handler:has_autosuggestion()reports nothing while a menu is visible.The shadow ghost itself.
display_controller_set_menu_shadowoverrides the shared autosuggestion layer (never clears it, so the history ghost survives menu-less frames) and raisesmenu_shadow_active, which relaxes the geometry + render ghost guards for that one case. Driven from a single chokepoint inrefresh_display; recomputed every refresh, so it tracks open / filter / leave-pre-navigation / close with no per-keybinding wiring.Curation
Gated by
completion.menu_shadow_ghost: curated on in lush mode, off in bash/zsh/posix (which show the menu box alone, matching readline/zle). Settable vialushrc.toml.Verification
meson test: 156/156, zero warnings (werror).🤖 Generated with Claude Code