|
@@ -1,29 +1,63 @@
|
|
|
import * as vscode from "vscode"
|
|
import * as vscode from "vscode"
|
|
|
import * as path from "path"
|
|
import * as path from "path"
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Represents an effective range in a document along with the corresponding text.
|
|
|
|
|
+ */
|
|
|
export interface EffectiveRange {
|
|
export interface EffectiveRange {
|
|
|
|
|
+ /** The range within the document. */
|
|
|
range: vscode.Range
|
|
range: vscode.Range
|
|
|
|
|
+ /** The text within the specified range. */
|
|
|
text: string
|
|
text: string
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Represents diagnostic information extracted from a VSCode diagnostic.
|
|
|
|
|
+ */
|
|
|
export interface DiagnosticData {
|
|
export interface DiagnosticData {
|
|
|
|
|
+ /** The diagnostic message. */
|
|
|
message: string
|
|
message: string
|
|
|
|
|
+ /** The severity level of the diagnostic. */
|
|
|
severity: vscode.DiagnosticSeverity
|
|
severity: vscode.DiagnosticSeverity
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Optional diagnostic code.
|
|
|
|
|
+ * Can be a string, number, or an object with value and target.
|
|
|
|
|
+ */
|
|
|
code?: string | number | { value: string | number; target: vscode.Uri }
|
|
code?: string | number | { value: string | number; target: vscode.Uri }
|
|
|
|
|
+ /** Optional source identifier for the diagnostic (e.g., the extension name). */
|
|
|
source?: string
|
|
source?: string
|
|
|
|
|
+ /** The range within the document where the diagnostic applies. */
|
|
|
range: vscode.Range
|
|
range: vscode.Range
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Contextual information for a VSCode text editor.
|
|
|
|
|
+ */
|
|
|
export interface EditorContext {
|
|
export interface EditorContext {
|
|
|
|
|
+ /** The file path of the current document. */
|
|
|
filePath: string
|
|
filePath: string
|
|
|
|
|
+ /** The effective text selected or derived from the document. */
|
|
|
selectedText: string
|
|
selectedText: string
|
|
|
|
|
+ /** Optional list of diagnostics associated with the effective range. */
|
|
|
diagnostics?: DiagnosticData[]
|
|
diagnostics?: DiagnosticData[]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * Utility class providing helper methods for working with VSCode editors and documents.
|
|
|
|
|
+ */
|
|
|
export class EditorUtils {
|
|
export class EditorUtils {
|
|
|
- // Cache file paths for performance
|
|
|
|
|
|
|
+ /** Cache mapping text documents to their computed file paths. */
|
|
|
private static readonly filePathCache = new WeakMap<vscode.TextDocument, string>()
|
|
private static readonly filePathCache = new WeakMap<vscode.TextDocument, string>()
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Computes the effective range of text from the given document based on the user's selection.
|
|
|
|
|
+ * If the selection is non-empty, returns that directly.
|
|
|
|
|
+ * Otherwise, if the current line is non-empty, expands the range to include the adjacent lines.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param document - The text document to extract text from.
|
|
|
|
|
+ * @param range - The user selected range or selection.
|
|
|
|
|
+ * @returns An EffectiveRange object containing the effective range and its text, or null if no valid text is found.
|
|
|
|
|
+ */
|
|
|
static getEffectiveRange(
|
|
static getEffectiveRange(
|
|
|
document: vscode.TextDocument,
|
|
document: vscode.TextDocument,
|
|
|
range: vscode.Range | vscode.Selection,
|
|
range: vscode.Range | vscode.Selection,
|
|
@@ -39,16 +73,12 @@ export class EditorUtils {
|
|
|
return null
|
|
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)
|
|
|
|
|
|
|
+ const startLineIndex = Math.max(0, currentLine.lineNumber - 1)
|
|
|
|
|
+ const endLineIndex = Math.min(document.lineCount - 1, currentLine.lineNumber + 1)
|
|
|
|
|
|
|
|
- // Only create new positions if needed
|
|
|
|
|
const effectiveRange = new vscode.Range(
|
|
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),
|
|
|
|
|
|
|
+ new vscode.Position(startLineIndex, 0),
|
|
|
|
|
+ new vscode.Position(endLineIndex, document.lineAt(endLineIndex).text.length),
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
@@ -61,8 +91,15 @@ export class EditorUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Retrieves the file path of a given text document.
|
|
|
|
|
+ * Utilizes an internal cache to avoid redundant computations.
|
|
|
|
|
+ * If the document belongs to a workspace, attempts to compute a relative path; otherwise, returns the absolute fsPath.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param document - The text document for which to retrieve the file path.
|
|
|
|
|
+ * @returns The file path as a string.
|
|
|
|
|
+ */
|
|
|
static getFilePath(document: vscode.TextDocument): string {
|
|
static getFilePath(document: vscode.TextDocument): string {
|
|
|
- // Check cache first
|
|
|
|
|
let filePath = this.filePathCache.get(document)
|
|
let filePath = this.filePathCache.get(document)
|
|
|
if (filePath) {
|
|
if (filePath) {
|
|
|
return filePath
|
|
return filePath
|
|
@@ -77,7 +114,6 @@ export class EditorUtils {
|
|
|
filePath = !relativePath || relativePath.startsWith("..") ? document.uri.fsPath : relativePath
|
|
filePath = !relativePath || relativePath.startsWith("..") ? document.uri.fsPath : relativePath
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Cache the result
|
|
|
|
|
this.filePathCache.set(document, filePath)
|
|
this.filePathCache.set(document, filePath)
|
|
|
return filePath
|
|
return filePath
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
@@ -86,6 +122,12 @@ export class EditorUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Converts a VSCode Diagnostic object to a local DiagnosticData instance.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param diagnostic - The VSCode diagnostic to convert.
|
|
|
|
|
+ * @returns The corresponding DiagnosticData object.
|
|
|
|
|
+ */
|
|
|
static createDiagnosticData(diagnostic: vscode.Diagnostic): DiagnosticData {
|
|
static createDiagnosticData(diagnostic: vscode.Diagnostic): DiagnosticData {
|
|
|
return {
|
|
return {
|
|
|
message: diagnostic.message,
|
|
message: diagnostic.message,
|
|
@@ -96,15 +138,36 @@ export class EditorUtils {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Determines whether two VSCode ranges intersect.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param range1 - The first range.
|
|
|
|
|
+ * @param range2 - The second range.
|
|
|
|
|
+ * @returns True if the ranges intersect; otherwise, false.
|
|
|
|
|
+ */
|
|
|
static hasIntersectingRange(range1: vscode.Range, range2: vscode.Range): boolean {
|
|
static hasIntersectingRange(range1: vscode.Range, range2: vscode.Range): boolean {
|
|
|
- return !(
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ range1.end.line < range2.start.line ||
|
|
|
|
|
+ (range1.end.line === range2.start.line && range1.end.character <= range2.start.character)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ if (
|
|
|
range2.end.line < range1.start.line ||
|
|
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)
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ (range2.end.line === range1.start.line && range2.end.character <= range1.start.character)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Builds the editor context from the provided text editor or from the active text editor.
|
|
|
|
|
+ * The context includes file path, effective selected text, and any diagnostics that intersect with the effective range.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param editor - (Optional) A specific text editor instance. If not provided, the active text editor is used.
|
|
|
|
|
+ * @returns An EditorContext object if successful; otherwise, null.
|
|
|
|
|
+ */
|
|
|
static getEditorContext(editor?: vscode.TextEditor): EditorContext | null {
|
|
static getEditorContext(editor?: vscode.TextEditor): EditorContext | null {
|
|
|
try {
|
|
try {
|
|
|
if (!editor) {
|
|
if (!editor) {
|