Skip to content

Commit 9150fdc

Browse files
committed
fix: keep folder picker open when selecting folders with Tab/Enter
- Modified ChatTextArea.tsx handleMentionSelect to keep menu open for folder selection - Added special handling for folder paths that updates input with trailing slash - Updated context-mentions.ts to handle folder paths with trailing slashes - Allows users to navigate into folders and select nested files via keyboard Fixes #8076
1 parent 7b1e3a0 commit 9150fdc

File tree

2 files changed

+69
-20
lines changed

2 files changed

+69
-20
lines changed

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,48 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
339339
}
340340
}
341341

342+
// Special handling for folder selection - keep menu open and update input
343+
if (type === ContextMenuOptionType.Folder && value) {
344+
// Update the input to show the folder path with trailing slash
345+
const beforeCursor = textAreaRef.current?.value.slice(0, cursorPosition) || ""
346+
const _afterCursor = textAreaRef.current?.value.slice(cursorPosition) || ""
347+
348+
// Find the position of the last '@' symbol before the cursor
349+
const lastAtIndex = beforeCursor.lastIndexOf("@")
350+
351+
if (lastAtIndex !== -1) {
352+
// Replace everything after @ with the folder path
353+
const beforeMention = textAreaRef.current?.value.slice(0, lastAtIndex) || ""
354+
// Add folder path with trailing slash to allow continued typing
355+
const folderPath = value.endsWith("/") ? value : value + "/"
356+
const newValue = beforeMention + "@" + folderPath
357+
358+
setInputValue(newValue)
359+
const newCursorPosition = newValue.length
360+
setCursorPosition(newCursorPosition)
361+
setIntendedCursorPosition(newCursorPosition)
362+
363+
// Update search query to the folder path to show its contents
364+
setSearchQuery(folderPath)
365+
setSelectedType(ContextMenuOptionType.Folder)
366+
367+
// Request folder contents from the extension
368+
vscode.postMessage({
369+
type: "searchFiles",
370+
query: folderPath,
371+
requestId: Math.random().toString(36).substring(2, 9),
372+
})
373+
374+
// Focus the textarea but keep menu open
375+
setTimeout(() => {
376+
if (textAreaRef.current) {
377+
textAreaRef.current.focus()
378+
}
379+
}, 0)
380+
return
381+
}
382+
}
383+
342384
setShowContextMenu(false)
343385
setSelectedType(null)
344386

@@ -347,7 +389,7 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
347389

348390
if (type === ContextMenuOptionType.URL) {
349391
insertValue = value || ""
350-
} else if (type === ContextMenuOptionType.File || type === ContextMenuOptionType.Folder) {
392+
} else if (type === ContextMenuOptionType.File) {
351393
insertValue = value || ""
352394
} else if (type === ContextMenuOptionType.Problems) {
353395
insertValue = "problems"

webview-ui/src/utils/context-mentions.ts

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -259,28 +259,35 @@ export function getContextMenuOptions(
259259
]
260260
}
261261

262+
// Special handling for folder paths - if query ends with /, we're looking inside a folder
263+
const isLookingInsideFolder = query.endsWith("/")
264+
// const _folderPath = isLookingInsideFolder ? query.slice(0, -1) : ""
265+
262266
const lowerQuery = query.toLowerCase()
263267
const suggestions: ContextMenuQueryItem[] = []
264268

265-
// Check for top-level option matches
266-
if ("git".startsWith(lowerQuery)) {
267-
suggestions.push({
268-
type: ContextMenuOptionType.Git,
269-
label: "Git Commits",
270-
description: "Search repository history",
271-
icon: "$(git-commit)",
272-
})
273-
} else if ("git-changes".startsWith(lowerQuery)) {
274-
suggestions.push(workingChanges)
275-
}
276-
if ("problems".startsWith(lowerQuery)) {
277-
suggestions.push({ type: ContextMenuOptionType.Problems })
278-
}
279-
if ("terminal".startsWith(lowerQuery)) {
280-
suggestions.push({ type: ContextMenuOptionType.Terminal })
281-
}
282-
if (query.startsWith("http")) {
283-
suggestions.push({ type: ContextMenuOptionType.URL, value: query })
269+
// Only show top-level options if we're not looking inside a folder
270+
if (!isLookingInsideFolder) {
271+
// Check for top-level option matches
272+
if ("git".startsWith(lowerQuery)) {
273+
suggestions.push({
274+
type: ContextMenuOptionType.Git,
275+
label: "Git Commits",
276+
description: "Search repository history",
277+
icon: "$(git-commit)",
278+
})
279+
} else if ("git-changes".startsWith(lowerQuery)) {
280+
suggestions.push(workingChanges)
281+
}
282+
if ("problems".startsWith(lowerQuery)) {
283+
suggestions.push({ type: ContextMenuOptionType.Problems })
284+
}
285+
if ("terminal".startsWith(lowerQuery)) {
286+
suggestions.push({ type: ContextMenuOptionType.Terminal })
287+
}
288+
if (query.startsWith("http")) {
289+
suggestions.push({ type: ContextMenuOptionType.URL, value: query })
290+
}
284291
}
285292

286293
// Add exact SHA matches to suggestions

0 commit comments

Comments
 (0)