@@ -415,11 +415,11 @@ defmodule Code.Formatter do
415
415
# {}
416
416
# {1, 2}
417
417
defp quoted_to_algebra ( { :{} , meta , args } , _context , state ) do
418
- tuple_to_algebra ( meta , args , state )
418
+ tuple_to_algebra ( meta , args , :flex_glue , state )
419
419
end
420
420
421
421
defp quoted_to_algebra ( { :__block__ , meta , [ { left , right } ] } , _context , state ) do
422
- tuple_to_algebra ( meta , [ left , right ] , state )
422
+ tuple_to_algebra ( meta , [ left , right ] , :flex_glue , state )
423
423
end
424
424
425
425
defp quoted_to_algebra ( { :__block__ , meta , [ list ] } , _context , state ) when is_list ( list ) do
@@ -558,7 +558,7 @@ defmodule Code.Formatter do
558
558
end
559
559
560
560
doc =
561
- with_next_break_fits ( next_break_fits? ( right_arg ) , right , fn right ->
561
+ with_next_break_fits ( next_break_fits? ( right_arg , state ) , right , fn right ->
562
562
concat ( group ( left ) , group ( nest ( glue ( op , group ( right ) ) , 2 , :break ) ) )
563
563
end )
564
564
@@ -727,7 +727,7 @@ defmodule Code.Formatter do
727
727
728
728
true ->
729
729
next_break_fits? =
730
- op in @ next_break_fits_operators and next_break_fits? ( right_arg ) and
730
+ op in @ next_break_fits_operators and next_break_fits? ( right_arg , state ) and
731
731
not Keyword . get ( meta , :eol , false )
732
732
733
733
with_next_break_fits ( next_break_fits? , right , fn right ->
@@ -887,7 +887,7 @@ defmodule Code.Formatter do
887
887
# expression.{arguments}
888
888
defp remote_to_algebra ( { { :. , _ , [ target , :{} ] } , meta , args } , _context , state ) do
889
889
{ target_doc , state } = remote_target_to_algebra ( target , state )
890
- { call_doc , state } = tuple_to_algebra ( meta , args , state )
890
+ { call_doc , state } = tuple_to_algebra ( meta , args , :glue , state )
891
891
{ concat ( concat ( target_doc , "." ) , call_doc ) , state }
892
892
end
893
893
@@ -1008,8 +1008,8 @@ defmodule Code.Formatter do
1008
1008
# * :required - never skip parens
1009
1009
#
1010
1010
defp call_args_to_algebra ( [ ] , meta , _context , _parens , _list_to_keyword? , state ) do
1011
- { args_doc , state } =
1012
- args_to_algebra_with_comments ( [ ] , meta , false , false , false , state , & { & 1 , & 2 } )
1011
+ { args_doc , _join , state } =
1012
+ args_to_algebra_with_comments ( [ ] , meta , false , false , :glue , state , & { & 1 , & 2 } )
1013
1013
1014
1014
{ { surround ( "(" , args_doc , ")" ) , state } , false }
1015
1015
end
@@ -1056,19 +1056,19 @@ defmodule Code.Formatter do
1056
1056
if left != [ ] and keyword? and skip_parens? and generators_count == 0 do
1057
1057
call_args_to_algebra_with_no_parens_keywords ( meta , left , right , context , extra , state )
1058
1058
else
1059
- next_break_fits? = next_break_fits? ( right )
1059
+ next_break_fits? = next_break_fits? ( right , state )
1060
1060
force_keyword? = keyword? and force_keyword? ( right )
1061
1061
non_empty_eol? = left != [ ] and not next_break_fits? and Keyword . get ( meta , :eol , false )
1062
- force_unfit? = generators_count > 1 or force_keyword? or non_empty_eol?
1062
+ join = if generators_count > 1 or force_keyword? or non_empty_eol? , do: :line , else: :glue
1063
1063
args = if keyword? , do: left ++ right , else: left ++ [ right ]
1064
1064
1065
- { args_doc , state } =
1065
+ { args_doc , _join , state } =
1066
1066
args_to_algebra_with_comments (
1067
1067
args ,
1068
1068
meta ,
1069
1069
skip_parens? ,
1070
1070
next_break_fits? ,
1071
- force_unfit? ,
1071
+ join ,
1072
1072
state ,
1073
1073
& quoted_to_algebra ( & 1 , context , & 2 )
1074
1074
)
@@ -1098,11 +1098,11 @@ defmodule Code.Formatter do
1098
1098
defp call_args_to_algebra_with_no_parens_keywords ( meta , left , right , context , extra , state ) do
1099
1099
to_algebra_fun = & quoted_to_algebra ( & 1 , context , & 2 )
1100
1100
1101
- { left_doc , state } =
1102
- args_to_algebra_with_comments ( left , meta , true , false , false , state , to_algebra_fun )
1101
+ { left_doc , _join , state } =
1102
+ args_to_algebra_with_comments ( left , meta , true , false , :glue , state , to_algebra_fun )
1103
1103
1104
- { right_doc , state } =
1105
- args_to_algebra_with_comments ( right , meta , false , false , false , state , to_algebra_fun )
1104
+ { right_doc , _join , state } =
1105
+ args_to_algebra_with_comments ( right , meta , false , false , :glue , state , to_algebra_fun )
1106
1106
1107
1107
right_doc = "," |> glue ( right_doc ) |> force_keyword ( right ) |> group ( :inherit )
1108
1108
@@ -1241,15 +1241,19 @@ defmodule Code.Formatter do
1241
1241
1242
1242
defp bitstring_to_algebra ( meta , args , state ) do
1243
1243
last = length ( args ) - 1
1244
+ join = if Keyword . get ( meta , :eol , false ) , do: :line , else: :flex_glue
1244
1245
to_algebra_fun = & bitstring_segment_to_algebra ( & 1 , & 2 , last )
1245
- force_unfit? = Keyword . get ( meta , :eol , false )
1246
1246
1247
- { args_doc , state } =
1247
+ { args_doc , join , state } =
1248
1248
args
1249
1249
|> Enum . with_index ( )
1250
- |> args_to_algebra_with_comments ( meta , false , false , force_unfit? , state , to_algebra_fun )
1250
+ |> args_to_algebra_with_comments ( meta , false , false , join , state , to_algebra_fun )
1251
1251
1252
- { surround ( "<<" , args_doc , ">>" ) , state }
1252
+ if join == :flex_glue do
1253
+ { "<<" |> concat ( args_doc ) |> nest ( 2 ) |> concat ( ">>" ) |> group ( ) , state }
1254
+ else
1255
+ { surround ( "<<" , args_doc , ">>" ) , state }
1256
+ end
1253
1257
end
1254
1258
1255
1259
defp bitstring_segment_to_algebra ( { { :<- , meta , [ left , right ] } , i } , state , last ) do
@@ -1298,22 +1302,22 @@ defmodule Code.Formatter do
1298
1302
## Literals
1299
1303
1300
1304
defp list_to_algebra ( meta , args , state ) do
1301
- to_algebra_fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
1302
- force_unfit? = Keyword . get ( meta , :eol , false )
1305
+ join = if Keyword . get ( meta , :eol , false ) , do: :line , else: :glue
1306
+ fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
1303
1307
1304
- { args_doc , state } =
1305
- args_to_algebra_with_comments ( args , meta , false , false , force_unfit? , state , to_algebra_fun )
1308
+ { args_doc , _join , state } =
1309
+ args_to_algebra_with_comments ( args , meta , false , false , join , state , fun )
1306
1310
1307
1311
{ surround ( "[" , args_doc , "]" ) , state }
1308
1312
end
1309
1313
1310
1314
defp map_to_algebra ( meta , name_doc , [ { :| , _ , [ left , right ] } ] , state ) do
1315
+ join = if Keyword . get ( meta , :eol , false ) , do: :line , else: :glue
1311
1316
fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
1312
- force_unfit? = Keyword . get ( meta , :eol , false )
1313
1317
{ left_doc , state } = fun . ( left , state )
1314
1318
1315
- { right_doc , state } =
1316
- args_to_algebra_with_comments ( right , meta , false , false , force_unfit? , state , fun )
1319
+ { right_doc , _join , state } =
1320
+ args_to_algebra_with_comments ( right , meta , false , false , join , state , fun )
1317
1321
1318
1322
args_doc =
1319
1323
left_doc
@@ -1325,33 +1329,27 @@ defmodule Code.Formatter do
1325
1329
end
1326
1330
1327
1331
defp map_to_algebra ( meta , name_doc , args , state ) do
1328
- force_unfit? = Keyword . get ( meta , :eol , false )
1332
+ join = if Keyword . get ( meta , :eol , false ) , do: :line , else: :glue
1329
1333
fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
1330
1334
1331
- { args_doc , state } =
1332
- args_to_algebra_with_comments ( args , meta , false , false , force_unfit? , state , fun )
1335
+ { args_doc , _join , state } =
1336
+ args_to_algebra_with_comments ( args , meta , false , false , join , state , fun )
1333
1337
1334
1338
name_doc = "%" |> concat ( name_doc ) |> concat ( "{" )
1335
1339
{ surround ( name_doc , args_doc , "}" ) , state }
1336
1340
end
1337
1341
1338
- defp tuple_to_algebra ( meta , args , state ) do
1339
- force_unfit? = Keyword . get ( meta , :eol , false )
1342
+ defp tuple_to_algebra ( meta , args , join , state ) do
1343
+ join = if Keyword . get ( meta , :eol , false ) , do: :line , else: join
1340
1344
fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
1341
1345
1342
- next_break_fits? =
1343
- args != [ ] and next_break_fits? ( Enum . fetch! ( args , - 1 ) ) and
1344
- not Keyword . get ( meta , :eol , false )
1345
-
1346
- { args_doc , state } =
1347
- args_to_algebra_with_comments ( args , meta , false , next_break_fits? , force_unfit? , state , fun )
1348
-
1349
- doc = surround ( "{" , args_doc , "}" )
1346
+ { args_doc , join , state } =
1347
+ args_to_algebra_with_comments ( args , meta , false , false , join , state , fun )
1350
1348
1351
- if next_break_fits? do
1352
- { next_break_fits ( doc , :disabled ) , state }
1349
+ if join == :flex_glue do
1350
+ { "{" |> concat ( args_doc ) |> nest ( 1 ) |> concat ( "}" ) |> group ( ) , state }
1353
1351
else
1354
- { doc , state }
1352
+ { surround ( "{" , args_doc , "}" ) , state }
1355
1353
end
1356
1354
end
1357
1355
@@ -1456,15 +1454,7 @@ defmodule Code.Formatter do
1456
1454
defp heredoc_line ( [ "" , _ | _ ] ) , do: nest ( line ( ) , :reset )
1457
1455
defp heredoc_line ( _ ) , do: line ( )
1458
1456
1459
- defp args_to_algebra_with_comments (
1460
- args ,
1461
- meta ,
1462
- skip_parens? ,
1463
- next_break_fits? ,
1464
- force_unfit? ,
1465
- state ,
1466
- fun
1467
- ) do
1457
+ defp args_to_algebra_with_comments ( args , meta , skip_parens? , next_break_fits? , join , state , fun ) do
1468
1458
min_line = line ( meta )
1469
1459
max_line = end_line ( meta )
1470
1460
@@ -1498,13 +1488,16 @@ defmodule Code.Formatter do
1498
1488
1499
1489
cond do
1500
1490
args_docs == [ ] ->
1501
- { @ empty , state }
1491
+ { @ empty , :empty , state }
1502
1492
1503
- force_unfit? or comments? ->
1504
- { args_docs |> Enum . reduce ( & line ( & 2 , & 1 ) ) |> force_unfit ( ) , state }
1493
+ join == :line or comments? ->
1494
+ { args_docs |> Enum . reduce ( & line ( & 2 , & 1 ) ) |> force_unfit ( ) , :line , state }
1505
1495
1506
- true ->
1507
- { args_docs |> Enum . reduce ( & glue ( & 2 , & 1 ) ) , state }
1496
+ join == :glue ->
1497
+ { args_docs |> Enum . reduce ( & glue ( & 2 , & 1 ) ) , :glue , state }
1498
+
1499
+ join == :flex_glue ->
1500
+ { args_docs |> Enum . reduce ( & flex_glue ( & 2 , & 1 ) ) , :flex_glue , state }
1508
1501
end
1509
1502
end
1510
1503
@@ -1674,7 +1667,11 @@ defmodule Code.Formatter do
1674
1667
defp clause_args_to_algebra ( args , min_line , state ) do
1675
1668
meta = [ line: min_line ]
1676
1669
fun = & clause_args_to_algebra / 2
1677
- args_to_algebra_with_comments ( [ args ] , meta , false , false , false , state , fun )
1670
+
1671
+ { args_docs , _join , state } =
1672
+ args_to_algebra_with_comments ( [ args ] , meta , false , false , :glue , state , fun )
1673
+
1674
+ { args_docs , state }
1678
1675
end
1679
1676
1680
1677
# fn a, b, c when d -> e end
@@ -1916,43 +1913,61 @@ defmodule Code.Formatter do
1916
1913
end
1917
1914
end
1918
1915
1919
- defp next_break_fits? ( { :<<>> , meta , [ _ | _ ] = entries } ) do
1920
- meta [ :format ] == :bin_heredoc or not interpolated? ( entries )
1916
+ defp next_break_fits? ( { :{} , meta , _args } , state ) do
1917
+ eol_or_comments? ( meta , state )
1918
+ end
1919
+
1920
+ defp next_break_fits? ( { :__block__ , meta , [ { _ , _ } ] } , state ) do
1921
+ eol_or_comments? ( meta , state )
1921
1922
end
1922
1923
1923
- defp next_break_fits? ( { { :. , _ , [ String , :to_charlist ] } , _ , [ { :<<>> , meta , [ _ | _ ] } ] } ) do
1924
+ defp next_break_fits? ( { :<<>> , meta , [ _ | _ ] = entries } , state ) do
1925
+ meta [ :format ] == :bin_heredoc or
1926
+ ( not interpolated? ( entries ) and eol_or_comments? ( meta , state ) )
1927
+ end
1928
+
1929
+ defp next_break_fits? ( { { :. , _ , [ String , :to_charlist ] } , _ , [ { :<<>> , meta , [ _ | _ ] } ] } , _state ) do
1924
1930
meta [ :format ] == :list_heredoc
1925
1931
end
1926
1932
1927
- defp next_break_fits? ( { { :. , _ , [ _left , :{} ] } , _ , _ } ) do
1933
+ defp next_break_fits? ( { { :. , _ , [ _left , :{} ] } , _ , _ } , _state ) do
1928
1934
true
1929
1935
end
1930
1936
1931
- defp next_break_fits? ( { :__block__ , meta , [ string ] } ) when is_binary ( string ) do
1937
+ defp next_break_fits? ( { :__block__ , meta , [ string ] } , _state ) when is_binary ( string ) do
1932
1938
meta [ :format ] == :bin_heredoc
1933
1939
end
1934
1940
1935
- defp next_break_fits? ( { :__block__ , meta , [ list ] } ) when is_list ( list ) do
1941
+ defp next_break_fits? ( { :__block__ , meta , [ list ] } , _state ) when is_list ( list ) do
1936
1942
meta [ :format ] != :charlist
1937
1943
end
1938
1944
1939
- defp next_break_fits? ( { form , _ , [ _ | _ ] } ) when form in [ :fn , :%{} , :% ] do
1945
+ defp next_break_fits? ( { form , _ , [ _ | _ ] } , _state ) when form in [ :fn , :%{} , :% ] do
1940
1946
true
1941
1947
end
1942
1948
1943
- defp next_break_fits? ( { fun , meta , args } ) when is_atom ( fun ) and is_list ( args ) do
1949
+ defp next_break_fits? ( { fun , meta , args } , _state ) when is_atom ( fun ) and is_list ( args ) do
1944
1950
meta [ :terminator ] in [ @ double_heredoc , @ single_heredoc ] and
1945
1951
fun |> Atom . to_string ( ) |> String . starts_with? ( "sigil_" )
1946
1952
end
1947
1953
1948
- defp next_break_fits? ( { { :__block__ , _ , [ atom ] } , expr } ) when is_atom ( atom ) do
1949
- next_break_fits? ( expr )
1954
+ defp next_break_fits? ( { { :__block__ , _ , [ atom ] } , expr } , state ) when is_atom ( atom ) do
1955
+ next_break_fits? ( expr , state )
1950
1956
end
1951
1957
1952
- defp next_break_fits? ( _ ) do
1958
+ defp next_break_fits? ( _ , _state ) do
1953
1959
false
1954
1960
end
1955
1961
1962
+ defp eol_or_comments? ( meta , % { comments: comments } ) do
1963
+ Keyword . get ( meta , :eol , false ) or
1964
+ (
1965
+ min_line = line ( meta )
1966
+ max_line = end_line ( meta )
1967
+ Enum . any? ( comments , fn { line , _ , _ } -> line > min_line and line < max_line end )
1968
+ )
1969
+ end
1970
+
1956
1971
defp last_arg_to_keyword ( [ _ | _ ] = arg , _list_to_keyword? ) do
1957
1972
{ keyword? ( arg ) , arg }
1958
1973
end
0 commit comments