KristofferC / Crayons.jl

Colored and styled strings for terminals.
Other
150 stars 14 forks source link

Add option to convert Crayon to string without checking if colors are available #62

Open ronisbr opened 2 years ago

ronisbr commented 2 years ago

Hi!

Using Julia-1.8, I am getting some inference problems when calling this function:

        write(buf_line, string(crayon))

The relevant information obtained from SnoopCompile is:

││││││││││┌ @ /Users/ronan.arraes/.julia/dev/PrettyTables/src/backends/text/display.jl:326 PrettyTables.string(crayon)
│││││││││││┌ @ strings/io.jl:185 Base.print_to_string(xs...)
││││││││││││┌ @ strings/io.jl:144 Base.print(s, x)
│││││││││││││┌ @ /Users/ronan.arraes/.julia/packages/Crayons/u3AH8/src/crayon.jl:110 Crayons._have_color()
││││││││││││││┌ @ /Users/ronan.arraes/.julia/packages/Crayons/u3AH8/src/crayon.jl:104 Base.get_have_color()
│││││││││││││││┌ @ ttyhascolor.jl:21 Base.ttyhascolor()
││││││││││││││││┌ @ ttyhascolor.jl:7 #self#(Base.get(Base.ENV, "TERM", ""))
│││││││││││││││││┌ @ ttyhascolor.jl:12 Base.success(Base.cmd_gen(Core.tuple(Core.tuple("tput"), Core.tuple("setaf"), Core.tuple("0"))))
││││││││││││││││││┌ @ process.jl:522 Base.success(Base._spawn(cmd))
│││││││││││││││││││┌ @ process.jl:510 Base.test_success(x)
││││││││││││││││││││┌ @ process.jl:503 Base.repr(Base.getproperty(proc, :cmd))
│││││││││││││││││││││┌ @ strings/io.jl:282 Base.#repr#453(Base.nothing, #self#, x)
││││││││││││││││││││││┌ @ strings/io.jl:282 Core.kwfunc(Base.sprint)(Core.apply_type(Core.NamedTuple, (:context,))(Core.tuple(context)), Base.sprint, Base.show, x)
│││││││││││││││││││││││┌ @ strings/io.jl:108 Base.#sprint#450(Core.tuple(context, sizehint, _3, f), args...)
││││││││││││││││││││││││┌ @ strings/io.jl:114 f(Core.tuple(s), args...)
│││││││││││││││││││││││││┌ @ cmd.jl:133 Base.collect(Base.Int, Base.getproperty(cmd, :cpus))
││││││││││││││││││││││││││┌ @ array.jl:647 Base._collect(_, itr, Base.IteratorSize(itr))
│││││││││││││││││││││││││││┌ @ array.jl:649 Base._similar_shape(itr, isz)
││││││││││││││││││││││││││││┌ @ array.jl:663 Base.length(itr)
│││││││││││││││││││││││││││││ no matching method found for call signature (Tuple{typeof(length), Nothing}): Base.length(itr::Nothing)
││││││││││││││││││││││││││││└────────────────

The problem seems related to the function have_color(). If I change the code to:

        write(buf_line, Crayons.CSI)
        Crayons._print(buf_line, crayon)
        write(buf_line, Crayons.END_ANSI)

The problem is gone and I can see a gain in allocations at first call:

Before:   0.702563 seconds (758.04 k allocations: 41.054 MiB, 1.56% gc time, 99.89% compilation time)
After:   0.645968 seconds (698.16 k allocations: 37.900 MiB, 2.14% gc time, 99.88% compilation time)

Since I am checking if display has colors, is it possible to provide a function to convert a crayon to string without checking if Base has colors?

Note: I can make a PR as soon as you accept this and we select a name (I am terrible in naming things... :D)

ronisbr commented 2 years ago

This issue seems related to: https://github.com/JuliaLang/julia/issues/44680