summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/components/InputPrompt.tsx
diff options
context:
space:
mode:
authorSandy Tao <[email protected]>2025-07-18 14:54:10 -0700
committerGitHub <[email protected]>2025-07-18 21:54:10 +0000
commit4915050ad47236a6d8349ed87b68cd202f96efbe (patch)
tree63b9eb50bccc10d7918e7dd8bca3eeaa59dae829 /packages/cli/src/ui/components/InputPrompt.tsx
parentb5f5ea2c31e296bc1f51cd315badbd4f40c99059 (diff)
improve command completion trigger logic based on cursor position (#4462)
Co-authored-by: Jacob Richman <[email protected]>
Diffstat (limited to 'packages/cli/src/ui/components/InputPrompt.tsx')
-rw-r--r--packages/cli/src/ui/components/InputPrompt.tsx48
1 files changed, 46 insertions, 2 deletions
diff --git a/packages/cli/src/ui/components/InputPrompt.tsx b/packages/cli/src/ui/components/InputPrompt.tsx
index 4d66b10c..46326431 100644
--- a/packages/cli/src/ui/components/InputPrompt.tsx
+++ b/packages/cli/src/ui/components/InputPrompt.tsx
@@ -10,7 +10,7 @@ import { Colors } from '../colors.js';
import { SuggestionsDisplay } from './SuggestionsDisplay.js';
import { useInputHistory } from '../hooks/useInputHistory.js';
import { TextBuffer } from './shared/text-buffer.js';
-import { cpSlice, cpLen } from '../utils/textUtils.js';
+import { cpSlice, cpLen, toCodePoints } from '../utils/textUtils.js';
import chalk from 'chalk';
import stringWidth from 'string-width';
import { useShellHistory } from '../hooks/useShellHistory.js';
@@ -58,10 +58,54 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
setShellModeActive,
}) => {
const [justNavigatedHistory, setJustNavigatedHistory] = useState(false);
+
+ // Check if cursor is after @ or / without unescaped spaces
+ const isCursorAfterCommandWithoutSpace = useCallback(() => {
+ const [row, col] = buffer.cursor;
+ const currentLine = buffer.lines[row] || '';
+
+ // Convert current line to code points for Unicode-aware processing
+ const codePoints = toCodePoints(currentLine);
+
+ // Search backwards from cursor position within the current line only
+ for (let i = col - 1; i >= 0; i--) {
+ const char = codePoints[i];
+
+ if (char === ' ') {
+ // Check if this space is escaped by counting backslashes before it
+ let backslashCount = 0;
+ for (let j = i - 1; j >= 0 && codePoints[j] === '\\'; j--) {
+ backslashCount++;
+ }
+
+ // If there's an odd number of backslashes, the space is escaped
+ const isEscaped = backslashCount % 2 === 1;
+
+ if (!isEscaped) {
+ // Found unescaped space before @ or /, return false
+ return false;
+ }
+ // If escaped, continue searching backwards
+ } else if (char === '@' || char === '/') {
+ // Found @ or / without unescaped space in between
+ return true;
+ }
+ }
+
+ return false;
+ }, [buffer.cursor, buffer.lines]);
+
+ const shouldShowCompletion = useCallback(
+ () =>
+ (isAtCommand(buffer.text) || isSlashCommand(buffer.text)) &&
+ isCursorAfterCommandWithoutSpace(),
+ [buffer.text, isCursorAfterCommandWithoutSpace],
+ );
+
const completion = useCompletion(
buffer.text,
config.getTargetDir(),
- isAtCommand(buffer.text) || isSlashCommand(buffer.text),
+ shouldShowCompletion(),
slashCommands,
commandContext,
config,