From 64e6c8d6c1848f55dc686639926d964d3a21b2ca Mon Sep 17 00:00:00 2001 From: mattirn Date: Fri, 15 Feb 2019 16:05:25 +0100 Subject: [PATCH] Widgets: accept-and-infer-next-history, accept-and-hold & accept-line-and-down-history refactoring... widgets: accept-and-infer-next-history & accept-and-hold manage acceptAndHold() when buffer is empty. --- .../java/org/jline/reader/LineReader.java | 3 + .../org/jline/reader/impl/LineReaderImpl.java | 57 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/reader/src/main/java/org/jline/reader/LineReader.java b/reader/src/main/java/org/jline/reader/LineReader.java index b6e50da33..7c32998c4 100644 --- a/reader/src/main/java/org/jline/reader/LineReader.java +++ b/reader/src/main/java/org/jline/reader/LineReader.java @@ -95,7 +95,10 @@ public interface LineReader { String CALLBACK_FINISH = "callback-finish"; String CALLBACK_KEYMAP = "callback-keymap"; + String ACCEPT_AND_INFER_NEXT_HISTORY = "accept-and-infer-next-history"; + String ACCEPT_AND_HOLD = "accept-and-hold"; String ACCEPT_LINE = "accept-line"; + String ACCEPT_LINE_AND_DOWN_HISTORY = "accept-line-and-down-history"; String ARGUMENT_BASE = "argument-base"; String BACKWARD_CHAR = "backward-char"; String BACKWARD_DELETE_CHAR = "backward-delete-char"; diff --git a/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java b/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java index 3739a083f..06dbd13a5 100644 --- a/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java +++ b/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java @@ -241,6 +241,11 @@ protected enum BellType { protected int smallTerminalOffset = 0; + /* + * accept-and-infer-next-history, accept-and-hold & accept-line-and-down-history + */ + protected boolean nextCommandFromHistory = false; + protected int nextHistoryId = -1; public LineReaderImpl(Terminal terminal) throws IOException { @@ -497,6 +502,17 @@ public String readLine(String prompt, String rightPrompt, MaskingCallback maskin if (buffer != null) { buf.write(buffer); } + if (nextCommandFromHistory && nextHistoryId > 0) { + if (history.size() > nextHistoryId) { + history.moveTo(nextHistoryId); + } else { + history.moveTo(history.last()); + } + buf.write(history.current()); + } else { + nextHistoryId = -1; + } + nextCommandFromHistory = false; undo.clear(); parsedLine = null; keyMap = MAIN; @@ -2712,6 +2728,42 @@ protected boolean quit() { return acceptLine(); } + protected boolean acceptAndHold() { + nextCommandFromHistory = false; + acceptLine(); + if (!buf.toString().isEmpty()) { + nextHistoryId = Integer.MAX_VALUE; + nextCommandFromHistory = true; + } + return nextCommandFromHistory; + } + + protected boolean acceptLineAndDownHistory() { + nextCommandFromHistory = false; + acceptLine(); + if (nextHistoryId < 0) { + nextHistoryId = history.index(); + } + if (history.size() > nextHistoryId + 1) { + nextHistoryId++; + nextCommandFromHistory = true; + } + return nextCommandFromHistory; + } + + protected boolean acceptAndInferNextHistory() { + nextCommandFromHistory = false; + acceptLine(); + if (!buf.toString().isEmpty()) { + nextHistoryId = searchBackwards(buf.toString(), history.last()); + if (nextHistoryId >= 0 && history.size() > nextHistoryId + 1) { + nextHistoryId++; + nextCommandFromHistory = true; + } + } + return nextCommandFromHistory; + } + protected boolean acceptLine() { parsedLine = null; if (!isSet(Option.DISABLE_EVENT_EXPANSION)) { @@ -3345,7 +3397,10 @@ protected boolean whatCursorPosition() { protected Map builtinWidgets() { Map widgets = new HashMap<>(); + addBuiltinWidget(widgets, ACCEPT_AND_INFER_NEXT_HISTORY, this::acceptAndInferNextHistory); + addBuiltinWidget(widgets, ACCEPT_AND_HOLD, this::acceptAndHold); addBuiltinWidget(widgets, ACCEPT_LINE, this::acceptLine); + addBuiltinWidget(widgets, ACCEPT_LINE_AND_DOWN_HISTORY, this::acceptLineAndDownHistory); addBuiltinWidget(widgets, ARGUMENT_BASE, this::argumentBase); addBuiltinWidget(widgets, BACKWARD_CHAR, this::backwardChar); addBuiltinWidget(widgets, BACKWARD_DELETE_CHAR, this::backwardDeleteChar); @@ -5399,6 +5454,7 @@ public KeyMap emacs() { bind(emacs, CLEAR_SCREEN, ctrl('L')); bind(emacs, ACCEPT_LINE, ctrl('M')); bind(emacs, DOWN_LINE_OR_HISTORY, ctrl('N')); + bind(emacs, ACCEPT_LINE_AND_DOWN_HISTORY, ctrl('O')); bind(emacs, UP_LINE_OR_HISTORY, ctrl('P')); bind(emacs, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R')); bind(emacs, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S')); @@ -5442,6 +5498,7 @@ public KeyMap emacs() { bind(emacs, END_OF_HISTORY, alt('>')); bind(emacs, LIST_CHOICES, alt('?')); bind(emacs, DO_LOWERCASE_VERSION, range("^[A-^[Z")); + bind(emacs, ACCEPT_AND_HOLD, alt('a')); bind(emacs, BACKWARD_WORD, alt('b')); bind(emacs, CAPITALIZE_WORD, alt('c')); bind(emacs, KILL_WORD, alt('d'));