Skip to content

Commit 0f4cc92

Browse files
committed
fix: formatting format incorrectly when contain special character
Signed-off-by: Thanabodee Charoenpiriyakij <wingyminus@gmail.com>
1 parent ad6a03b commit 0f4cc92

File tree

4 files changed

+56
-5
lines changed

4 files changed

+56
-5
lines changed

apps/engine/lib/engine/code_mod/diff.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ defmodule Engine.CodeMod.Diff do
101101
end
102102

103103
defp advance(<<c::utf8, rest::binary>>, {line, unit}, edits) do
104-
increment = CodeUnit.count(:utf8, <<c::utf8>>)
104+
increment = CodeUnit.count(:utf16, <<c::utf8>>)
105105
advance(rest, {line, unit + increment}, edits)
106106
end
107107

apps/engine/test/engine/code_mod/diff_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ defmodule Engine.CodeMod.DiffTest do
180180
final = ~S[{"🎸", "after"}]
181181

182182
assert [edit] = diff(orig, final)
183-
assert_normalized(edit == edit(1, 10, 1, 12, ""))
183+
assert_normalized(edit == edit(1, 8, 1, 10, ""))
184184
assert_edited(orig, final)
185185
end
186186

@@ -189,7 +189,7 @@ defmodule Engine.CodeMod.DiffTest do
189189
final = ~S[🎸🎺🎸]
190190

191191
assert [edit] = diff(orig, final)
192-
assert_normalized(edit == edit(1, 5, 1, 5, "🎺"))
192+
assert_normalized(edit == edit(1, 3, 1, 3, "🎺"))
193193
assert_edited(orig, final)
194194
end
195195

@@ -198,7 +198,7 @@ defmodule Engine.CodeMod.DiffTest do
198198
final = ~S[🎸🎸]
199199

200200
assert [edit] = diff(orig, final)
201-
assert_normalized(edit == edit(1, 5, 1, 13, ""))
201+
assert_normalized(edit == edit(1, 3, 1, 7, ""))
202202
assert_edited(orig, final)
203203
end
204204

apps/engine/test/engine/code_mod/format_test.exs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,23 @@ defmodule Engine.CodeMod.FormatTest do
114114

115115
assert result == formatted()
116116
end
117+
118+
test "it handles special characters", %{project: project} do
119+
assert {:ok, result} =
120+
~q"""
121+
[
122+
{"Karolína Plíšková","Kristýna Plíšková"}
123+
]
124+
"""
125+
|> modify(project: project)
126+
127+
assert result ==
128+
"""
129+
[
130+
{"Karolína Plíšková", "Kristýna Plíšková"}
131+
]
132+
"""
133+
|> String.trim()
134+
end
117135
end
118136
end

apps/forge/lib/test/code_mod_case.ex

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Forge.Test.CodeMod.Case do
2+
alias Forge.CodeUnit
23
alias Forge.Document
34
alias Forge.Test.CodeSigil
45

@@ -41,7 +42,8 @@ defmodule Forge.Test.CodeMod.Case do
4142

4243
def apply_edits(original, text_edits, opts) do
4344
document = Document.new("file:///file.ex", original, 0)
44-
{:ok, edited_document} = Document.apply_content_changes(document, 1, text_edits)
45+
utf8_edits = Enum.map(text_edits, &convert_edit_utf16_to_utf8(document, &1))
46+
{:ok, edited_document} = Document.apply_content_changes(document, 1, utf8_edits)
4547
edited_document = Document.to_string(edited_document)
4648

4749
if Keyword.get(opts, :trim, true) do
@@ -50,4 +52,35 @@ defmodule Forge.Test.CodeMod.Case do
5052
edited_document
5153
end
5254
end
55+
56+
defp convert_edit_utf16_to_utf8(document, %Document.Edit{} = edit) do
57+
case edit.range do
58+
nil ->
59+
edit
60+
61+
range ->
62+
start_pos = convert_position_utf16_to_utf8(document, range.start)
63+
end_pos = convert_position_utf16_to_utf8(document, range.end)
64+
%{edit | range: %{range | start: start_pos, end: end_pos}}
65+
end
66+
end
67+
68+
defp convert_position_utf16_to_utf8(document, %Document.Position{} = position) do
69+
case Document.fetch_text_at(document, position.line) do
70+
{:ok, line_text} ->
71+
case CodeUnit.utf16_offset_to_utf8_offset(line_text, position.character - 1) do
72+
{:ok, utf8_position} ->
73+
Document.Position.new(document, position.line, utf8_position)
74+
75+
{:error, :out_of_bounds} ->
76+
Document.Position.new(document, position.line, byte_size(line_text) + 1)
77+
78+
{:error, :misaligned} ->
79+
position
80+
end
81+
82+
:error ->
83+
position
84+
end
85+
end
5386
end

0 commit comments

Comments
 (0)