Skip to content

Commit 1a3b843

Browse files
authored
fix: do not clamp character recvd from client (#123)
1 parent e9d69dd commit 1a3b843

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

apps/expert/lib/expert/protocol/conversions.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,15 @@ defmodule Expert.Protocol.Conversions do
148148
{:ok, character}
149149
end
150150

151-
defp extract_elixir_character(%LSPosition{} = position, line(ascii?: true, text: text)) do
152-
character = min(position.character + 1, byte_size(text) + 1)
153-
{:ok, character}
151+
defp extract_elixir_character(%LSPosition{} = position, line(ascii?: true)) do
152+
{:ok, position.character + 1}
154153
end
155154

156155
defp extract_elixir_character(%LSPosition{} = position, line(text: utf8_text)) do
157-
with {:ok, code_unit} <- CodeUnit.utf16_offset_to_utf8_offset(utf8_text, position.character) do
158-
character = min(code_unit, byte_size(utf8_text) + 1)
159-
{:ok, character}
156+
case CodeUnit.utf16_offset_to_utf8_offset(utf8_text, position.character) do
157+
{:ok, _code_unit} = result -> result
158+
{:error, :out_of_bounds} -> {:ok, position.character + 1}
159+
{:error, _reason} = result -> result
160160
end
161161
end
162162
end

apps/expert/test/conversions_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ defmodule Expert.Protocol.ConversionsTest do
5454

5555
test "position > line length of a document with characters" do
5656
assert {:ok, pos} = Conversions.to_elixir(lsp_position(0, 15), doc("abcde"))
57-
assert %ExPosition{line: 1, character: 6} = pos
57+
assert %ExPosition{line: 1, character: 16} = pos
5858
end
5959

6060
# This is not specified in LSP but some clients fail to synchronize text properly

apps/expert/test/forge/document_test.exs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,44 @@ defmodule Forge.DocumentTest do
9696
{:ok, doc} = run_changes("hello there", [range_change])
9797
assert "hello people" == text(doc)
9898
end
99+
100+
test "applying batched incremental changes" do
101+
content = """
102+
defmodule Proxy do
103+
String.dow
104+
end
105+
"""
106+
107+
expected = """
108+
defmodule Proxy do
109+
String.downcase(string)
110+
end
111+
"""
112+
113+
changes = [
114+
%{text: "", range: new_range(1, 11, 1, 12), range_length: 1},
115+
%{text: "", range: new_range(1, 10, 1, 11), range_length: 1},
116+
%{text: "", range: new_range(1, 9, 1, 10), range_length: 1},
117+
%{text: "d", range: new_range(1, 9, 1, 9), range_length: 0},
118+
%{text: "o", range: new_range(1, 10, 1, 10), range_length: 0},
119+
%{text: "w", range: new_range(1, 11, 1, 11), range_length: 0},
120+
%{text: "n", range: new_range(1, 12, 1, 12), range_length: 0},
121+
%{text: "c", range: new_range(1, 13, 1, 13), range_length: 0},
122+
%{text: "a", range: new_range(1, 14, 1, 14), range_length: 0},
123+
%{text: "s", range: new_range(1, 15, 1, 15), range_length: 0},
124+
%{text: "e", range: new_range(1, 16, 1, 17), range_length: 0},
125+
%{text: "", range: new_range(1, 9, 1, 17), range_length: 8},
126+
%{text: "", range: new_range(1, 9, 1, 9), range_length: 0},
127+
%{text: "downcase(", range: new_range(1, 9, 1, 9), range_length: 0},
128+
%{text: "string", range: new_range(1, 18, 1, 18), range_length: 0},
129+
%{text: ")", range: new_range(1, 24, 1, 24), range_length: 0},
130+
%{text: "", range: new_range(1, 25, 1, 25), range_length: 0}
131+
]
132+
133+
{:ok, doc} = run_changes(content, changes)
134+
135+
assert text(doc) == expected
136+
end
99137
end
100138

101139
describe "apply_content_changes" do

0 commit comments

Comments
 (0)