Skip to content

Commit 4dfc134

Browse files
committed
Extend single-line list formatting beyond function arguments
Previously, single-line list formatting was limited to lists within function arguments. This change extends the behavior to all lists, applying the same rules: - Lists with >6 items always: expand - Lists with >1 items and at least one non-simple item: expand - Otherwise: try to fit on one line
1 parent f7d6074 commit 4dfc134

File tree

42 files changed

+363
-903
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+363
-903
lines changed

src/Nixfmt/Pretty.hs

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ instance (Pretty a) => Pretty (Item a) where
110110
pretty (Item x) = group x
111111

112112
-- For lists, attribute sets and let bindings
113-
prettyItems :: (Pretty a) => Items a -> Doc
114-
prettyItems (Items items) = go items
113+
prettyItemsWith :: (Pretty a) => Doc -> Items a -> Doc
114+
prettyItemsWith separator (Items items) = go items
115115
where
116116
go [] = mempty
117117
go [item] = pretty item
@@ -120,9 +120,9 @@ prettyItems (Items items) = go items
120120
pretty (LanguageAnnotation lang)
121121
<> hardspace
122122
<> group stringItem
123-
<> if null rest then mempty else hardline <> go rest
123+
<> if null rest then mempty else separator <> go rest
124124
go (item : rest) =
125-
pretty item <> if null rest then mempty else hardline <> go rest
125+
pretty item <> if null rest then mempty else separator <> go rest
126126

127127
instance Pretty Trivia where
128128
pretty [] = mempty
@@ -197,7 +197,7 @@ prettySet _ (krec, paropen@(LoneAnn _), Items [], parclose@Ann{preTrivia = []})
197197
-- Singleton sets are allowed to fit onto one line,
198198
-- but apart from that always expand.
199199
prettySet wide (krec, paropen@Ann{trailComment = post}, binders, parclose) =
200-
let !surrounded = surroundWith sep (nest $ pretty post <> prettyItems binders)
200+
let !surrounded = surroundWith sep (nest $ pretty post <> prettyItemsWith hardline binders)
201201
in pretty (fmap (,hardspace) krec)
202202
<> pretty (paropen{trailComment = Nothing})
203203
<> surrounded
@@ -242,14 +242,16 @@ prettyTerm (List paropen@Ann{trailComment = Nothing} (Items []) parclose@Ann{pre
242242
-- If the brackets are on different lines, keep them like that
243243
sep = if sourceLine paropen /= sourceLine parclose then hardline else hardspace
244244
-- General list
245-
-- Always expand if len > 1
246245
prettyTerm (List paropen@Ann{trailComment = post} items parclose) =
247246
pretty (paropen{trailComment = Nothing})
248-
<> surroundWith sur (nest $ pretty post <> prettyItems items)
247+
<> surroundWith sur (nest $ pretty post <> prettyItemsWith sur items)
249248
<> pretty parclose
250249
where
251-
-- If the brackets are on different lines, keep them like that
252-
sur = if sourceLine paropen /= sourceLine parclose then hardline else line
250+
sur
251+
| sourceLine paropen /= sourceLine parclose = hardline -- If the brackets are on different lines, keep them like that
252+
| length (unItems items) > 6 = hardline -- More than 6 items: always expand
253+
| length (unItems items) > 1 && not (all (isSimple . Term) items) = hardline -- More than 1 item containing non-simple items: expand
254+
| otherwise = line -- Otherwise, try to fit onto one line
253255
prettyTerm (Set krec paropen items parclose) = prettySet False (krec, paropen, items, parclose)
254256
-- Parentheses
255257
prettyTerm (Parenthesized paropen expr parclose@Ann{preTrivia = closePre}) =
@@ -412,36 +414,19 @@ prettyApp indentFunction pre hasPost f a =
412414
-- This is very hacky, but selections shouldn't be in a priority group,
413415
-- because if they get expanded before anything else,
414416
-- only the `.`-and-after part gets to a new line, which looks very odd
415-
absorbApp (Application f' a'@(Term Selection{})) = group' Transparent (absorbApp f') <> line <> nest (group' RegularG $ absorbInner a')
417+
absorbApp (Application f' a'@(Term Selection{})) = group' Transparent (absorbApp f') <> line <> nest (group' RegularG $ pretty a')
416418
-- If two consecutive arguments are lists, treat them specially: Don't priority expand, and also
417419
-- if one does not fit onto the line then put both on a new line each.
418420
-- Note that this does not handle the case where the two last arguments are lists, as the last argument
419421
-- is handled elsewhere and cannot be pattern-matched here.
420422
absorbApp (Application (Application f' l1@(Term List{})) l2@(Term List{})) =
421-
group' Transparent (group' Transparent (absorbApp f') <> nest (group' RegularG $ line <> group (absorbInner l1) <> line <> group (absorbInner l2)))
422-
absorbApp (Application f' a') = group' Transparent (absorbApp f') <> line <> nest (group' Priority $ absorbInner a')
423+
group' Transparent (group' Transparent (absorbApp f') <> nest (group' RegularG $ line <> group (pretty l1) <> line <> group (pretty l2)))
424+
absorbApp (Application f' a') = group' Transparent (absorbApp f') <> line <> nest (group' Priority $ pretty a')
423425
-- First argument
424426
absorbApp expr
425427
| indentFunction && null comment' = nest $ group' RegularG $ line' <> pretty expr
426428
| otherwise = pretty expr
427429

428-
-- Render the inner arguments of a function call
429-
absorbInner :: Expression -> Doc
430-
-- If lists have only simple items, try to render them single-line instead of expanding
431-
-- This is just a copy of the list rendering code, but with `sepBy line` instead of `sepBy hardline`
432-
absorbInner (Term (List paropen@Ann{trailComment = post'} items parclose))
433-
| length (unItems items) <= 6 && all (isSimple . Term) items =
434-
pretty (paropen{trailComment = Nothing})
435-
<> surroundWith sur (nest $ pretty post' <> sepBy line (unItems items))
436-
<> pretty parclose
437-
where
438-
-- If the brackets are on different lines, keep them like that
439-
sur
440-
| sourceLine paropen /= sourceLine parclose = hardline
441-
| null $ unItems items = hardspace
442-
| otherwise = line
443-
absorbInner expr = pretty expr
444-
445430
-- Render the last argument of a function call
446431
absorbLast :: Expression -> Doc
447432
absorbLast (Term t)
@@ -512,9 +497,9 @@ prettyApp indentFunction pre hasPost f a =
512497
group' RegularG $
513498
(pre <> group' Transparent (absorbApp fWithoutCommandAndWithoutArg))
514499
<> line
515-
<> nest (group (absorbInner l1))
500+
<> nest (group (pretty l1))
516501
<> line
517-
<> nest (group (absorbInner l2))
502+
<> nest (group (pretty l2))
518503
<> post
519504
_ ->
520505
renderSimple
@@ -696,7 +681,7 @@ instance Pretty Expression where
696681
convertTrailing (Just (TrailingComment t)) = [LineComment (" " <> t)]
697682

698683
letPart = group $ pretty let_ <> hardline <> letBody
699-
letBody = nest $ prettyItems binders
684+
letBody = nest $ prettyItemsWith hardline binders
700685
inPart =
701686
group $
702687
pretty in_

test/correct-indent-4.nix

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -466,12 +466,7 @@ rec {
466466
}:
467467
assert isInt depthLimit;
468468
let
469-
specialAttrs = [
470-
"__functor"
471-
"__functionArgs"
472-
"__toString"
473-
"__pretty"
474-
];
469+
specialAttrs = [ "__functor" "__functionArgs" "__toString" "__pretty" ];
475470
stepIntoAttr = evalNext: name: if elem name specialAttrs then id else evalNext;
476471
transform =
477472
depth:
@@ -543,11 +538,7 @@ rec {
543538
else if isString v then
544539
let
545540
lines = filter (v: !isList v) (split "\n" v);
546-
escapeSingleline = escape [
547-
"\\"
548-
"\""
549-
"\${"
550-
];
541+
escapeSingleline = escape [ "\\" "\"" "\${" ];
551542
escapeMultiline = replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
552543
singlelineResult =
553544
"\"" + concatStringsSep "\\n" (map escapeSingleline lines) + "\"";

test/diff/apply/out-pure.nix

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,7 @@
155155
utils.lib.eachDefaultSystem (system: { });
156156
}
157157
{
158-
escapeSingleline = libStr.escape [
159-
"\\"
160-
''"''
161-
"\${"
162-
];
158+
escapeSingleline = libStr.escape [ "\\" ''"'' "\${" ];
163159
escapeMultiline = libStr.replaceStrings [ "\${" "''" ] [ "''\${" "'''" ];
164160
test =
165161
foo

test/diff/apply_with_lists/out-pure.nix

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
[
44
(f [ ] [ rhs lhs ])
5-
(lib.mkMerge [
6-
false
7-
false
8-
])
5+
(lib.mkMerge [ false false ])
96
(replaceStrings
107
[ "\${" "''" ]
118
#force multiline
@@ -46,30 +43,12 @@
4643
[ "services" "xserver" "displayManager" "sddm" "enable" ]
4744
[ "services" "displayManager" "sddm" "enable" ]
4845
)
49-
(map (
50-
buildAllowCommand "allow" [
51-
"snapshot"
52-
"mount"
53-
"destroy"
54-
]
55-
))
56-
(map
57-
(
58-
x:
59-
"${x} ${
60-
escapeShellArgs [
61-
stateDir
62-
workDir
63-
logsDir
64-
]
65-
}"
66-
)
67-
[
68-
"+${unconfigureRunner}" # runs as root
69-
configureRunner
70-
setupWorkDir
71-
]
72-
)
46+
(map (buildAllowCommand "allow" [ "snapshot" "mount" "destroy" ]))
47+
(map (x: "${x} ${escapeShellArgs [ stateDir workDir logsDir ]}") [
48+
"+${unconfigureRunner}" # runs as root
49+
configureRunner
50+
setupWorkDir
51+
])
7352
(lib.checkListOfEnum "${pname}: theme accent"
7453
[ "Blue" "Flamingo" "Green" ]
7554
[ accent ]
@@ -82,17 +61,11 @@
8261
[ coq.coq-version ssreflect.version ]
8362
[
8463
{
85-
cases = [
86-
(lib.versions.range "8.15" "8.20")
87-
lib.pred.true
88-
];
64+
cases = [ (lib.versions.range "8.15" "8.20") lib.pred.true ];
8965
out = "2.0.4";
9066
}
9167
{
92-
cases = [
93-
"8.5"
94-
lib.pred.true
95-
];
68+
cases = [ "8.5" lib.pred.true ];
9669
out = "20170512";
9770
}
9871
]

test/diff/apply_with_lists/out.nix

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
[
44
(f [ ] [ rhs lhs ])
5-
(lib.mkMerge [
6-
false
7-
false
8-
])
5+
(lib.mkMerge [ false false ])
96
(replaceStrings
107
[ "\${" "''" ]
118
#force multiline
@@ -52,30 +49,12 @@
5249
]
5350
[ "services" "displayManager" "sddm" "enable" ]
5451
)
55-
(map (
56-
buildAllowCommand "allow" [
57-
"snapshot"
58-
"mount"
59-
"destroy"
60-
]
61-
))
62-
(map
63-
(
64-
x:
65-
"${x} ${
66-
escapeShellArgs [
67-
stateDir
68-
workDir
69-
logsDir
70-
]
71-
}"
72-
)
73-
[
74-
"+${unconfigureRunner}" # runs as root
75-
configureRunner
76-
setupWorkDir
77-
]
78-
)
52+
(map (buildAllowCommand "allow" [ "snapshot" "mount" "destroy" ]))
53+
(map (x: "${x} ${escapeShellArgs [ stateDir workDir logsDir ]}") [
54+
"+${unconfigureRunner}" # runs as root
55+
configureRunner
56+
setupWorkDir
57+
])
7958
(lib.checkListOfEnum "${pname}: theme accent"
8059
[
8160
"Blue"

0 commit comments

Comments
 (0)