Skip to content

Commit

Permalink
REPL: more deleted words pushed into the kill ring (JuliaLang#23593)
Browse files Browse the repository at this point in the history
The two ways of deleting the previous word, deleting
the next word and clearing the space now hook into the
kill ring. Implements item 2 of JuliaLang#8447.
  • Loading branch information
rfourquet committed Sep 8, 2017
1 parent 22987e3 commit 172f36e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 23 deletions.
48 changes: 30 additions & 18 deletions base/repl/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -621,45 +621,54 @@ function edit_werase(buf::IOBuffer)
pos1 = position(buf)
char_move_word_left(buf, isspace)
pos0 = position(buf)
pos0 < pos1 || return false
edit_splice!(buf, pos0 => pos1)
true
end

function edit_werase(s::MIState)
push_undo(s)
edit_werase(buffer(s)) ? refresh_line(s) : pop_undo(s)
:edit_werase
if push_kill!(s, edit_werase(buffer(s)), rev=true)
refresh_line(s)
:edit_werase
else
pop_undo(s)
:ignore
end
end

function edit_delete_prev_word(buf::IOBuffer)
pos1 = position(buf)
char_move_word_left(buf)
pos0 = position(buf)
pos0 < pos1 || return false
edit_splice!(buf, pos0 => pos1)
true
end

function edit_delete_prev_word(s::MIState)
push_undo(s)
edit_delete_prev_word(buffer(s)) ? refresh_line(s) : pop_undo(s)
:edit_delete_prev_word
if push_kill!(s, edit_delete_prev_word(buffer(s)), rev=true)
refresh_line(s)
:edit_delete_prev_word
else
pop_undo(s)
:ignore
end
end

function edit_delete_next_word(buf::IOBuffer)
pos0 = position(buf)
char_move_word_right(buf)
pos1 = position(buf)
pos0 < pos1 || return false
edit_splice!(buf, pos0 => pos1)
true
end

function edit_delete_next_word(s)
push_undo(s)
edit_delete_next_word(buffer(s)) ? refresh_line(s) : pop_undo(s)
:edit_delete_next_word
if push_kill!(s, edit_delete_next_word(buffer(s)))
refresh_line(s)
:edit_delete_next_word
else
pop_undo(s)
:ignore
end
end

function edit_yank(s::MIState)
Expand Down Expand Up @@ -687,10 +696,12 @@ function edit_yank_pop(s::MIState, require_previous_yank=true)
end
end

function push_kill!(s::MIState, killed::String, concat=false)
function push_kill!(s::MIState, killed::String, concat = s.key_repeats > 0; rev=false)
isempty(killed) && return false
if concat
s.kill_ring[end] *= killed
if concat && !isempty(s.kill_ring)
s.kill_ring[end] = rev ?
killed * s.kill_ring[end] : # keep expected order for backward deletion
s.kill_ring[end] * killed
else
push!(s.kill_ring, killed)
length(s.kill_ring) > KILL_RING_MAX[] && shift!(s.kill_ring)
Expand All @@ -708,15 +719,15 @@ function edit_kill_line(s::MIState)
killbuf = killbuf[1:end-1]
char_move_left(buf)
end
push_kill!(s, killbuf, s.key_repeats > 0) || return :ignore
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)
buf = buffer(s)
push_kill!(s, content(buf, region(buf))) || return :ignore
push_kill!(s, content(buf, region(buf)), false) || return :ignore
if REGION_ANIMATION_DURATION[] > 0.0
edit_exchange_point_and_mark(s)
sleep(REGION_ANIMATION_DURATION[])
Expand All @@ -727,7 +738,7 @@ end

function edit_kill_region(s::MIState)
push_undo(s)
if push_kill!(s, edit_splice!(s))
if push_kill!(s, edit_splice!(s), false)
refresh_line(s)
:edit_kill_region
else
Expand Down Expand Up @@ -807,6 +818,7 @@ 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
Expand Down
33 changes: 28 additions & 5 deletions test/lineedit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,14 @@ seek(buf,0)

buf = IOBuffer("type X\n ")
seekend(buf)
@test LineEdit.edit_delete_prev_word(buf)
@test !isempty(LineEdit.edit_delete_prev_word(buf))
@test position(buf) == 5
@test buf.size == 5
@test content(buf) == "type "

buf = IOBuffer("4 +aaa+ x")
seek(buf,8)
@test LineEdit.edit_delete_prev_word(buf)
@test !isempty(LineEdit.edit_delete_prev_word(buf))
@test position(buf) == 3
@test buf.size == 4
@test content(buf) == "4 +x"
Expand All @@ -316,11 +316,11 @@ buf = IOBuffer("x = func(arg1,arg2 , arg3)")
seekend(buf)
LineEdit.char_move_word_left(buf)
@test position(buf) == 21
@test LineEdit.edit_delete_prev_word(buf)
@test !isempty(LineEdit.edit_delete_prev_word(buf))
@test content(buf) == "x = func(arg1,arg3)"
@test LineEdit.edit_delete_prev_word(buf)
@test !isempty(LineEdit.edit_delete_prev_word(buf))
@test content(buf) == "x = func(arg3)"
@test LineEdit.edit_delete_prev_word(buf)
@test !isempty(LineEdit.edit_delete_prev_word(buf))
@test content(buf) == "x = arg3)"

# Unicode combining characters
Expand Down Expand Up @@ -617,6 +617,29 @@ end
LineEdit.edit_kill_line(s)
@test s.kill_ring[end] == "çhing"
@test s.kill_idx == 3
# repetition (concatenation of killed strings
edit_insert(s, "A B C")
LineEdit.edit_delete_prev_word(s)
s.key_repeats = 1
LineEdit.edit_delete_prev_word(s)
s.key_repeats = 0
@test s.kill_ring[end] == "B C"
LineEdit.edit_yank(s)
LineEdit.edit_werase(s)
@test s.kill_ring[end] == "C"
s.key_repeats = 1
LineEdit.edit_werase(s)
s.key_repeats = 0
@test s.kill_ring[end] == "B C"
LineEdit.edit_yank(s)
LineEdit.edit_move_word_left(s)
LineEdit.edit_move_word_left(s)
LineEdit.edit_delete_next_word(s)
@test s.kill_ring[end] == "B"
s.key_repeats = 1
LineEdit.edit_delete_next_word(s)
s.key_repeats = 0
@test s.kill_ring[end] == "B C"
end

@testset "undo" begin
Expand Down

0 comments on commit 172f36e

Please sign in to comment.