diff --git a/src/main/core/app/service.ts b/src/main/core/app/service.ts index 5a4fc1e1f5..311809106e 100644 --- a/src/main/core/app/service.ts +++ b/src/main/core/app/service.ts @@ -231,7 +231,7 @@ class AppService implements IInitializable, IDisposable { const { host, username, port } = connection; - if (appId === 'vscode' || appId === 'vscodium' || appId === 'cursor') { + if (appId === 'vscode' || appId === 'vscodium' || appId === 'cursor' || appId === 'zed') { await shell.openExternal(buildRemoteEditorUrl(appId, host, username, target)); return; } @@ -351,7 +351,8 @@ class AppService implements IInitializable, IDisposable { ); } - const quoted = (p: string) => `'${p.replace(/'/g, "'\\''")}'`; + const quoted = (p: string) => + process.platform !== 'win32' ? `'${p.replace(/'/g, "'\\''")}'` : `"${p.replace(/"/g, '""')}"`; const commands: string[] = platformConfig?.openCommands ?? []; const command = commands .map((cmd) => cmd.replace('{{path}}', quoted(target)).replace('{{path_raw}}', target)) diff --git a/src/main/core/app/utils.ts b/src/main/core/app/utils.ts index d1e099602b..c8c06f3320 100644 --- a/src/main/core/app/utils.ts +++ b/src/main/core/app/utils.ts @@ -176,7 +176,9 @@ export const resolveAppVersion = async (): Promise => { export const checkCommand = (cmd: string): Promise => new Promise((resolve) => { - exec(`command -v ${cmd} >/dev/null 2>&1`, { env: buildExternalToolEnv() }, (error) => { + const check = + process.platform !== 'win32' ? `command -v ${cmd} >/dev/null 2>&1` : `where ${cmd}`; + exec(check, { env: buildExternalToolEnv() }, (error) => { resolve(!error); }); }); diff --git a/src/main/utils/remoteOpenIn.ts b/src/main/utils/remoteOpenIn.ts index 37932695ee..83dc3f1909 100644 --- a/src/main/utils/remoteOpenIn.ts +++ b/src/main/utils/remoteOpenIn.ts @@ -1,6 +1,6 @@ import { quoteShellArg } from './shellEscape'; -type RemoteEditorScheme = 'vscode' | 'vscodium' | 'cursor'; +type RemoteEditorScheme = 'vscode' | 'vscodium' | 'cursor' | 'zed'; export function buildRemoteSshAuthority(host: string, username: string): string { const normalizedHost = host.trim(); @@ -24,7 +24,13 @@ export function buildRemoteEditorUrl( const authority = buildRemoteSshAuthority(host, username); const encodedAuthority = encodeURIComponent(authority); const normalizedTargetPath = targetPath.startsWith('/') ? targetPath : `/${targetPath}`; - return `${scheme}://vscode-remote/ssh-remote+${encodedAuthority}${normalizedTargetPath}`; + + switch (scheme) { + case 'zed': + return `zed://ssh/${encodedAuthority}${normalizedTargetPath}`; + default: + return `${scheme}://vscode-remote/ssh-remote+${encodedAuthority}${normalizedTargetPath}`; + } } type RemoteTerminalExecInput = { diff --git a/src/shared/openInApps.ts b/src/shared/openInApps.ts index b979e850d6..eacb9bdff7 100644 --- a/src/shared/openInApps.ts +++ b/src/shared/openInApps.ts @@ -89,7 +89,7 @@ const _OPEN_IN_APPS = { appNames: ['Cursor'], }, win32: { - openCommands: ['start "" cursor {{path}}'], + openCommands: ['cursor {{path}}'], checkCommands: ['cursor'], }, linux: { @@ -116,7 +116,7 @@ const _OPEN_IN_APPS = { appNames: ['Visual Studio Code'], }, win32: { - openCommands: ['start "" code {{path}}', 'start "" code-insiders {{path}}'], + openCommands: ['code {{path}}', 'code-insiders {{path}}'], checkCommands: ['code', 'code-insiders'], }, linux: { @@ -143,7 +143,7 @@ const _OPEN_IN_APPS = { appNames: ['VSCodium'], }, win32: { - openCommands: ['start "" codium {{path}}'], + openCommands: ['codium {{path}}'], checkCommands: ['codium'], }, linux: { @@ -169,7 +169,7 @@ const _OPEN_IN_APPS = { appNames: ['Windsurf'], }, win32: { - openCommands: ['start "" windsurf {{path}}'], + openCommands: ['windsurf {{path}}'], checkCommands: ['windsurf'], }, linux: { @@ -289,6 +289,7 @@ const _OPEN_IN_APPS = { label: 'Zed', iconPath: ICON_PATHS.zed, autoInstall: true, + supportsRemote: true, platforms: { darwin: { openCommands: ['command -v zed >/dev/null 2>&1 && zed {{path}}', 'open -a "Zed" {{path}}'], @@ -299,6 +300,10 @@ const _OPEN_IN_APPS = { openCommands: ['zed {{path}}', 'xdg-open {{path}}'], checkCommands: ['zed'], }, + win32: { + openCommands: ['zed {{path}}'], + checkCommands: ['zed'], + }, }, }, kiro: { @@ -317,7 +322,7 @@ const _OPEN_IN_APPS = { appNames: ['Kiro'], }, win32: { - openCommands: ['start "" kiro {{path}}'], + openCommands: ['kiro {{path}}'], checkCommands: ['kiro'], }, linux: { @@ -341,7 +346,7 @@ const _OPEN_IN_APPS = { appNames: ['Antigravity'], }, win32: { - openCommands: ['start "" antigravity {{path}}'], + openCommands: ['antigravity {{path}}'], checkCommands: ['antigravity'], }, linux: { @@ -365,7 +370,7 @@ const _OPEN_IN_APPS = { appNames: ['Trae'], }, win32: { - openCommands: ['start "" trae "{{path_raw}}"'], + openCommands: ['trae "{{path_raw}}"'], checkCommands: ['trae'], }, linux: { @@ -389,7 +394,7 @@ const _OPEN_IN_APPS = { appNames: ['Trae Solo'], }, win32: { - openCommands: ['start "" trae-solo "{{path_raw}}"'], + openCommands: ['trae-solo "{{path_raw}}"'], checkCommands: ['trae-solo'], }, linux: {