diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl index 10236ea3f6d0c..5e09ce730b6c6 100644 --- a/base/repl/LineEdit.jl +++ b/base/repl/LineEdit.jl @@ -205,7 +205,9 @@ const COMMAND_GROUPS = Dict(:movement => [:edit_move_left, :edit_move_right, :edit_move_word_left, :edit_move_word_right, :edit_move_up, :edit_move_down, :edit_exchange_point_and_mark], :deletion => [:edit_clear, :edit_backspace, :edit_delete, :edit_werase, - :edit_delete_prev_word, :edit_delete_next_word, :edit_kill_line, :edit_kill_region], + :edit_delete_prev_word, + :edit_delete_next_word, + :edit_kill_line_forwards, :edit_kill_line_backwards, :edit_kill_region], :insertion => [:edit_insert, :edit_insert_newline, :edit_yank], :replacement => [:edit_yank_pop, :edit_transpose_chars, :edit_transpose_words, :edit_upper_case, :edit_lower_case, :edit_title_case, :edit_indent, @@ -870,21 +872,32 @@ function push_kill!(s::MIState, killed::String, concat = s.key_repeats > 0; rev= true end -function edit_kill_line(s::MIState) - set_action!(s, :edit_kill_line) - push_undo(s) +function edit_kill_line(s::MIState, backwards::Bool=false) buf = buffer(s) - pos = position(buf) - endpos = endofline(buf) - endpos == pos && buf.size > pos && (endpos += 1) - if push_kill!(s, edit_splice!(s, pos => endpos)) + if backwards + set_action!(s, :edit_kill_line_backwards) + pos = beginofline(buf) + endpos = position(buf) + pos == endpos && pos > 0 && (pos -= 1) + else + set_action!(s, :edit_kill_line_forwards) + pos = position(buf) + endpos = endofline(buf) + endpos == pos && buf.size > pos && (endpos += 1) + end + push_undo(s) + if push_kill!(s, edit_splice!(s, pos => endpos); rev=backwards) refresh_line(s) else pop_undo(s) + beep(s) return :ignore end end +edit_kill_line_forwards(s) = edit_kill_line(s, false) +edit_kill_line_backwards(s) = edit_kill_line(s, true) + function edit_copy_region(s::MIState) set_action!(s, :edit_copy_region) buf = buffer(s) @@ -1996,8 +2009,8 @@ AnyDict( "\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), - "^K" => (s,o...)->edit_kill_line(s), + "^U" => (s,o...)->edit_kill_line_backwards(s), + "^K" => (s,o...)->edit_kill_line_forwards(s), "^Y" => (s,o...)->edit_yank(s), "\ey" => (s,o...)->edit_yank_pop(s), "\ew" => (s,o...)->edit_copy_region(s), @@ -2011,16 +2024,19 @@ AnyDict( "^W" => (s,o...)->edit_werase(s), # Meta D "\ed" => (s,o...)->edit_delete_next_word(s), - "^C" => (s,o...)->begin - try # raise the debugger if present - ccall(:jl_raise_debugger, Int, ()) + "^C" => function (s,o...) + if isempty(s) + try # raise the debugger if present + ccall(:jl_raise_debugger, Int, ()) + end + cancel_beep(s) + refresh_line(s) + print(terminal(s), "^C\n\n") + transition(s, :reset) + refresh_line(s) + else + edit_clear(s) end - cancel_beep(s) - move_input_end(s) - refresh_line(s) - print(terminal(s), "^C\n\n") - transition(s, :reset) - refresh_line(s) end, "^Z" => (s,o...)->(return :suspend), # Right Arrow diff --git a/base/repl/REPL.jl b/base/repl/REPL.jl index 3396777cd0a08..c291bd7de8ca4 100644 --- a/base/repl/REPL.jl +++ b/base/repl/REPL.jl @@ -732,12 +732,14 @@ function mode_keymap(julia_prompt::Prompt) end end, "^C" => function (s,o...) - LineEdit.move_input_end(s) - LineEdit.refresh_line(s) - print(LineEdit.terminal(s), "^C\n\n") - transition(s, julia_prompt) - transition(s, :reset) - LineEdit.refresh_line(s) + if isempty(s) + print(LineEdit.terminal(s), "^C\n\n") + transition(s, julia_prompt) + transition(s, :reset) + LineEdit.refresh_line(s) + else + LineEdit.edit_clear(s) + end end) end diff --git a/test/lineedit.jl b/test/lineedit.jl index 0bd04b84694fa..de997ccfbcb98 100644 --- a/test/lineedit.jl +++ b/test/lineedit.jl @@ -649,6 +649,18 @@ end LineEdit.edit_delete_next_word(s) s.key_repeats = 0 @test s.kill_ring[end] == "B C" + + # edit_kill_line_backwards + LineEdit.edit_clear(s) + edit_insert(s, "begin\n a=1\n b=2") + LineEdit.edit_kill_line_backwards(s) + @test s.kill_ring[end] == " b=2" + s.key_repeats = 1 + LineEdit.edit_kill_line_backwards(s) + @test s.kill_ring[end] == "\n b=2" + LineEdit.edit_kill_line_backwards(s) + @test s.kill_ring[end] == " a=1\n b=2" + s.key_repeats = 0 end @testset "undo" begin @@ -696,6 +708,10 @@ end LineEdit.edit_kill_line(s) # no effect @test edit!(edit_undo!) == "one two three" + LineEdit.move_line_end(s) + @test edit!(LineEdit.edit_kill_line_backwards) == "" + @test edit!(edit_undo!) == "one two three" + LineEdit.move_line_start(s) LineEdit.edit_kill_line(s) LineEdit.edit_yank(s)