diff --git a/src/integrations/WorkspaceTracker.ts b/src/integrations/WorkspaceTracker.ts index 48c3ff6..aa3eeca 100644 --- a/src/integrations/WorkspaceTracker.ts +++ b/src/integrations/WorkspaceTracker.ts @@ -3,6 +3,8 @@ import * as path from "path" import { listFiles } from "../parse-source-code/index" import { ClaudeDevProvider } from "../providers/ClaudeDevProvider" +const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) + class WorkspaceTracker { private providerRef: WeakRef private disposables: vscode.Disposable[] = [] @@ -15,12 +17,17 @@ class WorkspaceTracker { async initializeFilePaths() { // should not auto get filepaths for desktop since it would immediately show permission popup before claude every creates a file - const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) + if (!cwd) { return } const [files, _] = await listFiles(cwd, true, 500) - files.forEach((file) => this.filePaths.add(file)) + files + .map((file) => { + const relativePath = path.relative(cwd, file) + return file.endsWith("/") ? relativePath + "/" : relativePath + }) + .forEach((file) => this.filePaths.add(file)) this.workspaceDidUpdate() } @@ -74,8 +81,16 @@ class WorkspaceTracker { private async onWorkspaceFoldersChanged(event: vscode.WorkspaceFoldersChangeEvent) { for (const folder of event.added) { - const [files, _] = await listFiles(folder.uri.fsPath, true, 50) - files.forEach((file) => this.filePaths.add(file)) + const [files, _] = await listFiles(folder.uri.fsPath, true, 50) // at most 50 files + if (!cwd) { + continue + } + files + .map((file) => { + const relativePath = path.relative(cwd, file) + return file.endsWith("/") ? relativePath + "/" : relativePath + }) + .forEach((file) => this.filePaths.add(file)) } for (const folder of event.removed) { this.filePaths.forEach((filePath) => { diff --git a/webview-ui/src/components/ChatTextArea.tsx b/webview-ui/src/components/ChatTextArea.tsx index 2646f34..4099da0 100644 --- a/webview-ui/src/components/ChatTextArea.tsx +++ b/webview-ui/src/components/ChatTextArea.tsx @@ -55,10 +55,12 @@ const ChatTextArea = forwardRef( const searchPaths = React.useMemo(() => { return [ { type: "problems", path: "problems" }, - ...filePaths.map((path) => ({ - type: path.endsWith("/") ? "folder" : "file", - path: path, - })), + ...filePaths + .map((file) => "/" + file) + .map((path) => ({ + type: path.endsWith("/") ? "folder" : "file", + path: path, + })), ] }, [filePaths]) diff --git a/webview-ui/src/components/ContextMenu.tsx b/webview-ui/src/components/ContextMenu.tsx index 740ee51..67db54d 100644 --- a/webview-ui/src/components/ContextMenu.tsx +++ b/webview-ui/src/components/ContextMenu.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useRef, useState } from "react" import { getContextMenuOptions } from "../utils/mention-context" +import { removeLeadingNonAlphanumeric } from "./CodeAccordian" interface ContextMenuProps { onSelect: (type: string, value: string) => void @@ -45,6 +46,46 @@ const ContextMenu: React.FC = ({ } }, [selectedIndex]) + const renderOptionContent = (option: { type: string; value: string }) => { + switch (option.value) { + case "file": + case "folder": + case "problems": + case "url": + return ( + + {option.value === "file" + ? "Add File" + : option.value === "folder" + ? "Add Folder" + : option.value === "problems" + ? "Problems" + : option.value === "url" + ? "Paste URL to scrape" + : ""} + + ) + default: + return ( + + {removeLeadingNonAlphanumeric(option.value) + "\u200E"} + + ) + } + } + return (
= ({ bottom: "calc(100% - 10px)", left: 15, right: 15, + overflowX: "hidden", }} onMouseDown={onMouseDown}>
= ({ index === selectedIndex && option.type !== "url" ? "var(--vscode-list-activeSelectionBackground)" : "", - // opacity: option.type === "url" ? 0.5 : 1, // Make URL option appear disabled }} onMouseEnter={() => option.type !== "url" && setSelectedIndex(index)}> -
- - {option.value === "file" - ? "Add File" - : option.value === "folder" - ? "Add Folder" - : option.value === "problems" - ? "Problems" - : option.value === "url" - ? "Paste URL to scrape" - : option.value} +
+ + {renderOptionContent(option)}
{(option.value === "file" || option.value === "folder") && ( - + )} {(option.type === "problems" || ((option.type === "file" || option.type === "folder") && option.value !== "file" && option.value !== "folder")) && ( - + )}
))}