Skip to content

Commit 46b23bf

Browse files
committed
fix: allow folder drill-down in context picker
- Modified handleMentionSelect to handle folder selection specially - When selecting a folder, ensure path ends with "/" - Insert folder mention without trailing space to keep menu open - Trigger immediate search for folder contents - Fixes #8076 where Tab/Enter would close picker preventing drill-down
1 parent 205f3e4 commit 46b23bf

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

.review/pr-8274

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit e46929b8d8add0cd3c412d69f8ac882c405a4ba9

tmp/pr-8287-Roo-Code

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 88a473b017af37091c85ce3056e444e856f80d6e

webview-ui/src/components/chat/ChatTextArea.tsx

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,70 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
342342
}
343343
}
344344

345+
// Special handling for folder selection with concrete value
346+
if (type === ContextMenuOptionType.Folder && value) {
347+
if (textAreaRef.current) {
348+
// Ensure the path ends with "/"
349+
let folderPath = value
350+
if (!folderPath.endsWith("/")) {
351+
folderPath += "/"
352+
}
353+
354+
// Insert the folder mention without a trailing space
355+
const beforeCursor = textAreaRef.current.value.slice(0, cursorPosition)
356+
const afterCursor = textAreaRef.current.value.slice(cursorPosition)
357+
const lastAtIndex = beforeCursor.lastIndexOf("@")
358+
359+
let newValue: string
360+
let newCursorPosition: number
361+
362+
if (lastAtIndex !== -1) {
363+
// Replace everything after the @ with the folder path
364+
const beforeMention = textAreaRef.current.value.slice(0, lastAtIndex)
365+
// Don't add a trailing space after the folder path
366+
newValue = beforeMention + "@" + folderPath + afterCursor
367+
newCursorPosition = lastAtIndex + 1 + folderPath.length
368+
} else {
369+
// Insert at cursor position
370+
newValue = beforeCursor + "@" + folderPath + afterCursor
371+
newCursorPosition = cursorPosition + 1 + folderPath.length
372+
}
373+
374+
setInputValue(newValue)
375+
setCursorPosition(newCursorPosition)
376+
setIntendedCursorPosition(newCursorPosition)
377+
378+
// Keep the menu open and search for folder contents
379+
// Don't call setShowContextMenu(false)
380+
setSelectedType(null)
381+
setSelectedMenuIndex(0)
382+
383+
// Extract the query for searching folder contents
384+
const query = folderPath
385+
setSearchQuery(query)
386+
387+
// Trigger file search for the folder contents
388+
const reqId = Math.random().toString(36).substring(2, 9)
389+
setSearchRequestId(reqId)
390+
setSearchLoading(true)
391+
392+
// Send message to extension to search files in the folder
393+
vscode.postMessage({
394+
type: "searchFiles",
395+
query: query,
396+
requestId: reqId,
397+
})
398+
399+
// Focus the textarea
400+
setTimeout(() => {
401+
if (textAreaRef.current) {
402+
textAreaRef.current.focus()
403+
}
404+
}, 0)
405+
}
406+
return
407+
}
408+
345409
setShowContextMenu(false)
346410
setSelectedType(null)
347411

@@ -387,7 +451,7 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
387451
}
388452
},
389453
// eslint-disable-next-line react-hooks/exhaustive-deps
390-
[setInputValue, cursorPosition],
454+
[setInputValue, cursorPosition, setSearchRequestId, setSearchLoading],
391455
)
392456

393457
const handleKeyDown = useCallback(

0 commit comments

Comments
 (0)