Skip to content

Commit e550086

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 6c23c38 commit e550086

File tree

2 files changed

+45
-27
lines changed

2 files changed

+45
-27
lines changed

base/errorshow.jl

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

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

@@ -605,7 +634,7 @@ end
605634
const update_stackframes_callback = Ref{Function}(identity)
606635

607636
const STACKTRACE_MODULECOLORS = Iterators.Stateful(Iterators.cycle([:magenta, :cyan, :green, :yellow]))
608-
const STACKTRACE_FIXEDCOLORS = IdDict(Base => :light_black, Core => :light_black)
637+
const STACKTRACE_FIXEDCOLORS = IdDict(Base => :julia_stacktrace_basemodule, Core => :julia_stacktrace_basemodule)
609638

610639
function show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
611640
num_frames = length(trace)
@@ -690,9 +719,9 @@ function show_reduced_backtrace(io::IO, t::Vector)
690719
cycle_length = repeated_cycle[1][2]
691720
repetitions = repeated_cycle[1][3]
692721
popfirst!(repeated_cycle)
693-
printstyled(io,
694-
"--- the above ", cycle_length, " lines are repeated ",
695-
repetitions, " more time", repetitions>1 ? "s" : "", " ---", color = :light_black)
722+
repmsg = string("--- the above ", cycle_length, " lines are repeated ",
723+
repetitions, " more time", repetitions>1 ? "s" : "", " ---")
724+
print(io, AnnotatedString(repmsg, [(1:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
696725
if i < length(displayed_stackframes)
697726
println(io)
698727
stacktrace_linebreaks() && println(io)
@@ -745,41 +774,30 @@ function print_stackframe(io, i, frame::StackFrame, n::Int, ndigits_max, modulec
745774
digit_align_width = ndigits_max + 2
746775

747776
# frame number
748-
print(io, " ", lpad("[" * string(i) * "]", digit_align_width))
749-
print(io, " ")
777+
frameindex = lpad('[' * string(i) * ']', digit_align_width)
778+
print(io, ' ', AnnotatedString(frameindex, [(1:ncodeunits(frameindex), :face => :julia_stacktrace_frameindex)]), ' ')
750779

751780
StackTraces.show_spec_linfo(IOContext(io, :backtrace=>true), frame)
752781
if n > 1
753-
printstyled(io, " (repeats $n times)"; color=:light_black)
782+
repmsg = " (repeats $n times)"
783+
print(io, AnnotatedString(repmsg, [(2:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
754784
end
755785
println(io)
756786

757787
# @ Module path / file : line
758788
print_module_path_file(io, modul, file, line; modulecolor, digit_align_width)
759789

760790
# inlined
761-
printstyled(io, inlined ? " [inlined]" : "", color = :light_black)
791+
print(io, if inlined AnnotatedString("[inlined]", [(1:9, :face => :julia_stacktrace_inlined)]) else "" end)
762792
end
763793

764-
function print_module_path_file(io, modul, file, line; modulecolor = :light_black, digit_align_width = 0)
765-
printstyled(io, " " ^ digit_align_width * "@", color = :light_black)
766-
767-
# module
794+
function print_module_path_file(io, modul, file, line; modulecolor = :bright_black, digit_align_width = 0)
795+
print(io, ' ' ^ digit_align_width, AnnotatedString("@", [(1:1, :face => :julia_stacktrace_location)]))
768796
if modul !== nothing && modulecolor !== nothing
769-
print(io, " ")
770-
printstyled(io, modul, color = modulecolor)
797+
mstr = string(modul)
798+
print(io, " ", AnnotatedString(mstr, [(1:ncodeunits(mstr), :face => modulecolor)]))
771799
end
772-
773-
# filepath
774-
file = fixup_stdlib_path(file)
775-
stacktrace_expand_basepaths() && (file = something(find_source_file(file), file))
776-
stacktrace_contract_userdir() && (file = contractuser(file))
777-
print(io, " ")
778-
dir = dirname(file)
779-
!isempty(dir) && printstyled(io, dir, Filesystem.path_separator, color = :light_black)
780-
781-
# filename, separator, line
782-
printstyled(io, basename(file), ":", line; color = :light_black, underline = true)
800+
print(io, ' ', stacktrace_path(file, line))
783801
end
784802

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

base/path.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,6 @@ function uripath(path::AbstractString)
626626
s, r"[^A-Za-z0-9\-_.~]+" => percent_escape)
627627
string("file://", gethostname(), '/',
628628
join(map(encode_uri_component,
629-
split(path, Filesystem.path_separator, keepempty=false)),
629+
split(path, path_separator_re, keepempty=false)),
630630
'/'))
631631
end

0 commit comments

Comments
 (0)