Skip to content

Commit f9299a9

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/api-config-error-when-switch-provider
2 parents 081faf3 + 8472ae0 commit f9299a9

34 files changed

+2322
-386
lines changed

.vscode/launch.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@
1010
"type": "extensionHost",
1111
"request": "launch",
1212
"runtimeExecutable": "${execPath}",
13-
"args": [
14-
"--extensionDevelopmentPath=${workspaceFolder}",
15-
],
13+
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
1614
"sourceMaps": true,
1715
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
18-
"preLaunchTask": "compile",
16+
"preLaunchTask": "debug-mode",
1917
"env": {
2018
"NODE_ENV": "development",
2119
"VSCODE_DEBUG_MODE": "true"
2220
},
23-
"resolveSourceMapLocations": [
24-
"${workspaceFolder}/**",
25-
"!**/node_modules/**"
26-
]
27-
},
21+
"resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"],
22+
"presentation": {
23+
"hidden": false,
24+
"group": "tasks",
25+
"order": 1
26+
}
27+
}
2828
]
2929
}

.vscode/tasks.json

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"label": "compile",
88
"type": "npm",
99
"script": "compile",
10-
"dependsOn": ["npm: build:webview"],
1110
"group": {
1211
"kind": "build",
1312
"isDefault": true
@@ -30,56 +29,75 @@
3029
}
3130
},
3231
{
32+
"label": "debug-mode",
33+
"dependsOn": ["compile", "npm: dev"],
34+
"group": {
35+
"kind": "build",
36+
"isDefault": false
37+
},
38+
"dependsOrder": "parallel",
39+
"presentation": {
40+
"reveal": "always",
41+
"panel": "new"
42+
}
43+
},
44+
{
45+
"label": "npm: dev",
3346
"type": "npm",
34-
"script": "build:webview",
47+
"script": "dev",
3548
"group": "build",
36-
"problemMatcher": [],
49+
"problemMatcher": {
50+
"owner": "vite",
51+
"pattern": {
52+
"regexp": "^$"
53+
},
54+
"background": {
55+
"activeOnStart": true,
56+
"beginsPattern": ".*VITE.*",
57+
"endsPattern": ".*Local:.*"
58+
}
59+
},
3760
"isBackground": true,
38-
"label": "npm: build:webview",
3961
"presentation": {
4062
"group": "watch",
4163
"reveal": "never"
4264
}
4365
},
4466
{
67+
"label": "npm: build:webview",
4568
"type": "npm",
46-
"script": "watch:esbuild",
69+
"script": "build:webview",
4770
"group": "build",
48-
"problemMatcher": "$esbuild-watch",
71+
"problemMatcher": [],
4972
"isBackground": true,
50-
"label": "npm: watch:esbuild",
5173
"presentation": {
5274
"group": "watch",
5375
"reveal": "never"
5476
}
5577
},
5678
{
79+
"label": "npm: watch:esbuild",
5780
"type": "npm",
58-
"script": "watch:tsc",
81+
"script": "watch:esbuild",
5982
"group": "build",
60-
"problemMatcher": "$tsc-watch",
83+
"problemMatcher": "$esbuild-watch",
6184
"isBackground": true,
62-
"label": "npm: watch:tsc",
6385
"presentation": {
6486
"group": "watch",
6587
"reveal": "never"
6688
}
6789
},
6890
{
91+
"label": "npm: watch:tsc",
6992
"type": "npm",
70-
"script": "watch-tests",
93+
"script": "watch:tsc",
94+
"group": "build",
7195
"problemMatcher": "$tsc-watch",
7296
"isBackground": true,
7397
"presentation": {
74-
"reveal": "never",
75-
"group": "watchers"
76-
},
77-
"group": "build"
78-
},
79-
{
80-
"label": "tasks: watch-tests",
81-
"dependsOn": ["npm: watch", "npm: watch-tests"],
82-
"problemMatcher": []
98+
"group": "watch",
99+
"reveal": "never"
100+
}
83101
}
84102
]
85103
}

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module.exports = {
3434
transformIgnorePatterns: [
3535
"node_modules/(?!(@modelcontextprotocol|delay|p-wait-for|globby|serialize-error|strip-ansi|default-shell|os-name)/)",
3636
],
37+
roots: ["<rootDir>/src", "<rootDir>/webview-ui/src"],
3738
modulePathIgnorePatterns: [".vscode-test"],
3839
reporters: [["jest-simple-dot-reporter", {}]],
3940
setupFiles: [],

src/activate/registerCommands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterComman
7575
dark: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "rocket.png"),
7676
}
7777

78-
tabProvider.resolveWebviewView(panel)
78+
await tabProvider.resolveWebviewView(panel)
7979

8080
// Lock the editor group so clicking on files doesn't open them over the panel
8181
await delay(100)

src/core/EditorUtils.ts

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,63 @@
11
import * as vscode from "vscode"
22
import * as path from "path"
33

4+
/**
5+
* Represents an effective range in a document along with the corresponding text.
6+
*/
47
export interface EffectiveRange {
8+
/** The range within the document. */
59
range: vscode.Range
10+
/** The text within the specified range. */
611
text: string
712
}
813

14+
/**
15+
* Represents diagnostic information extracted from a VSCode diagnostic.
16+
*/
917
export interface DiagnosticData {
18+
/** The diagnostic message. */
1019
message: string
20+
/** The severity level of the diagnostic. */
1121
severity: vscode.DiagnosticSeverity
22+
/**
23+
* Optional diagnostic code.
24+
* Can be a string, number, or an object with value and target.
25+
*/
1226
code?: string | number | { value: string | number; target: vscode.Uri }
27+
/** Optional source identifier for the diagnostic (e.g., the extension name). */
1328
source?: string
29+
/** The range within the document where the diagnostic applies. */
1430
range: vscode.Range
1531
}
1632

33+
/**
34+
* Contextual information for a VSCode text editor.
35+
*/
1736
export interface EditorContext {
37+
/** The file path of the current document. */
1838
filePath: string
39+
/** The effective text selected or derived from the document. */
1940
selectedText: string
41+
/** Optional list of diagnostics associated with the effective range. */
2042
diagnostics?: DiagnosticData[]
2143
}
2244

45+
/**
46+
* Utility class providing helper methods for working with VSCode editors and documents.
47+
*/
2348
export class EditorUtils {
24-
// Cache file paths for performance
49+
/** Cache mapping text documents to their computed file paths. */
2550
private static readonly filePathCache = new WeakMap<vscode.TextDocument, string>()
2651

52+
/**
53+
* Computes the effective range of text from the given document based on the user's selection.
54+
* If the selection is non-empty, returns that directly.
55+
* Otherwise, if the current line is non-empty, expands the range to include the adjacent lines.
56+
*
57+
* @param document - The text document to extract text from.
58+
* @param range - The user selected range or selection.
59+
* @returns An EffectiveRange object containing the effective range and its text, or null if no valid text is found.
60+
*/
2761
static getEffectiveRange(
2862
document: vscode.TextDocument,
2963
range: vscode.Range | vscode.Selection,
@@ -39,16 +73,12 @@ export class EditorUtils {
3973
return null
4074
}
4175

42-
// Optimize range creation by checking bounds first
43-
const startLine = Math.max(0, currentLine.lineNumber - 1)
44-
const endLine = Math.min(document.lineCount - 1, currentLine.lineNumber + 1)
76+
const startLineIndex = Math.max(0, currentLine.lineNumber - 1)
77+
const endLineIndex = Math.min(document.lineCount - 1, currentLine.lineNumber + 1)
4578

46-
// Only create new positions if needed
4779
const effectiveRange = new vscode.Range(
48-
startLine === currentLine.lineNumber ? range.start : new vscode.Position(startLine, 0),
49-
endLine === currentLine.lineNumber
50-
? range.end
51-
: new vscode.Position(endLine, document.lineAt(endLine).text.length),
80+
new vscode.Position(startLineIndex, 0),
81+
new vscode.Position(endLineIndex, document.lineAt(endLineIndex).text.length),
5282
)
5383

5484
return {
@@ -61,8 +91,15 @@ export class EditorUtils {
6191
}
6292
}
6393

94+
/**
95+
* Retrieves the file path of a given text document.
96+
* Utilizes an internal cache to avoid redundant computations.
97+
* If the document belongs to a workspace, attempts to compute a relative path; otherwise, returns the absolute fsPath.
98+
*
99+
* @param document - The text document for which to retrieve the file path.
100+
* @returns The file path as a string.
101+
*/
64102
static getFilePath(document: vscode.TextDocument): string {
65-
// Check cache first
66103
let filePath = this.filePathCache.get(document)
67104
if (filePath) {
68105
return filePath
@@ -77,7 +114,6 @@ export class EditorUtils {
77114
filePath = !relativePath || relativePath.startsWith("..") ? document.uri.fsPath : relativePath
78115
}
79116

80-
// Cache the result
81117
this.filePathCache.set(document, filePath)
82118
return filePath
83119
} catch (error) {
@@ -86,6 +122,12 @@ export class EditorUtils {
86122
}
87123
}
88124

125+
/**
126+
* Converts a VSCode Diagnostic object to a local DiagnosticData instance.
127+
*
128+
* @param diagnostic - The VSCode diagnostic to convert.
129+
* @returns The corresponding DiagnosticData object.
130+
*/
89131
static createDiagnosticData(diagnostic: vscode.Diagnostic): DiagnosticData {
90132
return {
91133
message: diagnostic.message,
@@ -96,15 +138,36 @@ export class EditorUtils {
96138
}
97139
}
98140

141+
/**
142+
* Determines whether two VSCode ranges intersect.
143+
*
144+
* @param range1 - The first range.
145+
* @param range2 - The second range.
146+
* @returns True if the ranges intersect; otherwise, false.
147+
*/
99148
static hasIntersectingRange(range1: vscode.Range, range2: vscode.Range): boolean {
100-
return !(
149+
if (
150+
range1.end.line < range2.start.line ||
151+
(range1.end.line === range2.start.line && range1.end.character <= range2.start.character)
152+
) {
153+
return false
154+
}
155+
if (
101156
range2.end.line < range1.start.line ||
102-
range2.start.line > range1.end.line ||
103-
(range2.end.line === range1.start.line && range2.end.character < range1.start.character) ||
104-
(range2.start.line === range1.end.line && range2.start.character > range1.end.character)
105-
)
157+
(range2.end.line === range1.start.line && range2.end.character <= range1.start.character)
158+
) {
159+
return false
160+
}
161+
return true
106162
}
107163

164+
/**
165+
* Builds the editor context from the provided text editor or from the active text editor.
166+
* The context includes file path, effective selected text, and any diagnostics that intersect with the effective range.
167+
*
168+
* @param editor - (Optional) A specific text editor instance. If not provided, the active text editor is used.
169+
* @returns An EditorContext object if successful; otherwise, null.
170+
*/
108171
static getEditorContext(editor?: vscode.TextEditor): EditorContext | null {
109172
try {
110173
if (!editor) {

0 commit comments

Comments
 (0)