11import * as vscode from "vscode"
22import * as path from "path"
33
4+ /**
5+ * Represents an effective range in a document along with the corresponding text.
6+ */
47export 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+ */
917export 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+ */
1736export 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+ */
2348export 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