Skip to content

Commit

Permalink
Merge pull request #201 from NixOS/preserve-more-newlines
Browse files Browse the repository at this point in the history
Preserve more newlines
  • Loading branch information
tomberek authored May 28, 2024
2 parents 3bcb63c + 84b3b6c commit 3b79463
Show file tree
Hide file tree
Showing 18 changed files with 106 additions and 56 deletions.
19 changes: 5 additions & 14 deletions src/Nixfmt/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -341,26 +341,17 @@ term = label "term" $ do
_ -> Selection t sel def

items :: Parser a -> Parser (Items a)
items p = Items <$> many (item p) <> (toList <$> optional lastItem)
items p = Items <$> many (item p) <> (toList <$> optional itemComment)

item :: Parser a -> Parser (Item a)
item p = detachedComment <|> CommentedItem <$> takeTrivia <*> p
item p = itemComment <|> Item <$> p

lastItem :: Parser (Item a)
lastItem = do
itemComment :: Parser (Item a)
itemComment = do
trivia <- takeTrivia
case trivia of
[] -> empty
_ -> pure $ DetachedComments trivia

detachedComment :: Parser (Item a)
detachedComment = do
trivia <- takeTrivia
case break (== EmptyLine) trivia of
-- Return a set of comments that don't annotate the next item
(detached, EmptyLine : trivia') -> pushTrivia trivia' >> pure (DetachedComments detached)
-- The remaining trivia annotate the next item
_ -> pushTrivia trivia >> empty
_ -> pure $ Comments trivia

-- ABSTRACTIONS

Expand Down
31 changes: 12 additions & 19 deletions src/Nixfmt/Pretty.hs
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,12 @@ instance Pretty Trivium where
| otherwise = comment l <> hardline

instance (Pretty a) => Pretty (Item a) where
pretty (DetachedComments trivia) = pretty trivia
pretty (CommentedItem trivia x) = pretty trivia <> group x
pretty (Comments trivia) = pretty trivia
pretty (Item x) = group x

-- For lists, attribute sets and let bindings
prettyItems :: (Pretty a) => Doc -> Items a -> Doc
-- Special case: Preserve an empty line with no items
-- usually, trailing newlines after the last element are not preserved
prettyItems _ (Items [DetachedComments []]) = emptyline
prettyItems sep items = prettyItems' $ unItems items
where
prettyItems' :: (Pretty a) => [Item a] -> Doc
prettyItems' [] = mempty
prettyItems' [item] = pretty item
prettyItems' (item : xs) =
pretty item
<> case item of CommentedItem _ _ -> sep; DetachedComments _ -> emptyline
<> prettyItems' xs
prettyItems :: (Pretty a) => Items a -> Doc
prettyItems (Items items) = sepBy hardline items

instance Pretty [Trivium] where
pretty [] = mempty
Expand Down Expand Up @@ -170,7 +159,7 @@ prettySet _ (krec, Ann [] paropen Nothing, Items [], parclose@(Ann [] _ _)) =
prettySet wide (krec, Ann pre paropen post, binders, parclose) =
pretty (fmap (,hardspace) krec)
<> pretty (Ann pre paropen Nothing)
<> surroundWith sep (nest $ pretty post <> prettyItems hardline binders)
<> surroundWith sep (nest $ pretty post <> prettyItems binders)
<> pretty parclose
where
sep = if wide && not (null (unItems binders)) then hardline else line
Expand Down Expand Up @@ -207,7 +196,7 @@ prettyTerm (List (Ann leading paropen Nothing) (Items []) (Ann [] parclose trail
-- Always expand if len > 1
prettyTerm (List (Ann pre paropen post) items parclose) =
pretty (Ann pre paropen Nothing)
<> surroundWith line (nest $ pretty post <> prettyItems hardline items)
<> surroundWith line (nest $ pretty post <> prettyItems items)
<> pretty parclose
prettyTerm (Set krec paropen items parclose) = prettySet False (krec, paropen, items, parclose)
-- Parentheses
Expand Down Expand Up @@ -561,14 +550,18 @@ instance Pretty Expression where
(binderComments, bindersWithoutComments) =
foldr
( \item (start, rest) -> case item of
(DetachedComments inner) | null rest -> (inner : start, rest)
(Comments inner)
| null rest ->
-- Only move all non-empty-line trivia below the `in`
let (comments, el) = break (== EmptyLine) (reverse inner)
in (reverse comments : start, Comments (reverse el) : rest)
_ -> (start, item : rest)
)
([], [])
(unItems binders)

letPart = group $ pretty let_ <> hardline <> letBody
letBody = nest $ prettyItems hardline (Items bindersWithoutComments)
letBody = nest $ prettyItems (Items bindersWithoutComments)
inPart =
group $
pretty (Ann [] in_ Nothing)
Expand Down
44 changes: 21 additions & 23 deletions src/Nixfmt/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,10 @@ instance (Eq a) => Eq (Ann a) where
-- show (Ann _ a _) = show a

data Item a
= -- | An item with a list of line comments that apply to it. There is no
-- empty line between the comments and the stuff it applies to.
CommentedItem Trivia a
| -- | A list of line comments not associated with any item. Followed by an
-- empty line unless they're the last comments in a set or list.
DetachedComments Trivia
= -- | An item
Item a
| -- | Trivia interleaved in items
Comments Trivia
deriving (Foldable, Show)

newtype Items a = Items {unItems :: [Item a]}
Expand Down Expand Up @@ -279,33 +277,33 @@ instance LanguageElement Term where
walkSubprograms = \case
-- Map each item to a singleton list, then handle that
(List _ items _) | Prelude.length (unItems items) == 1 -> case Prelude.head (unItems items) of
(CommentedItem c item) -> [emptySet c, Term item]
(DetachedComments _) -> []
(Item item) -> [Term item]
(Comments _) -> []
(List _ items _) ->
unItems items >>= \case
CommentedItem comment item ->
[Term (List (ann TBrackOpen) (Items [CommentedItem comment item]) (ann TBrackClose))]
DetachedComments c ->
[Term (List (ann TBrackOpen) (Items [DetachedComments c]) (ann TBrackClose))]
Item item ->
[Term (List (ann TBrackOpen) (Items [Item item]) (ann TBrackClose))]
Comments c ->
[Term (List (ann TBrackOpen) (Items [Comments c]) (ann TBrackClose))]
(Set _ _ items _) | Prelude.length (unItems items) == 1 -> case Prelude.head (unItems items) of
(CommentedItem c (Inherit _ from sels _)) ->
(Term <$> maybeToList from) ++ concatMap walkSubprograms sels ++ [emptySet c]
(CommentedItem c (Assignment sels _ expr _)) ->
expr : concatMap walkSubprograms sels ++ [emptySet c]
(DetachedComments _) -> []
(Item (Inherit _ from sels _)) ->
(Term <$> maybeToList from) ++ concatMap walkSubprograms sels
(Item (Assignment sels _ expr _)) ->
expr : concatMap walkSubprograms sels
(Comments _) -> []
(Set _ _ items _) ->
unItems items >>= \case
-- Map each binding to a singleton set
(CommentedItem comment item) ->
[Term (Set Nothing (ann TBraceOpen) (Items [CommentedItem comment item]) (ann TBraceClose))]
(DetachedComments c) -> [emptySet c]
(Item item) ->
[Term (Set Nothing (ann TBraceOpen) (Items [Item item]) (ann TBraceClose))]
(Comments c) -> [emptySet c]
(Selection term sels Nothing) -> Term term : (sels >>= walkSubprograms)
(Selection term sels (Just (_, def))) -> Term term : (sels >>= walkSubprograms) ++ [Term def]
(Parenthesized _ expr _) -> [expr]
-- The others are already minimal
_ -> []
where
emptySet c = Term (Set Nothing (ann TBraceOpen) (Items [DetachedComments c]) (ann TBraceClose))
emptySet c = Term (Set Nothing (ann TBraceOpen) (Items [Comments c]) (ann TBraceClose))

instance LanguageElement Expression where
mapFirstToken' f = \case
Expand Down Expand Up @@ -342,8 +340,8 @@ instance LanguageElement Expression where
body
: ( unItems items >>= \case
-- Map each binding to a singleton set
(CommentedItem _ item) -> [Term (Set Nothing (ann TBraceOpen) (Items [CommentedItem [] item]) (ann TBraceClose))]
(DetachedComments _) -> []
(Item item) -> [Term (Set Nothing (ann TBraceOpen) (Items [Item item]) (ann TBraceClose))]
(Comments _) -> []
)
(Assert _ cond _ body) -> [cond, body]
(If _ expr0 _ expr1 _ expr2) -> [expr0, expr1, expr2]
Expand Down
2 changes: 2 additions & 0 deletions test/diff/attr_set/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
c = 1;

e = 1;

}

rec
Expand All @@ -102,6 +103,7 @@
e = 1;

# f

}
{
x =
Expand Down
2 changes: 2 additions & 0 deletions test/diff/idioms_lib_3/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ let
libAttr = lib.attrsets;

inherit (lib) isFunction;

in
rec {

Expand Down Expand Up @@ -528,6 +529,7 @@ rec {
) x
)
);

in
''
<?xml version="1.0" encoding="UTF-8"?>
Expand Down
3 changes: 3 additions & 0 deletions test/diff/idioms_lib_4/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ let
assert type.check value;
setType type.name ({ inherit name; } // value)
);

in

rec {
Expand Down Expand Up @@ -887,6 +888,7 @@ rec {
else
abis.unknown;
};

in
mkSystem parsed;

Expand Down Expand Up @@ -927,4 +929,5 @@ rec {
"${cpu.name}-${vendor.name}-${kernelName kernel}${optExecFormat}${optAbi}";

################################################################################

}
2 changes: 2 additions & 0 deletions test/diff/idioms_lib_5/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,9 @@ let
yes = true;
}
.${validity.valid};

};

in
{
inherit assertValidity commonMeta;
Expand Down
6 changes: 6 additions & 0 deletions test/diff/idioms_nixos_1/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let
kernelModulesConf = pkgs.writeText "nixos.conf" ''
${concatStringsSep "\n" config.boot.kernelModules}
'';

in

{
Expand Down Expand Up @@ -214,6 +215,7 @@ in
lib.kernelConfig functions to build list elements.
'';
};

};

###### implementation
Expand Down Expand Up @@ -262,6 +264,7 @@ in
"hid_logitech_hidpp"
"hid_logitech_dj"
"hid_microsoft"

]
++ optionals pkgs.stdenv.hostPlatform.isx86 [
# Misc. x86 keyboard stuff.
Expand Down Expand Up @@ -381,6 +384,9 @@ in
assertion = attrs.assertion cfg;
inherit (attrs) message;
}) config.system.requiredKernelConfig;

})

];

}
4 changes: 4 additions & 0 deletions test/diff/idioms_nixos_2/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ let
'';

inherit (config.system) stateVersion;

in
{

Expand Down Expand Up @@ -383,6 +384,7 @@ in
is used to also support MariaDB version >= 10.6.
'';
};

};

config = {
Expand Down Expand Up @@ -762,6 +764,7 @@ in
The package can be upgraded by explicitly declaring the service-option
`services.nextcloud.package`.
'';

in
(optional (cfg.poolConfig != null) ''
Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release.
Expand Down Expand Up @@ -1016,6 +1019,7 @@ in
${toString i} --value="${toString v}"
'') ([ cfg.hostName ] ++ cfg.config.extraTrustedDomains)
);

in
{
wantedBy = [ "multi-user.target" ];
Expand Down
1 change: 1 addition & 0 deletions test/diff/idioms_pkgs_3/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ let
'') defaultPrefs
)
);

in

buildStdenv.mkDerivation ({
Expand Down
3 changes: 3 additions & 0 deletions test/diff/idioms_pkgs_4/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ let
config
;
};

in

[
Expand Down Expand Up @@ -189,6 +190,7 @@ in
# Curl should be in /usr/bin or so.
curl = null;
};

}
)

Expand All @@ -212,4 +214,5 @@ in
if localSystem.isLinux then [ prevStage.patchelf ] else [ ];
};
})

]
3 changes: 3 additions & 0 deletions test/diff/idioms_pkgs_5/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ let
);

finalPackage = mkDerivationSimple overrideAttrs args;

in
finalPackage;

Expand Down Expand Up @@ -727,6 +728,7 @@ let
"The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}.";
v
) env;

in

extendDerivation validity.handled (
Expand Down Expand Up @@ -785,6 +787,7 @@ let
# derivation (e.g., in assertions).
passthru
) (derivation (derivationArg // optionalAttrs envIsExportable checkedEnv));

in
fnOrAttrs:
if builtins.isFunction fnOrAttrs then
Expand Down
1 change: 1 addition & 0 deletions test/diff/key_value/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@ rec {
;

p = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { } a;

}
11 changes: 11 additions & 0 deletions test/diff/let_in/in.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ let
2
];

a =
let
b = 0;


# foo
# bar
in # baz
# qux
null;

in


Expand Down
Loading

0 comments on commit 3b79463

Please sign in to comment.