Skip to content

Commit

Permalink
Use StyledStrings Faces for stacktrace printing
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tecosaur committed Oct 29, 2023
1 parent 0e9de25 commit 2cfe896
Showing 1 changed file with 45 additions and 26 deletions.
71 changes: 45 additions & 26 deletions base/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,40 @@ function showerror(io::IO, ex, bt; backtrace=true)
end
end

function stacktrace_path(file::Union{Nothing, String}, line::Union{Nothing, Int64})
realfile = if !isnothing(file) && file != "" && !startswith(String(file), "REPL")
fixup_stdlib_path(String(file))
end
pathstr = file
if !isnothing(pathstr)
stacktrace_expand_basepaths() && (pathstr = something(find_source_file(file), file))
stacktrace_contract_userdir() && (pathstr = contractuser(pathstr))
end
linestr = if !isnothing(line) && line > 0
string(something(pathstr, ""), ':', line)
else
something(pathstr, "")
end
if !isnothing(realfile)
flen = ncodeunits(basename(realfile))
llen = ncodeunits(string(line))
AnnotatedString(linestr,
[(1:ncodeunits(linestr), :link => Filesystem.uripath(realfile)),
(1:ncodeunits(linestr)-flen-llen-1, :face => :julia_stacktrace_location),
(ncodeunits(linestr)-flen-llen:ncodeunits(linestr)-llen-1, :face => :julia_stacktrace_filename),
(ncodeunits(linestr)-llen:ncodeunits(linestr), :face => :julia_stacktrace_fileline)])
else
AnnotatedString(linestr, [(1:ncodeunits(linestr), :face => :julia_stacktrace_location)])
end
end

stacktrace_path(location::LineNumberNode) =
stacktrace_path(if !isnothing(location.file) String(location.file) end, location.line)

function showerror(io::IO, ex::LoadError, bt; backtrace=true)
!isa(ex.error, LoadError) && print(io, "LoadError: ")
showerror(io, ex.error, bt, backtrace=backtrace)
print(io, "\nin expression starting at $(ex.file):$(ex.line)")
print(io, "\nin expression starting at ", stacktrace_path(ex.file, ex.line))
end
showerror(io::IO, ex::LoadError) = showerror(io, ex, [])

Expand Down Expand Up @@ -595,7 +625,7 @@ end
const update_stackframes_callback = Ref{Function}(identity)

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

function show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
num_frames = length(trace)
Expand Down Expand Up @@ -680,9 +710,9 @@ function show_reduced_backtrace(io::IO, t::Vector)
cycle_length = repeated_cycle[1][2]
repetitions = repeated_cycle[1][3]
popfirst!(repeated_cycle)
printstyled(io,
"--- the above ", cycle_length, " lines are repeated ",
repetitions, " more time", repetitions>1 ? "s" : "", " ---", color = :light_black)
repmsg = string("--- the above ", cycle_length, " lines are repeated ",
repetitions, " more time", repetitions>1 ? "s" : "", " ---")
print(io, AnnotatedString(repmsg, [(1:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
if i < length(displayed_stackframes)
println(io)
stacktrace_linebreaks() && println(io)
Expand Down Expand Up @@ -735,41 +765,30 @@ function print_stackframe(io, i, frame::StackFrame, n::Int, ndigits_max, modulec
digit_align_width = ndigits_max + 2

# frame number
print(io, " ", lpad("[" * string(i) * "]", digit_align_width))
print(io, " ")
frameindex = lpad('[' * string(i) * ']', digit_align_width)
print(io, ' ', AnnotatedString(frameindex, [(1:ncodeunits(frameindex), :face => :julia_stacktrace_frameindex)]), ' ')

StackTraces.show_spec_linfo(IOContext(io, :backtrace=>true), frame)
if n > 1
printstyled(io, " (repeats $n times)"; color=:light_black)
repmsg = " (repeats $n times)"
print(io, AnnotatedString(repmsg, [(2:ncodeunits(repmsg), :face => :julia_stacktrace_repetition)]))
end
println(io)

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

# inlined
printstyled(io, inlined ? " [inlined]" : "", color = :light_black)
print(io, if inlined AnnotatedString("[inlined]", [(1:9, :face => :julia_stacktrace_inlined)]) else "" end)
end

function print_module_path_file(io, modul, file, line; modulecolor = :light_black, digit_align_width = 0)
printstyled(io, " " ^ digit_align_width * "@", color = :light_black)

# module
function print_module_path_file(io, modul, file, line; modulecolor = :bright_black, digit_align_width = 0)
print(io, ' ' ^ digit_align_width, AnnotatedString("@", [(1:1, :face => :julia_stacktrace_location)]))
if modul !== nothing && modulecolor !== nothing
print(io, " ")
printstyled(io, modul, color = modulecolor)
mstr = string(modul)
print(io, " ", AnnotatedString(mstr, [(1:ncodeunits(mstr), :face => modulecolor)]))
end

# filepath
file = fixup_stdlib_path(file)
stacktrace_expand_basepaths() && (file = something(find_source_file(file), file))
stacktrace_contract_userdir() && (file = contractuser(file))
print(io, " ")
dir = dirname(file)
!isempty(dir) && printstyled(io, dir, Filesystem.path_separator, color = :light_black)

# filename, separator, line
printstyled(io, basename(file), ":", line; color = :light_black, underline = true)
print(io, ' ', stacktrace_path(file, line))
end

function show_backtrace(io::IO, t::Vector)
Expand Down

0 comments on commit 2cfe896

Please sign in to comment.