Skip to content

Commit 2cfe896

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 2cfe896

File tree

1 file changed

+45
-26
lines changed

1 file changed

+45
-26
lines changed

base/errorshow.jl

+45-26
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,40 @@ 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 = if !isnothing(line) && line > 0
111+
string(something(pathstr, ""), ':', line)
112+
else
113+
something(pathstr, "")
114+
end
115+
if !isnothing(realfile)
116+
flen = ncodeunits(basename(realfile))
117+
llen = ncodeunits(string(line))
118+
AnnotatedString(linestr,
119+
[(1:ncodeunits(linestr), :link => Filesystem.uripath(realfile)),
120+
(1:ncodeunits(linestr)-flen-llen-1, :face => :julia_stacktrace_location),
121+
(ncodeunits(linestr)-flen-llen:ncodeunits(linestr)-llen-1, :face => :julia_stacktrace_filename),
122+
(ncodeunits(linestr)-llen:ncodeunits(linestr), :face => :julia_stacktrace_fileline)])
123+
else
124+
AnnotatedString(linestr, [(1:ncodeunits(linestr), :face => :julia_stacktrace_location)])
125+
end
126+
end
127+
128+
stacktrace_path(location::LineNumberNode) =
129+
stacktrace_path(if !isnothing(location.file) String(location.file) end, location.line)
130+
101131
function showerror(io::IO, ex::LoadError, bt; backtrace=true)
102132
!isa(ex.error, LoadError) && print(io, "LoadError: ")
103133
showerror(io, ex.error, bt, backtrace=backtrace)
104-
print(io, "\nin expression starting at $(ex.file):$(ex.line)")
134+
print(io, "\nin expression starting at ", stacktrace_path(ex.file, ex.line))
105135
end
106136
showerror(io::IO, ex::LoadError) = showerror(io, ex, [])
107137

@@ -595,7 +625,7 @@ end
595625
const update_stackframes_callback = Ref{Function}(identity)
596626

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

600630
function show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
601631
num_frames = length(trace)
@@ -680,9 +710,9 @@ function show_reduced_backtrace(io::IO, t::Vector)
680710
cycle_length = repeated_cycle[1][2]
681711
repetitions = repeated_cycle[1][3]
682712
popfirst!(repeated_cycle)
683-
printstyled(io,
684-
"--- the above ", cycle_length, " lines are repeated ",
685-
repetitions, " more time", repetitions>1 ? "s" : "", " ---", color = :light_black)
713+
repmsg = string("--- the above ", cycle_length, " lines are repeated ",
714+
repetitions, " more time", repetitions>1 ? "s" : "", " ---")
715+
print(io, AnnotatedString(repmsg, [(1:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
686716
if i < length(displayed_stackframes)
687717
println(io)
688718
stacktrace_linebreaks() && println(io)
@@ -735,41 +765,30 @@ function print_stackframe(io, i, frame::StackFrame, n::Int, ndigits_max, modulec
735765
digit_align_width = ndigits_max + 2
736766

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

741771
StackTraces.show_spec_linfo(IOContext(io, :backtrace=>true), frame)
742772
if n > 1
743-
printstyled(io, " (repeats $n times)"; color=:light_black)
773+
repmsg = " (repeats $n times)"
774+
print(io, AnnotatedString(repmsg, [(2:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
744775
end
745776
println(io)
746777

747778
# @ Module path / file : line
748779
print_module_path_file(io, modul, file, line; modulecolor, digit_align_width)
749780

750781
# inlined
751-
printstyled(io, inlined ? " [inlined]" : "", color = :light_black)
782+
print(io, if inlined AnnotatedString("[inlined]", [(1:9, :face => :julia_stacktrace_inlined)]) else "" end)
752783
end
753784

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
785+
function print_module_path_file(io, modul, file, line; modulecolor = :bright_black, digit_align_width = 0)
786+
print(io, ' ' ^ digit_align_width, AnnotatedString("@", [(1:1, :face => :julia_stacktrace_location)]))
758787
if modul !== nothing && modulecolor !== nothing
759-
print(io, " ")
760-
printstyled(io, modul, color = modulecolor)
788+
mstr = string(modul)
789+
print(io, " ", AnnotatedString(mstr, [(1:ncodeunits(mstr), :face => modulecolor)]))
761790
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)
791+
print(io, ' ', stacktrace_path(file, line))
773792
end
774793

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

0 commit comments

Comments
 (0)