Skip to content

Commit dc3f34e

Browse files
committed
Fixes #3952, #3969
Adds Windsurf support, and dyanmic support for other vscode-clones Avoids requiring shell integration for rebase
1 parent 35b8a4e commit dc3f34e

File tree

6 files changed

+79
-16
lines changed

6 files changed

+79
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
1515
- Adds dynamic model loading for GitHub Models and HuggingFace models
1616
- Adds a `gitlens.ai.modelOptions.temperature` setting to specify the temperature (randomness) for AI models that support it
1717
- Adds a _Switch Model_ button to the AI confirmation prompts
18+
- Adds Windsurf support — closes [#3969](https://github.com/gitkraken/vscode-gitlens/issues/3969)
1819

1920
### Changed
2021

2122
- Improves performance of updates to active and recent branches on the _Home_ view
2223

2324
### Fixed
2425

26+
- Fixes [#3952](https://github.com/gitkraken/vscode-gitlens/issues/3952) - Interactive rebase doesn't work in GL without VS Code added to path
2527
- Fixes [#3938](https://github.com/gitkraken/vscode-gitlens/issues/3938) - GitLens automatically initiating an external sign-in after install on vscode.dev
2628
- Fixes [#3946](https://github.com/gitkraken/vscode-gitlens/issues/3946) - Home View doesn't update repo state changes made when hidden
2729

src/commands/git/rebase.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { DirectiveQuickPickItem } from '../../quickpicks/items/directive';
1212
import { createDirectiveQuickPickItem, Directive } from '../../quickpicks/items/directive';
1313
import type { FlagsQuickPickItem } from '../../quickpicks/items/flags';
1414
import { createFlagsQuickPickItem } from '../../quickpicks/items/flags';
15-
import { getEditorCommand } from '../../system/-webview/vscode';
15+
import { getHostEditorCommand } from '../../system/-webview/vscode';
1616
import { pluralize } from '../../system/string';
1717
import type { ViewsWithRepositoryFolders } from '../../views/viewBase';
1818
import type {
@@ -87,7 +87,7 @@ export class RebaseGitCommand extends QuickCommand<State> {
8787
if (state.flags.includes('--interactive')) {
8888
await this.container.rebaseEditor.enableForNextUse();
8989

90-
const editor = getEditorCommand();
90+
const editor = await getHostEditorCommand();
9191
configs = ['-c', `"sequence.editor=${editor}"`];
9292
}
9393

src/env/browser/platform.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { Platform } from '../node/platform';
2+
13
export const isWeb = true;
24

35
const _platform = (navigator as any)?.userAgentData?.platform;
@@ -7,7 +9,7 @@ export const isLinux = _platform === 'Linux' || _userAgent.includes('Linux');
79
export const isMac = _platform === 'macOS' || _userAgent.includes('Macintosh');
810
export const isWindows = _platform === 'Windows' || _userAgent.includes('Windows');
911

10-
export function getPlatform(): string {
12+
export function getPlatform(): Platform {
1113
if (isWindows) return 'web-windows';
1214
if (isMac) return 'web-macOS';
1315
if (isLinux) return 'web-linux';

src/env/node/git/git.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { parseGitRemoteUrl } from '../../../git/parsers/remoteParser';
3838
import { isUncommitted, isUncommittedStaged, shortenRevision } from '../../../git/utils/revision.utils';
3939
import { configuration } from '../../../system/-webview/configuration';
4040
import { splitPath } from '../../../system/-webview/path';
41-
import { getEditorCommand } from '../../../system/-webview/vscode';
41+
import { getHostEditorCommand } from '../../../system/-webview/vscode';
4242
import { splitAt } from '../../../system/array';
4343
import { log } from '../../../system/decorators/log';
4444
import { join } from '../../../system/iterable';
@@ -2322,7 +2322,7 @@ export class Git {
23222322
const git = normalizePath(location.path ?? 'git');
23232323

23242324
const coreEditorConfig = configuration.get('terminal.overrideGitEditor')
2325-
? `-c "core.editor=${getEditorCommand()}" `
2325+
? `-c "core.editor=${await getHostEditorCommand()}" `
23262326
: '';
23272327

23282328
const parsedArgs = args.map(arg => (arg.startsWith('#') || /['();$|>&<]/.test(arg) ? `"${arg}"` : arg));

src/env/node/platform.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ export const isLinux = platform === 'linux';
99
export const isMac = platform === 'darwin';
1010
export const isWindows = platform === 'win32';
1111

12-
export function getPlatform(): string {
12+
type OperatingSystems = 'windows' | 'macOS' | 'linux' | 'unknown';
13+
export type Platform = OperatingSystems | 'web' | `web-${OperatingSystems}` | 'unknown';
14+
15+
export function getPlatform(): Platform {
1316
if (isWindows) return 'windows';
1417
if (isMac) return 'macOS';
1518
if (isLinux) return 'linux';

src/system/-webview/vscode.ts

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import type {
88
WorkspaceFolder,
99
} from 'vscode';
1010
import { version as codeVersion, ColorThemeKind, env, Uri, ViewColumn, window, workspace } from 'vscode';
11+
import { getPlatform } from '@env/platform';
1112
import type { IconPath } from '../../@types/vscode.iconpath';
1213
import { imageMimetypes, Schemes, trackableSchemes } from '../../constants';
1314
import type { Container } from '../../container';
1415
import { isGitUri } from '../../git/gitUri';
1516
import { Logger } from '../logger';
16-
import { extname, normalizePath } from '../path';
17+
import { extname, joinPaths, normalizePath } from '../path';
1718
import { satisfies } from '../version';
1819
import { executeCoreCommand } from './command';
1920
import { configuration } from './configuration';
@@ -70,26 +71,81 @@ export function findOrOpenEditors(uris: Uri[], options?: TextDocumentShowOptions
7071
}
7172
}
7273

73-
export function getEditorCommand(): string {
74-
let editor;
74+
let _hostExecutablePath: string | undefined;
75+
export async function getHostExecutablePath(): Promise<string> {
76+
if (_hostExecutablePath != null) return _hostExecutablePath;
77+
78+
const platform = getPlatform();
79+
80+
let app: string;
7581
switch (env.appName) {
82+
case 'Visual Studio Code':
83+
app = 'code';
84+
break;
7685
case 'Visual Studio Code - Insiders':
77-
editor = 'code-insiders --wait --reuse-window';
86+
app = 'code-insiders';
7887
break;
7988
case 'Visual Studio Code - Exploration':
80-
editor = 'code-exploration --wait --reuse-window';
89+
app = 'code-exploration';
8190
break;
8291
case 'VSCodium':
83-
editor = 'codium --wait --reuse-window';
92+
app = 'codium';
8493
break;
8594
case 'Cursor':
86-
editor = 'cursor --wait --reuse-window';
95+
app = 'cursor';
8796
break;
88-
default:
89-
editor = 'code --wait --reuse-window';
97+
case 'Windsurf':
98+
app = 'windsurf';
99+
break;
100+
default: {
101+
try {
102+
const bytes = await workspace.fs.readFile(Uri.file(joinPaths(env.appRoot, 'product.json')));
103+
const product = JSON.parse(new TextDecoder().decode(bytes));
104+
app = product.applicationName;
105+
} catch {
106+
app = 'code';
107+
}
108+
109+
break;
110+
}
111+
}
112+
113+
_hostExecutablePath = app;
114+
if (env.remoteName) return app;
115+
116+
async function checkPath(path: string) {
117+
try {
118+
await workspace.fs.stat(Uri.file(path));
119+
return path;
120+
} catch {
121+
return undefined;
122+
}
123+
}
124+
125+
switch (platform) {
126+
case 'windows':
127+
case 'linux':
128+
_hostExecutablePath =
129+
(await checkPath(joinPaths(env.appRoot, '..', '..', 'bin', app))) ??
130+
(await checkPath(joinPaths(env.appRoot, 'bin', app))) ??
131+
app;
90132
break;
133+
case 'macOS':
134+
_hostExecutablePath =
135+
(await checkPath(joinPaths(env.appRoot, 'bin', app))) ??
136+
(await checkPath(joinPaths(env.appRoot, '..', '..', 'bin', app))) ??
137+
app;
138+
break;
139+
default:
140+
throw new Error(`Unsupported platform: ${platform}`);
91141
}
92-
return editor;
142+
143+
return _hostExecutablePath;
144+
}
145+
146+
export async function getHostEditorCommand(): Promise<string> {
147+
const path = normalizePath(await getHostExecutablePath()).replace(/ /g, '\\ ');
148+
return `${path} --wait --reuse-window`;
93149
}
94150

95151
export function getEditorIfActive(document: TextDocument): TextEditor | undefined {

0 commit comments

Comments
 (0)