Skip to content

Commit b9ba7c4

Browse files
committed
REPL: add an Options type to handle REPL options
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
1 parent f58b7ff commit b9ba7c4

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed

base/repl/LineEdit.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mutable struct Prompt <: TextInterface
2727
# Same as prefix except after the prompt
2828
prompt_suffix::Union{String,Function}
2929
keymap_dict::Dict{Char}
30-
keymap_func_data # ::AbstractREPL
30+
repl # ::AbstractREPL
3131
complete # ::REPLCompletionProvider
3232
on_enter::Function
3333
on_done::Function
@@ -75,6 +75,8 @@ mutable struct PromptState <: ModeState
7575
indent::Int
7676
end
7777

78+
options(s::PromptState) = isdefined(s.p, :repl) ? s.p.repl.options : Base.REPL.Options()
79+
7880
setmark(s) = mark(buffer(s))
7981

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

117119
for f in [:terminal, :on_enter, :add_history, :buffer, :(Base.isempty),
118120
:replace_line, :refresh_multi_line, :input_string, :update_display_buffer,
119-
:empty_undo, :push_undo, :pop_undo]
121+
:empty_undo, :push_undo, :pop_undo, :options]
120122
@eval ($f)(s::MIState, args...) = $(f)(state(s), args...)
121123
end
122124

@@ -549,7 +551,8 @@ end
549551
# align: delete up to 4 spaces to align to a multiple of 4 chars
550552
# adjust: also delete spaces on the right of the cursor to try to keep aligned what is
551553
# on the right
552-
function edit_backspace(s::PromptState, align::Bool=false, adjust=align)
554+
function edit_backspace(s::PromptState, align::Bool=options(s).backspace_align,
555+
adjust=options(s).backspace_adjust)
553556
push_undo(s)
554557
if edit_backspace(buffer(s), align, adjust)
555558
refresh_line(s)
@@ -571,7 +574,7 @@ function endofline(buf, pos=position(buf))
571574
eol == 0 ? buf.size : pos + eol - 1
572575
end
573576

574-
function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=align)
577+
function edit_backspace(buf::IOBuffer, align::Bool=false, adjust::Bool=false)
575578
!align && adjust &&
576579
throw(DomainError((align, adjust),
577580
"if `adjust` is `true`, `align` must be `true`"))
@@ -1649,7 +1652,7 @@ AnyDict(
16491652
end,
16501653
'\n' => KeyAlias('\r'),
16511654
# Backspace/^H
1652-
'\b' => (s,o...)->edit_backspace(s, true),
1655+
'\b' => (s,o...)->edit_backspace(s),
16531656
127 => KeyAlias('\b'),
16541657
# Meta Backspace
16551658
"\e\b" => (s,o...)->edit_delete_prev_word(s),
@@ -1860,14 +1863,14 @@ function Prompt(prompt;
18601863
prompt_prefix = "",
18611864
prompt_suffix = "",
18621865
keymap_dict = default_keymap_dict,
1863-
keymap_func_data = nothing,
1866+
repl = nothing,
18641867
complete = EmptyCompletionProvider(),
18651868
on_enter = default_enter_cb,
18661869
on_done = ()->nothing,
18671870
hist = EmptyHistoryProvider(),
18681871
sticky = false)
18691872

1870-
Prompt(prompt, prompt_prefix, prompt_suffix, keymap_dict, keymap_func_data,
1873+
Prompt(prompt, prompt_prefix, prompt_suffix, keymap_dict, repl,
18711874
complete, on_enter, on_done, hist, sticky)
18721875
end
18731876

@@ -1968,7 +1971,7 @@ end
19681971
edit_redo!(s) = nothing
19691972

19701973
keymap(s::PromptState, prompt::Prompt) = prompt.keymap_dict
1971-
keymap_data(s::PromptState, prompt::Prompt) = prompt.keymap_func_data
1974+
keymap_data(s::PromptState, prompt::Prompt) = prompt.repl
19721975
keymap(ms::MIState, m::ModalInterface) = keymap(state(ms), mode(ms))
19731976
keymap_data(ms::MIState, m::ModalInterface) = keymap_data(state(ms), mode(ms))
19741977

base/repl/REPL.jl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,16 @@ function run_frontend(repl::BasicREPL, backend::REPLBackendRef)
241241
dopushdisplay && popdisplay(d)
242242
end
243243

244+
## Custom Options
245+
246+
mutable struct Options
247+
backspace_align::Bool
248+
backspace_adjust::Bool
249+
end
250+
251+
Options(; backspace_align=true, backspace_adjust=backspace_align) =
252+
Options(backspace_align, backspace_adjust)
253+
244254
## LineEditREPL ##
245255

246256
mutable struct LineEditREPL <: AbstractREPL
@@ -257,11 +267,12 @@ mutable struct LineEditREPL <: AbstractREPL
257267
envcolors::Bool
258268
waserror::Bool
259269
specialdisplay::Union{Void,Display}
270+
options::Options
260271
interface::ModalInterface
261272
backendref::REPLBackendRef
262273
LineEditREPL(t,hascolor,prompt_color,input_color,answer_color,shell_color,help_color,history_file,in_shell,in_help,envcolors) =
263274
new(t,true,prompt_color,input_color,answer_color,shell_color,help_color,history_file,in_shell,
264-
in_help,envcolors,false,nothing)
275+
in_help,envcolors,false,nothing, Options())
265276
end
266277
outstream(r::LineEditREPL) = r.t
267278
specialdisplay(r::LineEditREPL) = r.specialdisplay
@@ -741,7 +752,7 @@ function setup_interface(
741752
prompt_prefix = hascolor ? repl.prompt_color : "",
742753
prompt_suffix = hascolor ?
743754
(repl.envcolors ? Base.input_color : repl.input_color) : "",
744-
keymap_func_data = repl,
755+
repl = repl,
745756
complete = replc,
746757
on_enter = return_callback)
747758

@@ -750,7 +761,7 @@ function setup_interface(
750761
prompt_prefix = hascolor ? repl.help_color : "",
751762
prompt_suffix = hascolor ?
752763
(repl.envcolors ? Base.input_color : repl.input_color) : "",
753-
keymap_func_data = repl,
764+
repl = repl,
754765
complete = replc,
755766
# When we're done transform the entered line into a call to help("$line")
756767
on_done = respond(Docs.helpmode, repl, julia_prompt))
@@ -760,7 +771,7 @@ function setup_interface(
760771
prompt_prefix = hascolor ? repl.shell_color : "",
761772
prompt_suffix = hascolor ?
762773
(repl.envcolors ? Base.input_color : repl.input_color) : "",
763-
keymap_func_data = repl,
774+
repl = repl,
764775
complete = ShellCompletionProvider(),
765776
# Transform "foo bar baz" into `foo bar baz` (shell quoting)
766777
# and pass into Base.repl_cmd for processing (handles `ls` and `cd`

test/lineedit.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ let buf = IOBuffer()
330330
@test position(buf) == 0
331331
LineEdit.edit_move_right(buf)
332332
@test nb_available(buf) == 0
333-
LineEdit.edit_backspace(buf)
333+
LineEdit.edit_backspace(buf, false, false)
334334
@test content(buf) == "a"
335335
end
336336

@@ -699,9 +699,9 @@ end
699699
@test edit!(edit_undo!) == "one two three"
700700

701701
LineEdit.move_line_end(s)
702-
LineEdit.edit_backspace(s)
703-
LineEdit.edit_backspace(s)
704-
@test edit!(LineEdit.edit_backspace) == "one two th"
702+
LineEdit.edit_backspace(s, false, false)
703+
LineEdit.edit_backspace(s, false, false)
704+
@test edit!(s->LineEdit.edit_backspace(s, false, false)) == "one two th"
705705
@test edit!(edit_undo!) == "one two thr"
706706
@test edit!(edit_undo!) == "one two thre"
707707
@test edit!(edit_undo!) == "one two three"

0 commit comments

Comments
 (0)