Skip to content

feat: C-l recenter cycle, M-g prefix goto-line, C-h k describe-key - #117

Merged
danielxvu merged 6 commits into
neomgfrom
fm-quick-keybinds
Jul 5, 2026
Merged

feat: C-l recenter cycle, M-g prefix goto-line, C-h k describe-key#117
danielxvu merged 6 commits into
neomgfrom
fm-quick-keybinds

Conversation

@danielxvu

Copy link
Copy Markdown
Owner

feat: three Emacs keybinding gaps

Verified against Emacs 30.2:

  • C-l recenter cycle — was center-only; now cycles middle → top → bottom on consecutive presses (recenter-top-bottom), via a CFRECT flag + w_frame in reposition.
  • M-g prefix → goto-lineM-g was unbound; now a real prefix map so M-g g and M-g M-g both reach goto-line (new gotomap/metagmap; the metamap '['..'h' element split into three sorted elements to give 'g' its own prefix slot).
  • C-h k → describe-key — bound to describe-key-briefly (mg has no doc strings), matching the reflex.

Debugging + review notes

  • A first M-g attempt used a self-referential gotomap (ESC→itself for infinite M-g M-g M-g…) — it SIGSEGV'd at startup because fixmap() walks prefix maps recursively (a cycle → stack overflow). Root-caused via an lldb backtrace, fixed with a separate acyclic metagmap.
  • A fourth binding, C-x z repeat, was dropped: the whole-branch review found it re-invoked the last command bypassing mgwrap/doin, so repeating selfinsert inserted the z from C-x z (xxz, silent corruption) and repeating after undo reversed it. A correct repeat needs dispatch-context capture — deferred to its own spec, FM-REPEAT.

Verification

macOS 325/325 · TSan zero races · Alpine/musl 325/325 · legacy plain-C clean (all plain C, ships in both builds).

Based on neomg.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp

Daniel Vu and others added 6 commits July 5, 2026 18:49
Four small Emacs keybind gaps in one PR: C-l recenter cycle (middle->top->bottom,
via a CFRECT flag + step counter in reposition); M-g -> goto-line (direct bind,
since mg's one-prefix-per-element keymap makes a faithful M-g prefix
disproportionate); C-x z repeat (last_command stored in mgwrap + a repeat cmd);
C-h k -> describe-key (bind helpmap k to desckey). M-/ dabbrev and the M-g
prefix form split into their own specs. Emacs 30.2 behavior verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp
Per review: full faithfulness. M-g becomes a real prefix via a self-referential
gotomap (ESC re-enters itself so M-g M-g / M-g M-g M-g all reach goto-line) and
splitting the metamap '['..'h' element into three sorted elements to give 'g'
its own prefix slot. doscan confirms elements scan by ascending k_num and NULL
k_funcp entries descend into k_prefmap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp
4 tasks: C-h k -> desckey (cHa); M-g prefix (self-ref gotomap + split metamap
'['..'h' into 3 sorted elements, KEYMAPE 8->10); C-l recenter cycle (CFRECT flag
+ w_frame 0/1/ntrows in reposition); C-x z repeat (expose last_command in
mgwrap + repeat cmd + cXmap 'z', KEYMAPE 6->7). Each with a pty test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp
…-h k describe-key

Four Emacs keybind gaps (verified vs Emacs 30.2):
- C-l cycles recenter middle->top->bottom (CFRECT flag + w_frame in reposition),
  was center-only.
- M-g is a prefix map: M-g g and M-g M-g -> goto-line (new gotomap + metagmap;
  metamap '['..'h' element split into three sorted elements). NOT self-referential
  -- fixmap() walks prefix maps recursively at startup, so an ESC->self cycle
  overflowed the stack (SIGSEGV); metagmap breaks the cycle.
- C-x z repeats the last command (last_command exposed from mgwrap + repeat cmd,
  press z to keep repeating), cXmap grown for 'z'.
- C-h k -> describe-key-briefly (cHa 'k'), matching the Emacs reflex.

macOS 326/326.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp
Whole-branch review found repeat() bypasses mgwrap/doin, so repeating selfinsert
inserts the 'z' from C-x z (x -> 'xz', silent corruption) and repeating after
undo reverses it (frozen rptcount). A correct repeat needs dispatch-context
capture (key sequence + f/n + rptcount + ABORT) -- a separate feature, deferred
to FM-REPEAT. Ship the three verified-correct keybinds: C-l recenter cycle, M-g
prefix goto-line, C-h k describe-key. Spec updated (metagmap, not self-ref).

macOS 325/325.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp
danielxvu pushed a commit that referenced this pull request Jul 5, 2026
… deferral

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pj1ZHaD7aNhVWJ69SFKJcp
@danielxvu
danielxvu merged commit be29422 into neomg Jul 5, 2026
14 of 16 checks passed
@danielxvu
danielxvu deleted the fm-quick-keybinds branch July 5, 2026 23:41
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