chore: up down for history (#19)
Co-authored-by: Shubham Naik <shub@memgpt.ai>
This commit is contained in:
@@ -55,6 +55,11 @@ export function Input({
|
||||
const [cursorPos, setCursorPos] = useState<number | undefined>(undefined);
|
||||
const [currentCursorPosition, setCurrentCursorPosition] = useState(0);
|
||||
|
||||
// Command history
|
||||
const [history, setHistory] = useState<string[]>([]);
|
||||
const [historyIndex, setHistoryIndex] = useState(-1);
|
||||
const [temporaryInput, setTemporaryInput] = useState("");
|
||||
|
||||
// Sync with external mode changes (from plan approval dialog)
|
||||
useEffect(() => {
|
||||
if (externalMode !== undefined) {
|
||||
@@ -140,6 +145,44 @@ export function Input({
|
||||
}
|
||||
});
|
||||
|
||||
// Handle up/down arrow keys for command history
|
||||
useInput((_input, key) => {
|
||||
// Don't interfere with autocomplete navigation
|
||||
if (isAutocompleteActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.upArrow) {
|
||||
// Navigate backwards in history
|
||||
if (history.length === 0) return;
|
||||
|
||||
if (historyIndex === -1) {
|
||||
// Starting to navigate history - save current input
|
||||
setTemporaryInput(value);
|
||||
// Go to most recent command
|
||||
setHistoryIndex(history.length - 1);
|
||||
setValue(history[history.length - 1] ?? "");
|
||||
} else if (historyIndex > 0) {
|
||||
// Go to older command
|
||||
setHistoryIndex(historyIndex - 1);
|
||||
setValue(history[historyIndex - 1] ?? "");
|
||||
}
|
||||
} else if (key.downArrow) {
|
||||
// Navigate forwards in history
|
||||
if (historyIndex === -1) return; // Not in history mode
|
||||
|
||||
if (historyIndex < history.length - 1) {
|
||||
// Go to newer command
|
||||
setHistoryIndex(historyIndex + 1);
|
||||
setValue(history[historyIndex + 1] ?? "");
|
||||
} else {
|
||||
// At the end of history - restore temporary input
|
||||
setHistoryIndex(-1);
|
||||
setValue(temporaryInput);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Reset escape and ctrl-c state when user types (value changes)
|
||||
useEffect(() => {
|
||||
if (value !== previousValueRef.current && value !== "") {
|
||||
@@ -151,6 +194,16 @@ export function Input({
|
||||
previousValueRef.current = value;
|
||||
}, [value]);
|
||||
|
||||
// Exit history mode when user starts typing
|
||||
useEffect(() => {
|
||||
// If user is in history mode and the value changes (they're typing)
|
||||
// Exit history mode but keep the modified text
|
||||
if (historyIndex !== -1 && value !== history[historyIndex]) {
|
||||
setHistoryIndex(-1);
|
||||
setTemporaryInput("");
|
||||
}
|
||||
}, [value, historyIndex, history]);
|
||||
|
||||
// Clean up timers on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
@@ -184,6 +237,16 @@ export function Input({
|
||||
return;
|
||||
}
|
||||
const previousValue = value;
|
||||
|
||||
// Add to history if not empty and not a duplicate of the last entry
|
||||
if (previousValue.trim() && previousValue !== history[history.length - 1]) {
|
||||
setHistory([...history, previousValue]);
|
||||
}
|
||||
|
||||
// Reset history navigation
|
||||
setHistoryIndex(-1);
|
||||
setTemporaryInput("");
|
||||
|
||||
setValue(""); // Clear immediately for responsiveness
|
||||
const result = await onSubmit(previousValue);
|
||||
// If message was NOT submitted (e.g. pending approval), restore it
|
||||
|
||||
Reference in New Issue
Block a user