Skip to content

Commit

Permalink
REPL: don't record some no-op actions in "undo"
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Sep 10, 2017
1 parent 8c2fc37 commit bee2f92
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 16 deletions.
41 changes: 25 additions & 16 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 @@ -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 @@ -669,6 +669,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 @@ -684,6 +685,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 @@ -747,6 +753,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 bee2f92

Please sign in to comment.