diff --git a/base/errorshow.jl b/base/errorshow.jl index a4583bc819856..4616181f6c4d8 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -541,13 +541,10 @@ function show_method_candidates(io::IO, ex::MethodError, @nospecialize kwargs=() end end -# Contains file name and file number. Gets set when a backtrace -# or methodlist is shown. Used by the REPL to make it possible to open -# the location of a stackframe/method in the editor. -global LAST_SHOWN_LINE_INFOS = Tuple{String, Int}[] - function show_trace_entry(io, frame, n; prefix = "") - push!(LAST_SHOWN_LINE_INFOS, (string(frame.file), frame.line)) + if haskey(io, :LAST_SHOWN_LINE_INFOS) + push!(io[:LAST_SHOWN_LINE_INFOS], (string(frame.file), frame.line)) + end print(io, "\n", prefix) show(io, frame, full_path=true) n > 1 && print(io, " (repeats ", n, " times)") @@ -634,7 +631,9 @@ function show_reduced_backtrace(io::IO, t::Vector, with_prefix::Bool) end function show_backtrace(io::IO, t::Vector) - resize!(LAST_SHOWN_LINE_INFOS, 0) + if haskey(io, :LAST_SHOWN_LINE_INFOS) + resize!(io[:LAST_SHOWN_LINE_INFOS], 0) + end filtered = process_backtrace(t) isempty(filtered) && return diff --git a/base/methodshow.jl b/base/methodshow.jl index e878660a0305e..2762acfb52a5c 100644 --- a/base/methodshow.jl +++ b/base/methodshow.jl @@ -240,6 +240,7 @@ function show_method_table(io::IO, ms::MethodList, max::Int=-1, header::Bool=tru end n = rest = 0 local last + LAST_SHOWN_LINE_INFOS = get(io, :LAST_SHOWN_LINE_INFOS, Tuple{String,Int}[]) resize!(LAST_SHOWN_LINE_INFOS, 0) for meth in ms @@ -373,6 +374,7 @@ show(io::IO, mime::MIME"text/html", mt::Core.MethodTable) = show(io, mime, Metho # pretty-printing of AbstractVector{Method} function show(io::IO, mime::MIME"text/plain", mt::AbstractVector{Method}) + LAST_SHOWN_LINE_INFOS = get(io, :LAST_SHOWN_LINE_INFOS, Tuple{String,Int}[]) resize!(LAST_SHOWN_LINE_INFOS, 0) first = true for (i, m) in enumerate(mt) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 30af00a6cdc06..a85ae7354f886 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -211,8 +211,22 @@ function display(d::REPLDisplay, mime::MIME"text/plain", x) io = foldl(IOContext, d.repl.options.iocontext, init=IOContext(io, :limit => true, :module => Main)) end + + infos = Tuple{String,Int}[] + io = IOContext(io, :LAST_SHOWN_LINE_INFOS => infos) + show(io, mime, x) println(io) + + if !isempty(infos) + d.repl.last_shown_line_infos = infos + println( + io, + "\nTo edit a specific method, type the corresponding number into the " * + "REPL and press Ctrl+Q", + ) + end + nothing end display(d::REPLDisplay, x) = display(d, MIME("text/plain"), x) @@ -430,11 +444,12 @@ mutable struct LineEditREPL <: AbstractREPL specialdisplay::Union{Nothing,AbstractDisplay} options::Options mistate::Union{MIState,Nothing} + last_shown_line_infos::Vector{Tuple{String,Int}} interface::ModalInterface backendref::REPLBackendRef LineEditREPL(t,hascolor,prompt_color,input_color,answer_color,shell_color,help_color,history_file,in_shell,in_help,envcolors) = new(t,hascolor,prompt_color,input_color,answer_color,shell_color,help_color,history_file,in_shell, - in_help,envcolors,false,nothing, Options(), nothing) + in_help,envcolors,false,nothing, Options(), nothing, Tuple{String,Int}[]) end outstream(r::LineEditREPL) = r.t specialdisplay(r::LineEditREPL) = r.specialdisplay @@ -1092,10 +1107,10 @@ function setup_interface( end, # Open the editor at the location of a stackframe or method - # This is accessing a global variable that gets set in + # This is accessing a contextual variable that gets set in # the show_backtrace and show_method_table functions. "^Q" => (s, o...) -> begin - linfos = Base.LAST_SHOWN_LINE_INFOS + linfos = repl.last_shown_line_infos str = String(take!(LineEdit.buffer(s))) n = tryparse(Int, str) n === nothing && @goto writeback