Skip to content

Commit 473cafb

Browse files
committed
fix: clamp start_char for comletion prefix
1 parent b237fd5 commit 473cafb

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

apps/expert/lib/expert/code_intelligence/completion/builder.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ defmodule Expert.CodeIntelligence.Completion.Builder do
108108

109109
defp prefix_range(%Env{} = env) do
110110
end_char = env.position.character
111-
start_char = end_char - prefix_length(env)
111+
start_char = max(end_char - prefix_length(env), 1)
112112
{start_char, end_char}
113113
end
114114

apps/expert/test/expert/code_intelligence/completion/builder_test.exs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ defmodule Expert.CodeIntelligence.Completion.BuilderTest do
22
alias Expert.CodeIntelligence.Completion.SortScope
33
alias Forge.Ast
44
alias Forge.Ast.Env
5+
alias Forge.Document
6+
alias Forge.Document.Position
7+
alias Forge.Protocol.Convertible
58
alias GenLSP.Structures.CompletionItem
69

710
use ExUnit.Case, async: true
@@ -82,4 +85,46 @@ defmodule Expert.CodeIntelligence.Completion.BuilderTest do
8285
|> snippet("", label: "")
8386
end
8487
end
88+
89+
describe "non-ascii line range clamp" do
90+
test "plain_text clamps start_char >= 1 and serializes on non-ASCII line" do
91+
doc = Document.new("file:///builder_test.ex", "⚠️ hello", 0)
92+
pos = Position.new(doc, 1, 1)
93+
94+
env = %Env{document: doc, position: pos, prefix: "a"}
95+
96+
item = plain_text(env, "X", label: "X")
97+
98+
assert {:ok, lsp_text_edit_or_list} = Convertible.to_lsp(item.text_edit)
99+
100+
lsp_edits = List.wrap(lsp_text_edit_or_list)
101+
102+
refute Enum.empty?(lsp_edits)
103+
104+
for %{range: %{start: %{character: start_ch}, end: %{character: end_ch}}} <- lsp_edits do
105+
assert start_ch == 0
106+
assert end_ch == 0
107+
end
108+
end
109+
110+
test "snippet clamps start_char >= 1 and serializes on non-ASCII line" do
111+
doc = Document.new("file:///builder_test.ex", "⚠️ hello", 0)
112+
pos = Position.new(doc, 1, 1)
113+
114+
env = %Env{document: doc, position: pos, prefix: "a"}
115+
116+
item = snippet(env, "X$0", label: "X")
117+
118+
assert {:ok, lsp_text_edit_or_list} = Convertible.to_lsp(item.text_edit)
119+
120+
lsp_edits = List.wrap(lsp_text_edit_or_list)
121+
122+
refute Enum.empty?(lsp_edits)
123+
124+
for %{range: %{start: %{character: start_ch}, end: %{character: end_ch}}} <- lsp_edits do
125+
assert start_ch == 0
126+
assert end_ch == 0
127+
end
128+
end
129+
end
85130
end

0 commit comments

Comments
 (0)