From 4f317ce6d7b283634d0ad0419e8afb61a906edd5 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Sun, 16 Jul 2017 08:47:04 +0200 Subject: [PATCH] REPL: jump to first/last history entries --- base/repl/LineEdit.jl | 6 +++++- base/repl/REPL.jl | 28 ++++++++++++++++++++-------- test/repl.jl | 14 ++++++++++++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/base/repl/LineEdit.jl b/base/repl/LineEdit.jl index 05802bb6cc747..7d49eb64918f2 100644 --- a/base/repl/LineEdit.jl +++ b/base/repl/LineEdit.jl @@ -588,6 +588,8 @@ end history_prev(::EmptyHistoryProvider) = ("", false) history_next(::EmptyHistoryProvider) = ("", false) +history_first(::EmptyHistoryProvider) = ("", false) +history_last(::EmptyHistoryProvider) = ("", false) history_search(::EmptyHistoryProvider, args...) = false add_history(::EmptyHistoryProvider, s) = nothing add_history(s::PromptState) = add_history(mode(s).hist, s) @@ -1443,7 +1445,9 @@ const history_keymap = AnyDict( # Page Up "\e[5~" => (s,o...)->(history_prev(s, mode(s).hist)), # Page Down - "\e[6~" => (s,o...)->(history_next(s, mode(s).hist)) + "\e[6~" => (s,o...)->(history_next(s, mode(s).hist)), + "\e<" => (s,o...)->(history_first(s, mode(s).hist)), + "\e>" => (s,o...)->(history_last(s, mode(s).hist)), ) const prefix_history_keymap = merge!( diff --git a/base/repl/REPL.jl b/base/repl/REPL.jl index ca6c38afabe6a..83e9e9feeaf66 100644 --- a/base/repl/REPL.jl +++ b/base/repl/REPL.jl @@ -29,6 +29,8 @@ import ..LineEdit: history_next_prefix, history_prev, history_prev_prefix, + history_first, + history_last, history_search, accept_result, terminal @@ -463,9 +465,10 @@ function LineEdit.accept_result(s, p::LineEdit.HistoryPrompt{REPLHistoryProvider end function history_prev(s::LineEdit.MIState, hist::REPLHistoryProvider, - save_idx::Int = hist.cur_idx) + num::Int=1, save_idx::Int = hist.cur_idx) + num <= 0 && history_next(s, hist, -num, save_idx) hist.last_idx = -1 - m = history_move(s, hist, hist.cur_idx-1, save_idx) + m = history_move(s, hist, hist.cur_idx-num, save_idx) if m === :ok LineEdit.move_input_start(s) LineEdit.reset_key_repeats(s) do @@ -473,15 +476,19 @@ function history_prev(s::LineEdit.MIState, hist::REPLHistoryProvider, end LineEdit.refresh_line(s) elseif m === :skip - hist.cur_idx -= 1 - history_prev(s, hist, save_idx) + history_prev(s, hist, num+1, save_idx) else Terminals.beep(LineEdit.terminal(s)) end end function history_next(s::LineEdit.MIState, hist::REPLHistoryProvider, - save_idx::Int = hist.cur_idx) + num::Int=1, save_idx::Int = hist.cur_idx) + if num == 0 + Terminals.beep(LineEdit.terminal(s)) + return + end + num < 0 && history_prev(s, hist, -num, save_idx) cur_idx = hist.cur_idx max_idx = length(hist.history) + 1 if cur_idx == max_idx && 0 < hist.last_idx @@ -489,18 +496,23 @@ function history_next(s::LineEdit.MIState, hist::REPLHistoryProvider, cur_idx = hist.last_idx hist.last_idx = -1 end - m = history_move(s, hist, cur_idx+1, save_idx) + m = history_move(s, hist, cur_idx+num, save_idx) if m === :ok LineEdit.move_input_end(s) LineEdit.refresh_line(s) elseif m === :skip - hist.cur_idx += 1 - history_next(s, hist, save_idx) + history_next(s, hist, num+1, save_idx) else Terminals.beep(LineEdit.terminal(s)) end end +history_first(s::LineEdit.MIState, hist::REPLHistoryProvider) = + history_prev(s, hist, hist.cur_idx - 1) + +history_last(s::LineEdit.MIState, hist::REPLHistoryProvider) = + history_next(s, hist, length(hist.history) - hist.cur_idx + 1) + function history_move_prefix(s::LineEdit.PrefixSearchState, hist::REPLHistoryProvider, prefix::AbstractString, diff --git a/test/repl.jl b/test/repl.jl index 5fb4d2655dd9e..802659d457182 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -336,6 +336,20 @@ begin @test LineEdit.mode(s) == repl_mode @test buffercontents(LineEdit.buffer(s)) == "wip" @test position(LineEdit.buffer(s)) == 3 + LineEdit.history_next(s, hp) + @test buffercontents(LineEdit.buffer(s)) == "wip" + LineEdit.history_prev(s, hp, 2) + @test LineEdit.mode(s) == shell_mode + @test buffercontents(LineEdit.buffer(s)) == "ls" + LineEdit.history_first(s, hp) + @test LineEdit.mode(s) == repl_mode + @test buffercontents(LineEdit.buffer(s)) == "é" + LineEdit.history_next(s, hp, 6) + @test LineEdit.mode(s) == shell_mode + @test buffercontents(LineEdit.buffer(s)) == "ls" + LineEdit.history_last(s, hp) + @test buffercontents(LineEdit.buffer(s)) == "wip" + @test position(LineEdit.buffer(s)) == 3 LineEdit.move_line_start(s) @test position(LineEdit.buffer(s)) == 0