import * as vscode from "vscode"; import * as path from "path"; /** * 创建文件(本来不存在的情况) */ export async function createFile( filePath: string, content: string = "" ): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = filePath; if (!path.isAbsolute(filePath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您创建文件了" ); } } const fileUri = vscode.Uri.file(absolutePath); // 检测文件是否已存在 try { await vscode.workspace.fs.stat(fileUri); throw new Error(`文件已存在: ${absolutePath}`); } catch (error: any) { // 如果文件不存在,继续创建 if (error.code !== "FileNotFound") { throw error; } } // 确保目录存在 const dirPath = path.dirname(absolutePath); const dirUri = vscode.Uri.file(dirPath); try { await vscode.workspace.fs.stat(dirUri); } catch { await vscode.workspace.fs.createDirectory(dirUri); } // 创建文件 const contentBytes = Buffer.from(content, "utf-8"); await vscode.workspace.fs.writeFile(fileUri, contentBytes); } catch (error) { throw error; } } /** * 创建文件(如果存在则覆盖) */ export async function createOrOverwriteFile( filePath: string, content: string = "" ): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = filePath; if (!path.isAbsolute(filePath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您创建文件了" ); } } // 确保目录存在 const dirPath = path.dirname(absolutePath); const dirUri = vscode.Uri.file(dirPath); try { await vscode.workspace.fs.stat(dirUri); } catch { await vscode.workspace.fs.createDirectory(dirUri); } // 创建或覆盖文件 const fileUri = vscode.Uri.file(absolutePath); const contentBytes = Buffer.from(content, "utf-8"); await vscode.workspace.fs.writeFile(fileUri, contentBytes); } catch (error) { throw error; } } /** * 创建目录 */ export async function createDirectory(dirPath: string): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = dirPath; if (!path.isAbsolute(dirPath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, dirPath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您创建目录了" ); } } const dirUri = vscode.Uri.file(absolutePath); // 检测创建目录是否存在 try { const stat = await vscode.workspace.fs.stat(dirUri); if (stat.type === vscode.FileType.Directory) { throw new Error(`目录已存在: ${absolutePath}`); } else { throw new Error(`路径已存在且不是目录: ${absolutePath}`); } } catch (error: any) { // 如果目录不存在,继续创建 if (error.code !== "FileNotFound") { throw error; } } // 创建目录 await vscode.workspace.fs.createDirectory(dirUri); } catch (error) { throw error; } } /** * 批量创建文件 */ export async function createMultipleFiles( files: { path: string; content: string }[] ): Promise<{ path: string; success: boolean; error?: string }[]> { const results = []; for (const file of files) { try { await createFile(file.path, file.content); results.push({ path: file.path, success: true }); } catch (error) { results.push({ path: file.path, success: false, error: error instanceof Error ? error.message : "未知错误", }); } } return results; } // 删除文件 export async function deleteFile(filePath: string): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = filePath; if (!path.isAbsolute(filePath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您删除文件了" ); } } const fileUri = vscode.Uri.file(absolutePath); // 检查文件是否存在 try { const stat = await vscode.workspace.fs.stat(fileUri); if (stat.type !== vscode.FileType.File) { throw new Error(`路径不是文件: ${absolutePath}`); } } catch (error) { throw new Error(`文件不存在: ${absolutePath}`); } // 删除文件 await vscode.workspace.fs.delete(fileUri); } catch (error) { throw error; } } // 修改文件内容(完全替换) export async function updateFile( filePath: string, content: string ): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = filePath; if (!path.isAbsolute(filePath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您修改文件了" ); } } const fileUri = vscode.Uri.file(absolutePath); // 检查文件是否存在 try { const stat = await vscode.workspace.fs.stat(fileUri); if (stat.type !== vscode.FileType.File) { throw new Error(`路径不是文件: ${absolutePath}`); } } catch (error) { throw new Error(`文件不存在: ${absolutePath}`); } // 修改文件内容 const contentBytes = Buffer.from(content, "utf-8"); await vscode.workspace.fs.writeFile(fileUri, contentBytes); } catch (error) { throw error; } } /** * 追加文件内容 */ export async function appendToFile( filePath: string, content: string ): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = filePath; if (!path.isAbsolute(filePath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您追加文件内容了" ); } } const fileUri = vscode.Uri.file(absolutePath); // 检查文件是否存在并读取原内容 let existingContent = ""; try { const contentBytes = await vscode.workspace.fs.readFile(fileUri); existingContent = Buffer.from(contentBytes).toString("utf-8"); } catch (error) { throw new Error(`文件不存在: ${absolutePath}`); } // 追加内容 const newContent = existingContent + content; const contentBytes = Buffer.from(newContent, "utf-8"); await vscode.workspace.fs.writeFile(fileUri, contentBytes); } catch (error) { throw error; } } // 部分修改文件内容(查找替换) export async function replaceFile( filePath: string, searchValue: string | RegExp, replaceValue: string ): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = filePath; if (!path.isAbsolute(filePath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您修改文件了" ); } } const fileUri = vscode.Uri.file(absolutePath); // 读取文件内容 let fileContent: string; try { const contentBytes = await vscode.workspace.fs.readFile(fileUri); fileContent = Buffer.from(contentBytes).toString("utf-8"); } catch (error) { throw new Error(`文件不存在: ${absolutePath}`); } // 转义特殊字符,将字符串作为字面量处理 const escapeRegExp = (str: string) => { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }; // 替换内容 - 如果是字符串,先转义特殊字符 let newContent: string; if (typeof searchValue === "string") { const escapedSearch = escapeRegExp(searchValue); newContent = fileContent.replace( new RegExp(escapedSearch, "g"), replaceValue ); } else { newContent = fileContent.replace(searchValue, replaceValue); } // 检查是否有内容被替换 if (fileContent === newContent) { throw new Error(`未找到要替换的内容: ${searchValue}`); } // 写回文件 const contentBytes = Buffer.from(newContent, "utf-8"); await vscode.workspace.fs.writeFile(fileUri, contentBytes); } catch (error) { throw error; } } // 在指定位置插入内容 export async function insertAtLine( filePath: string, lineNumber: number, content: string ): Promise { try { // 如果是相对路径,转换为绝对路径 let absolutePath = filePath; if (!path.isAbsolute(filePath)) { const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath); } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您修改文件了" ); } } const fileUri = vscode.Uri.file(absolutePath); // 读取文件内容 let fileContent: string; try { const contentBytes = await vscode.workspace.fs.readFile(fileUri); fileContent = Buffer.from(contentBytes).toString("utf-8"); } catch (error) { throw new Error(`文件不存在: ${absolutePath}`); } const lines = fileContent.split("\n"); // 插入内容 lines.splice(lineNumber, 0, content); // 写回文件 const newContent = lines.join("\n"); const newContentBytes = Buffer.from(newContent, "utf-8"); await vscode.workspace.fs.writeFile(fileUri, newContentBytes); } catch (error) { throw error; } } /** * 重命名文件 */ export async function renameFile( oldPath: string, newPath: string ): Promise { try { // 如果是相对路径,转换为绝对路径 let absoluteOldPath = oldPath; let absoluteNewPath = newPath; const workspaceFolders = vscode.workspace.workspaceFolders; if (workspaceFolders && workspaceFolders.length > 0) { const workspaceRoot = workspaceFolders[0].uri.fsPath; if (!path.isAbsolute(oldPath)) { absoluteOldPath = path.join(workspaceRoot, oldPath); } if (!path.isAbsolute(newPath)) { absoluteNewPath = path.join(workspaceRoot, newPath); } } else { throw new Error( "请先打开一个文件夹作为工作区,这样我就能为您重命名文件了" ); } const oldUri = vscode.Uri.file(absoluteOldPath); const newUri = vscode.Uri.file(absoluteNewPath); // 检查原文件是否存在 try { await vscode.workspace.fs.stat(oldUri); } catch (error) { throw new Error(`文件不存在: ${absoluteOldPath}`); } // 检查新文件名是否已存在 try { await vscode.workspace.fs.stat(newUri); throw new Error(`目标文件已存在: ${absoluteNewPath}`); } catch (error: any) { // 如果文件不存在,继续重命名 if ( error.code !== "FileNotFound" && !error.message.includes("目标文件已存在") ) { throw error; } if (error.message.includes("目标文件已存在")) { throw error; } } // 确保目标目录存在 const newDir = path.dirname(absoluteNewPath); const newDirUri = vscode.Uri.file(newDir); try { await vscode.workspace.fs.stat(newDirUri); } catch { await vscode.workspace.fs.createDirectory(newDirUri); } // 重命名文件 await vscode.workspace.fs.rename(oldUri, newUri, { overwrite: false }); } catch (error) { throw error; } }