Skip to content

Commit a903d35

Browse files
committed
feat(expert): fold multiline bitstrings
1 parent 16e3d2a commit a903d35

2 files changed

Lines changed: 67 additions & 3 deletions

File tree

‎apps/expert/lib/expert/provider/handlers/code_folding.ex‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ defmodule Expert.Provider.Handlers.CodeFolding do
4040
defp block_ranges(ast) do
4141
{_, ranges} =
4242
Macro.prewalk(ast, [], fn
43-
{:fn, meta, _clauses} = node, acc when is_list(meta) ->
44-
{node, collect_anonymous_function(meta, acc)}
43+
{form, meta, _args} = node, acc when form in [:fn, :<<>>] and is_list(meta) ->
44+
{node, collect_delimited_block(meta, acc)}
4545

4646
{_form, meta, _args} = node, acc when is_list(meta) ->
4747
{node, collect_block(meta, acc)}
@@ -66,7 +66,7 @@ defmodule Expert.Provider.Handlers.CodeFolding do
6666
end
6767
end
6868

69-
defp collect_anonymous_function(meta, acc) do
69+
defp collect_delimited_block(meta, acc) do
7070
opening_line = Keyword.get(meta, :line)
7171
closing_line = meta_line(meta, :closing)
7272

‎apps/expert/test/expert/provider/handlers/code_folding_test.exs‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,70 @@ defmodule Expert.Provider.Handlers.CodeFoldingTest do
144144
end
145145
end
146146

147+
describe "bitstrings" do
148+
test "folds a multi-line bitstring" do
149+
source = """
150+
payload = <<
151+
1,
152+
2
153+
>>
154+
"""
155+
156+
assert fold(source) == [range(0, 2)]
157+
end
158+
159+
test "folds nested bitstrings with segment types" do
160+
source = """
161+
<<
162+
<<
163+
1::size(8),
164+
2
165+
>>::binary,
166+
3
167+
>>
168+
"""
169+
170+
assert fold(source) == [range(0, 5), range(1, 3)]
171+
end
172+
173+
test "folds bitstring patterns inside a function" do
174+
source = """
175+
def decode(payload) do
176+
<<
177+
tag::8,
178+
rest::binary
179+
>> = payload
180+
{tag, rest}
181+
end
182+
"""
183+
184+
assert fold(source) == [range(0, 5), range(1, 3)]
185+
end
186+
187+
test "does not fold single-line or empty bitstrings" do
188+
assert fold("<<1, 2>>\n") == []
189+
assert fold("<<>>\n") == []
190+
assert fold("<<\n>>\n") == []
191+
end
192+
193+
test "does not fold a bitstring without a closing delimiter" do
194+
assert fold("<<\n 1,\n 2\n") == []
195+
end
196+
197+
test "does not treat sigil contents as bitstring delimiters" do
198+
source = ~S'''
199+
~s"""
200+
<<
201+
1,
202+
2
203+
>>
204+
"""
205+
'''
206+
207+
assert fold(source) == [range(0, 4)]
208+
end
209+
end
210+
147211
describe "heredocs" do
148212
test "folds a multi-line @moduledoc heredoc" do
149213
source = """

0 commit comments

Comments
 (0)