()
| 31 | } |
| 32 | |
| 33 | export function useCompletion(): UseCompletionReturn { |
| 34 | const [suggestions, setSuggestions] = useState<Suggestion[]>([]); |
| 35 | const [activeSuggestionIndex, setActiveSuggestionIndex] = |
| 36 | useState<number>(-1); |
| 37 | const [visibleStartIndex, setVisibleStartIndex] = useState<number>(0); |
| 38 | const [showSuggestions, setShowSuggestions] = useState<boolean>(false); |
| 39 | const [isLoadingSuggestions, setIsLoadingSuggestions] = |
| 40 | useState<boolean>(false); |
| 41 | const [isPerfectMatch, setIsPerfectMatch] = useState<boolean>(false); |
| 42 | |
| 43 | const resetCompletionState = useCallback(() => { |
| 44 | setSuggestions([]); |
| 45 | setActiveSuggestionIndex(-1); |
| 46 | setVisibleStartIndex(0); |
| 47 | setShowSuggestions(false); |
| 48 | setIsLoadingSuggestions(false); |
| 49 | setIsPerfectMatch(false); |
| 50 | }, []); |
| 51 | |
| 52 | const navigateUp = useCallback(() => { |
| 53 | if (suggestions.length === 0) return; |
| 54 | |
| 55 | setActiveSuggestionIndex((prevActiveIndex) => { |
| 56 | // Calculate new active index, handling wrap-around |
| 57 | const newActiveIndex = |
| 58 | prevActiveIndex <= 0 ? suggestions.length - 1 : prevActiveIndex - 1; |
| 59 | |
| 60 | // Adjust scroll position based on the new active index |
| 61 | setVisibleStartIndex((prevVisibleStart) => { |
| 62 | // Case 1: Wrapped around to the last item |
| 63 | if ( |
| 64 | newActiveIndex === suggestions.length - 1 && |
| 65 | suggestions.length > MAX_SUGGESTIONS_TO_SHOW |
| 66 | ) { |
| 67 | return Math.max(0, suggestions.length - MAX_SUGGESTIONS_TO_SHOW); |
| 68 | } |
| 69 | // Case 2: Scrolled above the current visible window |
| 70 | if (newActiveIndex < prevVisibleStart) { |
| 71 | return newActiveIndex; |
| 72 | } |
| 73 | // Otherwise, keep the current scroll position |
| 74 | return prevVisibleStart; |
| 75 | }); |
| 76 | |
| 77 | return newActiveIndex; |
| 78 | }); |
| 79 | }, [suggestions.length]); |
| 80 | |
| 81 | const navigateDown = useCallback(() => { |
| 82 | if (suggestions.length === 0) return; |
| 83 | |
| 84 | setActiveSuggestionIndex((prevActiveIndex) => { |
| 85 | // Calculate new active index, handling wrap-around |
| 86 | const newActiveIndex = |
| 87 | prevActiveIndex >= suggestions.length - 1 ? 0 : prevActiveIndex + 1; |
| 88 | |
| 89 | // Adjust scroll position based on the new active index |
| 90 | setVisibleStartIndex((prevVisibleStart) => { |
no outgoing calls
no test coverage detected