Skip to content

Commit 8d7b24b

Browse files
tecosaurtopolarity
authored andcommitted
Introduce annotated display invalidation barrier
Many headaches have been caused by the split implementation of Annotated* display. This is an area that will require more work, however for now the pain can be alleviated with an invalidation barrier. Co-authored-by: Cody Tapscott <topolarity@tapscott.me>
1 parent c4b6798 commit 8d7b24b

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

base/strings/annotated_io.jl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,73 @@ function _insert_annotations!(io::AnnotatedIOBuffer, annotations::Vector{RegionA
199199
push!(io.annotations, setindex(annotations[index], start+offset:stop+offset, :region))
200200
end
201201
end
202+
203+
# NOTE: This is an interim solution to the invalidations caused
204+
# by the split styled display implementation. This should be
205+
# replaced by a more robust solution (such as a consolidation of
206+
# the type and method definitions) in the near future.
207+
module AnnotatedDisplay
208+
209+
using ..Base: IO, SubString, AnnotatedString, AnnotatedChar, AnnotatedIOBuffer
210+
using ..Base: eachregion, invoke_in_world, tls_world_age
211+
212+
# Write
213+
214+
ansi_write(f::Function, io::IO, x::Any) = f(io, x)
215+
216+
ansi_write_(f::Function, io::IO, @nospecialize(x::Any)) =
217+
invoke_in_world(tls_world_age(), ansi_write, f, io, x)
218+
219+
Base.write(io::IO, s::Union{<:AnnotatedString, SubString{<:AnnotatedString}}) =
220+
ansi_write_(write, io, s)
221+
222+
Base.write(io::IO, c::AnnotatedChar) =
223+
ansi_write_(write, io, c)
224+
225+
function Base.write(io::IO, aio::AnnotatedIOBuffer)
226+
if get(io, :color, false) == true
227+
# This does introduce an overhead that technically
228+
# could be avoided, but I'm not sure that it's currently
229+
# worth the effort to implement an efficient version of
230+
# writing from a AnnotatedIOBuffer with style.
231+
# In the meantime, by converting to an `AnnotatedString` we can just
232+
# reuse all the work done to make that work.
233+
ansi_write_(io, read(aio, AnnotatedString))
234+
else
235+
write(io, aio.io)
236+
end
237+
end
238+
239+
# Print
240+
241+
Base.print(io::IO, s::Union{<:AnnotatedString, SubString{<:AnnotatedString}}) =
242+
(ansi_write_(print, io, s); nothing)
243+
244+
Base.print(io::AnnotatedIOBuffer, s::Union{<:AnnotatedString, SubString{<:AnnotatedString}}) =
245+
(write(io, s); nothing)
246+
247+
Base.print(io::AnnotatedIOBuffer, c::AnnotatedChar) =
248+
(write(io, c); nothing)
249+
250+
# Escape
251+
252+
Base.escape_string(io::IO, s::Union{<:AnnotatedString, SubString{<:AnnotatedString}},
253+
esc = ""; keep = (), ascii::Bool=false, fullhex::Bool=false) =
254+
(ansi_write_((io, s) -> escape_string(io, s, esc; keep, ascii, fullhex), io, s); nothing)
255+
256+
# Show
257+
258+
show_annot(io::IO, ::Any) = nothing
259+
show_annot(io::IO, ::MIME, ::Any) = nothing
260+
261+
show_annot_(io::IO, @nospecialize(x::Any)) =
262+
invoke_in_world(tls_world_age(), show_annot, io, x)
263+
264+
265+
show_annot_(io::IO, m::MIME, @nospecialize(x::Any)) =
266+
invoke_in_world(tls_world_age(), show_annot, io, m, x)
267+
268+
Base.show(io::IO, m::MIME"text/html", s::Union{<:AnnotatedString, SubString{<:AnnotatedString}}) =
269+
show_annot_(io, m, s)
270+
271+
end

0 commit comments

Comments
 (0)