Add 'No results' type to context menu

This commit is contained in:
Saoud Rizwan
2024-09-18 11:00:48 -04:00
parent b94f6fd4e1
commit f104754d3e
4 changed files with 26 additions and 20 deletions

View File

@@ -5,6 +5,7 @@ import { ClaudeDevProvider } from "../providers/ClaudeDevProvider"
const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0)
// Note: this is not a drop-in replacement for listFiles at the start of tasks, since that will be done for Desktops when there is no workspace selected
class WorkspaceTracker { class WorkspaceTracker {
private providerRef: WeakRef<ClaudeDevProvider> private providerRef: WeakRef<ClaudeDevProvider>
private disposables: vscode.Disposable[] = [] private disposables: vscode.Disposable[] = []

View File

@@ -92,6 +92,10 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
const handleMentionSelect = useCallback( const handleMentionSelect = useCallback(
(type: string, value: string) => { (type: string, value: string) => {
if (type === "noResults") {
return
}
if (value === "file" || value === "folder") { if (value === "file" || value === "folder") {
setSelectedType(type.toLowerCase()) setSelectedType(type.toLowerCase())
setSearchQuery("") setSearchQuery("")
@@ -147,7 +151,9 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
if (optionsLength === 0) return prevIndex if (optionsLength === 0) return prevIndex
// Find selectable options (non-URL types) // Find selectable options (non-URL types)
const selectableOptions = options.filter((option) => option.type !== "url") const selectableOptions = options.filter(
(option) => option.type !== "url" && option.type !== "noResults"
)
if (selectableOptions.length === 0) return -1 // No selectable options if (selectableOptions.length === 0) return -1 // No selectable options
@@ -170,7 +176,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
const selectedOption = getContextMenuOptions(searchQuery, selectedType, searchPaths)[ const selectedOption = getContextMenuOptions(searchQuery, selectedType, searchPaths)[
selectedMenuIndex selectedMenuIndex
] ]
if (selectedOption && selectedOption.type !== "url") { if (selectedOption && selectedOption.type !== "url" && selectedOption.type !== "noResults") {
handleMentionSelect(selectedOption.type, selectedOption.value) handleMentionSelect(selectedOption.type, selectedOption.value)
} }
return return
@@ -297,6 +303,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
const newCursorPosition = cursorPosition + trimmedUrl.length + 1 const newCursorPosition = cursorPosition + trimmedUrl.length + 1
setCursorPosition(newCursorPosition) setCursorPosition(newCursorPosition)
setIntendedCursorPosition(newCursorPosition) setIntendedCursorPosition(newCursorPosition)
setShowContextMenu(false)
return return
} }

View File

@@ -52,6 +52,7 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
case "folder": case "folder":
case "problems": case "problems":
case "url": case "url":
case "noResults":
return ( return (
<span <span
style={{ style={{
@@ -67,7 +68,7 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
? "Problems" ? "Problems"
: option.value === "url" : option.value === "url"
? "Paste URL to scrape" ? "Paste URL to scrape"
: ""} : "No results found"}
</span> </span>
) )
default: default:
@@ -113,21 +114,25 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
{filteredOptions.map((option, index) => ( {filteredOptions.map((option, index) => (
<div <div
key={option.value} key={option.value}
onClick={() => option.type !== "url" && onSelect(option.type, option.value)} onClick={() =>
option.type !== "url" && option.type !== "noResults" && onSelect(option.type, option.value)
}
style={{ style={{
padding: "8px 12px", padding: "8px 12px",
cursor: option.type !== "url" ? "pointer" : "default", cursor: option.type !== "url" && option.type !== "noResults" ? "pointer" : "default",
color: "var(--vscode-dropdown-foreground)", color: "var(--vscode-dropdown-foreground)",
borderBottom: "1px solid var(--vscode-dropdown-border)", borderBottom: "1px solid var(--vscode-dropdown-border)",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "space-between", justifyContent: "space-between",
backgroundColor: backgroundColor:
index === selectedIndex && option.type !== "url" index === selectedIndex && option.type !== "url" && option.type !== "noResults"
? "var(--vscode-list-activeSelectionBackground)" ? "var(--vscode-list-activeSelectionBackground)"
: "", : "",
}} }}
onMouseEnter={() => option.type !== "url" && setSelectedIndex(index)}> onMouseEnter={() =>
option.type !== "url" && option.type !== "noResults" && setSelectedIndex(index)
}>
<div <div
style={{ style={{
display: "flex", display: "flex",

View File

@@ -60,16 +60,19 @@ export function getContextMenuOptions(
): { type: string; value: string; icon: string }[] { ): { type: string; value: string; icon: string }[] {
if (query === "") { if (query === "") {
if (selectedType === "file") { if (selectedType === "file") {
return searchPaths const files = searchPaths
.filter((item) => item.type === "file") .filter((item) => item.type === "file")
.map((item) => ({ type: "file", value: item.path, icon: "file" })) .map((item) => ({ type: "file", value: item.path, icon: "file" }))
return files.length > 0 ? files : [{ type: "noResults", value: "noResults", icon: "info" }]
} }
if (selectedType === "folder") { if (selectedType === "folder") {
return searchPaths const folders = searchPaths
.filter((item) => item.type === "folder") .filter((item) => item.type === "folder")
.map((item) => ({ type: "folder", value: item.path, icon: "folder" })) .map((item) => ({ type: "folder", value: item.path, icon: "folder" }))
return folders.length > 0 ? folders : [{ type: "noResults", value: "noResults", icon: "info" }]
} }
return [ return [
{ type: "url", value: "url", icon: "link" }, { type: "url", value: "url", icon: "link" },
{ {
@@ -98,17 +101,7 @@ export function getContextMenuOptions(
icon: item.type === "file" ? "file" : item.type === "problems" ? "warning" : "folder", icon: item.type === "file" ? "file" : item.type === "problems" ? "warning" : "folder",
})) }))
} else { } else {
// If no matches, show all options return [{ type: "noResults", value: "noResults", icon: "info" }]
return [
{ type: "url", value: "url", icon: "link" },
{
type: "problems",
value: "problems",
icon: "warning",
},
{ type: "folder", value: "folder", icon: "folder" },
{ type: "file", value: "file", icon: "file" },
]
} }
} }
} }