|
@@ -0,0 +1,110 @@
|
|
|
|
|
+import * as vscode from 'vscode';
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Format a single file's content as AI context.
|
|
|
|
|
+ */
|
|
|
|
|
+function formatFileContent(filePath: string, content: string): string {
|
|
|
|
|
+ const ext = filePath.split('.').pop() ?? '';
|
|
|
|
|
+ return [
|
|
|
|
|
+ `--- ${filePath} ---`,
|
|
|
|
|
+ '```' + ext,
|
|
|
|
|
+ content,
|
|
|
|
|
+ '```',
|
|
|
|
|
+ '',
|
|
|
|
|
+ ].join('\n');
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Copy the current editor selection to clipboard with AI-friendly formatting.
|
|
|
|
|
+ */
|
|
|
|
|
+export async function copySelection(): Promise<void> {
|
|
|
|
|
+ const editor = vscode.window.activeTextEditor;
|
|
|
|
|
+ if (!editor) {
|
|
|
|
|
+ vscode.window.showWarningMessage('No active editor');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const selection = editor.selection;
|
|
|
|
|
+ if (selection.isEmpty) {
|
|
|
|
|
+ vscode.window.showWarningMessage('No text selected');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const document = editor.document;
|
|
|
|
|
+ const filePath = vscode.workspace.asRelativePath(document.uri);
|
|
|
|
|
+ const text = document.getText(selection);
|
|
|
|
|
+ const lineStart = selection.start.line + 1;
|
|
|
|
|
+ const lineEnd = selection.end.line + 1;
|
|
|
|
|
+
|
|
|
|
|
+ const ext = filePath.split('.').pop() ?? '';
|
|
|
|
|
+ const header = lineStart === lineEnd
|
|
|
|
|
+ ? `${filePath}:${lineStart}`
|
|
|
|
|
+ : `${filePath}:${lineStart}-${lineEnd}`;
|
|
|
|
|
+
|
|
|
|
|
+ const result = [
|
|
|
|
|
+ `--- ${header} ---`,
|
|
|
|
|
+ '```' + ext,
|
|
|
|
|
+ text,
|
|
|
|
|
+ '```',
|
|
|
|
|
+ '',
|
|
|
|
|
+ ].join('\n');
|
|
|
|
|
+
|
|
|
|
|
+ await vscode.env.clipboard.writeText(result);
|
|
|
|
|
+ vscode.window.showInformationMessage(`Copied ${filePath}:${lineStart}-${lineEnd}`);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Copy the entire active file to clipboard with AI-friendly formatting.
|
|
|
|
|
+ */
|
|
|
|
|
+export async function copyActiveFile(): Promise<void> {
|
|
|
|
|
+ const editor = vscode.window.activeTextEditor;
|
|
|
|
|
+ if (!editor) {
|
|
|
|
|
+ vscode.window.showWarningMessage('No active editor');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const document = editor.document;
|
|
|
|
|
+ const filePath = vscode.workspace.asRelativePath(document.uri);
|
|
|
|
|
+ const content = document.getText();
|
|
|
|
|
+ const result = formatFileContent(filePath, content);
|
|
|
|
|
+
|
|
|
|
|
+ await vscode.env.clipboard.writeText(result);
|
|
|
|
|
+ vscode.window.showInformationMessage(`Copied file: ${filePath}`);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Select files from the workspace and copy their contents.
|
|
|
|
|
+ */
|
|
|
|
|
+export async function copyWorkspaceFiles(): Promise<void> {
|
|
|
|
|
+ const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
|
|
|
+ if (!workspaceFolders || workspaceFolders.length === 0) {
|
|
|
|
|
+ vscode.window.showWarningMessage('No workspace folder open');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const uris = await vscode.window.showOpenDialog({
|
|
|
|
|
+ canSelectFiles: true,
|
|
|
|
|
+ canSelectFolders: false,
|
|
|
|
|
+ canSelectMany: true,
|
|
|
|
|
+ openLabel: 'Select files to copy as context',
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ if (!uris || uris.length === 0) return;
|
|
|
|
|
+
|
|
|
|
|
+ const parts: string[] = [];
|
|
|
|
|
+
|
|
|
|
|
+ for (const uri of uris) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const doc = await vscode.workspace.openTextDocument(uri);
|
|
|
|
|
+ const filePath = vscode.workspace.asRelativePath(uri);
|
|
|
|
|
+ parts.push(formatFileContent(filePath, doc.getText()));
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ // skip binary files
|
|
|
|
|
+ vscode.window.showWarningMessage(`Skipped (binary/unreadable): ${uri.fsPath}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const result = parts.join('\n');
|
|
|
|
|
+ await vscode.env.clipboard.writeText(result);
|
|
|
|
|
+ vscode.window.showInformationMessage(`Copied ${uris.length} file(s) to clipboard`);
|
|
|
|
|
+}
|