Skip to content

Instantly share code, notes, and snippets.

@pfitzseb
Created June 16, 2019 07:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pfitzseb/2cd6758eec7ad52a5a4b4421400f9602 to your computer and use it in GitHub Desktop.
Save pfitzseb/2cd6758eec7ad52a5a4b4421400f9602 to your computer and use it in GitHub Desktop.
keyboard macro prototype
using REPL
using REPL.LineEdit
macro keyboard()
quote
debugprompt(@__MODULE__, Base.@locals)
println()
end
end
const prompt_color = if Sys.iswindows()
"\e[33m"
else
"\e[38;5;166m"
end
function debugprompt(mod, locals = Dict())
try
panel = REPL.LineEdit.Prompt("debug> ";
prompt_prefix = prompt_color,
prompt_suffix = Base.text_colors[:normal],
on_enter = s -> true)
panel.hist = REPL.REPLHistoryProvider(Dict{Symbol,Any}(:junodebug => panel))
panel.complete = REPL.LatexCompletions()
REPL.history_reset_state(panel.hist)
search_prompt, skeymap = LineEdit.setup_search_keymap(panel.hist)
search_prompt.complete = REPL.LatexCompletions()
panel.on_done = (s, buf, ok) -> begin
if !ok
LineEdit.transition(s, :abort)
REPL.LineEdit.reset_state(s)
return false
end
line = String(take!(buf))
if isempty(line)
println()
return true
end
try
r = interpret(line, mod, locals)
r ≠ nothing && display(r)
catch err
Base.display_error(stderr, err, stacktrace(catch_backtrace()))
end
println()
LineEdit.reset_state(s)
return true
end
panel.keymap_dict = LineEdit.keymap(Dict{Any,Any}[skeymap, LineEdit.history_keymap, LineEdit.default_keymap, LineEdit.escape_defaults])
REPL.run_interface(Base.active_repl.t, REPL.LineEdit.ModalInterface([panel, search_prompt]))
catch e
e isa InterruptException || rethrow(e)
end
end
maybe_quote(x) = (isa(x, Expr) || isa(x, Symbol)) ? QuoteNode(x) : x
function interpret(command::AbstractString, mod, locals)
expr = Base.parse_input_line(command)
Base.Meta.isexpr(expr, :toplevel) && (expr = expr.args[end])
res = gensym()
eval_expr = Expr(:let,
Expr(:block, map(x->Expr(:(=), x...), [(k, maybe_quote(v)) for (k, v) in locals])...),
Expr(:block,
Expr(:(=), res, expr),
Expr(:tuple, res, Expr(:tuple, [k for (k, v) in locals]...))
))
eval_res, res = Core.eval(mod, eval_expr)
eval_res
end
@boubalos
Copy link

that's really awesome!

@pfitzseb
Copy link
Author

This is basically the same functionality, but a lot nicer and in package form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment