Skip to content

Commit e37d838

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

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-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: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ 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
8+
alias Forge.Document.Range
9+
alias Forge.Document.Edit
510
alias GenLSP.Structures.CompletionItem
611

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

0 commit comments

Comments
 (0)