Skip to content

Commit d0694b5

Browse files
SihuiJosé Valim
authored andcommitted
When fn is followed by a newline, use multi-clause formatting style (#7737)
Signed-off-by: José Valim <[email protected]>
1 parent 16fe53b commit d0694b5

File tree

4 files changed

+47
-14
lines changed

4 files changed

+47
-14
lines changed

lib/elixir/lib/code/formatter.ex

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ defmodule Code.Formatter do
522522
end
523523

524524
defp quoted_to_algebra({:fn, meta, [_ | _] = clauses}, _context, state) do
525-
anon_fun_to_algebra(clauses, line(meta), end_line(meta), state)
525+
anon_fun_to_algebra(clauses, line(meta), end_line(meta), state, eol?(meta))
526526
end
527527

528528
defp quoted_to_algebra({fun, meta, args}, context, state) when is_atom(fun) and is_list(args) do
@@ -1598,7 +1598,13 @@ defmodule Code.Formatter do
15981598
## Anonymous functions
15991599

16001600
# fn -> block end
1601-
defp anon_fun_to_algebra([{:->, meta, [[], body]}] = clauses, _min_line, max_line, state) do
1601+
defp anon_fun_to_algebra(
1602+
[{:->, meta, [[], body]}] = clauses,
1603+
_min_line,
1604+
max_line,
1605+
state,
1606+
_multi_clauses_style
1607+
) do
16021608
min_line = line(meta)
16031609
{body_doc, state} = block_to_algebra(body, min_line, max_line, state)
16041610

@@ -1617,7 +1623,13 @@ defmodule Code.Formatter do
16171623
# fn x ->
16181624
# y
16191625
# end
1620-
defp anon_fun_to_algebra([{:->, meta, [args, body]}] = clauses, _min_line, max_line, state) do
1626+
defp anon_fun_to_algebra(
1627+
[{:->, meta, [args, body]}] = clauses,
1628+
_min_line,
1629+
max_line,
1630+
state,
1631+
false = _multi_clauses_style
1632+
) do
16211633
min_line = line(meta)
16221634
{args_doc, state} = clause_args_to_algebra(args, min_line, state)
16231635
{body_doc, state} = block_to_algebra(body, min_line, max_line, state)
@@ -1647,7 +1659,7 @@ defmodule Code.Formatter do
16471659
# args2 ->
16481660
# block2
16491661
# end
1650-
defp anon_fun_to_algebra(clauses, min_line, max_line, state) do
1662+
defp anon_fun_to_algebra(clauses, min_line, max_line, state, _multi_clauses_style) do
16511663
{clauses_doc, state} = clauses_to_algebra(clauses, min_line, max_line, state)
16521664
{"fn" |> line(clauses_doc) |> nest(2) |> line("end") |> force_unfit(), state}
16531665
end
@@ -2139,6 +2151,10 @@ defmodule Code.Formatter do
21392151
false
21402152
end
21412153

2154+
defp eol?(meta) do
2155+
Keyword.get(meta, :eol, false)
2156+
end
2157+
21422158
defp line(meta) do
21432159
Keyword.get(meta, :line, @max_line)
21442160
end

lib/elixir/src/elixir_parser.yrl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ eoe -> ';' : '$1'.
305305
eoe -> eol ';' : '$1'.
306306

307307
fn_eoe -> 'fn' : '$1'.
308-
fn_eoe -> 'fn' eoe : '$1'.
308+
fn_eoe -> 'fn' eoe : next_is_eol('$1').
309309

310310
do_eoe -> 'do' : '$1'.
311311
do_eoe -> 'do' eoe : '$1'.
@@ -659,7 +659,7 @@ meta_from_token_with_end_line(Begin, End) ->
659659
case ?formatter_metadata() of
660660
true ->
661661
[{end_line, line_from_location(?location(End))}
662-
| meta_from_token(Begin)];
662+
| eol_op(?location(Begin)) ++ meta_from_token(Begin)];
663663
false ->
664664
meta_from_token(Begin)
665665
end.

lib/elixir/test/elixir/code_formatter/comments_test.exs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -449,14 +449,15 @@ defmodule Code.Formatter.CommentsTest do
449449

450450
assert_format bad, ~S"""
451451
# fn
452-
# before head
453-
# middle head
454-
# after head
455-
fn hello ->
456-
# before body
457-
# middle body
458-
world
459-
# after body
452+
fn
453+
# before head
454+
# middle head
455+
hello ->
456+
# after head
457+
# before body
458+
# middle body
459+
world
460+
# after body
460461
end
461462
"""
462463
end

lib/elixir/test/elixir/code_formatter/general_test.exs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,22 @@ defmodule Code.Formatter.GeneralTest do
187187
assert_same code, @short_length
188188
end
189189

190+
test "with a single clause, followed by a newline, and can fit in one line" do
191+
assert_same """
192+
fn
193+
hello -> world
194+
end
195+
"""
196+
end
197+
198+
test "with a single clause, followed by a newline, and can not fit in one line" do
199+
assert_same """
200+
SomeModule.long_function_name_that_approaches_max_columns(argument, acc, fn
201+
%SomeStruct{key: key}, acc -> more_code(key, acc)
202+
end)
203+
"""
204+
end
205+
190206
test "with multiple clauses" do
191207
code = """
192208
fn

0 commit comments

Comments
 (0)