Skip to content

Commit

Permalink
fix(inlayHint&semanticTokens): Fix range send to server (#5192)
Browse files Browse the repository at this point in the history
From LSP spec [1]:
> .. the end position is exclusive. If you want to specify a range that
> contains a line including the line ending character(s) then use an end
> position denoting the start of the next line.

but it doesn't mention what we should send to server if the file hasn't
EOL. VS Code will set end = { line = last line number (0-based),
character = length of the last line}. This fix will change the behavior
to the same as VS Code so that some language servers (such as roslyn
language server) will work normally.

[1] https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#range

Signed-off-by: Adam Tao <[email protected]>
  • Loading branch information
tcx4c70 authored Nov 20, 2024
1 parent 18c34bc commit a455fc7
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/handler/inlayHint/buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export default class InlayHintBuffer implements SyncItem {
if (token.isCancellationRequested || this.regions.has(res[0], res[1])) return
const startLine = Math.max(0, res[0] - RenderRangeExtendSize)
const endLine = Math.min(this.doc.lineCount, res[1] + RenderRangeExtendSize)
let range = Range.create(startLine, 0, endLine, 0)
let range = this.doc.textDocument.intersectWith(Range.create(startLine, 0, endLine, 0))
let inlayHints = await this.requestInlayHints(range, token)
if (inlayHints == null || token.isCancellationRequested) return
this.regions.add(res[0], res[1])
Expand Down
2 changes: 1 addition & 1 deletion src/handler/semanticTokens/buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ export default class SemanticTokensBuffer implements SyncItem {
let region = await nvim.call('coc#window#visible_range') as [number, number]
if (!region || token.isCancellationRequested) return null
let endLine = Math.min(region[0] + workspace.env.lines * 2, region[1] + workspace.env.lines, doc.lineCount)
let range = Range.create(region[0] - 1, 0, endLine, 0)
let range = doc.textDocument.intersectWith(Range.create(region[0] - 1, 0, endLine, 0))
let res = await languages.provideDocumentRangeSemanticTokens(doc.textDocument, range, token)
if (!res || !SemanticTokens.is(res) || token.isCancellationRequested) return null
let legend = languages.getLegend(doc.textDocument, true)
Expand Down
18 changes: 18 additions & 0 deletions src/model/textdocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@ export class LinesTextDocument implements TextDocument {
return this.lines.length + (this.eol ? 1 : 0)
}

public intersectWith(range: Range): Range {
let start: Position = Position.create(0, 0)
if (start.line < range.start.line) {
start = range.start
} else if (range.start.line === start.line) {
start = Position.create(start.line, Math.max(start.character, range.start.character))
}

let end: Position = this.end
if (range.end.line < end.line) {
end = range.end
} else if (range.end.line === end.line) {
end = Position.create(end.line, Math.min(end.character, range.end.character))
}

return Range.create(start, end)
}

public getText(range?: Range): string {
if (range) {
let { start, end } = range
Expand Down

0 comments on commit a455fc7

Please sign in to comment.