vite-plugin-open-in-editor
Version:
Vite plugin to open files directly in any editor (Cursor, VSCode, etc) from Alt+Click or Qwik dev tools.
1 lines • 6.84 kB
Source Map (JSON)
{"version":3,"sources":["../src/parser.ts","../src/opener.ts","../src/index.ts"],"names":["path","fs","exec"],"mappings":"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","file":"index.cjs","sourcesContent":["import path from \"path\";\r\n\r\nexport interface ParsedFile {\r\n normalizedPath: string;\r\n line: string;\r\n column: string;\r\n}\r\n\r\nexport function parseFileParam(fileParam: string): ParsedFile {\r\n fileParam = decodeURIComponent(fileParam);\r\n\r\n // Buscar los dos últimos ':'\r\n const lastColon = fileParam.lastIndexOf(\":\");\r\n const secondLastColon = fileParam.lastIndexOf(\":\", lastColon - 1);\r\n\r\n let column = \"1\";\r\n let line = \"1\";\r\n let rawPath = fileParam;\r\n\r\n if (secondLastColon !== -1) {\r\n column = fileParam.substring(lastColon + 1);\r\n line = fileParam.substring(secondLastColon + 1, lastColon);\r\n rawPath = fileParam.substring(0, secondLastColon);\r\n }\r\n\r\n // Limpiar dobles slashes\r\n rawPath = rawPath.replace(/\\/+/g, \"/\");\r\n\r\n // Quitar src/src redundante (ajustable según el proyecto)\r\n rawPath = rawPath.replace(/\\/src\\/src\\//, \"/src/\");\r\n\r\n // Reparar el caso Windows /c:/ -> c:/\r\n rawPath = rawPath.replace(/^\\/?([a-zA-Z]):/, \"$1:\");\r\n\r\n const normalizedPath = path.normalize(rawPath);\r\n return { normalizedPath, line, column };\r\n}\r\n","import { exec } from \"child_process\";\r\nimport fs from \"fs\";\r\nimport type { ParsedFile } from \"./parser\";\r\n\r\nexport interface OpenFileOptions {\r\n parsedFile: ParsedFile;\r\n editorBin?: string;\r\n log?: boolean;\r\n}\r\n\r\nexport function openFile({\r\n parsedFile,\r\n editorBin = \"cursor\",\r\n log = false,\r\n}: OpenFileOptions): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const { normalizedPath, line, column } = parsedFile;\r\n\r\n if (!fs.existsSync(normalizedPath)) {\r\n return reject(new Error(`File not found: ${normalizedPath}`));\r\n }\r\n\r\n // Handle different editor commands\r\n let command: string;\r\n\r\n if (editorBin === \"code\" || editorBin === \"vscode\") {\r\n // VSCode uses -g flag for goto\r\n command = `code -g \"${normalizedPath}:${line}:${column}\"`;\r\n } else {\r\n // Cursor and other editors use --goto\r\n command = `${editorBin} --goto \"${normalizedPath}:${line}:${column}\"`;\r\n }\r\n\r\n if (log) console.log(\"Executing:\", command);\r\n\r\n exec(command, (err) => {\r\n if (err) {\r\n return reject(err);\r\n }\r\n resolve();\r\n });\r\n });\r\n}\r\n","import type { Plugin } from \"vite\";\r\nimport { parseFileParam } from \"./parser\";\r\nimport { openFile } from \"./opener\";\r\n\r\nexport interface OpenInEditorOptions {\r\n editorBin?: string;\r\n log?: boolean;\r\n}\r\n\r\nfunction vitePluginOpenInEditor(options: OpenInEditorOptions = {}): Plugin {\r\n const { editorBin = \"cursor\", log = false } = options;\r\n\r\n return {\r\n name: \"vite-plugin-open-in-editor\",\r\n configureServer(server) {\r\n server.middlewares.use(async (req, res, next) => {\r\n if (req.url?.startsWith(\"/__open-in-editor\")) {\r\n const url = new URL(req.url, \"http://localhost\");\r\n const fileParam = url.searchParams.get(\"file\");\r\n\r\n if (!fileParam) {\r\n res.writeHead(400);\r\n res.end(\"Missing file parameter\");\r\n return;\r\n }\r\n\r\n try {\r\n const parsedFile = parseFileParam(fileParam);\r\n await openFile({ parsedFile, editorBin, log });\r\n\r\n res.writeHead(200);\r\n res.end(\"Opened successfully\");\r\n } catch (err: any) {\r\n console.error(err);\r\n res.writeHead(500);\r\n res.end(err.message);\r\n }\r\n\r\n return;\r\n }\r\n\r\n next();\r\n });\r\n },\r\n };\r\n}\r\n\r\n// Export both as default and named export for flexibility\r\nexport default vitePluginOpenInEditor;\r\nexport { vitePluginOpenInEditor as openInEditor };\r\n"]}