Skip to content

Commit 5f2af90

Browse files
committed
Use StyledStrings Faces for stacktrace printing
This allows for the faces used (e.g. the file path) to be user-customised, which provides an escape from themes that make bright black invisible.
1 parent 0e9de25 commit 5f2af90

File tree

1 file changed

+44
-26
lines changed

1 file changed

+44
-26
lines changed

base/errorshow.jl

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,39 @@ function showerror(io::IO, ex, bt; backtrace=true)
9898
end
9999
end
100100

101+
function stacktrace_path(file::Union{Nothing, String}, line::Union{Nothing, Int64})
102+
realfile = if !isnothing(file) && file != "" && !startswith(String(file), "REPL")
103+
fixup_stdlib_path(String(file))
104+
end
105+
pathstr = file
106+
if !isnothing(pathstr)
107+
stacktrace_expand_basepaths() && (pathstr = something(find_source_file(file), file))
108+
stacktrace_contract_userdir() && (pathstr = contractuser(pathstr))
109+
end
110+
linestr, llen = if !isnothing(line) && line > 0
111+
string(something(pathstr, ""), ':', line), ncodeunits(string(line))
112+
else
113+
something(pathstr, ""), 0
114+
end
115+
if !isnothing(realfile)
116+
flen = ncodeunits(basename(realfile))
117+
AnnotatedString(linestr,
118+
[(1:ncodeunits(linestr), :link => Filesystem.uripath(realfile)),
119+
(1:ncodeunits(linestr)-flen-llen-1, :face => :julia_stacktrace_location),
120+
(ncodeunits(linestr)-flen-llen:ncodeunits(linestr)-llen-1, :face => :julia_stacktrace_filename),
121+
(ncodeunits(linestr)-llen:ncodeunits(linestr), :face => :julia_stacktrace_fileline)])
122+
else
123+
AnnotatedString(linestr, [(1:ncodeunits(linestr), :face => :julia_stacktrace_location)])
124+
end
125+
end
126+
127+
stacktrace_path(location::LineNumberNode) =
128+
stacktrace_path(if !isnothing(location.file) String(location.file) end, location.line)
129+
101130
function showerror(io::IO, ex::LoadError, bt; backtrace=true)
102131
!isa(ex.error, LoadError) && print(io, "LoadError: ")
103132
showerror(io, ex.error, bt, backtrace=backtrace)
104-
print(io, "\nin expression starting at $(ex.file):$(ex.line)")
133+
print(io, "\nin expression starting at ", stacktrace_path(ex.file, ex.line))
105134
end
106135
showerror(io::IO, ex::LoadError) = showerror(io, ex, [])
107136

@@ -595,7 +624,7 @@ end
595624
const update_stackframes_callback = Ref{Function}(identity)
596625

597626
const STACKTRACE_MODULECOLORS = Iterators.Stateful(Iterators.cycle([:magenta, :cyan, :green, :yellow]))
598-
const STACKTRACE_FIXEDCOLORS = IdDict(Base => :light_black, Core => :light_black)
627+
const STACKTRACE_FIXEDCOLORS = IdDict(Base => :julia_stacktrace_basemodule, Core => :julia_stacktrace_basemodule)
599628

600629
function show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
601630
num_frames = length(trace)
@@ -680,9 +709,9 @@ function show_reduced_backtrace(io::IO, t::Vector)
680709
cycle_length = repeated_cycle[1][2]
681710
repetitions = repeated_cycle[1][3]
682711
popfirst!(repeated_cycle)
683-
printstyled(io,
684-
"--- the above ", cycle_length, " lines are repeated ",
685-
repetitions, " more time", repetitions>1 ? "s" : "", " ---", color = :light_black)
712+
repmsg = string("--- the above ", cycle_length, " lines are repeated ",
713+
repetitions, " more time", repetitions>1 ? "s" : "", " ---")
714+
print(io, AnnotatedString(repmsg, [(1:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
686715
if i < length(displayed_stackframes)
687716
println(io)
688717
stacktrace_linebreaks() && println(io)
@@ -735,41 +764,30 @@ function print_stackframe(io, i, frame::StackFrame, n::Int, ndigits_max, modulec
735764
digit_align_width = ndigits_max + 2
736765

737766
# frame number
738-
print(io, " ", lpad("[" * string(i) * "]", digit_align_width))
739-
print(io, " ")
767+
frameindex = lpad('[' * string(i) * ']', digit_align_width)
768+
print(io, ' ', AnnotatedString(frameindex, [(1:ncodeunits(frameindex), :face => :julia_stacktrace_frameindex)]), ' ')
740769

741770
StackTraces.show_spec_linfo(IOContext(io, :backtrace=>true), frame)
742771
if n > 1
743-
printstyled(io, " (repeats $n times)"; color=:light_black)
772+
repmsg = " (repeats $n times)"
773+
print(io, AnnotatedString(repmsg, [(2:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
744774
end
745775
println(io)
746776

747777
# @ Module path / file : line
748778
print_module_path_file(io, modul, file, line; modulecolor, digit_align_width)
749779

750780
# inlined
751-
printstyled(io, inlined ? " [inlined]" : "", color = :light_black)
781+
print(io, if inlined AnnotatedString("[inlined]", [(1:9, :face => :julia_stacktrace_inlined)]) else "" end)
752782
end
753783

754-
function print_module_path_file(io, modul, file, line; modulecolor = :light_black, digit_align_width = 0)
755-
printstyled(io, " " ^ digit_align_width * "@", color = :light_black)
756-
757-
# module
784+
function print_module_path_file(io, modul, file, line; modulecolor = :bright_black, digit_align_width = 0)
785+
print(io, ' ' ^ digit_align_width, AnnotatedString("@", [(1:1, :face => :julia_stacktrace_location)]))
758786
if modul !== nothing && modulecolor !== nothing
759-
print(io, " ")
760-
printstyled(io, modul, color = modulecolor)
787+
mstr = string(modul)
788+
print(io, " ", AnnotatedString(mstr, [(1:ncodeunits(mstr), :face => modulecolor)]))
761789
end
762-
763-
# filepath
764-
file = fixup_stdlib_path(file)
765-
stacktrace_expand_basepaths() && (file = something(find_source_file(file), file))
766-
stacktrace_contract_userdir() && (file = contractuser(file))
767-
print(io, " ")
768-
dir = dirname(file)
769-
!isempty(dir) && printstyled(io, dir, Filesystem.path_separator, color = :light_black)
770-
771-
# filename, separator, line
772-
printstyled(io, basename(file), ":", line; color = :light_black, underline = true)
790+
print(io, ' ', stacktrace_path(file, line))
773791
end
774792

775793
function show_backtrace(io::IO, t::Vector)

0 commit comments

Comments
 (0)