1
Fork 0
mirror of https://github.com/RGBCube/alejandra synced 2025-08-01 21:17:45 +00:00

feat: try parentheses heuristics

This commit is contained in:
Kevin Amado 2022-03-01 21:54:20 -05:00
parent 64509489fb
commit f04306e80e
17 changed files with 1944 additions and 1581 deletions

View file

@ -21,45 +21,15 @@ pub(crate) struct BuildCtx {
pub vertical: bool, pub vertical: bool,
} }
impl BuildCtx {
pub fn new(
force_wide: bool,
path: String,
pos_old: crate::position::Position,
vertical: bool,
) -> BuildCtx {
BuildCtx {
force_wide,
force_wide_success: true,
indentation: 0,
path,
pos_old,
vertical,
}
}
}
pub(crate) fn build( pub(crate) fn build(
build_ctx: &mut BuildCtx,
element: rnix::SyntaxElement, element: rnix::SyntaxElement,
force_wide: bool,
path: String,
vertical: bool,
) -> Option<rowan::GreenNode> { ) -> Option<rowan::GreenNode> {
let mut builder = rowan::GreenNodeBuilder::new(); let mut builder = rowan::GreenNodeBuilder::new();
let mut build_ctx = BuildCtx::new(
force_wide,
path,
crate::position::Position::default(),
vertical,
);
build_step( build_step(&mut builder, build_ctx, &crate::builder::Step::Format(element));
&mut builder,
&mut build_ctx,
&crate::builder::Step::Format(element),
);
if force_wide { if build_ctx.force_wide {
if build_ctx.force_wide_success { Some(builder.finish()) } else { None } if build_ctx.force_wide_success { Some(builder.finish()) } else { None }
} else { } else {
Some(builder.finish()) Some(builder.finish())
@ -266,10 +236,17 @@ fn format_wider(
} }
pub(crate) fn fits_in_single_line( pub(crate) fn fits_in_single_line(
build_ctx: &crate::builder::BuildCtx, build_ctx_old: &crate::builder::BuildCtx,
element: rnix::SyntaxElement, element: rnix::SyntaxElement,
) -> bool { ) -> bool {
build(element, true, build_ctx.path.clone(), false).is_some() let mut build_ctx = crate::builder::BuildCtx {
force_wide: true,
force_wide_success: true,
vertical: false,
..build_ctx_old.clone()
};
build(&mut build_ctx, element).is_some()
} }
pub(crate) fn make_isolated_token( pub(crate) fn make_isolated_token(

View file

@ -1,12 +1,10 @@
use std::collections::LinkedList; use std::collections::LinkedList;
#[derive(Debug)]
pub(crate) enum Trivia { pub(crate) enum Trivia {
Comment(String), Comment(String),
Newlines(usize), Newlines(usize),
} }
#[derive(Debug)]
pub(crate) struct Child { pub(crate) struct Child {
pub element: rnix::SyntaxElement, pub element: rnix::SyntaxElement,

View file

@ -19,7 +19,16 @@ pub fn in_memory(path: String, before: String) -> (Status, String) {
return (Status::Error(errors[0].to_string()), before); return (Status::Error(errors[0].to_string()), before);
} }
let after = crate::builder::build(ast.node().into(), false, path, true) let mut build_ctx = crate::builder::BuildCtx {
force_wide: false,
force_wide_success: true,
indentation: 0,
path,
pos_old: crate::position::Position::default(),
vertical: true,
};
let after = crate::builder::build(&mut build_ctx, ast.node().into())
.unwrap() .unwrap()
.to_string(); .to_string();

View file

@ -1,13 +1,13 @@
use std::collections::LinkedList; use std::collections::LinkedList;
#[derive(Debug, Default)] #[derive(Default)]
pub(crate) struct Argument { pub(crate) struct Argument {
pub comments_before: LinkedList<String>, pub comments_before: LinkedList<String>,
pub item: Option<rnix::SyntaxElement>, pub item: Option<rnix::SyntaxElement>,
pub comment_after: Option<String>, pub comment_after: Option<String>,
} }
#[derive(Debug, Default)] #[derive(Default)]
pub(crate) struct Pattern { pub(crate) struct Pattern {
pub initial_at: Option<rnix::SyntaxElement>, pub initial_at: Option<rnix::SyntaxElement>,
pub comments_after_initial_at: LinkedList<String>, pub comments_after_initial_at: LinkedList<String>,

View file

@ -1,4 +1,4 @@
#[derive(Clone, Debug)] #[derive(Clone)]
pub(crate) struct Position { pub(crate) struct Position {
pub column: usize, pub column: usize,
pub line: usize, pub line: usize,

View file

@ -11,11 +11,28 @@ pub(crate) fn rule(
let closer = children.next().unwrap(); let closer = children.next().unwrap();
let vertical = opener.has_inline_comment let vertical = opener.has_inline_comment
|| opener.has_trivialities || opener.has_comments
|| expression.has_inline_comment || expression.has_inline_comment
|| expression.has_trivialities || expression.has_comments
|| closer.has_inline_comment || closer.has_inline_comment
|| closer.has_trivialities; || closer.has_comments
|| matches!(
expression.element.kind(),
rnix::SyntaxKind::NODE_IF_ELSE | rnix::SyntaxKind::NODE_LET_IN
)
|| (matches!(
expression.element.kind(),
rnix::SyntaxKind::NODE_APPLY
| rnix::SyntaxKind::NODE_ASSERT
| rnix::SyntaxKind::NODE_BIN_OP
| rnix::SyntaxKind::NODE_OR_DEFAULT
| rnix::SyntaxKind::NODE_LAMBDA
| rnix::SyntaxKind::NODE_SELECT
| rnix::SyntaxKind::NODE_WITH
) && second_through_penultimate_line_are_not_indented(
build_ctx,
expression.element.clone(),
));
// opener // opener
steps.push_back(crate::builder::Step::Format(opener.element)); steps.push_back(crate::builder::Step::Format(opener.element));
@ -77,3 +94,29 @@ pub(crate) fn rule(
steps steps
} }
fn second_through_penultimate_line_are_not_indented(
build_ctx: &crate::builder::BuildCtx,
element: rnix::SyntaxElement,
) -> bool {
let mut build_ctx =
crate::builder::BuildCtx { force_wide: false, ..build_ctx.clone() };
let formatted =
crate::builder::build(&mut build_ctx, element).unwrap().to_string();
let formatted_lines: Vec<&str> = formatted.split('\n').collect();
if formatted_lines.len() <= 2 {
return false;
}
let whitespace = format!("{0:<1$}", "", 2 * (build_ctx.indentation + 1));
formatted_lines
.iter()
.skip(1)
.rev()
.skip(1)
.any(|line| !line.is_empty() && !line.starts_with(&whitespace))
}

View file

@ -1,10 +1,12 @@
(a b) (a b)
(a b) (a b)
(a (
/* a
b /*
*/ b
c) */
c
)
( (
/* /*
a a

View file

@ -1,44 +1,56 @@
[ [
(assert b; e) (assert b; e)
(assert b; (
/* assert b;
d /*
*/ d
e) */
e
)
(assert b; e) (assert b; e)
(assert b; (
/* assert b;
d /*
*/ d
e) */
(assert e
/* )
a (
*/ assert
b; e) /*
(assert a
/* */
a b; e
*/ )
b; (
/* assert
d /*
*/ a
e) */
(assert b;
/* /*
a d
*/ */
b; e) e
(assert )
/* (
a assert
*/ /*
b; a
/* */
d b; e
*/ )
e) (
assert
/*
a
*/
b;
/*
d
*/
e
)
(assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc)
(assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc)
] ]

View file

@ -1,49 +1,63 @@
[ [
(1 + 1) (1 + 1)
(1 (
+ 1
/**/ +
1) /**/
(1 1
/**/ )
+ 1) (
(1 1
/**/ /**/
+ + 1
/**/ )
1) (
(1 1
/**/ /**/
+ +
/**/ /**/
(1 1
/**/ )
+ (
/**/ 1
(1 /**/
/**/ +
+ /**/
/**/ (
1))) 1
/**/
+
/**/
(
1
/**/
+
/**/
1
)
)
)
(1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1) (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1)
(1 (
+ 1 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1 + 1
+ 1) + 1
+ 1
)
] ]

View file

@ -81,24 +81,28 @@
#7 #7
} }
(let (
# 1 let
#2 # 1
a = 1; # 3 #2
b = 1; a = 1; # 3
c = 1; # 4 b = 1;
#5 c = 1; # 4
#5
#6 #6
d = 1; d = 1;
#7 #7
in in
d) d
)
({ (
a, # comment {
b ? 2, # comment a, # comment
}: b ? 2, # comment
_) }:
_
)
] ]

View file

@ -1,190 +1,286 @@
[ [
(if true (
then { if true
version = "1.2.3"; then {
} version = "1.2.3";
else { }
version = "3.2.1"; else {
}) version = "3.2.1";
(if true }
then '' )
some text (
'' if true
else '' then ''
other text some text
'') ''
(if ./a else ''
then b other text
else c) ''
(if )
/**/ (
a if ./a
/**/
then
/**/
b
/**/
else
/**/
c)
(if # test
a # test
then # test
b # test
else # test
c)
(if # test
/**/
a # test
/**/
then # test
b # test
/**/
else # test
/**/
c)
(if
if a
then b then b
else c else c
then b )
else if a (
then b if
else if a /**/
then b a
else c) /**/
(if then
if a /**/
b
/**/
else
/**/
c
)
(
if # test
a # test
then # test
b # test
else # test
c
)
(
if # test
/**/
a # test
/**/
then # test
b # test
/**/
else # test
/**/
c
)
(
if
if a
then b
else c
then b
else if a
then b
else if a
then b then b
else c else c
then b )
else if a (
then b if
else if a
/* then b
x else c
*/ then b
if a else if a
then b then b
else c)
(if
(if
(if
(if a
then b
else c)
then
(if a
then b
else c)
else
(if a
then b
else c))
then
(if
(if a
then b
else c)
then
(if a
then b
else c)
else
(if a
then b
else c))
else else
(if /*
(if a x
then b */
else c) if a
then then b
(if a else c
then b )
else c) (
else if
(if a (
then b if
else c))) (
then if
(if (
(if if a
(if a then b
then b else c
else c) )
then then
(if a (
then b if a
else c) then b
else else c
(if a )
then b else
else c)) (
if a
then b
else c
)
)
then
(
if
(
if a
then b
else c
)
then
(
if a
then b
else c
)
else
(
if a
then b
else c
)
)
else
(
if
(
if a
then b
else c
)
then
(
if a
then b
else c
)
else
(
if a
then b
else c
)
)
)
then then
(if (
(if a if
then b (
else c) if
then (
(if a if a
then b then b
else c) else c
else )
(if a then
then b (
else c)) if a
then b
else c
)
else
(
if a
then b
else c
)
)
then
(
if
(
if a
then b
else c
)
then
(
if a
then b
else c
)
else
(
if a
then b
else c
)
)
else
(
if
(
if a
then b
else c
)
then
(
if a
then b
else c
)
else
(
if a
then b
else c
)
)
)
else else
(if (
(if a if
then b (
else c) if
then (
(if a if a
then b then b
else c) else c
else )
(if a then
then b (
else c))) if a
else then b
(if else c
(if )
(if a else
then b (
else c) if a
then then b
(if a else c
then b )
else c) )
else then
(if a (
then b if
else c)) (
then if a
(if then b
(if a else c
then b )
else c) then
then (
(if a if a
then b then b
else c) else c
else )
(if a else
then b (
else c)) if a
else then b
(if else c
(if a )
then b )
else c) else
then (
(if a if
then b (
else c) if a
else then b
(if a else c
then b )
else c)))) then
(
if a
then b
else c
)
else
(
if a
then b
else c
)
)
)
)
] ]

View file

@ -1,51 +1,61 @@
[ [
(a: b: (
/* a: b:
c /*
*/ c
d) */
({}: b: d
/* )
c (
*/ {}: b:
d) /*
(a: {}: c
/* */
c d
*/ )
d) (
a: {}:
/*
c
*/
d
)
(a: d) (a: d)
(a:
/*
c
*/
d)
(a
/*
b
*/
:
d)
(a
/*
b
*/
:
/*
c
*/
d)
( (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a:
/*
c
*/
d
) )
( (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a
/*
b
*/
:
d
)
(
a
/*
b
*/
:
/*
c
*/
d
)
(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)
(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)
(
{
pkgs ? import ./.. {},
locationsXml,
}:
null
) )
({
pkgs ? import ./.. {},
locationsXml,
}:
null)
(a: b: c: {}: a: b: c: (a: b: c: {}: a: b: c:
a) a)
@ -53,19 +63,23 @@
# Stuff # Stuff
}) })
({pkgs, ...}: let (
in {pkgs, ...}: let
pkgs) in
pkgs
)
(a: {b, ...}: c: { (a: {b, ...}: c: {
# Stuff # Stuff
}) })
(a: { (
b, a: {
c, b,
... c,
}: d: { ...
# Stuff }: d: {
}) # Stuff
}
)
] ]

View file

@ -1,48 +1,68 @@
[ [
(a.b or c) (a.b or c)
(a.b (
or a.b
/**/ or
c) /**/
(a.b c
/**/ )
or c) (
(a.b a.b
/**/ /**/
or or c
/**/ )
c) (
(a.b a.b
/**/ /**/
or or
/**/ /**/
(a.b c
/**/ )
or (
/**/ a.b
(a.b /**/
/**/ or
or /**/
/**/ (
c))) a.b
(a.b /**/
/**/ or
or /**/
/**/ (
(a.b a.b
/**/ /**/
or or
/**/ /**/
(a.b c
/**/ )
or )
/**/ )
c))) (
a.b
/**/
or
/**/
(
a.b
/**/
or
/**/
(
a.b
/**/
or
/**/
c
)
)
)
(a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a) (a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a)
(a.a (
or a.a # test a.a
or a.a # test or a.a # test
or # test or a.a # test
a.a or # test
or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a) a.a
or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a
)
] ]

View file

@ -1,33 +1,45 @@
[ [
({} @ a: _) ({} @ a: _)
({} @ (
/**/ {} @
a: /**/
_) a:
({} _
/**/ )
@ a: (
_) {}
({} /**/
/**/ @ a:
@ _
/**/ )
a: (
_) {}
/**/
@
/**/
a:
_
)
(a @ {}: _) (a @ {}: _)
(a @ (
/**/ a @
{}: /**/
_) {}:
(a _
/**/ )
@ {}: (
_) a
(a /**/
/**/ @ {}:
@ _
/**/ )
{}: (
_) a
/**/
@
/**/
{}:
_
)
] ]

File diff suppressed because it is too large Load diff

View file

@ -1,55 +1,63 @@
[ [
(a.a) (a.a)
(a (
. a
/**/ .
a) /**/
(a a
/**/ )
.a) (
(a a
/**/ /**/
. .a
/**/ )
a) (
a
/**/
.
/**/
a
)
(a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a) (a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a)
(a (
.a a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a .a
.a) .a
.a
)
] ]

View file

@ -1,24 +1,30 @@
[ [
(with b; c) (with b; c)
(with b; (
/* with b;
b /*
*/ b
c) */
(with c
/* )
a (
*/ with
b; c) /*
(with a
/* */
a b; c
*/ )
b; (
/* with
b /*
*/ a
c) */
b;
/*
b
*/
c
)
(with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) (with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc)
(with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) (with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc)
{a = with b; 1;} {a = with b; 1;}
@ -41,21 +47,25 @@
# comment # comment
} }
(with a; with b; with c; {a = 1;}) (with a; with b; with c; {a = 1;})
(with a; (
with b; with a;
with c; { with b;
a = 1; with c; {
b = 2; a = 1;
}) b = 2;
(with a; }
/* )
comment (
*/ with a;
with b; /*
with c; { comment
a = 1; */
b = 2; with b;
}) with c; {
a = 1;
b = 2;
}
)
{ {
a = with b; with b; with b; 1; a = with b; with b; with b; 1;
} }