UNPKG

launch-ide

Version:

Automatically recognize the editor by running processes and open the specified file in it.

721 lines (720 loc) 18.9 kB
var G = Object.defineProperty, Y = Object.defineProperties; var ee = Object.getOwnPropertyDescriptors; var R = Object.getOwnPropertySymbols; var te = Object.prototype.hasOwnProperty, ne = Object.prototype.propertyIsEnumerable; var $ = (t, e, n) => e in t ? G(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n, v = (t, e) => { for (var n in e || (e = {})) te.call(e, n) && $(t, n, e[n]); if (R) for (var n of R(e)) ne.call(e, n) && $(t, n, e[n]); return t; }, B = (t, e) => Y(t, ee(e)); import b from "fs"; import a from "path"; import I, { execSync as oe } from "child_process"; import L from "os"; import C from "chalk"; import re from "dotenv"; const z = { kiro: ["/Kiro.app/Contents/MacOS/Electron", "/Kiro.app/Contents/MacOS/Kiro"], cursor: ["/Cursor.app/Contents/MacOS/Cursor"], comate: [ "/Comate.app/Contents/MacOS/Electron", "/Comate.app/Contents/MacOS/Comate" ], qoder: [ "/Qoder.app/Contents/MacOS/Electron", "/Qoder CN.app/Contents/MacOS/Electron", "/Qoder.app/Contents/MacOS/Qoder", "/Qoder CN.app/Contents/MacOS/Qoder" ], windsurf: [ "/Windsurf.app/Contents/MacOS/Electron", "/Windsurf.app/Contents/MacOS/Windsurf" ], devin: [ "Devin.app/Contents/MacOS/Devin", "Devin.app/Contents/MacOS/Electron" ], trae: [ "/Trae.app/Contents/MacOS/Electron", "/Trae CN.app/Contents/MacOS/Electron", "/Trae.app/Contents/MacOS/Trae", "/Trae CN.app/Contents/MacOS/Trae" ], codebuddy: [ "/Applications/CodeBuddy.app/Contents/MacOS/Electron", "/Applications/CodeBuddy CN.app/Contents/MacOS/Electron", "/Applications/CodeBuddy.app/Contents/MacOS/CodeBuddy", "/Applications/CodeBuddy CN.app/Contents/MacOS/CodeBuddy" ], antigravity: [ "/Antigravity.app/Contents/MacOS/Electron", "/Antigravity.app/Contents/MacOS/Antigravity" ], code: [ "/Visual Studio Code.app/Contents/MacOS/Electron", "/Visual Studio Code.app/Contents/MacOS/Code" ], "code-insiders": [ "/Visual Studio Code - Insiders.app/Contents/MacOS/Electron" ], webstorm: ["/WebStorm.app/Contents/MacOS/webstorm"], atom: [ "/Atom.app/Contents/MacOS/Atom", "/Atom Beta.app/Contents/MacOS/Atom Beta" ], hbuilder: ["/HBuilderX.app/Contents/MacOS/HBuilderX"], phpstorm: ["/PhpStorm.app/Contents/MacOS/phpstorm"], pycharm: ["/PyCharm.app/Contents/MacOS/pycharm"], idea: ["/IntelliJ IDEA.app/Contents/MacOS/idea"], codium: ["/VSCodium.app/Contents/MacOS/Electron"], goland: ["/GoLand.app/Contents/MacOS/goland"], colin: ["/CLion.app/Contents/MacOS/clion"], appcode: ["/AppCode.app/Contents/MacOS/appcode"], "atom-beta": ["/Atom Beta.app/Contents/MacOS/Atom Beta"], brackets: ["/Brackets.app/Contents/MacOS/Brackets"], rider: ["/Rider.app/Contents/MacOS/rider"], rubymine: ["/RubyMine.app/Contents/MacOS/rubymine"], sublime: ["/Sublime Text.app/Contents/MacOS/sublime_text"], zed: ["/Zed.app/Contents/MacOS/zed", "/Zed.app/Contents/MacOS/cli"] }, V = {}; for (let t of Object.values(z)) for (let e of t) V[e] = e; const se = B(v({}, V), { "/Sublime Text.app/Contents/MacOS/Sublime Text": "/Sublime Text.app/Contents/SharedSupport/bin/subl", "/Sublime Text.app/Contents/MacOS/sublime_text": "/Sublime Text.app/Contents/SharedSupport/bin/subl", "/Sublime Text 2.app/Contents/MacOS/Sublime Text 2": "/Sublime Text 2.app/Contents/SharedSupport/bin/subl", "/Sublime Text Dev.app/Contents/MacOS/Sublime Text": "/Sublime Text Dev.app/Contents/SharedSupport/bin/subl", "/MacVim.app/Contents/MacOS/MacVim": "mvim", "/Zed.app/Contents/MacOS/zed": "/Zed.app/Contents/MacOS/cli" }), W = { kiro: "kiro", cursor: "cursor", comate: "comate", qoder: "qoder", devin: "devin", windsurf: "windsurf", trae: "trae", codebuddy: "codebuddy", antigravity: "antigravity", code: "vscode", codium: "vscodium", zed: "zed" }, H = { kiro: ["kiro"], antigravity: ["antigravity"], webstorm: ["webstorm", "webstorm.sh"], cursor: ["cursor"], devin: ["devin"], windsurf: ["windsurf"], trae: ["trae"], comate: ["comate"], qoder: ["qoder"], codebuddy: ["codebuddy"], code: ["code"], "code-insiders": ["code-insiders"], atom: ["atom"], hbuilder: ["hbuilderx", "hbuilderx.sh"], phpstorm: ["phpstorm", "phpstorm.sh"], pycharm: ["pycharm", "pycharm.sh"], idea: ["idea", "idea.sh"], codium: ["vscodium"], goland: ["goland"], brackets: ["Brackets"], rider: ["rider"], rubymine: ["rubymine", "rubymine.sh"], sublime: ["sublime_text"], vim: ["vim"], emacs: ["emacs"], zed: ["zed"] }, Q = {}; Object.entries(H).forEach(([t, e]) => { for (let n of e) Q[n] = t; }); const ie = B(v({}, Q), { vscodium: "vscodium", codium: "codium", hbuilderx: "hbuilderx", "hbuilderx.sh": "hbuilderx", gvim: "gvim", sublime_text: "subl" }), X = { kiro: ["Kiro.exe"], antigravity: ["Antigravity.exe"], webstorm: ["webstorm.exe", "webstorm64.exe"], cursor: ["Cursor.exe"], windsurf: ["Windsurf.exe"], devin: ["Devin.exe"], trae: ["Trae.exe", "Trae CN.exe"], comate: ["comate.exe"], qoder: ["Qoder.exe", "Qoder CN.exe"], codebuddy: ["CodeBuddy.exe", "CodeBuddy CN.exe"], code: ["Code.exe"], "code-insiders": ["Code - Insiders.exe"], atom: ["atom.exe"], hbuilder: [ "HBuilderX.exe", "HBuilder.exe", "HBuilderX64.exe", "HBuilder64.exe" ], phpstorm: ["phpstorm.exe", "phpstorm64.exe"], pycharm: ["pycharm.exe", "pycharm64.exe"], idea: ["idea.exe", "idea64.exe"], codium: ["VSCodium.exe"], goland: ["goland.exe", "goland64.exe"], colin: ["clion.exe", "clion64.exe"], brackets: ["Brackets.exe"], rider: ["rider.exe", "rider64.exe"], rubymine: ["rubymine.exe", "rubymine64.exe"], sublime: ["sublime_text.exe"], notepad: ["notepad++.exe"], zed: ["zed.exe"] }, J = {}; for (let t of Object.values(X)) for (let e of t) J[e] = ""; const ae = J, q = { darwin: se, linux: ie, win32: ae }, D = { darwin: z, linux: H, win32: X }, m = "{file}", f = "{line}", x = "{column}"; function ce(t, e, n, o) { let s = "".concat(t, ":").concat(e, ":").concat(n); if (typeof o == "string") s = o.replace(m, t).replace(f, e.toString()).replace(x, n.toString()); else if (o instanceof Array) return o.map((r) => r.replace(m, t).replace(f, e.toString()).replace(x, n.toString())); return [s]; } const le = ["-g", "-r", "{file}:{line}:{column}"]; function de(t) { const { editorBasename: e, fileName: n, lineNumber: o, colNumber: s, workspace: r, openWindowParams: i, pathFormat: c } = t, w = pe({ editorBasename: e, openWindowParams: i, workspace: r }) || le; return ce(n, o, s, c || w); } function ue(t) { let e = a.basename(t).replace(/\.(exe|cmd|bat|sh)$/i, ""); const n = process.platform, o = Object.keys(D[n]); for (let s = 0; s < o.length; s++) if ((D[n][o[s]] || []).some( (i) => t.toLowerCase().endsWith(i.toLowerCase()) )) { e = o[s]; break; } return e.toLowerCase(); } function pe(t) { const { editorBasename: e, openWindowParams: n, workspace: o } = t; switch (e) { case "atom": case "atom beta": case "subl": case "sublime": case "sublime_text": case "wstorm": case "charm": return "".concat(m, ":").concat(f, ":").concat(x); case "notepad++": return ["-n" + f, "-c" + x, m]; case "vim": case "mvim": return ["+call cursor(".concat(f, ", ").concat(x, ")"), m]; case "joe": case "gvim": return ["+" + f, m]; case "emacs": case "emacsclient": return ["+" + f + ":" + x, m]; case "rmate": case "mate": case "mine": return ["--line", f, m]; case "code": case "code-insiders": case "code - insiders": case "codium": case "cursor": case "windsurf": case "devin": case "trae": case "codebuddy": case "antigravity": case "comate": case "qoder": case "vscodium": case "hbuilderx": case "hbuilder": case "kiro": return [ ...o ? [o] : [], "-g", ...n ? [n] : [], "".concat(m, ":").concat(f, ":").concat(x) ]; case "appcode": case "clion": case "clion64": case "idea": case "idea64": case "phpstorm": case "phpstorm64": case "pycharm": case "pycharm64": case "rubymine": case "rubymine64": case "webstorm": case "webstorm64": case "goland": case "goland64": case "rider": case "rider64": return [ ...o ? [o] : [], "--line", f, "--column", x, m ]; case "zed": return [ n === "-n" ? "-n" : "-a", "".concat(m, ":").concat(f, ":").concat(x) ]; } return ""; } function me(t) { let e = {}; process.env && (e = v({}, process.env)); let n = ""; if (t) { const o = a.resolve(t, ".env.local"); b.existsSync(o) && (n = o); } if (!n) { const o = a.resolve(process.cwd(), ".env.local"); b.existsSync(o) && (n = o); } if (n) { const o = b.readFileSync(n, "utf-8"), s = re.parse(o || ""); e = v(v({}, s), e); } return e; } function U(t, e) { return me(e)[t] || null; } const fe = { darwin: "ps ax -o comm=", linux: "ps -eo comm --sort=comm", win32: 'powershell -NoProfile -Command "Get-CimInstance -Query \\"select executablepath from win32_process where executablepath is not null\\" | % { $_.ExecutablePath }"' }; function Ce(t, e, n) { let o = null; const s = U("CODE_EDITOR", e || ""); if (s) { const r = j(s); if (r) o = r; else return [s]; } if (!o && t) { const r = j(t); r && (o = r); } if (!o && n) { const r = be(); if (r) return [r]; } try { let r; const i = process.platform, c = process.platform === "win32", g = fe[i], w = q[i]; K(c); const N = I.execSync(g, { encoding: "utf-8" }), h = Object.keys(w), y = N.split(c ? "\r\n" : "\n").map((M) => M.trim()); for (let M = 0; M < h.length; M++) { const l = h[M]; let S = "", E = ""; if (c) { const u = y.find( (P) => a.basename(P).toLowerCase() === l.toLowerCase() ); u && (E = a.basename(u), S = he(u)); } else if (i === "darwin") { const u = y.find( (P) => P.toLowerCase().endsWith(l.toLowerCase()) ); if (u) { const P = u.replace(l, ""), _ = w[l]; E = l, _.includes("/") ? S = "".concat(P).concat(_) : S = _; } } else N.indexOf(l) !== -1 && (E = l, S = w[l]); if (E && S) { if (o != null && o.includes(E)) return [S]; r || (r = [S]); } } if (r) return r; } catch (r) { } return process.env.VISUAL ? [process.env.VISUAL] : process.env.EDITOR ? [process.env.EDITOR] : [null]; } const j = (t) => { const e = process.platform; return D[e] && D[e][t] || null; }; function he(t) { if (a.basename(t).toLowerCase() === "zed.exe") { const e = a.join(a.dirname(t), "bin", "zed.exe"); if (b.existsSync(e)) return e; } return t; } const K = (t) => { if (t) try { I.execSync("chcp 65001"); } catch (e) { } }; function be() { const t = process.platform, e = Object.keys(q[t]); try { return Se(process.pid, t, e); } catch (n) { return console.log(C.red("Error while getting editor by PID:"), n), null; } } function Se(t, e, n) { let o = 0; const s = 50, r = 0; for (; t && t !== r && o < s; ) { const i = Oe(t, e); if (!i) break; const { command: c, parentPid: g } = i; if (ve(c, n)) return c; t = g, o++; } return null; } function Oe(t, e) { switch (e) { case "darwin": case "linux": return xe(t); case "win32": return ge(t); default: return null; } } function xe(t) { try { const n = I.execSync("ps -p ".concat(t, " -o ppid=,comm="), { encoding: "utf8" }).trim().split("\n"); return n.length ? ye(n[0].trim()) : null; } catch (e) { return null; } } function ge(t) { try { K(!0); const e = 'powershell -NoProfile -Command "Get-CimInstance -ClassName Win32_Process -Filter "ProcessId='.concat(t, '" | Select-Object ParentProcessId, ExecutablePath | ConvertTo-Csv -NoTypeInformation'), o = I.execSync(e, { encoding: "utf8" }).trim().split("\r\n").filter((i) => i.trim()).slice(1); if (o.length === 0) return null; const [s, r] = o[0].split(","); return !r || !s ? null : { command: r.slice(1, -1), parentPid: Number(s.slice(1, -1)) }; } catch (e) { return null; } } function ye(t) { const e = t.match(/^(\d+)\s+(.+)$/); return e ? { command: e[2], parentPid: parseInt(e[1]) } : null; } function ve(t, e) { return e.some( (n) => t.toLowerCase().endsWith(n.toLowerCase()) ); } const we = 262, A = /* @__PURE__ */ new Map(), Me = /* @__PURE__ */ new Set([ "appcode", "clion", "clion64", "idea", "idea64", "phpstorm", "phpstorm64", "pycharm", "pycharm64", "rubymine", "rubymine64", "webstorm", "webstorm64", "goland", "goland64", "rider", "rider64" ]); function Ee(t) { return Me.has(t); } function Pe() { try { return oe("git rev-parse --show-toplevel", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim(); } catch (t) { return ""; } } function Ie(t, e) { if (e) { const r = a.resolve(e); if (b.existsSync(r)) return r; } const n = Pe(); if (n) return n; const o = []; let s = a.dirname(a.resolve(t)); for (; ; ) { o.push(s); const r = a.dirname(s); if (r === s) break; s = r; } for (const r of [".idea", ".git"]) { const i = o.find( (c) => b.existsSync(a.join(c, r)) ); if (i) return i; } return a.dirname(a.resolve(t)); } function Ne(t) { const e = t.includes(a.sep) ? [t] : (process.env.PATH || "").split(a.delimiter).filter(Boolean).map((n) => a.join(n, t)); for (const n of e) try { if (b.existsSync(n)) return b.realpathSync(n); } catch (o) { } return null; } function _e(t) { const e = a.dirname(t); return [ // macOS: <IDE>.app/Contents/MacOS/<launcher> a.resolve(e, "../Resources/product-info.json"), // Linux/Windows: <IDE>/bin/<launcher> a.resolve(e, "../product-info.json") ]; } function Te(t) { const e = Number.parseInt(t.buildNumber || "", 10); if (!Number.isNaN(e)) return e >= we; const n = /^(\d{4})\.(\d+)/.exec(t.version || ""); if (!n) return !1; const o = Number(n[1]), s = Number(n[2]); return o > 2026 || o === 2026 && s >= 2; } function Be(t) { const e = A.get(t); if (e !== void 0) return e; const n = Ne(t); if (!n) return A.set(t, !1), !1; for (const o of _e(n)) try { const s = JSON.parse( b.readFileSync(o, "utf8") ), r = Te(s); return A.set(t, r), r; } catch (s) { } return A.set(t, !1), !1; } function Ae(t) { switch (t) { case "vim": case "emacs": case "nano": return !0; } return !1; } function De(t) { const e = U( "CODE_INSPECTOR_FORMAT_PATH", t ); if (e) try { return JSON.parse(e); } catch (n) { return null; } return null; } function ke(t, e) { console.log( C.red("Could not open " + a.basename(t) + " in the editor.") ), e && (e[e.length - 1] !== "." && (e += "."), console.log( C.red("The editor process exited with an error: " + e) )), console.log( "To set up the editor integration, add something like " + C.cyan("CODE_EDITOR=code") + " to the " + C.green(".env.local") + " file in your project folder, or add " + C.green('editor: "code"') + " to CodeInspectorPlugin config, and then restart the development server. Learn more: " + C.green("https://goo.gl/MMTaZt") ); } let O = null; function Re(t) { return t === "reuse" ? "-r" : t === "new" ? "-n" : ""; } function F(t, e) { const n = B(v({}, process.env), { NODE_OPTIONS: "" }); if (process.platform === "win32") { const o = (i) => i.replace(/([&|<>,;=^])/g, "^$1"), s = (i) => i.includes("^") ? '^"'.concat(i, '^"') : i.includes(" ") ? '"'.concat(i, '"') : i, r = [t, ...e.map(o)].map(s).join(" "); return I.exec(r, { // @ts-ignore shell: !0, env: n }); } return I.spawn(t, e, { stdio: "ignore", env: n }); } function He(t) { let { file: e, line: n = 1, column: o = 1, editor: s, method: r, format: i, onError: c, rootDir: g, usePid: w, type: N = "exec" } = t; if (!b.existsSync(e)) return; let [h, ...y] = Ce(s, g, w); const M = y.filter((d) => d !== null); let l = null; const S = De(g || "") || i; if (!h || h.toLowerCase() === "none") { typeof c == "function" ? c(e, "Failed to recognize IDE automatically") : console.log( "Failed to recognize IDE automatically, add something like " + C.cyan("CODE_EDITOR=code") + " to the " + C.green(".env.local") + " file in your project folder, or add " + C.green('editor: "code"') + " to CodeInspectorPlugin config, and then restart the development server. Learn more: " + C.green("https://goo.gl/MMTaZt") ); return; } const E = h, u = ue( h ); if ((N === "open" || N === "open-bg") && process.platform === "darwin" && W[u]) { const d = "".concat(W[u], "://file").concat(e, ":").concat(n, ":").concat(o), p = N === "open-bg" ? ["-g", d] : [d]; O = I.spawn("open", p, { stdio: "ignore", env: B(v({}, process.env), { NODE_OPTIONS: "" }) }); } else { process.platform === "linux" && e.startsWith("/mnt/") && /Microsoft/i.test(L.release()) && (e = a.relative("", e)); let p = Be(h) ? Ie(e, g) : null; p && process.platform === "linux" && p.startsWith("/mnt/") && /Microsoft/i.test(L.release()) && (p = a.relative("", p)), n ? (Ee(u) && (l = M.concat([ e, "--line", String(n), "--column", String(o) ])), y = y.concat( de({ editorBasename: u, fileName: e, lineNumber: n, colNumber: o, workspace: p, openWindowParams: Re(r), pathFormat: S }) )) : y.push(e), O && Ae(h) && O.kill("SIGKILL"), O = F(h, y); } const P = (d) => { typeof c == "function" ? c(e, d) : ke(e, d); }, _ = (d) => { let p = !1; const k = (T) => { if (!p) { if (p = !0, l) { const Z = l; l = null, O = F(E, Z), _(O); return; } P(T); } }; d.on("exit", function(T) { O === d && (O = null), T ? k("(code " + T + ")") : p = !0; }), d.on("error", function(T) { k(T.message); }); }; _(O); } export { ce as formatOpenPath, U as getEnvVariable, me as getEnvVariables, He as launchIDE };