-
Notifications
You must be signed in to change notification settings - Fork 274
Add Default IDE/Editor Integration #716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,6 +55,10 @@ export function setupEditorMenu(): void { | |
| { | ||
| type: "separator", | ||
| }, | ||
| { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could replace "Open in Visual Studio" |
||
| label: "Open in Default IDE", | ||
| click: () => BrowserWindow.getFocusedWindow()?.webContents.send("editor:open-default-ide"), | ||
| }, | ||
| { | ||
| label: "Open in Visual Studio Code", | ||
| click: () => BrowserWindow.getFocusedWindow()?.webContents.send("editor:open-vscode"), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,7 @@ | ||
| import { platform } from "os"; | ||
| import { ipcMain, shell } from "electron"; | ||
| import { exec } from "child_process"; | ||
| import { statSync } from "fs"; | ||
|
|
||
| ipcMain.on("editor:trash-items", async (ev, items) => { | ||
| const isWindows = platform() === "win32"; | ||
|
|
@@ -20,3 +22,118 @@ ipcMain.on("editor:show-item", (_, item) => { | |
|
|
||
| shell.showItemInFolder(item); | ||
| }); | ||
|
|
||
| ipcMain.on("editor:open-in-external-editor", (_, item) => { | ||
| const isWindows = platform() === "win32"; | ||
| item = isWindows ? item.replace(/\//g, "\\") : item.replace(/\\/g, "/"); | ||
|
|
||
| shell.openPath(item); | ||
| }); | ||
|
|
||
| async function checkCommandAvailable(command: string): Promise<boolean> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest to put it in |
||
| return new Promise((resolve) => { | ||
| exec(`${command} --version`, (error) => { | ||
| resolve(!error); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| async function openInIde(path: string, isDirectory: boolean): Promise<void> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest to put it in |
||
| const isWindows = platform() === "win32"; | ||
| const normalizedPath = isWindows ? path.replace(/\//g, "\\") : path.replace(/\\/g, "/"); | ||
|
|
||
| if (isDirectory) { | ||
| // Try to open directory in IDEs | ||
| const ideCommands = [ | ||
| { command: "code", args: [normalizedPath] }, | ||
| { command: "cursor", args: [normalizedPath] }, | ||
| { command: "subl", args: [normalizedPath] }, // Sublime Text | ||
| ]; | ||
|
|
||
| // Try each IDE in order | ||
| for (const ide of ideCommands) { | ||
| if (await checkCommandAvailable(ide.command)) { | ||
| const fullCommand = `${ide.command} "${normalizedPath}"`; | ||
| exec(fullCommand, (error) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using |
||
| if (error) { | ||
| console.error(`Failed to open with ${ide.command}:`, error); | ||
| } | ||
| }); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // On macOS, try JetBrains IDEs (PhpStorm, WebStorm, IntelliJ IDEA) | ||
| if (platform() === "darwin") { | ||
| exec(`open -a "PhpStorm" "${normalizedPath}"`, (error) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could use the same method than the part |
||
| if (!error) { | ||
| return; | ||
| } | ||
| exec(`open -a "WebStorm" "${normalizedPath}"`, (error) => { | ||
| if (!error) { | ||
| return; | ||
| } | ||
| exec(`open -a "IntelliJ IDEA" "${normalizedPath}"`, (error) => { | ||
| if (!error) { | ||
| return; | ||
| } | ||
| exec(`open -a "IntelliJ IDEA CE" "${normalizedPath}"`, (error) => { | ||
| if (!error) { | ||
| return; | ||
| } | ||
| // Fallback to shell.openPath | ||
| shell.openPath(normalizedPath); | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
| return; | ||
| } | ||
|
|
||
| // On Windows, try JetBrains IDEs via CLI | ||
| if (isWindows) { | ||
| if (await checkCommandAvailable("phpstorm")) { | ||
| exec(`phpstorm "${normalizedPath}"`, (error) => { | ||
| if (error) { | ||
| console.error("Failed to open with PhpStorm:", error); | ||
| } | ||
| }); | ||
| return; | ||
| } | ||
| if (await checkCommandAvailable("webstorm")) { | ||
| exec(`webstorm "${normalizedPath}"`, (error) => { | ||
| if (error) { | ||
| console.error("Failed to open with WebStorm:", error); | ||
| } | ||
| }); | ||
| return; | ||
| } | ||
| if (await checkCommandAvailable("idea")) { | ||
| exec(`idea "${normalizedPath}"`, (error) => { | ||
| if (error) { | ||
| console.error("Failed to open with IntelliJ IDEA:", error); | ||
| shell.openPath(normalizedPath); | ||
| } | ||
| }); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // Fallback: open with default application | ||
| shell.openPath(normalizedPath); | ||
| } else { | ||
| // For files, use shell.openPath which uses OS default application | ||
| shell.openPath(normalizedPath); | ||
| } | ||
| } | ||
|
|
||
| ipcMain.on("editor:open-with", async (_, item) => { | ||
| try { | ||
| const stats = statSync(item); | ||
| const isDirectory = stats.isDirectory(); | ||
| await openInIde(item, isDirectory); | ||
| } catch (e) { | ||
| // If stat fails, try as directory first, then as file | ||
| await openInIde(item, true); | ||
| } | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the import of "ImFinder " then to fix the lint issue