diff --git a/base/repl/REPL.jl b/base/repl/REPL.jl index 4309a83efb7e1..8c69a4e860ce3 100644 --- a/base/repl/REPL.jl +++ b/base/repl/REPL.jl @@ -507,7 +507,8 @@ function history_next(s::LineEdit.MIState, hist::REPLHistoryProvider, end history_first(s::LineEdit.MIState, hist::REPLHistoryProvider) = - history_prev(s, hist, hist.cur_idx - 1) + history_prev(s, hist, hist.cur_idx - 1 - + (hist.cur_idx > hist.start_idx+1 ? hist.start_idx : 0)) history_last(s::LineEdit.MIState, hist::REPLHistoryProvider) = history_next(s, hist, length(hist.history) - hist.cur_idx + 1) diff --git a/doc/src/manual/interacting-with-julia.md b/doc/src/manual/interacting-with-julia.md index 515a640dad5d8..c8ba66d6236f5 100644 --- a/doc/src/manual/interacting-with-julia.md +++ b/doc/src/manual/interacting-with-julia.md @@ -139,41 +139,41 @@ control-key, there are also meta-key bindings. These vary more by platform, but default to using alt- or option- held down with a key to send the meta-key (or can be configured to do so). -| Keybinding | Description | -|:------------------- |:------------------------------------------------------------------------------------------ | -| **Program control** |   | -| `^D` | Exit (when buffer is empty) | -| `^C` | Interrupt or cancel | -| `^L` | Clear console screen | -| Return/Enter, `^J` | New line, executing if it is complete | -| meta-Return/Enter | Insert new line without executing it | -| `?` or `;` | Enter help or shell mode (when at start of a line) | -| `^R`, `^S` | Incremental history search, described above | -| **Cursor movement** |   | -| Right arrow, `^F` | Move right one character | -| Left arrow, `^B` | Move left one character | -| Home, `^A` | Move to beginning of line | -| End, `^E` | Move to end of line | -| `^P` | Change to the previous or next history entry | -| `^N` | Change to the next history entry | -| Up arrow | Move up one line (or to the previous history entry) | -| Down arrow | Move down one line (or to the next history entry) | -| Page-up | Change to the previous history entry that matches the text before the cursor | -| Page-down | Change to the next history entry that matches the text before the cursor | -| `meta-F` | Move right one word | -| `meta-B` | Move left one word | -| `meta-<` | Change to the first history entry | -| `meta->` | Change to the last history entry | -| **Editing** |   | -| Backspace, `^H` | Delete the previous character | -| Delete, `^D` | Forward delete one character (when buffer has text) | -| meta-Backspace | Delete the previous word | -| `meta-D` | Forward delete the next word | -| `^W` | Delete previous text up to the nearest whitespace | -| `^K` | "Kill" to end of line, placing the text in a buffer | -| `^Y` | "Yank" insert the text from the kill buffer | -| `^T` | Transpose the characters about the cursor | -| `^Q` | Write a number in REPL and press `^Q` to open editor at corresponding stackframe or method | +| Keybinding | Description | +|:------------------- |:---------------------------------------------------------------------------------------------------------- | +| **Program control** |   | +| `^D` | Exit (when buffer is empty) | +| `^C` | Interrupt or cancel | +| `^L` | Clear console screen | +| Return/Enter, `^J` | New line, executing if it is complete | +| meta-Return/Enter | Insert new line without executing it | +| `?` or `;` | Enter help or shell mode (when at start of a line) | +| `^R`, `^S` | Incremental history search, described above | +| **Cursor movement** |   | +| Right arrow, `^F` | Move right one character | +| Left arrow, `^B` | Move left one character | +| Home, `^A` | Move to beginning of line | +| End, `^E` | Move to end of line | +| `^P` | Change to the previous or next history entry | +| `^N` | Change to the next history entry | +| Up arrow | Move up one line (or to the previous history entry) | +| Down arrow | Move down one line (or to the next history entry) | +| Page-up | Change to the previous history entry that matches the text before the cursor | +| Page-down | Change to the next history entry that matches the text before the cursor | +| `meta-F` | Move right one word | +| `meta-B` | Move left one word | +| `meta-<` | Change to the first history entry (of the current session if it is before the current position in history) | +| `meta->` | Change to the last history entry | +| **Editing** |   | +| Backspace, `^H` | Delete the previous character | +| Delete, `^D` | Forward delete one character (when buffer has text) | +| meta-Backspace | Delete the previous word | +| `meta-D` | Forward delete the next word | +| `^W` | Delete previous text up to the nearest whitespace | +| `^K` | "Kill" to end of line, placing the text in a buffer | +| `^Y` | "Yank" insert the text from the kill buffer | +| `^T` | Transpose the characters about the cursor | +| `^Q` | Write a number in REPL and press `^Q` to open editor at corresponding stackframe or method | ### Customizing keybindings diff --git a/test/repl.jl b/test/repl.jl index 3c3fc9a1cbf6f..f0fa57b525873 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -359,6 +359,17 @@ for prompt = ["TestΠ", () -> randstring(rand(1:10))] LineEdit.history_last(s, hp) @test buffercontents(LineEdit.buffer(s)) == "wip" @test position(LineEdit.buffer(s)) == 3 + # test that history_first jumps to beginning of current session's history + hp.start_idx -= 5 # temporarily alter history + LineEdit.history_first(s, hp) + @test hp.cur_idx == 6 + # we are at the beginning of current session's history, so history_first + # must now jump to the beginning of all history + LineEdit.history_first(s, hp) + @test hp.cur_idx == 1 + LineEdit.history_last(s, hp) + @test hp.cur_idx-1 == length(hp.history) + hp.start_idx += 5 LineEdit.move_line_start(s) @test position(LineEdit.buffer(s)) == 0