Skip to content

Commit

Permalink
Fix the world age of overridden base function implementations
Browse files Browse the repository at this point in the history
Rearrange all overrides so the implementation code can be precompiled,
with the only thing which is `eval`d at runtime being the method
overrides themselves.

Include global mutable "hook" bindings to allow us to fix the world age
of the implementations.
  • Loading branch information
c42f committed May 18, 2023
1 parent 2647d6a commit 6ece42b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 51 deletions.
16 changes: 13 additions & 3 deletions src/OhMyREPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ export colorscheme!, colorschemes, enable_autocomplete_brackets, enable_highligh

const SUPPORTS_256_COLORS = !(Sys.iswindows() && VERSION < v"1.5.3")

# Wrap the function `f` so that it's always invoked in the given `world_age`
function fix_world_age(f, world_age)
function (args...; kws...)
Base.invoke_in_world(world_age, f, args...; kws...)
end
end

include("repl_pass.jl")
include("repl.jl")
include("passes/Passes.jl")

include("BracketInserter.jl")
include("prompt.jl")
include("hooks.jl")

import .BracketInserter.enable_autocomplete_brackets

Expand Down Expand Up @@ -109,6 +117,10 @@ function setup_repl(repl, world_age)
reinsert_after_pkg(repl, world_age)
end
update_interface(repl.interface)

global _refresh_line_hook = fix_world_age(_refresh_line, world_age)
global _REPL_display_hook = fix_world_age(_REPL_display_hook, world_age)
global _Markdown_term_hook = fix_world_age(_Markdown_term_hook, world_age)
end

function __init__()
Expand All @@ -128,9 +140,7 @@ function __init__()
end

if ccall(:jl_generating_output, Cint, ()) == 0
include(joinpath(@__DIR__, "refresh_lines.jl"))
include(joinpath(@__DIR__, "output_prompt_overwrite.jl"))
include(joinpath(@__DIR__, "MarkdownHighlighter.jl"))
activate_hooks()
end
end

Expand Down
57 changes: 51 additions & 6 deletions src/MarkdownHighlighter.jl → src/hooks.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@

import REPL
import REPL.LineEdit
using Crayons
import Markdown

import .OhMyREPL.Passes.SyntaxHighlighter.SYNTAX_HIGHLIGHTER_SETTINGS
import .OhMyREPL.HIGHLIGHT_MARKDOWN
function _refresh_line(s::REPL.LineEdit.BufferLike)
LineEdit.refresh_multi_line(s)
OhMyREPL.Prompt.rewrite_with_ANSI(s)
end

function Markdown.term(io::IO, md::Markdown.Code, columns)
function _REPL_display(d::REPL.REPLDisplay, mime::MIME"text/plain", x)
x = Ref{Any}(x)
REPL.with_repl_linfo(d.repl) do io
if isdefined(REPL, :active_module)
mod = REPL.active_module(d)::Module
else
mod = Main
end
io = IOContext(io, :limit => true, :module => mod)
if OUTPUT_PROMPT !== nothing
output_prompt = OUTPUT_PROMPT isa String ? OUTPUT_PROMPT : OUTPUT_PROMPT()
write(io, OUTPUT_PROMPT_PREFIX)
write(io, output_prompt, "\e[0m")
end
get(io, :color, false) && write(io, REPL.answer_color(d.repl))
if isdefined(d.repl, :options) && isdefined(d.repl.options, :iocontext)
# this can override the :limit property set initially
io = foldl(IOContext, d.repl.options.iocontext, init=io)
end
show(io, mime, x[])
println(io)
end
return nothing
end

function _Markdown_term(io::IO, md::Markdown.Code, columns)
code = md.code
# Want to remove potential.
lang = md.language == "" ? "" : first(split(md.language))
Expand Down Expand Up @@ -35,11 +63,11 @@ function Markdown.term(io::IO, md::Markdown.Code, columns)
push!(outputs, "")
end

if do_syntax && HIGHLIGHT_MARKDOWN[]
if do_syntax && OhMyREPL.HIGHLIGHT_MARKDOWN[]
for (sourcecode, output) in zip(sourcecodes, outputs)
tokens = collect(tokenize(sourcecode))
crayons = fill(Crayon(), length(tokens))
SYNTAX_HIGHLIGHTER_SETTINGS(crayons, tokens, 0, sourcecode)
OhMyREPL.Passes.SyntaxHighlighter.SYNTAX_HIGHLIGHTER_SETTINGS(crayons, tokens, 0, sourcecode)
buff = IOBuffer()
if lang == "jldoctest" || lang == "julia-repl"
print(buff, Crayon(foreground = :red, bold = true), "julia> ", Crayon(reset = true))
Expand All @@ -66,3 +94,20 @@ function Markdown.term(io::IO, md::Markdown.Code, columns)
end
end
end

_refresh_line_hook = _refresh_line
_REPL_display_hook = _REPL_display
_Markdown_term_hook = _Markdown_term

function activate_hooks()
@eval begin
LineEdit.refresh_line(s::REPL.LineEdit.BufferLike) =
_refresh_line_hook(s)
Markdown.term(io::IO, md::Markdown.Code, columns) =
_Markdown_term_hook(io, md, columns)
end
if !isdefined(REPL, :IPython)
@eval REPL.display(d::REPL.REPLDisplay, mime::MIME"text/plain", x) =
_REPL_display_hook(d, mime, x)
end
end
28 changes: 0 additions & 28 deletions src/output_prompt_overwrite.jl

This file was deleted.

6 changes: 0 additions & 6 deletions src/refresh_lines.jl

This file was deleted.

9 changes: 1 addition & 8 deletions src/repl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import REPL.Terminals: raw!, width, height, cmove, getX, TerminalBuffer,
getY, clear_line, beep, disable_bracketed_paste, enable_bracketed_paste

using OhMyREPL
import OhMyREPL: untokenize_with_ANSI, apply_passes!, PASS_HANDLER
import OhMyREPL: untokenize_with_ANSI, apply_passes!, PASS_HANDLER, fix_world_age

@nospecialize # use only declared type signatures

Expand Down Expand Up @@ -79,13 +79,6 @@ function rewrite_with_ANSI(s, cursormove::Bool = false)
flush(terminal(s))
end

# Wrap the function `f` so that it's always invoked in the given `world_age`
function fix_world_age(f, world_age)
function (args...; kws...)
Base.invoke_in_world(world_age, f, args...; kws...)
end
end

function create_keybindings(prefix_hist_prompt, world_age)
D = Dict{Any, Any}()
D['\b'] = (s, data, c) -> if LineEdit.edit_backspace(s, true)
Expand Down

0 comments on commit 6ece42b

Please sign in to comment.