@@ -415,11 +415,11 @@ defmodule Code.Formatter do
415415 # {}
416416 # {1, 2}
417417 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 )
419419 end
420420
421421 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 )
423423 end
424424
425425 defp quoted_to_algebra ( { :__block__ , meta , [ list ] } , _context , state ) when is_list ( list ) do
@@ -558,7 +558,7 @@ defmodule Code.Formatter do
558558 end
559559
560560 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 ->
562562 concat ( group ( left ) , group ( nest ( glue ( op , group ( right ) ) , 2 , :break ) ) )
563563 end )
564564
@@ -727,7 +727,7 @@ defmodule Code.Formatter do
727727
728728 true ->
729729 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
731731 not Keyword . get ( meta , :eol , false )
732732
733733 with_next_break_fits ( next_break_fits? , right , fn right ->
@@ -887,7 +887,7 @@ defmodule Code.Formatter do
887887 # expression.{arguments}
888888 defp remote_to_algebra ( { { :. , _ , [ target , :{} ] } , meta , args } , _context , state ) do
889889 { 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 )
891891 { concat ( concat ( target_doc , "." ) , call_doc ) , state }
892892 end
893893
@@ -1008,8 +1008,8 @@ defmodule Code.Formatter do
10081008 # * :required - never skip parens
10091009 #
10101010 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 } )
10131013
10141014 { { surround ( "(" , args_doc , ")" ) , state } , false }
10151015 end
@@ -1056,19 +1056,19 @@ defmodule Code.Formatter do
10561056 if left != [ ] and keyword? and skip_parens? and generators_count == 0 do
10571057 call_args_to_algebra_with_no_parens_keywords ( meta , left , right , context , extra , state )
10581058 else
1059- next_break_fits? = next_break_fits? ( right )
1059+ next_break_fits? = next_break_fits? ( right , state )
10601060 force_keyword? = keyword? and force_keyword? ( right )
10611061 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
10631063 args = if keyword? , do: left ++ right , else: left ++ [ right ]
10641064
1065- { args_doc , state } =
1065+ { args_doc , _join , state } =
10661066 args_to_algebra_with_comments (
10671067 args ,
10681068 meta ,
10691069 skip_parens? ,
10701070 next_break_fits? ,
1071- force_unfit? ,
1071+ join ,
10721072 state ,
10731073 & quoted_to_algebra ( & 1 , context , & 2 )
10741074 )
@@ -1098,11 +1098,11 @@ defmodule Code.Formatter do
10981098 defp call_args_to_algebra_with_no_parens_keywords ( meta , left , right , context , extra , state ) do
10991099 to_algebra_fun = & quoted_to_algebra ( & 1 , context , & 2 )
11001100
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 )
11031103
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 )
11061106
11071107 right_doc = "," |> glue ( right_doc ) |> force_keyword ( right ) |> group ( :inherit )
11081108
@@ -1241,15 +1241,19 @@ defmodule Code.Formatter do
12411241
12421242 defp bitstring_to_algebra ( meta , args , state ) do
12431243 last = length ( args ) - 1
1244+ join = if Keyword . get ( meta , :eol , false ) , do: :line , else: :flex_glue
12441245 to_algebra_fun = & bitstring_segment_to_algebra ( & 1 , & 2 , last )
1245- force_unfit? = Keyword . get ( meta , :eol , false )
12461246
1247- { args_doc , state } =
1247+ { args_doc , join , state } =
12481248 args
12491249 |> 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 )
12511251
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
12531257 end
12541258
12551259 defp bitstring_segment_to_algebra ( { { :<- , meta , [ left , right ] } , i } , state , last ) do
@@ -1298,22 +1302,22 @@ defmodule Code.Formatter do
12981302 ## Literals
12991303
13001304 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 )
13031307
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 )
13061310
13071311 { surround ( "[" , args_doc , "]" ) , state }
13081312 end
13091313
13101314 defp map_to_algebra ( meta , name_doc , [ { :| , _ , [ left , right ] } ] , state ) do
1315+ join = if Keyword . get ( meta , :eol , false ) , do: :line , else: :glue
13111316 fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
1312- force_unfit? = Keyword . get ( meta , :eol , false )
13131317 { left_doc , state } = fun . ( left , state )
13141318
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 )
13171321
13181322 args_doc =
13191323 left_doc
@@ -1325,33 +1329,27 @@ defmodule Code.Formatter do
13251329 end
13261330
13271331 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
13291333 fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
13301334
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 )
13331337
13341338 name_doc = "%" |> concat ( name_doc ) |> concat ( "{" )
13351339 { surround ( name_doc , args_doc , "}" ) , state }
13361340 end
13371341
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
13401344 fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
13411345
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 )
13501348
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 }
13531351 else
1354- { doc , state }
1352+ { surround ( "{" , args_doc , "}" ) , state }
13551353 end
13561354 end
13571355
@@ -1456,15 +1454,7 @@ defmodule Code.Formatter do
14561454 defp heredoc_line ( [ "" , _ | _ ] ) , do: nest ( line ( ) , :reset )
14571455 defp heredoc_line ( _ ) , do: line ( )
14581456
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
14681458 min_line = line ( meta )
14691459 max_line = end_line ( meta )
14701460
@@ -1498,13 +1488,16 @@ defmodule Code.Formatter do
14981488
14991489 cond do
15001490 args_docs == [ ] ->
1501- { @ empty , state }
1491+ { @ empty , :empty , state }
15021492
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 }
15051495
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 }
15081501 end
15091502 end
15101503
@@ -1674,7 +1667,11 @@ defmodule Code.Formatter do
16741667 defp clause_args_to_algebra ( args , min_line , state ) do
16751668 meta = [ line: min_line ]
16761669 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 }
16781675 end
16791676
16801677 # fn a, b, c when d -> e end
@@ -1916,43 +1913,61 @@ defmodule Code.Formatter do
19161913 end
19171914 end
19181915
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 )
19211922 end
19221923
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
19241930 meta [ :format ] == :list_heredoc
19251931 end
19261932
1927- defp next_break_fits? ( { { :. , _ , [ _left , :{} ] } , _ , _ } ) do
1933+ defp next_break_fits? ( { { :. , _ , [ _left , :{} ] } , _ , _ } , _state ) do
19281934 true
19291935 end
19301936
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
19321938 meta [ :format ] == :bin_heredoc
19331939 end
19341940
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
19361942 meta [ :format ] != :charlist
19371943 end
19381944
1939- defp next_break_fits? ( { form , _ , [ _ | _ ] } ) when form in [ :fn , :%{} , :% ] do
1945+ defp next_break_fits? ( { form , _ , [ _ | _ ] } , _state ) when form in [ :fn , :%{} , :% ] do
19401946 true
19411947 end
19421948
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
19441950 meta [ :terminator ] in [ @ double_heredoc , @ single_heredoc ] and
19451951 fun |> Atom . to_string ( ) |> String . starts_with? ( "sigil_" )
19461952 end
19471953
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 )
19501956 end
19511957
1952- defp next_break_fits? ( _ ) do
1958+ defp next_break_fits? ( _ , _state ) do
19531959 false
19541960 end
19551961
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+
19561971 defp last_arg_to_keyword ( [ _ | _ ] = arg , _list_to_keyword? ) do
19571972 { keyword? ( arg ) , arg }
19581973 end
0 commit comments