Skip to content

Commit 16d418f

Browse files
authored
Fix Ruby LSP formatting range to comply with LSP specification (#2438)
The current implementation of formatting does not use the proper range for a response. Consider the following Ruby code: ```ruby class A def my_method [1] end end ``` Let's pretend that our RuboCop configuration specifies omitting whitespaces inside array declarations, which means the code above is not properly formatted. The code should be formatted like this: ```ruby class A def my_method [ 1 ] end end ``` When a client asks Ruby LSP to format the first code, the server sends a response (taken from the Zed editor) where the reported `end` property of the `Range` interface has `line` and `character` keys that do not match the source document. Both of them equal the character size of the document. ```json { "id":6, "result":[ { "range":{ "start":{ "line":0, "character":0 }, "end":{ "line":43, "character":43 } }, "newText":"class A\n def my_method\n [ 1 ]\n end\nend\n" } ], "jsonrpc":"2.0" } ``` For some reason, Visual Studio Code considers this response valid, and the code is formatted properly. However, some editors perform a check to ensure that the reported response from Ruby LSP is not out of bounds of the current text document. According to the LSP specification from the link below: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#range A range in a text document expressed as (zero-based) start and end positions. The correct response should be: ```json { "id":35, "result":[ { "range":{ "start":{ "line":0, "character":0 }, "end":{ "line":5, "character":0 } }, "newText":"class A\n def my_method\n [ 1 ]\n end\nend\n" } ], "jsonrpc":"2.0" } ```
1 parent c0b8aa1 commit 16d418f

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

lib/ruby_lsp/requests/formatting.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,16 @@ def perform
5858
formatted_text = @active_formatter.run_formatting(@uri, @document)
5959
return unless formatted_text
6060

61+
lines = @document.source.lines
6162
size = @document.source.size
63+
6264
return if formatted_text.size == size && formatted_text == @document.source
6365

6466
[
6567
Interface::TextEdit.new(
6668
range: Interface::Range.new(
6769
start: Interface::Position.new(line: 0, character: 0),
68-
end: Interface::Position.new(line: size, character: size),
70+
end: Interface::Position.new(line: lines.size, character: 0),
6971
),
7072
new_text: formatted_text,
7173
),

0 commit comments

Comments
 (0)