Skip to content

Commit

Permalink
REPL: add an Options type to handle REPL options
Browse files Browse the repository at this point in the history
It was previously not practical to disable the "align"
feature of backspace: overwriting the '\b' binding with:
`'\b' => (s,o...) -> Base.LineEdit.edit_backspace(s, false)`
worked to a certain extent, but for example it was disabling
the feature that '\b' must get you out of shell/help mode.

A new experimental Options type is introduced here, which is
meant to conveniently allow users to pass options controlling
the REPL behavior. For example:

atreplinit() do repl
    repl.options = Base.REPL.Options(backspace_align = false)
end
  • Loading branch information
rfourquet committed Sep 8, 2017
1 parent f58b7ff commit b9ba7c4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
19 changes: 11 additions & 8 deletions base/repl/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ mutable struct Prompt <: TextInterface
# Same as prefix except after the prompt
prompt_suffix::Union{String,Function}
keymap_dict::Dict{Char}
keymap_func_data # ::AbstractREPL
repl # ::AbstractREPL
complete # ::REPLCompletionProvider
on_enter::Function
on_done::Function
Expand Down Expand Up @@ -75,6 +75,8 @@ mutable struct PromptState <: ModeState
indent::Int
end

options(s::PromptState) = isdefined(s.p, :repl) ? s.p.repl.options : Base.REPL.Options()

setmark(s) = mark(buffer(s))

# the default mark is 0
Expand Down Expand Up @@ -116,7 +118,7 @@ terminal(s::PromptState) = s.terminal

for f in [:terminal, :on_enter, :add_history, :buffer, :(Base.isempty),
:replace_line, :refresh_multi_line, :input_string, :update_display_buffer,
:empty_undo, :push_undo, :pop_undo]
:empty_undo, :push_undo, :pop_undo, :options]
@eval ($f)(s::MIState, args...) = $(f)(state(s), args...)
end

Expand Down Expand Up @@ -549,7 +551,8 @@ end
# align: delete up to 4 spaces to align to a multiple of 4 chars
# adjust: also delete spaces on the right of the cursor to try to keep aligned what is
# on the right
function edit_backspace(s::PromptState, align::Bool=false, adjust=align)
function edit_backspace(s::PromptState, align::Bool=options(s).backspace_align,
adjust=options(s).backspace_adjust)
push_undo(s)
if edit_backspace(buffer(s), align, adjust)
refresh_line(s)
Expand All @@ -571,7 +574,7 @@ function endofline(buf, pos=position(buf))
eol == 0 ? buf.size : pos + eol - 1
end

function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=align)
function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=false)
!align && adjust &&
throw(DomainError((align, adjust),
"if `adjust` is `true`, `align` must be `true`"))
Expand Down Expand Up @@ -1649,7 +1652,7 @@ AnyDict(
end,
'\n' => KeyAlias('\r'),
# Backspace/^H
'\b' => (s,o...)->edit_backspace(s, true),
'\b' => (s,o...)->edit_backspace(s),
127 => KeyAlias('\b'),
# Meta Backspace
"\e\b" => (s,o...)->edit_delete_prev_word(s),
Expand Down Expand Up @@ -1860,14 +1863,14 @@ function Prompt(prompt;
prompt_prefix = "",
prompt_suffix = "",
keymap_dict = default_keymap_dict,
keymap_func_data = nothing,
repl = nothing,
complete = EmptyCompletionProvider(),
on_enter = default_enter_cb,
on_done = ()->nothing,
hist = EmptyHistoryProvider(),
sticky = false)

Prompt(prompt, prompt_prefix, prompt_suffix, keymap_dict, keymap_func_data,
Prompt(prompt, prompt_prefix, prompt_suffix, keymap_dict, repl,
complete, on_enter, on_done, hist, sticky)
end

Expand Down Expand Up @@ -1968,7 +1971,7 @@ end
edit_redo!(s) = nothing

keymap(s::PromptState, prompt::Prompt) = prompt.keymap_dict
keymap_data(s::PromptState, prompt::Prompt) = prompt.keymap_func_data
keymap_data(s::PromptState, prompt::Prompt) = prompt.repl
keymap(ms::MIState, m::ModalInterface) = keymap(state(ms), mode(ms))
keymap_data(ms::MIState, m::ModalInterface) = keymap_data(state(ms), mode(ms))

Expand Down
19 changes: 15 additions & 4 deletions base/repl/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,16 @@ function run_frontend(repl::BasicREPL, backend::REPLBackendRef)
dopushdisplay && popdisplay(d)
end

## Custom Options

mutable struct Options
backspace_align::Bool
backspace_adjust::Bool
end

Options(; backspace_align=true, backspace_adjust=backspace_align) =
Options(backspace_align, backspace_adjust)

## LineEditREPL ##

mutable struct LineEditREPL <: AbstractREPL
Expand All @@ -257,11 +267,12 @@ mutable struct LineEditREPL <: AbstractREPL
envcolors::Bool
waserror::Bool
specialdisplay::Union{Void,Display}
options::Options
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,true,prompt_color,input_color,answer_color,shell_color,help_color,history_file,in_shell,
in_help,envcolors,false,nothing)
in_help,envcolors,false,nothing, Options())
end
outstream(r::LineEditREPL) = r.t
specialdisplay(r::LineEditREPL) = r.specialdisplay
Expand Down Expand Up @@ -741,7 +752,7 @@ function setup_interface(
prompt_prefix = hascolor ? repl.prompt_color : "",
prompt_suffix = hascolor ?
(repl.envcolors ? Base.input_color : repl.input_color) : "",
keymap_func_data = repl,
repl = repl,
complete = replc,
on_enter = return_callback)

Expand All @@ -750,7 +761,7 @@ function setup_interface(
prompt_prefix = hascolor ? repl.help_color : "",
prompt_suffix = hascolor ?
(repl.envcolors ? Base.input_color : repl.input_color) : "",
keymap_func_data = repl,
repl = repl,
complete = replc,
# When we're done transform the entered line into a call to help("$line")
on_done = respond(Docs.helpmode, repl, julia_prompt))
Expand All @@ -760,7 +771,7 @@ function setup_interface(
prompt_prefix = hascolor ? repl.shell_color : "",
prompt_suffix = hascolor ?
(repl.envcolors ? Base.input_color : repl.input_color) : "",
keymap_func_data = repl,
repl = repl,
complete = ShellCompletionProvider(),
# Transform "foo bar baz" into `foo bar baz` (shell quoting)
# and pass into Base.repl_cmd for processing (handles `ls` and `cd`
Expand Down
8 changes: 4 additions & 4 deletions test/lineedit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ let buf = IOBuffer()
@test position(buf) == 0
LineEdit.edit_move_right(buf)
@test nb_available(buf) == 0
LineEdit.edit_backspace(buf)
LineEdit.edit_backspace(buf, false, false)
@test content(buf) == "a"
end

Expand Down Expand Up @@ -699,9 +699,9 @@ end
@test edit!(edit_undo!) == "one two three"

LineEdit.move_line_end(s)
LineEdit.edit_backspace(s)
LineEdit.edit_backspace(s)
@test edit!(LineEdit.edit_backspace) == "one two th"
LineEdit.edit_backspace(s, false, false)
LineEdit.edit_backspace(s, false, false)
@test edit!(s->LineEdit.edit_backspace(s, false, false)) == "one two th"
@test edit!(edit_undo!) == "one two thr"
@test edit!(edit_undo!) == "one two thre"
@test edit!(edit_undo!) == "one two three"
Expand Down

0 comments on commit b9ba7c4

Please sign in to comment.