diff --git a/src/main/java/com/flowingcode/vaadin/addons/xterm/TerminalHistory.java b/src/main/java/com/flowingcode/vaadin/addons/xterm/TerminalHistory.java index 7043934..e30856f 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/xterm/TerminalHistory.java +++ b/src/main/java/com/flowingcode/vaadin/addons/xterm/TerminalHistory.java @@ -98,7 +98,10 @@ public void setEnabled(boolean enabled) { registrations = null; } else if (enabled && registrations == null) { registrations = new ArrayList<>(); - registrations.add(((ITerminalConsole) terminal).addLineListener(ev -> add(ev.getLine()))); + registrations.add(((ITerminalConsole) terminal).addLineListener(ev -> { + add(ev.getLine()); + resetIterator(); + })); registrations.add(terminal.addCustomKeyListener(ev -> handleArrowUp(), Key.ARROW_UP)); registrations.add(terminal.addCustomKeyListener(ev -> handleArrowDown(), Key.ARROW_DOWN)); } @@ -168,13 +171,19 @@ public void add(String line) { line = line.trim(); if (!line.isEmpty()) { history.add(Objects.requireNonNull(line)); - iterator = null; + resetIterator(); if (maxSize != null && history.size() > maxSize) { history.removeLast(); } } } + private void resetIterator() + { + lastRet = null; + iterator = null; + } + private Optional find(Iterator iterator, Predicate predicate) { while (iterator.hasNext()) { String line = iterator.next(); diff --git a/src/test/java/com/flowingcode/vaadin/addons/xterm/integration/TerminalHistoryIT.java b/src/test/java/com/flowingcode/vaadin/addons/xterm/integration/TerminalHistoryIT.java index 1d4a38a..f502896 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/xterm/integration/TerminalHistoryIT.java +++ b/src/test/java/com/flowingcode/vaadin/addons/xterm/integration/TerminalHistoryIT.java @@ -71,4 +71,44 @@ public void testArrowKeysAndRestore() { assertThat(term.currentLine(), is("bar")); } + @Test + public void testArrowUpAfterRunningLastCommandFromHistory() { + XTermElement term = $(XTermElement.class).first(); + + term.sendKeys("foo1\n"); + term.sendKeys("foo2\n"); + + assertThat(term.currentLine(), isEmptyString()); + + term.sendKeys(Keys.ARROW_UP); + assertThat(term.currentLine(), is("foo2")); + term.sendKeys("\n"); + + term.sendKeys(Keys.ARROW_UP); + assertThat(term.currentLine(), is("foo2")); + + term.sendKeys(Keys.ARROW_UP); + assertThat(term.currentLine(), is("foo1")); + } + + @Test + public void testArrowUpAfterRunningEmptyCommand() { + XTermElement term = $(XTermElement.class).first(); + + term.sendKeys("foo1\n"); + term.sendKeys("foo2\n"); + + assertThat(term.currentLine(), isEmptyString()); + + term.sendKeys(Keys.ARROW_UP); + assertThat(term.currentLine(), is("foo2")); + term.sendKeys("\u0008\u0008\u0008\u0008"); // 4 backspaces + assertThat(term.currentLine(), isEmptyString()); + term.sendKeys("\n"); + + term.sendKeys(Keys.ARROW_UP); + // The position in the history should be back at the end + assertThat(term.currentLine(), is("foo2")); + } + }