Skip to content

Commit 1481359

Browse files
committed
Fix flex break at group end
1 parent 10ea380 commit 1481359

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

Diff for: lib/elixir/lib/code/formatter.ex

+11-11
Original file line numberDiff line numberDiff line change
@@ -802,30 +802,30 @@ defmodule Code.Formatter do
802802
{right, state} =
803803
binary_operand_to_algebra(right_arg, right_context, state, op, op_info, :right, 0)
804804

805-
doc =
805+
{op_string, right} =
806806
cond do
807807
op in @no_space_binary_operators ->
808-
op_doc = color_doc(op_string, :operator, state.inspect_opts)
809-
concat(concat(group(left), op_doc), group(right))
808+
{op_string, group(right)}
810809

811810
op in @no_newline_binary_operators ->
812-
op_doc = color_doc(" " <> op_string <> " ", :operator, state.inspect_opts)
813-
concat(concat(group(left), op_doc), group(right))
811+
{" " <> op_string <> " ", group(right)}
814812

815813
true ->
816814
eol? = eol?(meta, state)
817815

818816
next_break_fits? =
819817
op in @next_break_fits_operators and next_break_fits?(right_arg, state) and not eol?
820818

821-
with_next_break_fits(next_break_fits?, right, fn right ->
822-
op_doc = color_doc(" " <> op_string, :operator, state.inspect_opts)
823-
right = nest(glue(op_doc, group(right)), nesting, :break)
824-
right = if eol?, do: force_unfit(right), else: right
825-
concat(group(left), group(right))
826-
end)
819+
{" " <> op_string,
820+
with_next_break_fits(next_break_fits?, right, fn right ->
821+
right = nest(concat(break(), group(right)), nesting, :break)
822+
right = if eol?, do: force_unfit(right), else: right
823+
group(right)
824+
end)}
827825
end
828826

827+
op_doc = color_doc(op_string, :operator, state.inspect_opts)
828+
doc = concat(concat(group(left), op_doc), group(right))
829829
{doc, state}
830830
end
831831

Diff for: lib/elixir/lib/inspect/algebra.ex

+23-5
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,10 @@ defmodule Inspect.Algebra do
10311031
entries
10321032
) :: :fit | :no_fit | :break_next
10331033
when entries:
1034-
maybe_improper_list({integer(), mode(), t()}, {:tail, boolean(), entries} | [])
1034+
maybe_improper_list(
1035+
{integer(), mode(), t()} | :group_over,
1036+
{:tail, boolean(), entries} | []
1037+
)
10351038

10361039
# We need at least a break to consider the document does not fit since a
10371040
# large document without breaks has no option but fitting its current line.
@@ -1066,6 +1069,17 @@ defmodule Inspect.Algebra do
10661069
end
10671070
end
10681071

1072+
## Group over
1073+
# If we get to the end of the group and if fits, it is because
1074+
# something already broke elsewhere, so we can consider the group
1075+
# fits. This only appears when checking if a flex break fits.
1076+
1077+
defp fits(_w, _k, true, [:group_over | _]),
1078+
do: :fit
1079+
1080+
defp fits(w, k, b?, [:group_over | t]),
1081+
do: fits(w, k, b?, t)
1082+
10691083
## Breaks
10701084

10711085
defp fits(_, _, _, [{_, :break, doc_break(_, _)} | _]), do: :fit
@@ -1104,7 +1118,7 @@ defmodule Inspect.Algebra do
11041118
@spec format(
11051119
width :: non_neg_integer() | :infinity,
11061120
column :: non_neg_integer(),
1107-
[{integer, mode, t}]
1121+
[{integer, mode, t} | :group_over]
11081122
) :: [binary]
11091123
defp format(_, _, []), do: []
11101124
defp format(w, k, [{_, _, :doc_nil} | t]), do: format(w, k, t)
@@ -1121,7 +1135,7 @@ defmodule Inspect.Algebra do
11211135
defp format(w, k, [{i, m, doc_fits(x, _)} | t]), do: format(w, k, [{i, m, x} | t])
11221136
defp format(w, _, [{i, _, doc_collapse(max)} | t]), do: collapse(format(w, i, t), max, 0, i)
11231137

1124-
# Flex breaks are not conditional to the mode
1138+
# Flex breaks are conditional to the document and the mode
11251139
defp format(w, k, [{i, m, doc_break(s, :flex)} | t]) do
11261140
k = k + byte_size(s)
11271141

@@ -1151,6 +1165,10 @@ defmodule Inspect.Algebra do
11511165
end
11521166

11531167
# Groups must do the fitting decision.
1168+
defp format(w, k, [:group_over | t]) do
1169+
format(w, k, t)
1170+
end
1171+
11541172
defp format(w, k, [{i, :break, doc_group(x, :inherit)} | t]) do
11551173
format(w, k, [{i, :break, x} | t])
11561174
end
@@ -1164,8 +1182,8 @@ defmodule Inspect.Algebra do
11641182

11651183
case fits do
11661184
:fit -> format(w, k, [{i, :flat, x} | t])
1167-
:no_fit -> format(w, k, [{i, :break, x} | t])
1168-
:break_next -> format(w, k, [{i, :flat_no_break, x} | t])
1185+
:no_fit -> format(w, k, [{i, :break, x}, :group_over | t])
1186+
:break_next -> format(w, k, [{i, :flat_no_break, x}, :group_over | t])
11691187
end
11701188
end
11711189

Diff for: lib/elixir/test/elixir/code_formatter/integration_test.exs

+10
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,16 @@ defmodule Code.Formatter.IntegrationTest do
465465
"""
466466
end
467467

468+
test "nested tuples as lines" do
469+
assert_same """
470+
{:ok,
471+
{1, 2, 3,
472+
4, 5}} =
473+
call()
474+
""",
475+
line_length: 10
476+
end
477+
468478
test "first argument in a call without parens with comments" do
469479
assert_same """
470480
with bar ::

0 commit comments

Comments
 (0)