Repository: domluna/JuliaFormatter.jl
Pull request #342 (2020-12-07 15:13:37)

Ensure keyword arguments are separated with ; when using YASStyle
Ticks off another box in #198 


Patch:
diff --git a/src/fst.jl b/src/fst.jl
index ab5ad80a..570a2c34 100644
--- a/src/fst.jl
+++ b/src/fst.jl
@@ -695,3 +695,67 @@ function is_standalone_shortcircuit(cst::CSTParser.EXPR)
 
     return parent_is(cst, valid, ignore = ignore)
 end
+
+"""
+    separate_kwargs_with_semicolon!(fst::FST)
+
+Ensures keyword arguments are separated with a ";".
+
+### Examples
+
+Replace "," with ";".
+
+```julia
+a = f(x, y = 3)
+
+->
+
+a = f(x; y = 3)
+```
+
+Move ";" to the prior to the first positional argument.
+
+```julia
+a = f(x = 1; y = 2)
+
+->
+
+a = f(; x = 1, y = 2)
+```
+"""
+function separate_kwargs_with_semicolon!(fst::FST)
+    kw_idx = findfirst(n -> n.typ === CSTParser.Kw, fst.nodes)
+    kw_idx === nothing && return
+    sc_idx = findfirst(n -> n.typ === SEMICOLON, fst.nodes)
+    # first "," prior to a kwarg
+    comma_idx = findlast(is_comma, fst.nodes[1:kw_idx-1])
+    ph_idx = findlast(n -> n.typ === PLACEHOLDER, fst.nodes[1:kw_idx-1])
+    # @info "" kw_idx sc_idx comma_idx ph_idx
+
+    if sc_idx !== nothing && sc_idx > kw_idx
+        # move ; prior to first kwarg
+        fst[sc_idx].val = ","
+        fst[sc_idx].typ = CSTParser.PUNCTUATION
+        if comma_idx === nothing
+            if ph_idx !== nothing
+                fst[ph_idx] = Placeholder(1)
+                insert!(fst, ph_idx, Semicolon())
+            else
+                insert!(fst, kw_idx, Placeholder(1))
+                insert!(fst, kw_idx, Semicolon())
+            end
+        end
+    elseif sc_idx === nothing && comma_idx === nothing
+        if ph_idx !== nothing
+            fst[ph_idx] = Placeholder(1)
+            insert!(fst, ph_idx, Semicolon())
+        else
+            insert!(fst, kw_idx, Placeholder(1))
+            insert!(fst, kw_idx, Semicolon())
+        end
+    elseif sc_idx === nothing
+        fst[comma_idx].val = ";"
+        fst[comma_idx].typ = SEMICOLON
+    end
+    return
+end
diff --git a/src/styles/blue/pretty.jl b/src/styles/blue/pretty.jl
index 51e4f020..a28dc1e4 100644
--- a/src/styles/blue/pretty.jl
+++ b/src/styles/blue/pretty.jl
@@ -66,39 +66,6 @@ function p_do(bs::BlueStyle, cst::CSTParser.EXPR, s::State)
     t
 end
 
-function separate_kwargs_with_semicolon!(fst::FST)
-    kw_idx = findfirst(n -> n.typ === CSTParser.Kw, fst.nodes)
-    kw_idx === nothing && return
-    sc_idx = findfirst(n -> n.typ === SEMICOLON, fst.nodes)
-    # first "," prior to a kwarg
-    comma_idx = findlast(is_comma, fst.nodes[1:kw_idx-1])
-
-    if sc_idx !== nothing && sc_idx > kw_idx
-        # move ; prior to first kwarg
-        fst[sc_idx].val = ","
-        fst[sc_idx].typ = CSTParser.PUNCTUATION
-        if comma_idx === nothing
-            if fst[kw_idx-1].typ === PLACEHOLDER
-                fst[kw_idx-1] = Placeholder(1)
-            else
-                insert!(fst, kw_idx - 1, Placeholder(1))
-            end
-        end
-        insert!(fst, kw_idx - 1, Semicolon())
-    elseif sc_idx === nothing && comma_idx === nothing
-        if fst[kw_idx-1].typ === PLACEHOLDER
-            fst[kw_idx-1] = Placeholder(1)
-        else
-            insert!(fst, kw_idx - 1, Placeholder(1))
-        end
-        insert!(fst, kw_idx - 1, Semicolon())
-    elseif sc_idx === nothing
-        fst[comma_idx].val = ";"
-        fst[comma_idx].typ = SEMICOLON
-    end
-    return
-end
-
 function p_call(bs::BlueStyle, cst::CSTParser.EXPR, s::State)
     style = getstyle(bs)
     t = p_call(DefaultStyle(style), cst, s)
diff --git a/src/styles/yas/pretty.jl b/src/styles/yas/pretty.jl
index 861232e8..deae8498 100644
--- a/src/styles/yas/pretty.jl
+++ b/src/styles/yas/pretty.jl
@@ -157,6 +157,9 @@ function p_call(ys::YASStyle, cst::CSTParser.EXPR, s::State)
             add_node!(t, n, s, join_lines = true)
         end
     end
+    if !parent_is(cst, is_function_or_macro_def)
+        separate_kwargs_with_semicolon!(t)
+    end
     t
 end
 @inline p_vect(ys::YASStyle, cst::CSTParser.EXPR, s::State) = p_call(ys, cst, s)


Test patch:
diff --git a/test/files/Onda.jl/docs/make.jl b/test/files/Onda.jl/docs/make.jl
index 353c6c9c..57f2acc8 100644
--- a/test/files/Onda.jl/docs/make.jl
+++ b/test/files/Onda.jl/docs/make.jl
@@ -1,8 +1,8 @@
 using Onda
 using Documenter
 
-makedocs(modules=[Onda], sitename="Onda", authors="Beacon Biosignals, Inc.",
+makedocs(; modules=[Onda], sitename="Onda", authors="Beacon Biosignals, Inc.",
          pages=["API Documentation" => "index.md"])
 
 # this is commented out until Onda has been open-sourced
-deploydocs(repo="github.com/beacon-biosignals/Onda.jl.git")
+deploydocs(; repo="github.com/beacon-biosignals/Onda.jl.git")
diff --git a/test/files/Onda.jl/examples/tour.jl b/test/files/Onda.jl/examples/tour.jl
index 327c8364..d106d2de 100644
--- a/test/files/Onda.jl/examples/tour.jl
+++ b/test/files/Onda.jl/examples/tour.jl
@@ -17,7 +17,8 @@ using Onda, Dates, Test
 # specification; this type corresponds directly to the signal object defined
 # by the specification.
 
-eeg_signal = Signal(channel_names=[:fp1, :f3, :c3, :p3, :f7, :t3, :t5, :o1, :fz, :cz, :pz,
+eeg_signal = Signal(;
+                    channel_names=[:fp1, :f3, :c3, :p3, :f7, :t3, :t5, :o1, :fz, :cz, :pz,
                                    :fp2, :f4, :c4, :p4, :f8, :t4, :t6, :o2],
                     start_nanosecond=Nanosecond(0), stop_nanosecond=Nanosecond(Second(20)),
                     sample_unit=:microvolts, sample_resolution_in_unit=0.25,
@@ -27,7 +28,7 @@ eeg_signal = Signal(channel_names=[:fp1, :f3, :c3, :p3, :f7, :t3, :t5, :o1, :fz,
 ecg_signal = signal_from_template(eeg_signal; channel_names=[:avl, :avr],
                                   file_extension=Symbol("lpcm.zst"))
 
-spo2_signal = Signal(channel_names=[:spo2], start_nanosecond=Nanosecond(Second(3)),
+spo2_signal = Signal(; channel_names=[:spo2], start_nanosecond=Nanosecond(Second(3)),
                      stop_nanosecond=Nanosecond(Second(17)), sample_unit=:percentage,
                      sample_resolution_in_unit=(100 / typemax(UInt8)),
                      sample_offset_in_unit=0.0, sample_type=UInt8, sample_rate=20.5, # Hz
diff --git a/test/files/Onda.jl/src/samples.jl b/test/files/Onda.jl/src/samples.jl
index ccb21a5c..ca6c1f0d 100644
--- a/test/files/Onda.jl/src/samples.jl
+++ b/test/files/Onda.jl/src/samples.jl
@@ -214,7 +214,7 @@ but write encoded values to `result_storage` rather than allocating new storage.
 function encode!(result_storage, sample_resolution_in_unit, sample_offset_in_unit, samples,
                  dither_storage=nothing)
     return encode!(result_storage, eltype(result_storage), sample_resolution_in_unit,
-                   sample_offset_in_unit, samples, dither_storage=nothing)
+                   sample_offset_in_unit, samples; dither_storage=nothing)
 end
 
 function encode!(result_storage, ::Type{S}, sample_resolution_in_unit,
diff --git a/test/files/Onda.jl/test/dataset.jl b/test/files/Onda.jl/test/dataset.jl
index 08a8fdb6..1ee23bfc 100644
--- a/test/files/Onda.jl/test/dataset.jl
+++ b/test/files/Onda.jl/test/dataset.jl
@@ -44,20 +44,20 @@ using Test, Onda, Dates, MsgPack
             if sizeof(s.signal.sample_type) >= 8
                 # decoding from 64-bit to floating point is fairly lossy
                 tmp = similar(s.data)
-                @test isapprox(encode(d, nothing).data, s.data, rtol=10)
+                @test isapprox(encode(d, nothing).data, s.data; rtol=10)
                 encode!(tmp, d, nothing)
-                @test isapprox(tmp, s.data, rtol=10)
-                @test isapprox(encode(d, missing).data, s.data, rtol=10)
+                @test isapprox(tmp, s.data; rtol=10)
+                @test isapprox(encode(d, missing).data, s.data; rtol=10)
                 encode!(tmp, d, missing)
-                @test isapprox(tmp, s.data, rtol=10)
+                @test isapprox(tmp, s.data; rtol=10)
             else
                 tmp = similar(s.data)
                 encode!(tmp, d, nothing)
                 @test tmp == s.data
                 @test encode(d, nothing).data == s.data
                 encode!(tmp, d, missing)
-                @test isapprox(tmp, s.data, rtol=1)
-                @test isapprox(encode(d, missing).data, s.data, rtol=1)
+                @test isapprox(tmp, s.data; rtol=1)
+                @test isapprox(encode(d, missing).data, s.data; rtol=1)
             end
             chs = s.signal.channel_names
             i = 93
@@ -125,7 +125,7 @@ using Test, Onda, Dates, MsgPack
         foreach(x -> annotate!(recording, x), old_recording.annotations)
         foreach(x -> store!(dataset, uuid, x, load(old_dataset, old_uuid, x)),
                 keys(old_recording.signals))
-        merge!(dataset, old_dataset, only_recordings=true)
+        merge!(dataset, old_dataset; only_recordings=true)
         @test length(dataset.recordings) == 2
         r1 = dataset.recordings[old_uuid]
         @test r1 == old_recording
diff --git a/test/files/Onda.jl/test/printing.jl b/test/files/Onda.jl/test/printing.jl
index 7d7286f0..55e3bf7e 100644
--- a/test/files/Onda.jl/test/printing.jl
+++ b/test/files/Onda.jl/test/printing.jl
@@ -6,7 +6,7 @@ using Test, Onda, Dates, Random, UUIDs
 
     signal = Signal([:a, :b, Symbol("c-d")], Nanosecond(3), Nanosecond(Second(12345)),
                     :unit, 0.25, -0.5, Int16, 50.2, Symbol("lpcm.zst"), nothing)
-    @test sprint(show, signal, context=(:compact => true)) ==
+    @test sprint(show, signal; context=(:compact => true)) ==
           "Signal([:a, :b, Symbol(\"c-d\")])"
     @test sprint(show, signal) == """
                                   Signal:
@@ -23,7 +23,7 @@ using Test, Onda, Dates, Random, UUIDs
 
     samples = Samples(signal, true,
                       rand(Random.MersenneTwister(0), signal.sample_type, 3, 5))
-    @test sprint(show, samples, context=(:compact => true)) == "Samples(3×5 Array{Int16,2})"
+    @test sprint(show, samples; context=(:compact => true)) == "Samples(3×5 Array{Int16,2})"
     @test sprint(show, samples) == """
                                    Samples (00:00:00.099601594):
                                      signal.channel_names: [:a, :b, Symbol(\"c-d\")]
diff --git a/test/files/blowup/axis.jl b/test/files/blowup/axis.jl
index 83e26bff..90f9650f 100644
--- a/test/files/blowup/axis.jl
+++ b/test/files/blowup/axis.jl
@@ -29,22 +29,22 @@ Plots a 2-dimensional axis.
 $(ATTRIBUTES)
 """
 @recipe(Axis2D) do scene
-    return Attributes(visible=true, showgrid=true, showticks=true, showtickmarks=true, padding=0.0,
-                      ticks=Attributes(ranges_labels=(automatic, automatic), formatter=Formatters.plain,
+    return Attributes(; visible=true, showgrid=true, showticks=true, showtickmarks=true, padding=0.0,
+                      ticks=Attributes(; ranges_labels=(automatic, automatic), formatter=Formatters.plain,
                                        gap=1, title_gap=3, linewidth=(1, 1),
                                        linecolor=((:black, 0.4), (:black, 0.4)), linestyle=(nothing, nothing),
                                        textcolor=(:black, :black), textsize=(5, 5), rotation=(0.0, 0.0),
                                        align=((:center, :top), (:right, :center)),
                                        font=lift(dim2, theme(scene, :font))),
-                      tickmarks=Attributes(length=(1.0, 1.0), linewidth=(1, 1),
+                      tickmarks=Attributes(; length=(1.0, 1.0), linewidth=(1, 1),
                                            linecolor=((:black, 0.4), (:black, 0.2)),
                                            linestyle=(nothing, nothing)),
-                      grid=Attributes(linewidth=(0.5, 0.5), linecolor=((:black, 0.3), (:black, 0.3)),
+                      grid=Attributes(; linewidth=(0.5, 0.5), linecolor=((:black, 0.3), (:black, 0.3)),
                                       linestyle=(nothing, nothing)),
-                      frame=Attributes(linewidth=1.0, linecolor=:black, linestyle=nothing,
+                      frame=Attributes(; linewidth=1.0, linecolor=:black, linestyle=nothing,
                                        axis_position=nothing, axis_arrow=false, arrow_size=2.5,
                                        frames=((false, false), (false, false))),
-                      names=Attributes(axisnames=("x", "y"), title=nothing, textcolor=(:black, :black),
+                      names=Attributes(; axisnames=("x", "y"), title=nothing, textcolor=(:black, :black),
                                        textsize=(6, 6), rotation=(0.0, -1.5pi),
                                        align=((:center, :top), (:center, :bottom)),
                                        font=lift(dim2, theme(scene, :font))))
@@ -72,16 +72,16 @@ $(ATTRIBUTES)
     grid_thickness = 1
     gridthickness = ntuple(x -> 1.0f0, Val(3))
     tsize = 5 # in percent
-    return Attributes(visible=true, showticks=(true, true, true), showaxis=(true, true, true),
+    return Attributes(; visible=true, showticks=(true, true, true), showaxis=(true, true, true),
                       showgrid=(true, true, true), scale=Vec3f0(1), padding=0.1,
-                      names=Attributes(axisnames=("x", "y", "z"), textcolor=(:black, :black, :black),
+                      names=Attributes(; axisnames=("x", "y", "z"), textcolor=(:black, :black, :black),
                                        rotation=axisnames_rotation3d, textsize=(6.0, 6.0, 6.0),
                                        align=axisnames_align3d, font=lift(dim3, theme(scene, :font)), gap=3),
-                      ticks=Attributes(ranges_labels=(automatic, automatic), formatter=Formatters.plain,
+                      ticks=Attributes(; ranges_labels=(automatic, automatic), formatter=Formatters.plain,
                                        textcolor=(tick_color, tick_color, tick_color),
                                        rotation=tickrotations3d, textsize=(tsize, tsize, tsize),
                                        align=tickalign3d, gap=3, font=lift(dim3, theme(scene, :font))),
-                      frame=Attributes(linecolor=(grid_color, grid_color, grid_color),
+                      frame=Attributes(; linecolor=(grid_color, grid_color, grid_color),
                                        linewidth=(grid_thickness, grid_thickness, grid_thickness),
                                        axiscolor=(:black, :black, :black)))
 end
@@ -194,7 +194,7 @@ function draw_ticks(textbuffer, dim, origin, ticks, linewidth, linecolor, linest
                     rotation, align, font)
     for (tick, str) in ticks
         pos = ntuple(i -> i != dim ? origin[i] : tick, Val(2))
-        push!(textbuffer, str, Point(pos), rotation=rotation[dim], textsize=textsize[dim], align=align[dim],
+        push!(textbuffer, str, Point(pos); rotation=rotation[dim], textsize=textsize[dim], align=align[dim],
               color=textcolor[dim], font=font[dim])
     end
 end
@@ -205,7 +205,7 @@ function draw_tickmarks(linebuffer, dim, origin, ticks, dir::NTuple{N}, linewidt
         pos = ntuple(i -> i != dim ? origin[i] : tick, Val(2))
         posf0 = Point2f0(pos)
         dirf0 = Pointf0{N}(dir)
-        append!(linebuffer, [posf0, posf0 .+ dirf0], color=linecolor[dim], linewidth=linewidth[dim])
+        append!(linebuffer, [posf0, posf0 .+ dirf0]; color=linecolor[dim], linewidth=linewidth[dim])
     end
 end
 
@@ -214,7 +214,7 @@ function draw_grid(linebuffer, dim, origin, ticks, dir::NTuple{N}, linewidth, li
     for (tick, str) in ticks
         tup = ntuple(i -> i != dim ? origin[i] : tick, Val(N))
         posf0 = Pointf0{N}(tup)
-        append!(linebuffer, [posf0, posf0 .+ dirf0], color=linecolor[dim], linewidth=linewidth[dim])
+        append!(linebuffer, [posf0, posf0 .+ dirf0]; color=linecolor[dim], linewidth=linewidth[dim])
     end
 end
 
@@ -229,10 +229,10 @@ function draw_frame(linebuffer, limits::NTuple{N,Any}, linewidth, linecolor, lin
             start = unit(Point{N,Float32}, i) * Float32(mini[i])
             to = unit(Point{N,Float32}, i) * Float32(maxi[i])
             if false #axis_arrow
-                arrows(scene, [start, to], linewidth=linewidth, linecolor=linecolor, linestyle=linestyle,
+                arrows(scene, [start, to]; linewidth=linewidth, linecolor=linecolor, linestyle=linestyle,
                        arrowsize=arrow_size)
             else
-                append!(linebuffer, [start, to], linewidth=linewidth, color=linecolor)
+                append!(linebuffer, [start, to]; linewidth=linewidth, color=linecolor)
             end
         end
     end
@@ -248,7 +248,7 @@ function draw_frame(linebuffer, limits::NTuple{N,Any}, linewidth, linecolor, lin
                     if frames[N - dim + 1][3 - otherside]
                         p = ntuple(i -> i == dim ? limits[i][otherside] : limits[i][side], Val(N))
                         to = Point{N,Float32}(p)
-                        append!(linebuffer, [from, to], linewidth=linewidth, color=linecolor)
+                        append!(linebuffer, [from, to]; linewidth=linewidth, color=linecolor)
                     end
                 end
             end
@@ -277,13 +277,13 @@ function draw_titles(textbuffer, xticks, yticks, origin, limit_widths, tickfont,
     positions = (posx, posy)
     for i in 1:2
         if !isempty(axis_labels[i])
-            push!(textbuffer, axis_labels[i], positions[i], textsize=textsize[i], align=align[i],
+            push!(textbuffer, axis_labels[i], positions[i]; textsize=textsize[i], align=align[i],
                   rotation=rotation[i], color=textcolor[i], font=font[i])
         end
     end
     if title !== nothing
         # TODO give title own text attributes
-        push!(textbuffer, title, (half_width[1], (origin .+ (limit_widths))[2]), textsize=textsize[1],
+        push!(textbuffer, title, (half_width[1], (origin .+ (limit_widths))[2]); textsize=textsize[1],
               align=(:center, :top), rotation=rotation[1], color=textcolor[1], font=font[1])
     end
 end
@@ -401,7 +401,7 @@ function plot!(scene::SceneLike, ::Type{<:Axis2D}, attributes::Attributes, args.
 
     textbuffer = TextBuffer(cplot, Point{2})
 
-    grid_linebuffer = Node((LinesegmentBuffer(cplot, Point{2}, transparency=true,
+    grid_linebuffer = Node((LinesegmentBuffer(cplot, Point{2}; transparency=true,
                                               linestyle=lift(first, cplot[:grid, :linestyle])),
                             LinesegmentBuffer(cplot, Point{2}; transparency=true,
                                               linestyle=lift(last, cplot[:grid, :linestyle]))))
@@ -460,7 +460,7 @@ function draw_axis3d(textbuffer, linebuffer, limits, ranges_labels, args...)
         width = Float32(limit_widths[i])
         stop = origin .+ (width .* axis_vec)
         if showaxis[i]
-            append!(linebuffer, [origin, stop], color=axiscolors[i], linewidth=1.5f0)
+            append!(linebuffer, [origin, stop]; color=axiscolors[i], linewidth=1.5f0)
         end
         if showticks[i]
             range = ranges[i]
@@ -479,7 +479,7 @@ function draw_axis3d(textbuffer, linebuffer, limits, ranges_labels, args...)
                     str = labels[j]
                     if !isempty(str)
                         startpos = (origin .+ ((Float32(tick - origin[i]) * axis_vec)) .+ offset2)
-                        push!(textbuffer, str, startpos, color=ttextcolor[i], rotation=trotation[i],
+                        push!(textbuffer, str, startpos; color=ttextcolor[i], rotation=trotation[i],
                               textsize=ttextsize[i], align=talign[i], font=tfont[i])
                     end
                 end
@@ -491,7 +491,7 @@ function draw_axis3d(textbuffer, linebuffer, limits, ranges_labels, args...)
                     0.0f0
                 end
                 pos = (labelposition(ranges, i, tickdir, titlegap[i] + tick_widths, origin) .+ offset2)
-                push!(textbuffer, to_latex(axisnames[i]), pos, textsize=axisnames_size[i],
+                push!(textbuffer, to_latex(axisnames[i]), pos; textsize=axisnames_size[i],
                       color=axisnames_color[i], rotation=axisrotation[i], align=axisalign[i],
                       font=axisnames_font[i])
             end
@@ -505,7 +505,7 @@ function draw_axis3d(textbuffer, linebuffer, limits, ranges_labels, args...)
                 range = ranges[j]
                 for tick in range
                     offset = Float32(tick - origin[j]) * dir
-                    append!(linebuffer, [origin .+ offset, stop .+ offset], color=c, linewidth=thickness)
+                    append!(linebuffer, [origin .+ offset, stop .+ offset]; color=c, linewidth=thickness)
                 end
             end
         end
@@ -519,8 +519,8 @@ function plot!(scene::SceneLike, ::Type{<:Axis3D}, attributes::Attributes, args.
     axis = Axis3D(scene, attributes, args)
     # Disable any non linear transform for the axis plot!
     axis.transformation.transform_func[] = identity
-    textbuffer = TextBuffer(axis, Point{3}, transparency=true)
-    linebuffer = LinesegmentBuffer(axis, Point{3}, transparency=true)
+    textbuffer = TextBuffer(axis, Point{3}; transparency=true)
+    linebuffer = LinesegmentBuffer(axis, Point{3}; transparency=true)
 
     tstyle, ticks, frame = to_value.(getindex.(axis, (:names, :ticks, :frame)))
     titlevals = getindex.(tstyle, (:axisnames, :textcolor, :textsize, :rotation, :align, :font, :gap))
diff --git a/test/files/blowup/interfaces.jl b/test/files/blowup/interfaces.jl
index 46dc2ab7..0066f5b7 100644
--- a/test/files/blowup/interfaces.jl
+++ b/test/files/blowup/interfaces.jl
@@ -7,7 +7,7 @@ Attributes(x::AbstractPlot) = x.attributes
 default_theme(scene, T) = Attributes()
 
 function default_theme(scene)
-    return Attributes(color=theme(scene, :color), linewidth=1, transformation=automatic, model=automatic,
+    return Attributes(; color=theme(scene, :color), linewidth=1, transformation=automatic, model=automatic,
                       visible=true, transparency=false, overdraw=false, ambient=Vec3f0(0.55),
                       diffuse=Vec3f0(0.4), specular=Vec3f0(0.2), shininess=32.0f0, lightposition=:eyeposition,
                       nan_color=RGBAf0(0, 0, 0, 0), ssao=false)
@@ -693,7 +693,7 @@ function add_axis!(scene::Scene, attributes=Attributes())
             sl === automatic && return dl
             return sl
         end
-        axistype(scene, axis_attributes, lims, ticks=(ranges=ranges, labels=labels))
+        axistype(scene, axis_attributes, lims; ticks=(ranges=ranges, labels=labels))
     end
     return scene
 end
diff --git a/test/runtests.jl b/test/runtests.jl
index 343769e4..4789ccb3 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -39,9 +39,11 @@ function fmt(str, i, m; kwargs...)
     return fmt(str; kwargs..., i = i, m = m)
 end
 
-yasfmt(str, i, m; kwargs...) = fmt(str, i, m; style = YASStyle(), kwargs...)
-bluefmt(str, i = 4, m = 80; kwargs...) = fmt(str, i, m; style = BlueStyle(), kwargs...)
+yasfmt1(str) = fmt1(str; style = YASStyle(), options(DefaultStyle())...)
+yasfmt(str, i = 4, m = 80; kwargs...) = fmt(str, i, m; style = YASStyle(), kwargs...)
+
 bluefmt1(str) = fmt1(str; style = BlueStyle(), options(DefaultStyle())...)
+bluefmt(str, i = 4, m = 80; kwargs...) = fmt(str, i, m; style = BlueStyle(), kwargs...)
 
 @testset "JuliaFormatter" begin
     include("default_style.jl")
diff --git a/test/yas_style.jl b/test/yas_style.jl
index 990a811f..06012708 100644
--- a/test/yas_style.jl
+++ b/test/yas_style.jl
@@ -448,4 +448,43 @@
                                                   k_max=8)"""
         @test yasfmt(str, 4, 92, whitespace_in_kwargs = false) == str
     end
+
+    @testset "separate kw args with semicolon" begin
+        str_ = "xy = f(x, y=3)"
+        str = "xy = f(x; y = 3)"
+        @test yasfmt(str_) == str
+
+        str_ = "xy = f(x=1, y=2)"
+        str = "xy = f(; x = 1, y = 2)"
+        @test yasfmt1(str_) == str
+        @test yasfmt(str_) == str
+        @test yasfmt(str) == str
+
+        str_ = "xy = f(x = 1; y = 2)"
+        @test yasfmt1(str_) == str
+        @test yasfmt(str_) == str
+
+        str_ = """
+        x = foo(var = "some really really really really really really really really really really long string")
+        """
+        str = """
+        x = foo(;
+                var = "some really really really really really really really really really really long string")
+        """
+        @test yasfmt1(str_) == str
+        @test yasfmt(str_) == str
+
+        str = """
+        function g(x, y = 1)
+            return x + y
+        end
+        macro h(x, y = 1)
+            nothing
+        end
+        shortdef1(MatrixT, VectorT = nothing) = nothing
+        shortdef2(MatrixT, VectorT = nothing) where {T} = nothing
+        """
+        @test yasfmt1(str) == str
+        @test yasfmt(str) == str
+    end
 end