launch-ide
Version:
Automatically recognize the editor by running processes and open the specified file in it.
721 lines (720 loc) • 18.9 kB
JavaScript
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
};