Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always expand attrs #222

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 27 additions & 33 deletions src/Nixfmt/Pretty.hs
Original file line number Diff line number Diff line change
Expand Up @@ -150,23 +150,6 @@ instance Pretty Binder where
-- while we already pretty eagerly expand sets with more than one element,
-- in some situations even that is not sufficient. The wide parameter will
-- be even more eager at expanding, except for empty sets and inherit statements.
prettySet :: Bool -> (Maybe Leaf, Leaf, Items Binder, Leaf) -> Doc
-- Empty attribute set
prettySet _ (krec, Ann [] paropen Nothing, Items [], parclose@(Ann [] _ _)) =
pretty (fmap (,hardspace) krec) <> pretty paropen <> hardspace <> pretty parclose
-- Singleton sets are allowed to fit onto one line,
-- but apart from that always expand.
prettySet wide (krec, Ann pre paropen post, binders, parclose) =
pretty (fmap (,hardspace) krec)
<> pretty (Ann pre paropen Nothing)
<> surroundWith sep (nest $ pretty post <> prettyItems binders)
<> pretty parclose
where
sep = if wide && not (null (unItems binders)) then hardline else line

prettyTermWide :: Term -> Doc
prettyTermWide (Set krec paropen items parclose) = prettySet True (krec, paropen, items, parclose)
prettyTermWide t = prettyTerm t

-- | Pretty print a term without wrapping it in a group.
prettyTerm :: Term -> Doc
Expand Down Expand Up @@ -198,7 +181,19 @@ prettyTerm (List (Ann pre paropen post) items parclose) =
pretty (Ann pre paropen Nothing)
<> surroundWith line (nest $ pretty post <> prettyItems items)
<> pretty parclose
prettyTerm (Set krec paropen items parclose) = prettySet False (krec, paropen, items, parclose)
-- Empty attribute set
prettyTerm (Set krec (Ann [] paropen Nothing) (Items []) parclose@(Ann [] _ _)) =
pretty (fmap (,hardspace) krec) <> pretty paropen <> hardspace <> pretty parclose
-- Singleton sets are allowed to fit onto one line,
-- but apart from that always expand.
prettyTerm (Set krec (Ann pre paropen post) binders parclose) =
pretty (fmap (,hardspace) krec)
<> pretty (Ann pre paropen Nothing)
<> surroundWith sep (nest $ pretty post <> prettyItems binders)
<> pretty parclose
where
sep = if not (null (unItems binders)) then hardline else line

-- Parentheses
prettyTerm (Parenthesized paropen expr (Ann closePre parclose closePost)) =
group $
Expand All @@ -209,7 +204,7 @@ prettyTerm (Parenthesized paropen expr (Ann closePre parclose closePost)) =
inner =
case expr of
-- Start on the same line for these
_ | isAbsorbableExpr expr -> group $ absorbExpr False expr
_ | isAbsorbableExpr expr -> group $ absorbExpr expr
-- Parenthesized application
(Application f a) -> prettyApp True mempty True f a
-- Same thing for selections
Expand Down Expand Up @@ -371,7 +366,7 @@ prettyApp indentFunction pre hasPost f a =
<> pretty name
<> pretty colon
<> hardspace
<> prettyTermWide body
<> prettyTerm body
<> pretty close
-- Special case: Absorb parenthesized function application with absorbable body
absorbLast
Expand All @@ -388,7 +383,7 @@ prettyApp indentFunction pre hasPost f a =
pretty open
<> pretty fn
<> hardspace
<> prettyTermWide body
<> prettyTerm body
<> pretty close
absorbLast (Term (Parenthesized open expr close)) =
absorbParen open expr close
Expand Down Expand Up @@ -422,7 +417,7 @@ prettyWith True (With with expr0 semicolon (Term expr1)) =
<> pretty semicolon
-- Force-expand attrsets
<> hardspace
<> group' Priority (prettyTermWide expr1)
<> group' Priority (prettyTerm expr1)
-- Normal case
prettyWith _ (With with expr0 semicolon expr1) =
group
Expand Down Expand Up @@ -480,18 +475,17 @@ absorbParen (Ann pre' open post') expr (Ann pre'' close post'') =
-- Note that unlike for absorbable terms which can be force-absorbed, some expressions
-- may turn out to not be absorbable. In that case, they should start with a line' so that
-- they properly start on the next line if necessary.
absorbExpr :: Bool -> Expression -> Doc
absorbExpr True (Term t) | isAbsorbableTerm t = prettyTermWide t
absorbExpr False (Term t) | isAbsorbableTerm t = prettyTerm t
absorbExpr :: Expression -> Doc
absorbExpr (Term t) | isAbsorbableTerm t = prettyTerm t
-- With expression with absorbable body: Treat as absorbable term
absorbExpr _ expr@(With _ _ _ (Term t)) | isAbsorbableTerm t = prettyWith True expr
absorbExpr _ expr = pretty expr
absorbExpr expr@(With _ _ _ (Term t)) | isAbsorbableTerm t = prettyWith True expr
absorbExpr expr = pretty expr

-- Render the RHS value of an assignment or function parameter default value
absorbRHS :: Expression -> Doc
absorbRHS expr = case expr of
-- Absorbable expression. Always start on the same line
_ | isAbsorbableExpr expr -> hardspace <> group (absorbExpr True expr)
_ | isAbsorbableExpr expr -> hardspace <> group (absorbExpr expr)
-- Parenthesized expression. Same thing as the special case for parenthesized last argument in function calls.
(Term (Parenthesized open expr' close)) -> hardspace <> absorbParen open expr' close
-- Not all strings are absorbable, but in this case we always want to keep them attached.
Expand All @@ -511,11 +505,11 @@ absorbRHS expr = case expr of
-- Case 1: two arguments, LHS is absorbable term, RHS fits onto the last line
(Operation (Term t) (Ann [] op Nothing) b)
| isAbsorbable t && isUpdateOrConcat op ->
group' RegularG $ line <> group' Priority (prettyTermWide t) <> line <> pretty op <> hardspace <> pretty b
group' RegularG $ line <> group' Priority (prettyTerm t) <> line <> pretty op <> hardspace <> pretty b
-- Case 2a: LHS fits onto first line, RHS is an absorbable term
(Operation l (Ann [] op Nothing) (Term t))
| isAbsorbable t && isUpdateOrConcat op ->
group' RegularG $ line <> pretty l <> line <> group' Transparent (pretty op <> hardspace <> group' Priority (prettyTermWide t))
group' RegularG $ line <> pretty l <> line <> group' Transparent (pretty op <> hardspace <> group' Priority (prettyTerm t))
-- Case 2b: LHS fits onto first line, RHS is a function application
(Operation l (Ann [] op Nothing) (Application f a))
| isUpdateOrConcat op ->
Expand Down Expand Up @@ -609,15 +603,15 @@ instance Pretty Expression where
-- If there are multiple ID parameters to that function, treat them all at once
absorbAbs depth (Abstraction (IDParameter param0) colon0 body0) =
hardspace <> pretty param0 <> pretty colon0 <> absorbAbs (depth + 1) body0
absorbAbs _ expr | isAbsorbableExpr expr = hardspace <> group' Priority (absorbExpr False expr)
absorbAbs _ expr | isAbsorbableExpr expr = hardspace <> group' Priority (absorbExpr expr)
-- Force the content onto a new line when it is not absorbable and there are more than two arguments
absorbAbs depth x =
(if depth <= 2 then line else hardline) <> pretty x

-- Attrset parameter
pretty (Abstraction param colon (Term t))
| isAbsorbable t =
pretty param <> pretty colon <> line <> group (prettyTermWide t)
pretty param <> pretty colon <> line <> group (prettyTerm t)
pretty (Abstraction param colon body) =
pretty param <> pretty colon <> line <> pretty body
pretty (Application f a) =
Expand Down Expand Up @@ -725,7 +719,7 @@ instance Pretty [StringPart] where
-- Code copied over from parentheses. Could be factored out into a common function one day
inner = case expr of
-- Start on the same line for these
_ | isAbsorbableExpr expr -> group $ absorbExpr False expr
_ | isAbsorbableExpr expr -> group $ absorbExpr expr
-- Parenthesized application
(Application f a) -> prettyApp True mempty True f a
-- Same thing for selections
Expand Down
4 changes: 3 additions & 1 deletion test/correct/float-below-one.nix
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
{ foo = 0.3; }
{
foo = 0.3;
}
9 changes: 8 additions & 1 deletion test/correct/quotes-in-inherit.nix
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
{ inherit ({ "in" = 1; }) "in"; }
{
inherit
({
"in" = 1;
})
"in"
;
}
92 changes: 68 additions & 24 deletions test/diff/apply/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -106,46 +106,90 @@
}
''
{
name1 = function arg { asdf = 1; };
name1 = function arg {
asdf = 1;
};

name2 = function arg { asdf = 1; } argument;
name2 = function arg {
asdf = 1;
} argument;

name3 = function arg { asdf = 1; } { qwer = 12345; } argument;
name3 =
function arg
{
asdf = 1;
}
{
qwer = 12345;
}
argument;
}
{
name1 = function arg { asdf = 1; };
name1 = function arg {
asdf = 1;
};

name2 = function arg {
asdf = 1;
# multiline
} argument;

name3 = function arg {
asdf = 1;
# multiline
} { qwer = 12345; } argument;
name3 =
function arg
{
asdf = 1;
# multiline
}
{
qwer = 12345;
}
argument;
}
{
name4 = function arg { asdf = 1; } {
qwer = 12345;
qwer2 = 54321;
} argument;
name4 =
function arg
{
asdf = 1;
}
{
qwer = 12345;
qwer2 = 54321;
}
argument;
}
{
option1 = function arg { asdf = 1; } {
qwer = 12345;
qwer2 = 54321;
} lastArg;
option1 =
function arg
{
asdf = 1;
}
{
qwer = 12345;
qwer2 = 54321;
}
lastArg;

option2 = function arg { asdf = 1; } {
qwer = 12345;
qwer2 = 54321;
} lastArg;
option2 =
function arg
{
asdf = 1;
}
{
qwer = 12345;
qwer2 = 54321;
}
lastArg;

option3 = function arg { asdf = 1; } {
qwer = 12345;
qwer2 = 54321;
} lastArg;
option3 =
function arg
{
asdf = 1;
}
{
qwer = 12345;
qwer2 = 54321;
}
lastArg;
}
# https://github.com/kamadorueda/alejandra/issues/372#issuecomment-1435083516
{
Expand Down
16 changes: 12 additions & 4 deletions test/diff/attr_set/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
{
# a
}
{ a = 1; }
{ a = 1; }
{
a = 1;
}
{
a = 1;
}

{

Expand All @@ -16,7 +20,9 @@
};
}

{ b = 1; }
{
b = 1;
}
{
b = 1; # c
}
Expand All @@ -29,7 +35,9 @@
b = 1; # c
}

rec { c = 1; }
rec {
c = 1;
}
rec {
c = 1; # d
}
Expand Down
25 changes: 19 additions & 6 deletions test/diff/idioms_lib_3/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ rec {
''
[${mkSectionName sectName}]
''
+ toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues;
+ toKeyValue {
inherit mkKeyValue listsAsDuplicateKeys;
} sectValues;
in
# map input to ini sections
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
Expand Down Expand Up @@ -208,9 +210,14 @@ rec {
if globalSection == { } then
""
else
(toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } globalSection) + "\n"
(toKeyValue {
inherit mkKeyValue listsAsDuplicateKeys;
} globalSection)
+ "\n"
)
+ (toINI { inherit mkSectionName mkKeyValue listsAsDuplicateKeys; } sections);
+ (toINI {
inherit mkSectionName mkKeyValue listsAsDuplicateKeys;
} sections);

# Generate a git-config file from an attrset.
#
Expand Down Expand Up @@ -263,13 +270,19 @@ rec {
if isAttrs value && !lib.isDerivation value then
lib.mapAttrsToList (name: value: recurse ([ name ] ++ path) value) value
else if length path > 1 then
{ ${concatStringsSep "." (lib.reverseList (tail path))}.${head path} = value; }
{
${concatStringsSep "." (lib.reverseList (tail path))}.${head path} = value;
}
else
{ ${head path} = value; };
{
${head path} = value;
};
in
attrs: lib.foldl lib.recursiveUpdate { } (lib.flatten (recurse [ ] attrs));

toINI_ = toINI { inherit mkKeyValue mkSectionName; };
toINI_ = toINI {
inherit mkKeyValue mkSectionName;
};
in
toINI_ (gitFlattenAttrs attrs);

Expand Down
11 changes: 9 additions & 2 deletions test/diff/idioms_lib_4/out.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ with lib.lists;
with lib.types;
with lib.attrsets;
with lib.strings;
with (import ./inspect.nix { inherit lib; }).predicates;
with (import ./inspect.nix {
inherit lib;
}).predicates;

let
inherit (lib.options) mergeOneOption;
Expand All @@ -29,7 +31,12 @@ let
mapAttrs (
name: value:
assert type.check value;
setType type.name ({ inherit name; } // value)
setType type.name (
{
inherit name;
}
// value
)
);

in
Expand Down
Loading