JuliaFormatter.jl icon indicating copy to clipboard operation
JuliaFormatter.jl copied to clipboard

Last "format: off" comment has no effect if there are more than one

Open flwyd opened this issue 1 year ago • 0 comments

Consider the following self-formatting program:

#!/usr/bin/env julia

using JuliaFormatter

tautologies = []
if 0 == 0
push!(tautologies, 0)
if 1 == 1
#! format: off
push!(tautologies, 1)
if 2 == 2
push!(tautologies, 2)
#! format: on
if 3 == 3
push!(tautologies, 3)
if 4 == 4
push!(tautologies, 4)
if 5 == 5
push!(tautologies, 5)
end
end
end
end
end
end

if true
input = join(readlines(PROGRAM_FILE, keep=true))
output = JuliaFormatter.format_text(input, DefaultStyle())
print(output)
end

It does what you would expect, preventing the push!(tautologies, 1), if 2 == 2, and push!(tautologies, 2) lines from being indented, but indenting the rest of the file:

#!/usr/bin/env julia

using JuliaFormatter

tautologies = []
if 0 == 0
    push!(tautologies, 0)
    if 1 == 1
#! format: off
push!(tautologies, 1)
if 2 == 2
push!(tautologies, 2)
#! format: on
            if 3 == 3
                push!(tautologies, 3)
                if 4 == 4
                    push!(tautologies, 4)
                    if 5 == 5
                        push!(tautologies, 5)
                    end
                end
            end
        end
    end
end

if true
    input = join(readlines(PROGRAM_FILE, keep = true))
    output = JuliaFormatter.format_text(input, DefaultStyle())
    print(output)
end

Now, add another #! format: off comment after if 4 == 4:

#!/usr/bin/env julia

using JuliaFormatter

tautologies = []
if 0 == 0
push!(tautologies, 0)
if 1 == 1
#! format: off
push!(tautologies, 1)
if 2 == 2
push!(tautologies, 2)
#! format: on
if 3 == 3
push!(tautologies, 3)
if 4 == 4
#! format: off
push!(tautologies, 4)
if 5 == 5
push!(tautologies, 5)
end
end
end
end
end
end

if true
input = join(readlines(PROGRAM_FILE, keep=true))
output = JuliaFormatter.format_text(input, DefaultStyle())
print(output)
end

This doesn't do what you would expect; the second off has no effect:

#!/usr/bin/env julia

using JuliaFormatter

tautologies = []
if 0 == 0
    push!(tautologies, 0)
    if 1 == 1
#! format: off
push!(tautologies, 1)
if 2 == 2
push!(tautologies, 2)
#! format: on
            if 3 == 3
                push!(tautologies, 3)
                if 4 == 4
                    #! format: off
                    push!(tautologies, 4)
                    if 5 == 5
                        push!(tautologies, 5)
                    end
                end
            end
        end
    end
end

if true
    input = join(readlines(PROGRAM_FILE, keep = true))
    output = JuliaFormatter.format_text(input, DefaultStyle())
    print(output)
end

But if you add another #! format on directive, the one in the middle of the tautologies block now works:

#!/usr/bin/env julia

using JuliaFormatter

tautologies = []
if 0 == 0
push!(tautologies, 0)
if 1 == 1
#! format: off
push!(tautologies, 1)
if 2 == 2
push!(tautologies, 2)
#! format: on
if 3 == 3
push!(tautologies, 3)
if 4 == 4
#! format: off
push!(tautologies, 4)
if 5 == 5
push!(tautologies, 5)
end
end
end
end
end
end

#! format: on
if true
input = join(readlines(PROGRAM_FILE, keep=true))
output = JuliaFormatter.format_text(input, DefaultStyle())
print(output)
end

now becomes

#!/usr/bin/env julia

using JuliaFormatter

tautologies = []
if 0 == 0
    push!(tautologies, 0)
    if 1 == 1
#! format: off
push!(tautologies, 1)
if 2 == 2
push!(tautologies, 2)
#! format: on
            if 3 == 3
                push!(tautologies, 3)
                if 4 == 4
#! format: off
push!(tautologies, 4)
if 5 == 5
push!(tautologies, 5)
end
end
end
end
end
end

#! format: on
if true
    input = join(readlines(PROGRAM_FILE, keep = true))
    output = JuliaFormatter.format_text(input, DefaultStyle())
    print(output)
end

Adding a #! format: off right after the final #! format: on comment has no effect, the if true block still gets indented. Additionally, replacing that final #! format: on comment with a #! format: off causes the one in the middle to stop working.

Perhaps there's an assumption that every off-toggle is paired with an on-toggle, but that assumption only takes effect if there's more than one off? If there's just one #! format: off comment and no subesequent #! format: on then the formatter correctly disables formatting until the end of the text.

flwyd avatar Nov 08 '23 07:11 flwyd