Improvements to suggestions & slash commands (#344)
Co-authored-by: N. Taylor Mullen <ntaylormullen@google.com>
This commit is contained in:
parent
89aa1cad41
commit
416813452e
|
@ -314,7 +314,7 @@ export const App = ({
|
|||
resetCompletion={completion.resetCompletionState}
|
||||
/>
|
||||
{completion.showSuggestions && (
|
||||
<Box marginTop={1}>
|
||||
<Box>
|
||||
<SuggestionsDisplay
|
||||
suggestions={completion.suggestions}
|
||||
activeIndex={completion.activeSuggestionIndex}
|
||||
|
|
|
@ -76,6 +76,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
|||
const newValue = base + selectedSuggestion.value;
|
||||
onChangeAndMoveCursor(newValue);
|
||||
onSubmit(newValue); // Execute the command
|
||||
onChangeAndMoveCursor(''); // Clear query after submit
|
||||
} else {
|
||||
// Handle @ command completion
|
||||
const atIndex = query.lastIndexOf('@');
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Colors } from '../colors.js';
|
|||
export interface Suggestion {
|
||||
label: string;
|
||||
value: string;
|
||||
description?: string;
|
||||
}
|
||||
interface SuggestionsDisplayProps {
|
||||
suggestions: Suggestion[];
|
||||
|
@ -29,7 +30,7 @@ export function SuggestionsDisplay({
|
|||
}: SuggestionsDisplayProps) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Box borderStyle="round" paddingX={1} width={width}>
|
||||
<Box paddingX={1} width={width}>
|
||||
<Text color="gray">Loading suggestions...</Text>
|
||||
</Box>
|
||||
);
|
||||
|
@ -48,20 +49,29 @@ export function SuggestionsDisplay({
|
|||
const visibleSuggestions = suggestions.slice(startIndex, endIndex);
|
||||
|
||||
return (
|
||||
<Box borderStyle="round" flexDirection="column" paddingX={1} width={width}>
|
||||
<Box flexDirection="column" paddingX={1} width={width}>
|
||||
{scrollOffset > 0 && <Text color={Colors.Foreground}>▲</Text>}
|
||||
|
||||
{visibleSuggestions.map((suggestion, index) => {
|
||||
const originalIndex = startIndex + index;
|
||||
const isActive = originalIndex === activeIndex;
|
||||
const textColor = isActive ? Colors.AccentPurple : Colors.SubtleComment;
|
||||
|
||||
return (
|
||||
<Text
|
||||
key={`${suggestion}-${originalIndex}`}
|
||||
color={isActive ? Colors.Background : Colors.Foreground}
|
||||
backgroundColor={isActive ? Colors.AccentBlue : undefined}
|
||||
>
|
||||
{suggestion.label}
|
||||
</Text>
|
||||
<Box key={`${suggestion}-${originalIndex}`} width={width}>
|
||||
<Box flexDirection="row">
|
||||
<Box width={20} flexShrink={0}>
|
||||
<Text color={textColor}>{suggestion.label}</Text>
|
||||
</Box>
|
||||
{suggestion.description ? (
|
||||
<Box flexGrow={1}>
|
||||
<Text color={textColor} wrap="wrap">
|
||||
{suggestion.description}
|
||||
</Text>
|
||||
</Box>
|
||||
) : null}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
{endIndex < suggestions.length && <Text color="gray">▼</Text>}
|
||||
|
|
|
@ -94,7 +94,7 @@ export const useSlashCommandProcessor = (
|
|||
{
|
||||
name: 'quit',
|
||||
altName: 'exit',
|
||||
description: '',
|
||||
description: 'exit the cli',
|
||||
action: (_value: PartListUnion | string) => {
|
||||
onDebugMessage('Quitting. Good-bye.');
|
||||
process.exit(0);
|
||||
|
|
|
@ -119,20 +119,30 @@ export function useCompletion(
|
|||
// --- Handle Slash Command Completion ---
|
||||
if (trimmedQuery.startsWith('/')) {
|
||||
const partialCommand = trimmedQuery.substring(1);
|
||||
const commands = slashCommands
|
||||
.map((cmd) => cmd.name)
|
||||
.concat(
|
||||
slashCommands
|
||||
.map((cmd) => cmd.altName)
|
||||
.filter((cmd) => cmd !== undefined),
|
||||
);
|
||||
|
||||
const filteredSuggestions = commands
|
||||
.filter((name) => name.startsWith(partialCommand))
|
||||
// Filter out ? and any other single character commands
|
||||
.filter((name) => name.length > 1)
|
||||
.map((name) => ({ label: name, value: name }))
|
||||
.sort();
|
||||
const filteredSuggestions = slashCommands
|
||||
.filter(
|
||||
(cmd) =>
|
||||
cmd.name.startsWith(partialCommand) ||
|
||||
cmd.altName?.startsWith(partialCommand),
|
||||
)
|
||||
// Filter out ? and any other single character commands unless it's the only char
|
||||
.filter((cmd) => {
|
||||
const nameMatch = cmd.name.startsWith(partialCommand);
|
||||
const altNameMatch = cmd.altName?.startsWith(partialCommand);
|
||||
if (partialCommand.length === 1) {
|
||||
return nameMatch || altNameMatch; // Allow single char match if query is single char
|
||||
}
|
||||
return (
|
||||
(nameMatch && cmd.name.length > 1) ||
|
||||
(altNameMatch && cmd.altName && cmd.altName.length > 1)
|
||||
);
|
||||
})
|
||||
.map((cmd) => ({
|
||||
label: cmd.name, // Always show the main name as label
|
||||
value: cmd.name, // Value should be the main command name for execution
|
||||
description: cmd.description,
|
||||
}))
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
|
||||
setSuggestions(filteredSuggestions);
|
||||
setShowSuggestions(filteredSuggestions.length > 0);
|
||||
|
|
Loading…
Reference in New Issue