@@ -502,6 +502,34 @@ prettyApp indentFunction pre hasPost f a =
502
502
(\ fRendered -> group' RegularG $ fRendered <> line <> absorbLast a <> post)
503
503
<> (if hasPost && not (null comment') then hardline else mempty )
504
504
505
+ prettyOp :: Bool -> Expression -> Leaf -> Doc
506
+ prettyOp forceFirstTermWide operation op =
507
+ let -- Walk the operation tree and put a list of things on the same level.
508
+ -- We still need to keep the operators around because they might have comments attached to them.
509
+ -- An operator is put together with its succeeding expression. Only the first operand has none.
510
+ flatten :: Maybe Leaf -> Expression -> [(Maybe Leaf , Expression )]
511
+ flatten opL (Operation a opR b) | opR == op = flatten opL a ++ flatten (Just opR) b
512
+ flatten opL x = [(opL, x)]
513
+
514
+ -- Called on every operand except the first one (a.k.a. RHS)
515
+ absorbOperation :: Expression -> Doc
516
+ absorbOperation (Term t) | isAbsorbable t = hardspace <> pretty t
517
+ -- Force nested operations to start on a new line
518
+ absorbOperation x@ (Operation {}) = group' RegularG $ line <> pretty x
519
+ -- Force applications to start on a new line if more than the last argument is multiline
520
+ absorbOperation (Application f a) = group $ prettyApp False line False f a
521
+ absorbOperation x = hardspace <> pretty x
522
+
523
+ prettyOperation :: (Maybe Leaf , Expression ) -> Doc
524
+ -- First element
525
+ prettyOperation (Nothing , Term t) | isAbsorbableTerm t && forceFirstTermWide = prettyTermWide t
526
+ prettyOperation (Nothing , expr) = pretty expr
527
+ -- The others
528
+ prettyOperation (Just op', expr) =
529
+ line <> pretty (moveTrailingCommentUp op') <> nest (absorbOperation expr)
530
+ in group' RegularG $
531
+ (concatMap prettyOperation . flatten Nothing ) operation
532
+
505
533
prettyWith :: Bool -> Expression -> Doc
506
534
-- absorb the body
507
535
prettyWith True (With with expr0 semicolon (Term expr1)) =
@@ -608,15 +636,14 @@ absorbRHS expr = case expr of
608
636
-- Absorb if all arguments except the last fit into the line, start on new line otherwise
609
637
(Application f a) -> nest $ prettyApp False line False f a
610
638
(With {}) -> nest $ group' RegularG $ line <> pretty expr
611
- -- Special case `//` and `++` operations to be more compact in some cases
612
- -- Case 1: two arguments, LHS is absorbable term, RHS fits onto the last line
613
- (Operation (Term t) (LoneAnn op) b)
614
- | isAbsorbable t
615
- && isUpdateOrConcat op
616
- -- Exclude further operations on the RHS
617
- -- Hotfix for https://github.com/NixOS/nixfmt/issues/198
618
- && case b of (Operation {}) -> False ; _ -> True ->
619
- nest $ group' RegularG $ line <> group' Priority (prettyTermWide t) <> line <> pretty op <> hardspace <> pretty b
639
+ -- Special case `//` and `++` and `+` operations to be more compact in some cases
640
+ -- Case 1: LHS is absorbable term, unindent concatenations
641
+ -- https://github.com/NixOS/nixfmt/issues/228
642
+ (Operation (Term t) op@ (Ann {value}) _)
643
+ | isAbsorbableTerm t
644
+ && matchFirstToken (\ Ann {preTrivia} -> preTrivia == [] ) t
645
+ && elem value [TUpdate , TConcat , TPlus ] ->
646
+ hardspace <> prettyOp True expr op
620
647
-- Case 2a: LHS fits onto first line, RHS is an absorbable term
621
648
(Operation l (LoneAnn op) (Term t))
622
649
| isAbsorbable t && isUpdateOrConcat op ->
@@ -715,31 +742,7 @@ instance Pretty Expression where
715
742
| op' == TLess || op' == TGreater || op' == TLessEqual || op' == TGreaterEqual || op' == TEqual || op' == TUnequal =
716
743
pretty a <> softline <> pretty op <> hardspace <> pretty b
717
744
-- all other operators
718
- pretty operation@ (Operation _ op _) =
719
- let -- Walk the operation tree and put a list of things on the same level.
720
- -- We still need to keep the operators around because they might have comments attached to them.
721
- -- An operator is put together with its succeeding expression. Only the first operand has none.
722
- flatten :: Maybe Leaf -> Expression -> [(Maybe Leaf , Expression )]
723
- flatten opL (Operation a opR b) | opR == op = flatten opL a ++ flatten (Just opR) b
724
- flatten opL x = [(opL, x)]
725
-
726
- -- Called on every operand except the first one (a.k.a. RHS)
727
- absorbOperation :: Expression -> Doc
728
- absorbOperation (Term t) | isAbsorbable t = hardspace <> pretty t
729
- -- Force nested operations to start on a new line
730
- absorbOperation x@ (Operation {}) = group' RegularG $ line <> pretty x
731
- -- Force applications to start on a new line if more than the last argument is multiline
732
- absorbOperation (Application f a) = group $ prettyApp False line False f a
733
- absorbOperation x = hardspace <> pretty x
734
-
735
- prettyOperation :: (Maybe Leaf , Expression ) -> Doc
736
- -- First element
737
- prettyOperation (Nothing , expr) = pretty expr
738
- -- The others
739
- prettyOperation (Just op', expr) =
740
- line <> pretty (moveTrailingCommentUp op') <> nest (absorbOperation expr)
741
- in group' RegularG $
742
- (concatMap prettyOperation . flatten Nothing ) operation
745
+ pretty operation@ (Operation _ op _) = prettyOp False operation op
743
746
pretty (MemberCheck expr qmark sel) =
744
747
pretty expr
745
748
<> softline
0 commit comments