Skip to content

Commit

Permalink
REPL: enable "redo" after "undo"
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Sep 5, 2017
1 parent ac37603 commit eb42b26
Showing 1 changed file with 47 additions and 6 deletions.
53 changes: 47 additions & 6 deletions base/repl/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ mutable struct PromptState <: ModeState
p::Prompt
input_buffer::IOBuffer
undo_buffers::Vector{IOBuffer}
undo_idx::Int
ias::InputAreaState
# indentation of lines which do not include the prompt
# if negative, the width of the prompt is used
Expand Down Expand Up @@ -1668,7 +1669,8 @@ AnyDict(
# Meta Enter
"\e\r" => (s,o...)->edit_insert_newline(s),
"\e\n" => "\e\r",
"^_" => (s,o...)->(pop_undo(s) ? refresh_line(s) : beep(terminal(s))),
"^_" => (s,o...)->edit_undo!(s),
"\e_" => (s,o...)->edit_redo!(s),
# Simply insert it into the buffer by default
"*" => (s,data,c)->(edit_insert(s, c)),
"^U" => (s,o...)->edit_clear(s),
Expand Down Expand Up @@ -1855,7 +1857,7 @@ end
run_interface(::Prompt) = nothing

init_state(terminal, prompt::Prompt) =
PromptState(terminal, prompt, IOBuffer(), IOBuffer[], InputAreaState(1, 1),
PromptState(terminal, prompt, IOBuffer(), IOBuffer[], 0, InputAreaState(1, 1),
#=indent(spaces)=# -1)

function init_state(terminal, m::ModalInterface)
Expand Down Expand Up @@ -1894,20 +1896,59 @@ position(s::Union{MIState,ModeState}) = position(buffer(s))

function empty_undo(s::PromptState)
empty!(s.undo_buffers)
s.undo_idx = 0
end

empty_undo(s) = nothing

function push_undo(s::PromptState)
push!(s.undo_buffers, copy(s.input_buffer))
resize!(s.undo_buffers, s.undo_idx += 1)
s.undo_buffers[end] = copy(s.input_buffer)
end

push_undo(s) = nothing

# must be called after a push_undo
function pop_undo(s::PromptState)
length(s.undo_buffers) > 0 || return false
s.input_buffer = pop!(s.undo_buffers)
pop!(s.undo_buffers)
s.undo_idx -= 1
end

function edit_undo!(s::MIState)
s.last_action [:edit_redo!, :edit_undo!] && push_undo(s)
if edit_undo!(s.mode_state[s.current_mode])
:edit_undo!
else
s.last_action [:edit_redo!, :edit_undo!] && pop_undo(s)
beep(terminal(s))
:ignore
end
end

function edit_undo!(s::PromptState)
s.undo_idx > 1 || return false
s.input_buffer = s.undo_buffers[s.undo_idx -=1]
refresh_line(s)
true
end
edit_undo!(s) = nothing

function edit_redo!(s::MIState)
if s.last_action [:edit_redo!, :edit_undo!] && edit_redo!(s.mode_state[s.current_mode])
:edit_redo!
else
beep(terminal(s))
:ignore
end
end

function edit_redo!(s::PromptState)
s.undo_idx < length(s.undo_buffers) || return false
s.input_buffer = s.undo_buffers[s.undo_idx += 1]
refresh_line(s)
true
end
pop_undo(s) = nothing
edit_redo!(s) = nothing

keymap(s::PromptState, prompt::Prompt) = prompt.keymap_dict
keymap_data(s::PromptState, prompt::Prompt) = prompt.keymap_func_data
Expand Down

0 comments on commit eb42b26

Please sign in to comment.