From 2cdeef52669651cabe401f7c8aa769d44562798f Mon Sep 17 00:00:00 2001 From: Kristoffer Date: Tue, 6 Aug 2024 12:51:26 +0200 Subject: [PATCH] simplify the active_module implementation and make it a "Base feature" --- base/show.jl | 7 ++----- base/sysimg.jl | 1 + stdlib/REPL/src/LineEdit.jl | 9 ++++----- stdlib/REPL/src/REPL.jl | 27 ++++++++------------------- stdlib/REPL/test/repl.jl | 22 +++++++++++++--------- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/base/show.jl b/base/show.jl index fa66a198aef4d..b40011a4542e1 100644 --- a/base/show.jl +++ b/base/show.jl @@ -513,11 +513,8 @@ function _show_default(io::IO, @nospecialize(x)) print(io,')') end -function active_module() - REPL = REPL_MODULE_REF[] - REPL === Base && return Main - return invokelatest(REPL.active_module)::Module -end +_active_module::Module = Main +active_module() = _active_module # Check if a particular symbol is exported from a standard library module function is_exported_from_stdlib(name::Symbol, mod::Module) diff --git a/base/sysimg.jl b/base/sysimg.jl index 966ed76751f28..c3fea42412681 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -151,4 +151,5 @@ Base.TOML.reinit!(Base.TOML_CACHE.p, "") BINDIR = "" STDLIB = "" end +Base._active_module = Main end diff --git a/stdlib/REPL/src/LineEdit.jl b/stdlib/REPL/src/LineEdit.jl index 1f6a782a23397..e784410035b63 100644 --- a/stdlib/REPL/src/LineEdit.jl +++ b/stdlib/REPL/src/LineEdit.jl @@ -65,7 +65,6 @@ show(io::IO, x::Prompt) = show(io, string("Prompt(\"", prompt_string(x.prompt), mutable struct MIState interface::ModalInterface - active_module::Module current_mode::TextInterface aborted::Bool mode_state::IdDict{TextInterface,ModeState} @@ -78,7 +77,7 @@ mutable struct MIState async_channel::Channel{Function} end -MIState(i, mod, c, a, m) = MIState(i, mod, c, a, m, String[], 0, Char[], 0, :none, :none, Channel{Function}()) +MIState(i, c, a, m) = MIState(i, c, a, m, String[], 0, Char[], 0, :none, :none, Channel{Function}()) const BufferLike = Union{MIState,ModeState,IOBuffer} const State = Union{MIState,ModeState} @@ -365,7 +364,7 @@ end # Prompt Completions & Hints function complete_line(s::MIState) set_action!(s, :complete_line) - if complete_line(state(s), s.key_repeats, s.active_module) + if complete_line(state(s), s.key_repeats, Base.active_module()) return refresh_line(s) else beep(s) @@ -381,7 +380,7 @@ function check_for_hint(s::MIState) # Requires making space for them earlier in refresh_multi_line return clear_hint(st) end - completions, partial, should_complete = complete_line(st.p.complete, st, s.active_module; hint = true)::Tuple{Vector{String},String,Bool} + completions, partial, should_complete = complete_line(st.p.complete, st, Base.active_module(); hint = true)::Tuple{Vector{String},String,Bool} isempty(completions) && return clear_hint(st) # Don't complete for single chars, given e.g. `x` completes to `xor` if length(partial) > 1 && should_complete @@ -2749,7 +2748,7 @@ init_state(terminal, prompt::Prompt) = #=indent(spaces)=# -1, Threads.SpinLock(), 0.0, -Inf, nothing) function init_state(terminal, m::ModalInterface) - s = MIState(m, Main, m.modes[1], false, IdDict{Any,Any}()) + s = MIState(m, m.modes[1], false, IdDict{Any,Any}()) for mode in m.modes s.mode_state[mode] = init_state(terminal, mode) end diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 67f5860082c8a..409b7e1746748 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -329,7 +329,7 @@ function warn_on_non_owning_accesses(current_mod, ast) end return ast end -warn_on_non_owning_accesses(ast) = warn_on_non_owning_accesses(REPL.active_module(), ast) +warn_on_non_owning_accesses(ast) = warn_on_non_owning_accesses(Base.active_module(), ast) const repl_ast_transforms = Any[softscope, warn_on_non_owning_accesses] # defaults for new REPL backends @@ -497,7 +497,7 @@ end function display(d::REPLDisplay, mime::MIME"text/plain", x) x = Ref{Any}(x) with_repl_linfo(d.repl) do io - io = IOContext(io, :limit => true, :module => active_module(d)::Module) + io = IOContext(io, :limit => true, :module => Base.active_module()) if d.repl isa LineEditREPL mistate = d.repl.mistate mode = LineEdit.mode(mistate) @@ -527,7 +527,7 @@ show_repl(io::IO, ::MIME"text/plain", ex::Expr) = function print_response(repl::AbstractREPL, response, show_value::Bool, have_color::Bool) repl.waserror = response[2] with_repl_linfo(repl) do io - io = IOContext(io, :module => active_module(repl)::Module) + io = IOContext(io, :module => Base.active_module()) print_response(io, response, show_value, have_color, specialdisplay(repl)) end return nothing @@ -628,7 +628,7 @@ function run_repl(repl::AbstractREPL, @nospecialize(consumer = x -> nothing); ba Core.println(Core.stderr, e) Core.println(Core.stderr, catch_backtrace()) end - get_module = () -> active_module(repl) + get_module = () -> Base.active_module() if backend_on_current_task t = @async run_frontend(repl, backend_ref) errormonitor(t) @@ -760,15 +760,6 @@ REPLCompletionProvider() = REPLCompletionProvider(LineEdit.Modifiers()) mutable struct ShellCompletionProvider <: CompletionProvider end struct LatexCompletions <: CompletionProvider end -function active_module() # this method is also called from Base - isdefined(Base, :active_repl) || return Main - Base.active_repl === nothing && return Main - return active_module(Base.active_repl::AbstractREPL) -end -active_module((; mistate)::LineEditREPL) = mistate === nothing ? Main : mistate.active_module -active_module(::AbstractREPL) = Main -active_module(d::REPLDisplay) = active_module(d.repl) - setmodifiers!(c::CompletionProvider, m::LineEdit.Modifiers) = nothing setmodifiers!(c::REPLCompletionProvider, m::LineEdit.Modifiers) = c.modifiers = m @@ -776,13 +767,11 @@ setmodifiers!(c::REPLCompletionProvider, m::LineEdit.Modifiers) = c.modifiers = """ activate(mod::Module=Main) -Set `mod` as the default contextual module in the REPL, +Set `mod` as the default contextual module, both for evaluating expressions and printing them. """ function activate(mod::Module=Main) - mistate = (Base.active_repl::LineEditREPL).mistate - mistate === nothing && return nothing - mistate.active_module = mod + Base._active_module = mod Base.load_InteractiveUtils(mod) return nothing end @@ -1206,7 +1195,7 @@ enable_promptpaste(v::Bool) = JL_PROMPT_PASTE[] = v function contextual_prompt(repl::LineEditREPL, prompt::Union{String,Function}) function () - mod = active_module(repl) + mod = Base.active_module() prefix = mod == Main ? "" : string('(', mod, ") ") pr = prompt isa String ? prompt : prompt() prefix * pr @@ -1275,7 +1264,7 @@ function setup_interface( repl = repl, complete = replc, # When we're done transform the entered line into a call to helpmode function - on_done = respond(line::String->helpmode(outstream(repl), line, repl.mistate.active_module), + on_done = respond(line::String->helpmode(outstream(repl), line, Base._active_module), repl, julia_prompt, pass_empty=true, suppress_on_semicolon=false)) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 6f0c4a5c3d6ba..9351feb5299bb 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1157,16 +1157,20 @@ fake_repl() do stdin_write, stdout_read, repl s = readuntil(stdout_read, "\n\n") @test endswith(s, "(123, Base.Fix1)") - repl.mistate.active_module = Base # simulate activate_module(Base) - write(stdin_write, " ( 456 , Base.Fix2 , ) \n") - s = readuntil(stdout_read, "\n\n") - # ".Base" prefix not shown here - @test endswith(s, "(456, Fix2)") + try + Base._active_module = Base # simulate activate_module(Base) + write(stdin_write, " ( 456 , Base.Fix2 , ) \n") + s = readuntil(stdout_read, "\n\n") + # ".Base" prefix not shown here + @test endswith(s, "(456, Fix2)") - # Close REPL ^D - readuntil(stdout_read, "julia> ", keep=true) - write(stdin_write, '\x04') - Base.wait(repltask) + # Close REPL ^D + readuntil(stdout_read, "julia> ", keep=true) + write(stdin_write, '\x04') + Base.wait(repltask) + finally + Base._active_module = Main + end end help_result(line, mod::Module=Base) = Core.eval(mod, REPL._helpmode(IOBuffer(), line, mod))