From 9f20c5f95e43bccee21b1d89e33fbc3c61a70650 Mon Sep 17 00:00:00 2001 From: Allen Hutchison Date: Wed, 30 Apr 2025 08:31:32 -0700 Subject: Add @ command suggestions in the UI. (#219) --- packages/cli/src/ui/hooks/useInputHistory.ts | 63 +++++++++++----------------- 1 file changed, 25 insertions(+), 38 deletions(-) (limited to 'packages/cli/src/ui/hooks/useInputHistory.ts') diff --git a/packages/cli/src/ui/hooks/useInputHistory.ts b/packages/cli/src/ui/hooks/useInputHistory.ts index 9a6aaacb..21d7b9bf 100644 --- a/packages/cli/src/ui/hooks/useInputHistory.ts +++ b/packages/cli/src/ui/hooks/useInputHistory.ts @@ -7,19 +7,18 @@ import { useState, useCallback } from 'react'; import { useInput } from 'ink'; -// Props for the hook interface UseInputHistoryProps { - userMessages: readonly string[]; // History of user messages - onSubmit: (value: string) => void; // Original submit function from App - isActive: boolean; // To enable/disable the useInput hook + userMessages: readonly string[]; + onSubmit: (value: string) => void; + isActive: boolean; } -// Return type of the hook interface UseInputHistoryReturn { - query: string; // The current input query managed by the hook - setQuery: React.Dispatch>; // Setter for the query - handleSubmit: (value: string) => void; // Wrapped submit handler - inputKey: number; // Key to force input reset + query: string; + setQuery: React.Dispatch>; + handleSubmit: (value: string) => void; + inputKey: number; + setInputKey: React.Dispatch>; } export function useInputHistory({ @@ -27,36 +26,31 @@ export function useInputHistory({ onSubmit, isActive, }: UseInputHistoryProps): UseInputHistoryReturn { - const [query, setQuery] = useState(''); // Hook manages its own query state - const [historyIndex, setHistoryIndex] = useState(-1); // -1 means current query + const [query, setQuery] = useState(''); + const [historyIndex, setHistoryIndex] = useState(-1); const [originalQueryBeforeNav, setOriginalQueryBeforeNav] = useState(''); - const [inputKey, setInputKey] = useState(0); // Key for forcing input reset + const [inputKey, setInputKey] = useState(0); - // Function to reset navigation state, called on submit or manual reset const resetHistoryNav = useCallback(() => { setHistoryIndex(-1); setOriginalQueryBeforeNav(''); }, []); - // Wrapper for the onSubmit prop to include resetting history navigation const handleSubmit = useCallback( (value: string) => { const trimmedValue = value.trim(); if (trimmedValue) { - // Only submit non-empty values - onSubmit(trimmedValue); // Call the original submit function + onSubmit(trimmedValue); } - setQuery(''); // Clear the input field managed by this hook - resetHistoryNav(); // Reset history state - // Don't increment inputKey here, only on nav changes + setQuery(''); + resetHistoryNav(); }, [onSubmit, resetHistoryNav], ); useInput( (input, key) => { - // Do nothing if the hook is not active if (!isActive) { return; } @@ -68,58 +62,51 @@ export function useInputHistory({ let nextIndex = historyIndex; if (historyIndex === -1) { - // Starting navigation UP, save current input setOriginalQueryBeforeNav(query); - nextIndex = 0; // Go to the most recent item (index 0 in reversed view) + nextIndex = 0; } else if (historyIndex < userMessages.length - 1) { - // Continue navigating UP (towards older items) nextIndex = historyIndex + 1; } else { - return; // Already at the oldest item + return; } if (nextIndex !== historyIndex) { setHistoryIndex(nextIndex); - // History is ordered newest to oldest, so access from the end const newValue = userMessages[userMessages.length - 1 - nextIndex]; setQuery(newValue); - setInputKey((k) => k + 1); // Increment key on navigation change + setInputKey((k) => k + 1); didNavigate = true; } } else if (key.downArrow) { - if (historyIndex === -1) return; // Already at the bottom (current input) + if (historyIndex === -1) return; - const nextIndex = historyIndex - 1; // Move towards more recent items / current input + const nextIndex = historyIndex - 1; setHistoryIndex(nextIndex); if (nextIndex === -1) { - // Restore original query setQuery(originalQueryBeforeNav); } else { - // Set query based on reversed index const newValue = userMessages[userMessages.length - 1 - nextIndex]; setQuery(newValue); } - setInputKey((k) => k + 1); // Increment key on navigation change + setInputKey((k) => k + 1); didNavigate = true; } else { - // If user types anything other than arrows while navigating, reset history navigation state if (historyIndex !== -1 && !didNavigate) { - // Check if it's a key that modifies input content if (input || key.backspace || key.delete) { resetHistoryNav(); - // The actual query state update for typing is handled by the component's onChange calling setQuery } } } }, - { isActive }, // Pass isActive to useInput + { isActive }, ); return { query, - setQuery, // Return the hook's setQuery - handleSubmit, // Return the wrapped submit handler - inputKey, // Return the key + setQuery, + handleSubmit, + inputKey, + setInputKey, }; } -- cgit v1.2.3