Skip to content

Commit 1448237

Browse files
authored
Merge pull request #67 from leonardo3130/fix/fix-history-navigation
Fix history navigation
2 parents 541d0e9 + 57b3398 commit 1448237

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

src/index.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ const Terminal = ({
5757
const [history, setHistory] = useState<string[]>([]);
5858

5959
const [currentLineInput, setCurrentLineInput] = useState("");
60+
const [tmpInputValue, setTmpInputValue] = useState("");
61+
6062
const [cursorPos, setCursorPos] = useState(0);
6163

6264
const scrollIntoViewRef = useRef<HTMLDivElement>(null);
@@ -91,9 +93,17 @@ const Terminal = ({
9193

9294
// If we're not currently looking at history (oldIndex === -1) and user presses ArrowUp, jump to the last entry.
9395
if (oldIndex === -1 && direction === -1) {
96+
setTmpInputValue(currentLineInput);
9497
return history.length - 1;
9598
}
9699

100+
// If we're at the most recent history entry and user presses ArrowDown, go back to the temporary input value.
101+
if (oldIndex === history.length - 1 && direction === 1) {
102+
setCurrentLineInput(tmpInputValue);
103+
setTmpInputValue("");
104+
return -1;
105+
}
106+
97107
// If oldIndex === -1 and direction === 1 (ArrowDown), keep -1 (nothing to go to).
98108
if (oldIndex === -1 && direction === 1) {
99109
return -1;
@@ -119,15 +129,19 @@ const Terminal = ({
119129
setCursorPos(0);
120130

121131
// history update
122-
setHistory((previousHistory) =>
123-
currentLineInput.trim() === "" ||
124-
previousHistory[previousHistory.length - 1] === currentLineInput.trim()
125-
? previousHistory
126-
: [...previousHistory, currentLineInput],
127-
);
128-
setHistoryIndex(-1);
132+
if (currentLineInput.trim() !== "") {
133+
setHistory((previousHistory) =>
134+
previousHistory[previousHistory.length - 1] ===
135+
currentLineInput.trim()
136+
? previousHistory
137+
: [...previousHistory, currentLineInput],
138+
);
139+
}
129140

141+
setHistoryIndex(-1);
130142
setCurrentLineInput("");
143+
setTmpInputValue("");
144+
131145
setTimeout(
132146
() =>
133147
scrollIntoViewRef?.current?.scrollIntoView({

tests/terminal.history.spec.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,32 @@ describe("Terminal history persistence", () => {
102102

103103
expect(input).toHaveValue("first");
104104
});
105+
106+
test("preserves current input when navigating history and returning back down", () => {
107+
localStorage.setItem("terminal-history", JSON.stringify(["old1", "old2"]));
108+
109+
render(<Terminal onInput={() => { }} />);
110+
const input = screen.getByPlaceholderText("Terminal Hidden Input");
111+
112+
fireEvent.change(input, { target: { value: "new-typing" } });
113+
114+
fireEvent.keyDown(input, { key: "ArrowUp" });
115+
expect(input).toHaveValue("old2");
116+
117+
fireEvent.keyDown(input, { key: "ArrowDown" });
118+
expect(input).toHaveValue("new-typing");
119+
});
120+
121+
test("does not clear input when ArrowDown is pressed while at latest history entry", () => {
122+
localStorage.setItem("terminal-history", JSON.stringify(["cmdA", "cmdB"]));
123+
124+
render(<Terminal onInput={() => { }} />);
125+
const input = screen.getByPlaceholderText("Terminal Hidden Input");
126+
127+
fireEvent.keyDown(input, { key: "ArrowUp" });
128+
expect(input).toHaveValue("cmdB");
129+
130+
fireEvent.keyDown(input, { key: "ArrowDown" });
131+
expect(input).toHaveValue("");
132+
});
105133
});

0 commit comments

Comments
 (0)