diff options
Diffstat (limited to 'packages/cli/src/ui/hooks')
| -rw-r--r-- | packages/cli/src/ui/hooks/useCompletion.test.ts | 2 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useCompletion.ts | 26 |
2 files changed, 27 insertions, 1 deletions
diff --git a/packages/cli/src/ui/hooks/useCompletion.test.ts b/packages/cli/src/ui/hooks/useCompletion.test.ts index 7f2823c7..267bce13 100644 --- a/packages/cli/src/ui/hooks/useCompletion.test.ts +++ b/packages/cli/src/ui/hooks/useCompletion.test.ts @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** @vitest-environment jsdom */ + import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; import type { Mocked } from 'vitest'; import { renderHook, act } from '@testing-library/react'; diff --git a/packages/cli/src/ui/hooks/useCompletion.ts b/packages/cli/src/ui/hooks/useCompletion.ts index d3de5c6b..81acc992 100644 --- a/packages/cli/src/ui/hooks/useCompletion.ts +++ b/packages/cli/src/ui/hooks/useCompletion.ts @@ -28,6 +28,7 @@ export interface UseCompletionReturn { visibleStartIndex: number; showSuggestions: boolean; isLoadingSuggestions: boolean; + isPerfectMatch: boolean; setActiveSuggestionIndex: React.Dispatch<React.SetStateAction<number>>; setShowSuggestions: React.Dispatch<React.SetStateAction<boolean>>; resetCompletionState: () => void; @@ -50,6 +51,7 @@ export function useCompletion( const [showSuggestions, setShowSuggestions] = useState<boolean>(false); const [isLoadingSuggestions, setIsLoadingSuggestions] = useState<boolean>(false); + const [isPerfectMatch, setIsPerfectMatch] = useState<boolean>(false); const resetCompletionState = useCallback(() => { setSuggestions([]); @@ -57,6 +59,7 @@ export function useCompletion( setVisibleStartIndex(0); setShowSuggestions(false); setIsLoadingSuggestions(false); + setIsPerfectMatch(false); }, []); const navigateUp = useCallback(() => { @@ -127,6 +130,9 @@ export function useCompletion( const trimmedQuery = query.trimStart(); if (trimmedQuery.startsWith('/')) { + // Always reset perfect match at the beginning of processing. + setIsPerfectMatch(false); + const fullPath = trimmedQuery.substring(1); const hasTrailingSpace = trimmedQuery.endsWith(' '); @@ -183,6 +189,23 @@ export function useCompletion( } } + // Check for perfect, executable match + if (!hasTrailingSpace) { + if (leafCommand && partial === '' && leafCommand.action) { + // Case: /command<enter> - command has action, no sub-commands were suggested + setIsPerfectMatch(true); + } else if (currentLevel) { + // Case: /command subcommand<enter> + const perfectMatch = currentLevel.find( + (cmd) => + (cmd.name === partial || cmd.altName === partial) && cmd.action, + ); + if (perfectMatch) { + setIsPerfectMatch(true); + } + } + } + const depth = commandPathParts.length; // Provide Suggestions based on the now-corrected context @@ -223,7 +246,7 @@ export function useCompletion( const perfectMatch = potentialSuggestions.find( (s) => s.name === partial || s.altName === partial, ); - if (perfectMatch && !perfectMatch.subCommands) { + if (perfectMatch && perfectMatch.action) { potentialSuggestions = []; } } @@ -534,6 +557,7 @@ export function useCompletion( visibleStartIndex, showSuggestions, isLoadingSuggestions, + isPerfectMatch, setActiveSuggestionIndex, setShowSuggestions, resetCompletionState, |
