Skip to content

fix(opencode): expand single-line file mentions to enclosing LSP symbol using 1-based lines - #47503

Closed
kaeldrin-gh wants to merge 1 commit into
anomalyco:devfrom
kaeldrin-gh:lsp-line-off-by-one
Closed

kaeldrin-gh wants to merge 1 commit into
anomalyco:devfrom
kaeldrin-gh:lsp-line-off-by-one

Conversation

@kaeldrin-gh

@kaeldrin-gh kaeldrin-gh commented Sep 5, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #42887

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Single-line file mentions (@file.ts#42) were not expanded to the enclosing LSP symbol: the URL line numbers are 1-based while LSP ranges are 0-based, so r.start.line === start never matched. A truthiness check (r?.start?.line &&) also dropped symbols starting on line 0.

The fix compares r.start.line + 1 against the 1-based URL line, converts the matched range to 1-based inclusive lines, and derives the Read tool's offset/limit from the end-exclusive LSP range. Symbols on line 1 now match too.

How did you verify your code works?

  • Two new regression tests mock documentSymbol and assert the read call uses the expanded range (offset/limit): ?start=2&end=2 with a 0-based [1,4) symbol -> offset 2, limit 3; ?start=1&end=1 with a 0-based [0,3) symbol -> offset 1, limit 3.
  • Both tests fail without the fix and pass with it.
  • bun test test/session/prompt.test.ts from packages/opencode: 47 pass, 14 skip, 0 fail.
  • bun typecheck from packages/opencode: clean.

Screenshots / recordings

No UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Copilot AI lite review requested due to automatic review settings September 5, 2026 14:59
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

No duplicate PRs found

(Note: PR #42888 titled "expand single-line selection to enclosing LSP symbol" appears in search results but is addressing a different scope—selection expansion vs. file mention expansion—and is a previous related PR, not a duplicate.)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new lineCount computation ignores Range.end.character, which can undercount lines for symbols whose end position is within (not at the start of) the final line.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes single-line file://...?...start=N&end=N file mentions so they expand to the intended LSP document symbol range by correctly handling 1-based URL line numbers vs 0-based LSP ranges, and by allowing matches on line 0.

Changes:

  • Adjusted symbol-range matching in SessionPrompt to compare 1-based URL lines against 0-based LSP Range.start.line, and to avoid falsy checks that exclude line 0.
  • Converted LSP end-exclusive ranges into Read tool offset/limit semantics for expanded reads.
  • Added regression tests that mock documentSymbol and assert the resulting Read tool call uses the expanded offset/limit.
File summaries
File Description
packages/opencode/src/session/prompt.ts Fixes 1-based vs 0-based line comparisons and expands single-line file mentions using LSP symbol ranges.
packages/opencode/test/session/prompt.test.ts Adds regression tests (with mocked LSP symbols) covering expansion from line 1 and line 2.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/opencode/src/session/prompt.ts Outdated
Comment on lines 844 to 850
// URL line numbers are 1-based; LSP ranges are 0-based and end-exclusive.
if (r?.start?.line != null && r.start.line + 1 === start) {
const lineCount = Math.max(1, (r.end?.line ?? r.start.line) - r.start.line)
start = r.start.line + 1
end = start + lineCount - 1
break
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LSP ranges are end-exclusive by spec: the range [1,4) covers 0-based lines 1-3 (1-based 2-4), and a non-zero end.character on the exclusive end line does not add an extra line. \lineCount = end.line - start.line\ is therefore the correct line span; the character offset only matters if the end line were inclusive, which it isn't for document symbols.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

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.

Single-line file selection doesn't expand to enclosing symbol (off-by-one)

2 participants