From da41b6a8ea4d4e355159e9c791111c445cc6805c Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 20 Sep 2024 22:53:39 +0800 Subject: [PATCH] Call load_customisations! automatically, lazily I've been wary about doing lazy application of load_customisations!, but with the @noinline addition the calls are really cheap: only 1.5ns according to Chairmarks on my machine. Thus, the cost of calling it after initialisation will be negligeable for any non-trivial function. Having rolled this around further, other than printing I think only withfaces calls actually require loading of user styles to be valid. With these two realisations, calling load_customisations! lazily as appropriate seems like a bit of a no-brainer. We'll probably want to add this to public API eventually for non-text/html output implementations, but we can wait to see how this is bourne out first. --- src/StyledStrings.jl | 19 ++++++++++++------- src/faces.jl | 3 +++ src/io.jl | 6 ++++++ src/precompile.jl | 2 ++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/StyledStrings.jl b/src/StyledStrings.jl index 6d332a32..1eb4b5a9 100644 --- a/src/StyledStrings.jl +++ b/src/StyledStrings.jl @@ -25,19 +25,24 @@ Load customisations from the user's `faces.toml` file, if it exists as well as the current environment. This function should be called before producing any output in situations where -the user's customisations should be considered. +the user's customisations should be considered. This is called automatically +when printing text or HTML output, and when calling `withfaces`, but may need +to be called manually in unusual situations. Unless `force` is set, customisations are only applied when this function is called for the first time, and subsequent calls are a no-op. """ function load_customisations!(; force::Bool=false) !force && HAVE_LOADED_CUSTOMISATIONS[] && return - if !isempty(DEPOT_PATH) - userfaces = joinpath(first(DEPOT_PATH), "config", "faces.toml") - isfile(userfaces) && loaduserfaces!(userfaces) - end - Legacy.load_env_colors!() - HAVE_LOADED_CUSTOMISATIONS[] = true + (function () + @noinline + if !isempty(DEPOT_PATH) + userfaces = joinpath(first(DEPOT_PATH), "config", "faces.toml") + isfile(userfaces) && loaduserfaces!(userfaces) + end + Legacy.load_env_colors!() + HAVE_LOADED_CUSTOMISATIONS[] = true + end)() nothing end diff --git a/src/faces.jl b/src/faces.jl index 89217a8f..6dcbd096 100644 --- a/src/faces.jl +++ b/src/faces.jl @@ -465,6 +465,9 @@ red and blue mixed make purple ``` """ function withfaces(f, keyvals_itr) + # Before modifying the current `FACES`, we should ensure + # that we've loaded the user's customisations. + load_customisations!() if !(eltype(keyvals_itr) <: Pair{Symbol}) throw(MethodError(withfaces, (f, keyvals_itr))) end diff --git a/src/io.jl b/src/io.jl index bbd6efdf..4a60121c 100644 --- a/src/io.jl +++ b/src/io.jl @@ -227,6 +227,9 @@ end function _ansi_writer(io::IO, s::Union{<:AnnotatedString, SubString{<:AnnotatedString}}, string_writer::F) where {F <: Function} + # We need to make sure that the customisations are loaded + # before we start outputting any styled content. + load_customisations!() if get(io, :color, false)::Bool buf = IOBuffer() # Avoid the overhead in repeatadly printing to `stdout` lastface::Face = FACES.default[:default] @@ -442,6 +445,9 @@ function htmlstyle(io::IO, face::Face, lastface::Face=getface()) end function Base.show(io::IO, ::MIME"text/html", s::Union{<:AnnotatedString, SubString{<:AnnotatedString}}) + # We need to make sure that the customisations are loaded + # before we start outputting any styled content. + load_customisations!() htmlescape(str) = replace(str, '&' => "&", '<' => "<", '>' => ">") buf = IOBuffer() # Avoid potential overhead in repeatadly printing a more complex IO lastface::Face = getface() diff --git a/src/precompile.jl b/src/precompile.jl index 8406f9a7..0ae30d19 100644 --- a/src/precompile.jl +++ b/src/precompile.jl @@ -39,3 +39,5 @@ StyledStrings.resetfaces!() StyledStrings.withfaces(:yellow => StyledStrings.Face(foreground=:red), :green => :blue) do println(colorio, styled"{yellow:red} and {green:blue} mixed make {magenta:purple}") end + +StyledStrings.HAVE_LOADED_CUSTOMISATIONS[] = false