Repository: domluna/JuliaFormatter.jl (julia)

Issue:
Vcat for YASStyle
```
julia> format_text(s, YASStyle()) |> print
mpoly_rules = [
    @rule(~x::ismpoly - ~y::ismpoly => ~x + -1 * (~y))
    @rule(-(~x) => -1 * ~x)
    @acrule(~x::ismpoly + ~y::ismpoly => ~x + ~y)
    @rule(+(~x) => ~x)
    @acrule(~x::ismpoly * ~y::ismpoly => ~x * ~y)
    @rule(*(~x) => ~x)
    @rule((~x::ismpoly)^(~a::isnonnegint) => (~x)^(~a))
]
```

should be aligned to the `[`

Pull request description:
fixes #355 

This used to fallback to DefaultStyle. Now it aligns the argument to one
whitespace after the `[` and args are only joined to the same line only if
that was the case in the original source. If the arguments on the same
line exceed the maximum margin the arguments are split unto different
lines.

Patch:
diff --git a/Project.toml b/Project.toml
index 795484d29..cdb9cb3ed 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
 name = "JuliaFormatter"
 uuid = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
 authors = ["Dominique Luna <dluna132@gmail.com>"]
-version = "0.12.3"
+version = "0.13.0"
 
 [deps]
 CSTParser = "00ebfdb7-1f24-5e51-bd34-a7502290713f"
diff --git a/src/styles/yas/nest.jl b/src/styles/yas/nest.jl
index 0968fd7f5..09afd1847 100644
--- a/src/styles/yas/nest.jl
+++ b/src/styles/yas/nest.jl
@@ -2,11 +2,13 @@ function n_call!(ys::YASStyle, fst::FST, s::State)
     style = getstyle(ys)
     fst.indent = s.line_offset + sum(length.(fst[1:2]))
 
+    f = n -> n.typ === PLACEHOLDER || n.typ === NEWLINE
+
     for (i, n) in enumerate(fst.nodes)
         if n.typ === NEWLINE
             s.line_offset = fst.indent
         elseif n.typ === PLACEHOLDER
-            si = findnext(n -> n.typ === PLACEHOLDER, fst.nodes, i + 1)
+            si = findnext(f, fst.nodes, i + 1)
             nest_if_over_margin!(style, fst, s, i; stop_idx = si)
         elseif n.typ === TRAILINGSEMICOLON
             n.val = ""
@@ -28,17 +30,20 @@ end
 @inline n_ref!(ys::YASStyle, fst::FST, s::State) = n_call!(ys, fst, s)
 @inline n_macrocall!(ys::YASStyle, fst::FST, s::State) = n_call!(ys, fst, s)
 @inline n_typedcomprehension!(ys::YASStyle, fst::FST, s::State) = n_call!(ys, fst, s)
+@inline n_typedvcat!(ys::YASStyle, fst::FST, s::State) = n_call!(ys, fst, s)
 
 function n_tupleh!(ys::YASStyle, fst::FST, s::State)
     style = getstyle(ys)
     fst.indent = s.line_offset
     length(fst.nodes) > 0 && is_opener(fst[1]) && (fst.indent += 1)
 
+    f = n -> n.typ === PLACEHOLDER || n.typ === NEWLINE
+
     for (i, n) in enumerate(fst.nodes)
         if n.typ === NEWLINE
             s.line_offset = fst.indent
         elseif n.typ === PLACEHOLDER
-            si = findnext(n -> n.typ === PLACEHOLDER, fst.nodes, i + 1)
+            si = findnext(f, fst.nodes, i + 1)
             nest_if_over_margin!(style, fst, s, i; stop_idx = si)
         elseif n.typ === TRAILINGSEMICOLON
             n.val = ""
@@ -61,6 +66,7 @@ end
 @inline n_parameters!(ys::YASStyle, fst::FST, s::State) = n_tupleh!(ys, fst, s)
 @inline n_invisbrackets!(ys::YASStyle, fst::FST, s::State) = n_tupleh!(ys, fst, s)
 @inline n_comprehension!(ys::YASStyle, fst::FST, s::State) = n_tupleh!(ys, fst, s)
+@inline n_vcat!(ys::YASStyle, fst::FST, s::State) = n_tupleh!(ys, fst, s)
 
 function n_generator!(ys::YASStyle, fst::FST, s::State)
     style = getstyle(ys)
diff --git a/src/styles/yas/pretty.jl b/src/styles/yas/pretty.jl
index deae8498b..d83a6dbf9 100644
--- a/src/styles/yas/pretty.jl
+++ b/src/styles/yas/pretty.jl
@@ -164,6 +164,32 @@ function p_call(ys::YASStyle, cst::CSTParser.EXPR, s::State)
 end
 @inline p_vect(ys::YASStyle, cst::CSTParser.EXPR, s::State) = p_call(ys, cst, s)
 
+function p_vcat(ys::YASStyle, cst::CSTParser.EXPR, s::State)
+    style = getstyle(ys)
+    t = FST(cst, nspaces(s))
+    st = cst.typ === CSTParser.Vcat ? 1 : 2
+
+    for (i, a) in enumerate(cst)
+        n = pretty(style, a, s)
+        if !is_closer(a) && i > st
+            join_lines = i == st + 1 ? true : t.endline == n.startline
+            if join_lines && i != st + 1
+                add_node!(t, Placeholder(1), s)
+            end
+
+            add_node!(t, n, s; join_lines = join_lines)
+            if i != length(cst) - 1
+                has_semicolon(s.doc, n.startline) &&
+                    add_node!(t, InverseTrailingSemicolon(), s)
+            end
+        else
+            add_node!(t, n, s, join_lines = true)
+        end
+    end
+    t
+end
+@inline p_typedvcat(ys::YASStyle, cst::CSTParser.EXPR, s::State) = p_vcat(ys, cst, s)
+
 function p_ref(ys::YASStyle, cst::CSTParser.EXPR, s::State)
     style = getstyle(ys)
     t = FST(cst, nspaces(s))


Test patch:
diff --git a/test/yas_style.jl b/test/yas_style.jl
index 060127083..c08e59324 100644
--- a/test/yas_style.jl
+++ b/test/yas_style.jl
@@ -487,4 +487,80 @@
         @test yasfmt1(str) == str
         @test yasfmt(str) == str
     end
+
+    @testset "issue 355 - vcat/typedvcat" begin
+        str = """
+        mpoly_rules = T[@rule(~x::ismpoly - ~y::ismpoly => ~x + -1 * (~y))
+                        @rule(-(~x) => -1 * ~x)
+                        @acrule(~x::ismpoly + ~y::ismpoly => ~x + ~y)
+                        @rule(+(~x) => ~x)
+                        @acrule(~x::ismpoly * ~y::ismpoly => ~x * ~y)
+                        @rule(*(~x) => ~x)
+                        @rule((~x::ismpoly)^(~a::isnonnegint) => (~x)^(~a))]"""
+        @test yasfmt(str) == str
+
+        str = """
+        mpoly_rules = [@rule(~x::ismpoly - ~y::ismpoly => ~x + -1 * (~y))
+                       @rule(-(~x) => -1 * ~x)
+                       @acrule(~x::ismpoly + ~y::ismpoly => ~x + ~y)
+                       @rule(+(~x) => ~x)
+                       @acrule(~x::ismpoly * ~y::ismpoly => ~x * ~y)
+                       @rule(*(~x) => ~x)
+                       @rule((~x::ismpoly)^(~a::isnonnegint) => (~x)^(~a))]"""
+        @test yasfmt(str) == str
+
+        str_ = """
+        [10 20; 30 40; 50 60;
+         10
+         10]"""
+        @test yasfmt(str_, 4, 21) == str_
+
+        str = """
+        [10 20; 30 40;
+         50 60;
+         10
+         10]"""
+        @test yasfmt(str_, 4, 20) == str
+        @test yasfmt(str_, 4, 14) == str
+
+        str = """
+        [10 20;
+         30 40;
+         50 60;
+         10
+         10]"""
+        @test yasfmt(str_, 4, 13) == str
+
+        str_ = """
+        T[10 20; 30 40; 50 60;
+          10
+          10]"""
+        @test yasfmt(str_, 4, 22) == str_
+
+        str = """
+        T[10 20; 30 40;
+          50 60;
+          10
+          10]"""
+        @test yasfmt(str_, 4, 21) == str
+        @test yasfmt(str_, 4, 15) == str
+
+        str = """
+        T[10 20;
+          30 40;
+          50 60;
+          10
+          10]"""
+        @test yasfmt(str_, 4, 14) == str
+
+        # trailing ; is removed
+        str_ = "(T[10 20; 30 40; 50 60;])"
+        str = "(T[10 20; 30 40; 50 60])"
+        @test yasfmt(str_, 4, 24) == str
+
+        str = """
+        (T[10 20; 30 40;
+           50 60])"""
+        @test yasfmt(str_, 4, 23) == str
+    end
 end