Skip to content

fix broken annotate! for AnnotatedChar#60488

Merged
adienes merged 1 commit intoJuliaLang:masterfrom
matthias314:m3/annotate
Dec 30, 2025
Merged

fix broken annotate! for AnnotatedChar#60488
adienes merged 1 commit intoJuliaLang:masterfrom
matthias314:m3/annotate

Conversation

@matthias314
Copy link
Copy Markdown
Contributor

The function annotate! has been broken for AnnotatedChar, at least since the inclusion StyledStrings.jl into Julia 1.11:

julia> using StyledStrings; annotate!(AnnotatedChar('x'), :face, :red)
ERROR: FieldError: type NamedTuple has no field `value`, available fields: `label`, `val`
Stacktrace:
 [1] macro expansion
   @ ./namedtuple.jl:129 [inlined]
 [2] @NamedTuple{label::Symbol, value}(nt::@NamedTuple{label::Symbol, val::Symbol})
   @ Base ./namedtuple.jl:124
 [3] annotate!(c::AnnotatedChar{Char}, label::Symbol, val::Any)
   @ Base ./strings/annotated.jl:370
 [4] top-level scope
   @ REPL[1]:1

This PR fixed this:

julia> using StyledStrings; annotate!(AnnotatedChar('x'), :face, :red)
'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)

(The red color is shown in the REPL.)

Side remark: Given that no-one can use this function at present, I wonder if one should reconsider the choice of arguments. Even if the annotations do not form a dictionary, I would see some benefit in writing

annotate!(c, label => value)

An extension to more than one annotation

annotate!(c, label1 => value1, label2 => value2)

would then be more natural.

@adienes
Copy link
Copy Markdown
Member

adienes commented Dec 26, 2025

Given that no-one can use this function at present, I wonder if one should reconsider the choice of arguments. Even if the annotations do not form a dictionary, I would see some benefit in writing

this sounds like a fair suggestion, but since annotate! is not public this can be done later without really caring about how breaking it is or not.

@matthias314
Copy link
Copy Markdown
Contributor Author

annotate! is not public

Are you sure? It's in the list of public names:

julia> using StyledStrings; names(StyledStrings)
13-element Vector{Symbol}:
 Symbol("@styled_str")
 :AnnotatedChar
 :AnnotatedIOBuffer
 :AnnotatedString
 :Face
 :SimpleColor
 :StyledStrings
 :addface!
 :annotate!
 :annotatedstring
 :annotations
 :styled
 :withfaces

@adienes
Copy link
Copy Markdown
Member

adienes commented Dec 26, 2025

ah, you are right I was looking at Base.ispublic(Base, :annotate!) not Base.ispublic(StyledStrings, :annotate!)

@tecosaur
Copy link
Copy Markdown
Member

The API used to be based on Pairs, but in #55249 it was advocated to switch to a NamedTuple based design (implemented in #55741).

See: https://github.com/JuliaLang/julia/pull/55741/files#diff-2f01122b48405cb66bf6b682b0cb968aa4a6d6cfd0ec6975e2114d04c583dd1cL330-R345

-    annotate!(str::AnnotatedString, [range::UnitRange{Int}], label::Symbol => value)
-    annotate!(str::SubString{AnnotatedString}, [range::UnitRange{Int}], label::Symbol => value)
+    annotate!(str::AnnotatedString, [range::UnitRange{Int}], label::Symbol, value)
+    annotate!(str::SubString{AnnotatedString}, [range::UnitRange{Int}], label::Symbol, value)

This bugfix (thanks!) seems to correct an oversight from #55741.

There is still some scope for adjusting this API, because while it is the intended point for annotations to be changed (hence the public), the AnnotatedString API as a whole has been marked as experimental while use stabilises.

https://docs.julialang.org/en/v1/manual/strings/#man-annotated-strings

The API for AnnotatedStrings is considered experimental and is subject to change between Julia versions.

We should discuss whether any changes are worth it somewhere else though I think, it isn't worth holding up this bugfix PR.

@adienes adienes merged commit 9c6c091 into JuliaLang:master Dec 30, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants