mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 04:11:10 -05:00
Merge branch 'main' into cte/shadcn-ui-storybook
This commit is contained in:
@@ -1,113 +1,27 @@
|
||||
import * as vscode from "vscode"
|
||||
import * as path from "path"
|
||||
import { ClineProvider } from "./webview/ClineProvider"
|
||||
import { EditorUtils } from "./EditorUtils"
|
||||
|
||||
export const ACTION_NAMES = {
|
||||
EXPLAIN: "Roo Code: Explain Code",
|
||||
FIX: "Roo Code: Fix Code",
|
||||
FIX_LOGIC: "Roo Code: Fix Logic",
|
||||
IMPROVE: "Roo Code: Improve Code",
|
||||
ADD_TO_CONTEXT: "Roo Code: Add to Context",
|
||||
} as const
|
||||
|
||||
const COMMAND_IDS = {
|
||||
EXPLAIN: "roo-cline.explainCode",
|
||||
FIX: "roo-cline.fixCode",
|
||||
IMPROVE: "roo-cline.improveCode",
|
||||
ADD_TO_CONTEXT: "roo-cline.addToContext",
|
||||
} as const
|
||||
|
||||
interface DiagnosticData {
|
||||
message: string
|
||||
severity: vscode.DiagnosticSeverity
|
||||
code?: string | number | { value: string | number; target: vscode.Uri }
|
||||
source?: string
|
||||
range: vscode.Range
|
||||
}
|
||||
|
||||
interface EffectiveRange {
|
||||
range: vscode.Range
|
||||
text: string
|
||||
}
|
||||
|
||||
export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
public static readonly providedCodeActionKinds = [
|
||||
vscode.CodeActionKind.QuickFix,
|
||||
vscode.CodeActionKind.RefactorRewrite,
|
||||
]
|
||||
|
||||
// Cache file paths for performance
|
||||
private readonly filePathCache = new WeakMap<vscode.TextDocument, string>()
|
||||
|
||||
private getEffectiveRange(
|
||||
document: vscode.TextDocument,
|
||||
range: vscode.Range | vscode.Selection,
|
||||
): EffectiveRange | null {
|
||||
try {
|
||||
const selectedText = document.getText(range)
|
||||
if (selectedText) {
|
||||
return { range, text: selectedText }
|
||||
}
|
||||
|
||||
const currentLine = document.lineAt(range.start.line)
|
||||
if (!currentLine.text.trim()) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Optimize range creation by checking bounds first
|
||||
const startLine = Math.max(0, currentLine.lineNumber - 1)
|
||||
const endLine = Math.min(document.lineCount - 1, currentLine.lineNumber + 1)
|
||||
|
||||
// Only create new positions if needed
|
||||
const effectiveRange = new vscode.Range(
|
||||
startLine === currentLine.lineNumber ? range.start : new vscode.Position(startLine, 0),
|
||||
endLine === currentLine.lineNumber
|
||||
? range.end
|
||||
: new vscode.Position(endLine, document.lineAt(endLine).text.length),
|
||||
)
|
||||
|
||||
return {
|
||||
range: effectiveRange,
|
||||
text: document.getText(effectiveRange),
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error getting effective range:", error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private getFilePath(document: vscode.TextDocument): string {
|
||||
// Check cache first
|
||||
let filePath = this.filePathCache.get(document)
|
||||
if (filePath) {
|
||||
return filePath
|
||||
}
|
||||
|
||||
try {
|
||||
const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri)
|
||||
if (!workspaceFolder) {
|
||||
filePath = document.uri.fsPath
|
||||
} else {
|
||||
const relativePath = path.relative(workspaceFolder.uri.fsPath, document.uri.fsPath)
|
||||
filePath = !relativePath || relativePath.startsWith("..") ? document.uri.fsPath : relativePath
|
||||
}
|
||||
|
||||
// Cache the result
|
||||
this.filePathCache.set(document, filePath)
|
||||
return filePath
|
||||
} catch (error) {
|
||||
console.error("Error getting file path:", error)
|
||||
return document.uri.fsPath
|
||||
}
|
||||
}
|
||||
|
||||
private createDiagnosticData(diagnostic: vscode.Diagnostic): DiagnosticData {
|
||||
return {
|
||||
message: diagnostic.message,
|
||||
severity: diagnostic.severity,
|
||||
code: diagnostic.code,
|
||||
source: diagnostic.source,
|
||||
range: diagnostic.range, // Reuse the range object
|
||||
}
|
||||
}
|
||||
|
||||
private createAction(title: string, kind: vscode.CodeActionKind, command: string, args: any[]): vscode.CodeAction {
|
||||
const action = new vscode.CodeAction(title, kind)
|
||||
action.command = { command, title, arguments: args }
|
||||
@@ -126,32 +40,20 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
]
|
||||
}
|
||||
|
||||
private hasIntersectingRange(range1: vscode.Range, range2: vscode.Range): boolean {
|
||||
// Optimize range intersection check
|
||||
return !(
|
||||
range2.end.line < range1.start.line ||
|
||||
range2.start.line > range1.end.line ||
|
||||
(range2.end.line === range1.start.line && range2.end.character < range1.start.character) ||
|
||||
(range2.start.line === range1.end.line && range2.start.character > range1.end.character)
|
||||
)
|
||||
}
|
||||
|
||||
public provideCodeActions(
|
||||
document: vscode.TextDocument,
|
||||
range: vscode.Range | vscode.Selection,
|
||||
context: vscode.CodeActionContext,
|
||||
): vscode.ProviderResult<(vscode.CodeAction | vscode.Command)[]> {
|
||||
try {
|
||||
const effectiveRange = this.getEffectiveRange(document, range)
|
||||
const effectiveRange = EditorUtils.getEffectiveRange(document, range)
|
||||
if (!effectiveRange) {
|
||||
return []
|
||||
}
|
||||
|
||||
const filePath = this.getFilePath(document)
|
||||
const filePath = EditorUtils.getFilePath(document)
|
||||
const actions: vscode.CodeAction[] = []
|
||||
|
||||
// Create actions using helper method
|
||||
// Add explain actions
|
||||
actions.push(
|
||||
...this.createActionPair(ACTION_NAMES.EXPLAIN, vscode.CodeActionKind.QuickFix, COMMAND_IDS.EXPLAIN, [
|
||||
filePath,
|
||||
@@ -159,14 +61,13 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
]),
|
||||
)
|
||||
|
||||
// Only process diagnostics if they exist
|
||||
if (context.diagnostics.length > 0) {
|
||||
const relevantDiagnostics = context.diagnostics.filter((d) =>
|
||||
this.hasIntersectingRange(effectiveRange.range, d.range),
|
||||
EditorUtils.hasIntersectingRange(effectiveRange.range, d.range),
|
||||
)
|
||||
|
||||
if (relevantDiagnostics.length > 0) {
|
||||
const diagnosticMessages = relevantDiagnostics.map(this.createDiagnosticData)
|
||||
const diagnosticMessages = relevantDiagnostics.map(EditorUtils.createDiagnosticData)
|
||||
actions.push(
|
||||
...this.createActionPair(ACTION_NAMES.FIX, vscode.CodeActionKind.QuickFix, COMMAND_IDS.FIX, [
|
||||
filePath,
|
||||
@@ -175,9 +76,15 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
]),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
actions.push(
|
||||
...this.createActionPair(ACTION_NAMES.FIX_LOGIC, vscode.CodeActionKind.QuickFix, COMMAND_IDS.FIX, [
|
||||
filePath,
|
||||
effectiveRange.text,
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
// Add improve actions
|
||||
actions.push(
|
||||
...this.createActionPair(
|
||||
ACTION_NAMES.IMPROVE,
|
||||
@@ -187,6 +94,15 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
),
|
||||
)
|
||||
|
||||
actions.push(
|
||||
this.createAction(
|
||||
ACTION_NAMES.ADD_TO_CONTEXT,
|
||||
vscode.CodeActionKind.QuickFix,
|
||||
COMMAND_IDS.ADD_TO_CONTEXT,
|
||||
[filePath, effectiveRange.text],
|
||||
),
|
||||
)
|
||||
|
||||
return actions
|
||||
} catch (error) {
|
||||
console.error("Error providing code actions:", error)
|
||||
|
||||
141
src/core/EditorUtils.ts
Normal file
141
src/core/EditorUtils.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import * as vscode from "vscode"
|
||||
import * as path from "path"
|
||||
|
||||
export interface EffectiveRange {
|
||||
range: vscode.Range
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface DiagnosticData {
|
||||
message: string
|
||||
severity: vscode.DiagnosticSeverity
|
||||
code?: string | number | { value: string | number; target: vscode.Uri }
|
||||
source?: string
|
||||
range: vscode.Range
|
||||
}
|
||||
|
||||
export interface EditorContext {
|
||||
filePath: string
|
||||
selectedText: string
|
||||
diagnostics?: DiagnosticData[]
|
||||
}
|
||||
|
||||
export class EditorUtils {
|
||||
// Cache file paths for performance
|
||||
private static readonly filePathCache = new WeakMap<vscode.TextDocument, string>()
|
||||
|
||||
static getEffectiveRange(
|
||||
document: vscode.TextDocument,
|
||||
range: vscode.Range | vscode.Selection,
|
||||
): EffectiveRange | null {
|
||||
try {
|
||||
const selectedText = document.getText(range)
|
||||
if (selectedText) {
|
||||
return { range, text: selectedText }
|
||||
}
|
||||
|
||||
const currentLine = document.lineAt(range.start.line)
|
||||
if (!currentLine.text.trim()) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Optimize range creation by checking bounds first
|
||||
const startLine = Math.max(0, currentLine.lineNumber - 1)
|
||||
const endLine = Math.min(document.lineCount - 1, currentLine.lineNumber + 1)
|
||||
|
||||
// Only create new positions if needed
|
||||
const effectiveRange = new vscode.Range(
|
||||
startLine === currentLine.lineNumber ? range.start : new vscode.Position(startLine, 0),
|
||||
endLine === currentLine.lineNumber
|
||||
? range.end
|
||||
: new vscode.Position(endLine, document.lineAt(endLine).text.length),
|
||||
)
|
||||
|
||||
return {
|
||||
range: effectiveRange,
|
||||
text: document.getText(effectiveRange),
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error getting effective range:", error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
static getFilePath(document: vscode.TextDocument): string {
|
||||
// Check cache first
|
||||
let filePath = this.filePathCache.get(document)
|
||||
if (filePath) {
|
||||
return filePath
|
||||
}
|
||||
|
||||
try {
|
||||
const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri)
|
||||
if (!workspaceFolder) {
|
||||
filePath = document.uri.fsPath
|
||||
} else {
|
||||
const relativePath = path.relative(workspaceFolder.uri.fsPath, document.uri.fsPath)
|
||||
filePath = !relativePath || relativePath.startsWith("..") ? document.uri.fsPath : relativePath
|
||||
}
|
||||
|
||||
// Cache the result
|
||||
this.filePathCache.set(document, filePath)
|
||||
return filePath
|
||||
} catch (error) {
|
||||
console.error("Error getting file path:", error)
|
||||
return document.uri.fsPath
|
||||
}
|
||||
}
|
||||
|
||||
static createDiagnosticData(diagnostic: vscode.Diagnostic): DiagnosticData {
|
||||
return {
|
||||
message: diagnostic.message,
|
||||
severity: diagnostic.severity,
|
||||
code: diagnostic.code,
|
||||
source: diagnostic.source,
|
||||
range: diagnostic.range,
|
||||
}
|
||||
}
|
||||
|
||||
static hasIntersectingRange(range1: vscode.Range, range2: vscode.Range): boolean {
|
||||
return !(
|
||||
range2.end.line < range1.start.line ||
|
||||
range2.start.line > range1.end.line ||
|
||||
(range2.end.line === range1.start.line && range2.end.character < range1.start.character) ||
|
||||
(range2.start.line === range1.end.line && range2.start.character > range1.end.character)
|
||||
)
|
||||
}
|
||||
|
||||
static getEditorContext(editor?: vscode.TextEditor): EditorContext | null {
|
||||
try {
|
||||
if (!editor) {
|
||||
editor = vscode.window.activeTextEditor
|
||||
}
|
||||
if (!editor) {
|
||||
return null
|
||||
}
|
||||
|
||||
const document = editor.document
|
||||
const selection = editor.selection
|
||||
const effectiveRange = this.getEffectiveRange(document, selection)
|
||||
|
||||
if (!effectiveRange) {
|
||||
return null
|
||||
}
|
||||
|
||||
const filePath = this.getFilePath(document)
|
||||
const diagnostics = vscode.languages
|
||||
.getDiagnostics(document.uri)
|
||||
.filter((d) => this.hasIntersectingRange(effectiveRange.range, d.range))
|
||||
.map(this.createDiagnosticData)
|
||||
|
||||
return {
|
||||
filePath,
|
||||
selectedText: effectiveRange.text,
|
||||
...(diagnostics.length > 0 ? { diagnostics } : {}),
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error getting editor context:", error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as vscode from "vscode"
|
||||
import { CodeActionProvider, ACTION_NAMES } from "../CodeActionProvider"
|
||||
import { EditorUtils } from "../EditorUtils"
|
||||
|
||||
// Mock VSCode API
|
||||
jest.mock("vscode", () => ({
|
||||
@@ -16,13 +17,6 @@ jest.mock("vscode", () => ({
|
||||
start: { line: startLine, character: startChar },
|
||||
end: { line: endLine, character: endChar },
|
||||
})),
|
||||
Position: jest.fn().mockImplementation((line, character) => ({
|
||||
line,
|
||||
character,
|
||||
})),
|
||||
workspace: {
|
||||
getWorkspaceFolder: jest.fn(),
|
||||
},
|
||||
DiagnosticSeverity: {
|
||||
Error: 0,
|
||||
Warning: 1,
|
||||
@@ -31,6 +25,16 @@ jest.mock("vscode", () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
// Mock EditorUtils
|
||||
jest.mock("../EditorUtils", () => ({
|
||||
EditorUtils: {
|
||||
getEffectiveRange: jest.fn(),
|
||||
getFilePath: jest.fn(),
|
||||
hasIntersectingRange: jest.fn(),
|
||||
createDiagnosticData: jest.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
describe("CodeActionProvider", () => {
|
||||
let provider: CodeActionProvider
|
||||
let mockDocument: any
|
||||
@@ -55,68 +59,32 @@ describe("CodeActionProvider", () => {
|
||||
mockContext = {
|
||||
diagnostics: [],
|
||||
}
|
||||
})
|
||||
|
||||
describe("getEffectiveRange", () => {
|
||||
it("should return selected text when available", () => {
|
||||
mockDocument.getText.mockReturnValue("selected text")
|
||||
|
||||
const result = (provider as any).getEffectiveRange(mockDocument, mockRange)
|
||||
|
||||
expect(result).toEqual({
|
||||
range: mockRange,
|
||||
text: "selected text",
|
||||
})
|
||||
})
|
||||
|
||||
it("should return null for empty line", () => {
|
||||
mockDocument.getText.mockReturnValue("")
|
||||
mockDocument.lineAt.mockReturnValue({ text: "", lineNumber: 0 })
|
||||
|
||||
const result = (provider as any).getEffectiveRange(mockDocument, mockRange)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe("getFilePath", () => {
|
||||
it("should return relative path when in workspace", () => {
|
||||
const mockWorkspaceFolder = {
|
||||
uri: { fsPath: "/test" },
|
||||
}
|
||||
;(vscode.workspace.getWorkspaceFolder as jest.Mock).mockReturnValue(mockWorkspaceFolder)
|
||||
|
||||
const result = (provider as any).getFilePath(mockDocument)
|
||||
|
||||
expect(result).toBe("file.ts")
|
||||
})
|
||||
|
||||
it("should return absolute path when not in workspace", () => {
|
||||
;(vscode.workspace.getWorkspaceFolder as jest.Mock).mockReturnValue(null)
|
||||
|
||||
const result = (provider as any).getFilePath(mockDocument)
|
||||
|
||||
expect(result).toBe("/test/file.ts")
|
||||
// Setup default EditorUtils mocks
|
||||
;(EditorUtils.getEffectiveRange as jest.Mock).mockReturnValue({
|
||||
range: mockRange,
|
||||
text: "test code",
|
||||
})
|
||||
;(EditorUtils.getFilePath as jest.Mock).mockReturnValue("/test/file.ts")
|
||||
;(EditorUtils.hasIntersectingRange as jest.Mock).mockReturnValue(true)
|
||||
;(EditorUtils.createDiagnosticData as jest.Mock).mockImplementation((d) => d)
|
||||
})
|
||||
|
||||
describe("provideCodeActions", () => {
|
||||
beforeEach(() => {
|
||||
mockDocument.getText.mockReturnValue("test code")
|
||||
mockDocument.lineAt.mockReturnValue({ text: "test code", lineNumber: 0 })
|
||||
})
|
||||
|
||||
it("should provide explain and improve actions by default", () => {
|
||||
it("should provide explain, improve, fix logic, and add to context actions by default", () => {
|
||||
const actions = provider.provideCodeActions(mockDocument, mockRange, mockContext)
|
||||
|
||||
expect(actions).toHaveLength(4)
|
||||
expect(actions).toHaveLength(7) // 2 explain + 2 fix logic + 2 improve + 1 add to context
|
||||
expect((actions as any)[0].title).toBe(`${ACTION_NAMES.EXPLAIN} in New Task`)
|
||||
expect((actions as any)[1].title).toBe(`${ACTION_NAMES.EXPLAIN} in Current Task`)
|
||||
expect((actions as any)[2].title).toBe(`${ACTION_NAMES.IMPROVE} in New Task`)
|
||||
expect((actions as any)[3].title).toBe(`${ACTION_NAMES.IMPROVE} in Current Task`)
|
||||
expect((actions as any)[2].title).toBe(`${ACTION_NAMES.FIX_LOGIC} in New Task`)
|
||||
expect((actions as any)[3].title).toBe(`${ACTION_NAMES.FIX_LOGIC} in Current Task`)
|
||||
expect((actions as any)[4].title).toBe(`${ACTION_NAMES.IMPROVE} in New Task`)
|
||||
expect((actions as any)[5].title).toBe(`${ACTION_NAMES.IMPROVE} in Current Task`)
|
||||
expect((actions as any)[6].title).toBe(ACTION_NAMES.ADD_TO_CONTEXT)
|
||||
})
|
||||
|
||||
it("should provide fix action when diagnostics exist", () => {
|
||||
it("should provide fix action instead of fix logic when diagnostics exist", () => {
|
||||
mockContext.diagnostics = [
|
||||
{
|
||||
message: "test error",
|
||||
@@ -127,22 +95,33 @@ describe("CodeActionProvider", () => {
|
||||
|
||||
const actions = provider.provideCodeActions(mockDocument, mockRange, mockContext)
|
||||
|
||||
expect(actions).toHaveLength(6)
|
||||
expect(actions).toHaveLength(7) // 2 explain + 2 fix + 2 improve + 1 add to context
|
||||
expect((actions as any).some((a: any) => a.title === `${ACTION_NAMES.FIX} in New Task`)).toBe(true)
|
||||
expect((actions as any).some((a: any) => a.title === `${ACTION_NAMES.FIX} in Current Task`)).toBe(true)
|
||||
expect((actions as any).some((a: any) => a.title === `${ACTION_NAMES.FIX_LOGIC} in New Task`)).toBe(false)
|
||||
expect((actions as any).some((a: any) => a.title === `${ACTION_NAMES.FIX_LOGIC} in Current Task`)).toBe(
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
it("should handle errors gracefully", () => {
|
||||
const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})
|
||||
mockDocument.getText.mockImplementation(() => {
|
||||
throw new Error("Test error")
|
||||
})
|
||||
mockDocument.lineAt.mockReturnValue({ text: "test", lineNumber: 0 })
|
||||
it("should return empty array when no effective range", () => {
|
||||
;(EditorUtils.getEffectiveRange as jest.Mock).mockReturnValue(null)
|
||||
|
||||
const actions = provider.provideCodeActions(mockDocument, mockRange, mockContext)
|
||||
|
||||
expect(actions).toEqual([])
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("Error getting effective range:", expect.any(Error))
|
||||
})
|
||||
|
||||
it("should handle errors gracefully", () => {
|
||||
const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})
|
||||
;(EditorUtils.getEffectiveRange as jest.Mock).mockImplementation(() => {
|
||||
throw new Error("Test error")
|
||||
})
|
||||
|
||||
const actions = provider.provideCodeActions(mockDocument, mockRange, mockContext)
|
||||
|
||||
expect(actions).toEqual([])
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("Error providing code actions:", expect.any(Error))
|
||||
|
||||
consoleErrorSpy.mockRestore()
|
||||
})
|
||||
|
||||
75
src/core/__tests__/EditorUtils.test.ts
Normal file
75
src/core/__tests__/EditorUtils.test.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import * as vscode from "vscode"
|
||||
import { EditorUtils } from "../EditorUtils"
|
||||
|
||||
// Mock VSCode API
|
||||
jest.mock("vscode", () => ({
|
||||
Range: jest.fn().mockImplementation((startLine, startChar, endLine, endChar) => ({
|
||||
start: { line: startLine, character: startChar },
|
||||
end: { line: endLine, character: endChar },
|
||||
})),
|
||||
Position: jest.fn().mockImplementation((line, character) => ({
|
||||
line,
|
||||
character,
|
||||
})),
|
||||
workspace: {
|
||||
getWorkspaceFolder: jest.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
describe("EditorUtils", () => {
|
||||
let mockDocument: any
|
||||
|
||||
beforeEach(() => {
|
||||
mockDocument = {
|
||||
getText: jest.fn(),
|
||||
lineAt: jest.fn(),
|
||||
lineCount: 10,
|
||||
uri: { fsPath: "/test/file.ts" },
|
||||
}
|
||||
})
|
||||
|
||||
describe("getEffectiveRange", () => {
|
||||
it("should return selected text when available", () => {
|
||||
const mockRange = new vscode.Range(0, 0, 0, 10)
|
||||
mockDocument.getText.mockReturnValue("selected text")
|
||||
|
||||
const result = EditorUtils.getEffectiveRange(mockDocument, mockRange)
|
||||
|
||||
expect(result).toEqual({
|
||||
range: mockRange,
|
||||
text: "selected text",
|
||||
})
|
||||
})
|
||||
|
||||
it("should return null for empty line", () => {
|
||||
const mockRange = new vscode.Range(0, 0, 0, 10)
|
||||
mockDocument.getText.mockReturnValue("")
|
||||
mockDocument.lineAt.mockReturnValue({ text: "", lineNumber: 0 })
|
||||
|
||||
const result = EditorUtils.getEffectiveRange(mockDocument, mockRange)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe("getFilePath", () => {
|
||||
it("should return relative path when in workspace", () => {
|
||||
const mockWorkspaceFolder = {
|
||||
uri: { fsPath: "/test" },
|
||||
}
|
||||
;(vscode.workspace.getWorkspaceFolder as jest.Mock).mockReturnValue(mockWorkspaceFolder)
|
||||
|
||||
const result = EditorUtils.getFilePath(mockDocument)
|
||||
|
||||
expect(result).toBe("file.ts")
|
||||
})
|
||||
|
||||
it("should return absolute path when not in workspace", () => {
|
||||
;(vscode.workspace.getWorkspaceFolder as jest.Mock).mockReturnValue(null)
|
||||
|
||||
const result = EditorUtils.getFilePath(mockDocument)
|
||||
|
||||
expect(result).toBe("/test/file.ts")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -238,6 +238,16 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
|
||||
const prompt = supportPrompt.create(promptType, params, customSupportPrompts)
|
||||
|
||||
if (command.endsWith("addToContext")) {
|
||||
await visibleProvider.postMessageToWebview({
|
||||
type: "invoke",
|
||||
invoke: "setChatBoxMessage",
|
||||
text: prompt,
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (visibleProvider.cline && command.endsWith("InCurrentTask")) {
|
||||
await visibleProvider.postMessageToWebview({
|
||||
type: "invoke",
|
||||
|
||||
Reference in New Issue
Block a user