Skip to content

feat(editor): word-accept and cycling for inline suggestions (#140) - #175

Merged
LESdylan merged 2 commits into
developfrom
feat/suggest-word-cycle
Oct 18, 2026
Merged

LESdylan merged 2 commits into
developfrom
feat/suggest-word-cycle

Conversation

@qwO-Owp

@qwO-Owp qwO-Owp commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Part of #140 (PR3b). Frecency (PR3c) follows separately.

Key With a history ghost Otherwise
Alt-F, Ctrl-Right (\e[1;5C, \e[5C) take the next word of the ghost stock forward-word
Alt-N next older distinct match; bell at the oldest, no wrap stock non-incremental search
Alt-P back to the newer alternative; bell at the newest stock non-incremental search
  • Every key goes through the slot module, so a user bind/bindkey wins, and nothing changes while HELLISH_AUTOSUGGEST is off.
  • A widget's POSTDISPLAY ghost isn't history, so it is never cycled or taken word by word.
  • The cycle stores history indices. It resets when the line or the history length changes. Cost per Alt-N: O(HELLISH_SUGGEST_MAX × (line + offered)).

Review fix: a bind -x widget that ran history -c mid-cycle left the indices past the end. C11 covers it. Mutant M11, which removes the length check, keeps a stale ghost and produces an ASan heap error.

Mutants

Mutant Red cases
M1 6
M2 10
M3 5
M4 1 (C2)
M5 4
M6 1 (C4)
M7 2 (C9)
M8 4
M9 2
M10 1 (C5)
M11 2, plus ASan

Local gates

Gate Result
make re, make re OPT=1, make re OPT=1 SAFE=1 rc 0, no warnings
norminette (src, incs) 0 errors
golden suite 5363/5363
make pty-test (ASan) 119 ok / 0 failed / 6 skipped
autosuggest_test.py all clear, both readers
verify_alloc.sh identical on both heaps
make help-test 0 failed

Not checked locally: frontend_budget_test.py needs strace, which isn't installed here, so CI is its only run.

A known leak that isn't new: with AS_LEAKS=1, stock Alt-N followed by Ctrl-G leaks 336 bytes in 2 allocations inside libreadline's xmalloc. The same amount leaks on develop without this PR.

🤖 Generated with Claude Code

…#140)

Alt-F / Ctrl-Right take the next word of the ghost; Alt-N / Alt-P step to
the next older / back to the newer distinct history match. All four go
through the slot module: with no history ghost on screen, or when the
user bound the key, the stock readline function (forward-word,
non-incremental search) runs unchanged. The cycle keeps history indices,
not copies, and is dropped when the line or the history length changes,
so a bind -x widget running `history -c` mid-cycle cannot leave it
pointing past the end.

Tests: autosuggest_test.py W1-W6, C1-C11 on both readers. Mutants M1-M10
(slot wiring, word boundaries, cycle order, dedupe, bell ends, user-bind
precedence) each turn at least one case red. M11, dropping the
history-length check, leaves a ghost after `history -c` and draws an ASan
heap error. The 168-byte AS_LEAKS=1 report after stock Alt-N + Ctrl-G
shows up identically on develop without this change (readline's own
non-incremental search).
@LESdylan
LESdylan merged commit 1c6862f into develop Oct 18, 2026
62 checks passed
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.

2 participants