Repository navigation
Description
Problem
Go to Line (Ctrl+G / Cmd+G) only works for a document that is a single raw-mode code_block. In every other mode the plugin is installed in, it miscounts lines and cannot navigate:
- The plugin is added unconditionally for all modes in
pkgs/id/web/src/editor.ts(createGotoLinePlugin()in the shared plugin list, after the raw/rich branch), so rich, markdown and plain documents all get it. Those modes userichSchema(paragraphs, headings, list items, code blocks as separate textblocks). getLineCount(pkgs/id/web/src/goto-line.ts:19-27) counts\ncharacters indoc.textContent. ProseMirror'stextContentconcatenates textblocks with no separator, so block boundaries are invisible: a document of three paragraphs hastextContent === "alphabetagamma"and counts as 1 line.getLineStartPos(pkgs/id/web/src/goto-line.ts:30-61) maps a text offset to a document position with a hard-codedpos + 2, with a comment claiming rich mode is handled "via resolve" — there is no resolve; the +2 is only correct fordoc > code_block > textwith a single block. Each additional textblock adds its own position overhead, so even a correct count would land at the wrong position.
Evidence (verified on main d7f9973 with a temporary vitest probe driving the real plugin, removed after)
Rich schema, doc = three paragraphs alpha / beta / gamma:
doc.textContentis"alphabetagamma"(no newlines).- Opening the dialog shows placeholder
Line # (1–1)andmax=1for a three-line document. - Entering
2and pressing Enter does nothing: the id(web): Go to Line accepts 0/negatives as line 1, truncates fractions, and silently closes on out-of-range lines #712 strict validation rejects it as out of range, the dialog stays open and the selection does not move. Go to Line is effectively dead in rich/markdown/plain mode.
Raw schema, doc = two code_blocks (a\nb and c\nd, four lines total):
textContentis"a\nbc\nd"— the last line of the first block and the first line of the second are merged — and the dialog reports 3 lines instead of 4.
Dedup: #712 (closed) fixed invalid/out-of-range input handling for the single-block case; #718 (closed) fixed the dialog singleton across editor recreation. Neither touches line counting/position mapping outside a single code block. No open issue covers this.
Why it matters
Ctrl+G is installed and advertised in every editable mode, but outside a single raw code block it tells the user their document has one line (or merges block-boundary lines) and refuses every jump past it. Plain-text and markdown files — primary id use cases — are exactly the affected modes.
Acceptance criteria
- Line counting and line-start positions are computed from the document structure (walking textblocks and their positions), not from
doc.textContentoffsets plus a constant. - A defined line semantics for non-raw modes (e.g. one line per textblock, plus
\n-split lines inside code blocks) is implemented and documented in the module comment. - Regression tests: rich doc of several paragraphs (dialog range matches, Enter on line N moves the cursor to the start of the Nth paragraph); mixed doc (paragraph + multi-line code_block + paragraph); raw doc with two code_blocks counts all lines; existing single-code_block tests and the id(web): Go to Line accepts 0/negatives as line 1, truncates fractions, and silently closes on out-of-range lines #712 invalid-input tests still pass.
- Or, if Go to Line is deliberately raw-only, the plugin is not installed (or cleanly no-ops with feedback) in rich/markdown/plain modes, and that restriction is tested — silently offering a broken dialog is the unacceptable part.
Activity
dezren39 commentedon Oct 24, 2026
id train triage (2026-10-24): needs-decision — Muse: assign to Session A (phases 0-10 review); Go to Line miscounts outside a single raw code_block (editor.ts).
fix(id-web): widen the goto-line test helper to accept both schemas