Skip to content

Commit

Permalink
Merge pull request JuliaLang#23653 from JuliaLang/rf/undo-less
Browse files Browse the repository at this point in the history
REPL: don't record some no-op actions in "undo"
  • Loading branch information
rfourquet committed Sep 19, 2017
2 parents e34dba1 + 553fcdd commit 42761d5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
49 changes: 29 additions & 20 deletions base/repl/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ const Region = Pair{<:Integer,<:Integer}
_region(s) = getmark(s) => position(s)
region(s) = Pair(extrema(_region(s))...)

bufend(s) = buffer(s).size

indexes(reg::Region) = first(reg)+1:last(reg)

content(s, reg::Region = 0=>buffer(s).size) = String(buffer(s).data[indexes(reg)])
content(s, reg::Region = 0=>bufend(s)) = String(buffer(s).data[indexes(reg)])

const REGION_ANIMATION_DURATION = Ref(0.2)

Expand Down Expand Up @@ -769,15 +771,15 @@ function edit_kill_line(s::MIState)
push_undo(s)
buf = buffer(s)
pos = position(buf)
killbuf = readline(buf, chomp=false)
if length(killbuf) > 1 && killbuf[end] == '\n'
killbuf = killbuf[1:end-1]
char_move_left(buf)
endpos = endofline(buf)
endpos == pos && buf.size > pos && (endpos += 1)
if push_kill!(s, edit_splice!(s, pos => endpos))
refresh_line(s)
:edit_kill_line
else
pop_undo(s)
:ignore
end
push_kill!(s, killbuf) || return :ignore
edit_splice!(buf, pos => position(buf))
refresh_line(s)
:edit_kill_line
end

function edit_copy_region(s::MIState)
Expand Down Expand Up @@ -873,10 +875,13 @@ edit_clear(buf::IOBuffer) = truncate(buf, 0)

function edit_clear(s::MIState)
push_undo(s)
push_kill!(s, content(s), false) || return :ignore
edit_clear(buffer(s))
refresh_line(s)
:edit_clear
if push_kill!(s, edit_splice!(s, 0 => bufend(s)), false)
refresh_line(s)
:edit_clear
else
pop_undo(s)
:ignore
end
end

function replace_line(s::PromptState, l::IOBuffer)
Expand Down Expand Up @@ -1512,12 +1517,12 @@ function setup_search_keymap(hp)
update_display_buffer(s, data) : beep(s)),
127 => KeyAlias('\b'),
# Meta Backspace
"\e\b" => (s,data,c)->(edit_delete_prev_word(data.query_buffer) ?
update_display_buffer(s, data) : beep(s)),
"\e\b" => (s,data,c)->(isempty(edit_delete_prev_word(data.query_buffer)) ?
beep(s) : update_display_buffer(s, data)),
"\e\x7f" => "\e\b",
# Word erase to whitespace
"^W" => (s,data,c)->(edit_werase(data.query_buffer) ?
update_display_buffer(s, data) : beep(s)),
"^W" => (s,data,c)->(isempty(edit_werase(data.query_buffer)) ?
beep(s) : update_display_buffer(s, data)),
# ^C and ^D
"^C" => (s,data,c)->(edit_clear(data.query_buffer);
edit_clear(data.response_buffer);
Expand Down Expand Up @@ -1669,12 +1674,14 @@ function edit_tab(s::MIState, jump_spaces=false, delete_trailing=jump_spaces)
complete_line(s)
else
push_undo(s)
edit_insert_tab(buffer(s), jump_spaces, delete_trailing)
edit_insert_tab(buffer(s), jump_spaces, delete_trailing) || pop_undo(s)
refresh_line(s)
:edit_insert_tab
end
end

# return true iff the content of the buffer is modified
# return false when only the position changed
function edit_insert_tab(buf::IOBuffer, jump_spaces=false, delete_trailing=jump_spaces)
i = position(buf)
if jump_spaces && i < buf.size && buf.data[i+1] == _space
Expand All @@ -1683,12 +1690,14 @@ function edit_insert_tab(buf::IOBuffer, jump_spaces=false, delete_trailing=jump_
edit_splice!(buf, i => (spaces == 0 ? buf.size : i+spaces-1))
else
jump = spaces == 0 ? buf.size : i+spaces-1
return seek(buf, jump)
seek(buf, jump)
return false
end
end
# align to multiples of 4:
align = 4 - strwidth(String(buf.data[1+beginofline(buf, i):i])) % 4
return edit_insert(buf, ' '^align)
edit_insert(buf, ' '^align)
return true
end


Expand Down
11 changes: 11 additions & 0 deletions test/lineedit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ end
@test edit!(edit_undo!) == "one two three"

@test edit!(LineEdit.edit_clear) == ""
@test edit!(LineEdit.edit_clear) == "" # should not be saved twice
@test edit!(edit_undo!) == "one two three"

@test edit!(LineEdit.edit_insert_newline) == "one two three\n"
Expand All @@ -686,6 +687,11 @@ end
LineEdit.move_line_start(s)
@test edit!(LineEdit.edit_kill_line) == ""
@test edit!(edit_undo!) == "one two three"
# undo stack not updated if killing nothing:
LineEdit.move_line_start(s)
LineEdit.edit_kill_line(s)
LineEdit.edit_kill_line(s) # no effect
@test edit!(edit_undo!) == "one two three"

LineEdit.move_line_start(s)
LineEdit.edit_kill_line(s)
Expand Down Expand Up @@ -749,6 +755,11 @@ end
@test edit!(LineEdit.edit_tab) == "one two three "
@test edit!(edit_undo!) == "one two three "
@test edit!(edit_undo!) == "one two three"
LineEdit.move_line_start(s)
edit_insert(s, " ")
LineEdit.move_line_start(s)
@test edit!(s->LineEdit.edit_tab(s, true, true)) == " one two three" # tab moves cursor to position 2
@test edit!(edit_undo!) == "one two three" # undo didn't record cursor movement
# TODO: add tests for complete_line, which don't work directly

# pop initial insert of "one two three"
Expand Down

0 comments on commit 42761d5

Please sign in to comment.