From 31ca9a758e66e1915123c7ba732576e587a0e859 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Sun, 3 Sep 2017 15:46:02 +0200 Subject: [PATCH] REPL: more deleted words pushed into the kill ring 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 #8447. --- base/repl/LineEdit.jl | 50 +++++++++++++++++++++++++++---------------- test/lineedit.jl | 35 ++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl index a2fa7e245e796..f4eace2db352b 100644 --- a/base/repl/LineEdit.jl +++ b/base/repl/LineEdit.jl @@ -620,45 +620,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) @@ -686,10 +695,14 @@ 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) + if rev # keep expected order for edit_werase & edit_delete_prev_word + s.kill_ring[end] = killed * s.kill_ring[end] + else + s.kill_ring[end] *= killed + end else push!(s.kill_ring, killed) length(s.kill_ring) > KILL_RING_MAX[] && shift!(s.kill_ring) @@ -707,7 +720,7 @@ 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 @@ -715,7 +728,7 @@ 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[]) @@ -725,7 +738,7 @@ function edit_copy_region(s::MIState) end function edit_kill_region(s::MIState) - push_kill!(s, edit_splice!(s)) || return :ignore + push_kill!(s, edit_splice!(s), false) || return :ignore push_undo(s) refresh_line(s) :edit_kill_region @@ -802,6 +815,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 diff --git a/test/lineedit.jl b/test/lineedit.jl index 194a6b4d676c8..fd8bf308f6539 100644 --- a/test/lineedit.jl +++ b/test/lineedit.jl @@ -297,14 +297,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" @@ -313,11 +313,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 @@ -607,12 +607,35 @@ end # next action will fail, as yank-pop doesn't know a yank was just issued @test transform!(LineEdit.edit_yank_pop, s) == ("a ≡ notçhing", 7, 0) s.last_action = :edit_yank - # not this should work: + # now this should work: @test transform!(LineEdit.edit_yank_pop, s) == ("ça ≡ nothingçhing", 12, 0) @test s.kill_idx == 1 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