Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 35 additions & 26 deletions src/vs/workbench/browser/parts/editor/editorCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { EditorGroupColumn, columnToEditorGroup } from '../../../services/editor
import { EditorGroupLayout, GroupDirection, GroupLocation, GroupsOrder, IEditorGroup, IEditorGroupsService, IEditorReplacement, IModalEditorPart, preferredSideBySideGroupDirection } from '../../../services/editor/common/editorGroupsService.js';
import { mainWindow } from '../../../../base/browser/window.js';
import { IEditorResolverService } from '../../../services/editor/common/editorResolverService.js';
import { IEditorService, SIDE_GROUP } from '../../../services/editor/common/editorService.js';
import { IEditorService, MODAL_GROUP, SIDE_GROUP } from '../../../services/editor/common/editorService.js';
import { IPathService } from '../../../services/path/common/pathService.js';
import { IUntitledTextEditorService } from '../../../services/untitled/common/untitledTextEditorService.js';
import { DIFF_FOCUS_OTHER_SIDE, DIFF_FOCUS_PRIMARY_SIDE, DIFF_FOCUS_SECONDARY_SIDE, registerDiffEditorCommands } from './diffEditorCommands.js';
Expand Down Expand Up @@ -115,6 +115,7 @@ export const TOGGLE_MODAL_EDITOR_SIDEBAR_COMMAND_ID = 'workbench.action.toggleMo

export const API_OPEN_EDITOR_COMMAND_ID = '_workbench.open';
export const API_OPEN_DIFF_EDITOR_COMMAND_ID = '_workbench.diff';
export const API_OPEN_DIFF_EDITOR_IN_MODAL_COMMAND_ID = '_workbench.diffInModal';
export const API_OPEN_WITH_EDITOR_COMMAND_ID = '_workbench.openWith';

export const EDITOR_CORE_NAVIGATION_COMMANDS = [
Expand Down Expand Up @@ -424,17 +425,43 @@ function registerEditorGroupsLayoutCommands(): void {

function registerOpenEditorAPICommands(): void {

function mixinContext(context: IOpenEvent<unknown> | undefined, options: ITextEditorOptions | undefined, column: EditorGroupColumn | undefined): [ITextEditorOptions | undefined, EditorGroupColumn | undefined] {
function mixinContext(context: IOpenEvent<unknown> | undefined, options: ITextEditorOptions | undefined, column: EditorGroupColumn | undefined, columnOverride?: EditorGroupColumn): [ITextEditorOptions | undefined, EditorGroupColumn | undefined] {
if (!context) {
return [options, column];
return [options, columnOverride ?? column];
}

return [
{ ...context.editorOptions, ...(options ?? Object.create(null)) },
context.sideBySide ? SIDE_GROUP : column
columnOverride ?? (context.sideBySide ? SIDE_GROUP : column)
];
}

async function openDiffEditor(accessor: ServicesAccessor, originalResource: UriComponents, modifiedResource: UriComponents, labelAndOrDescription?: string | { label: string; description: string }, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?], context?: IOpenEvent<unknown>, columnOverride?: EditorGroupColumn): Promise<void> {
const editorService = accessor.get(IEditorService);
const editorGroupsService = accessor.get(IEditorGroupsService);
const configurationService = accessor.get(IConfigurationService);

const [columnArg, optionsArg] = columnAndOptions ?? [];
const [options, column] = mixinContext(context, optionsArg, columnArg, columnOverride);

let label: string | undefined = undefined;
let description: string | undefined = undefined;
if (typeof labelAndOrDescription === 'string') {
label = labelAndOrDescription;
} else if (labelAndOrDescription) {
label = labelAndOrDescription.label;
description = labelAndOrDescription.description;
}

await editorService.openEditor({
original: { resource: URI.from(originalResource, true) },
modified: { resource: URI.from(modifiedResource, true) },
label,
description,
options
}, columnToEditorGroup(editorGroupsService, configurationService, column));
}

// partial, renderer-side API command to open editor only supporting
// arguments that do not need to be converted from the extension host
// complements https://github.com/microsoft/vscode/blob/2b164efb0e6a5de3826bff62683eaeafe032284f/src/vs/workbench/api/common/extHostApiCommands.ts#L373
Expand Down Expand Up @@ -513,29 +540,11 @@ function registerOpenEditorAPICommands(): void {
});

CommandsRegistry.registerCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, async function (accessor: ServicesAccessor, originalResource: UriComponents, modifiedResource: UriComponents, labelAndOrDescription?: string | { label: string; description: string }, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?], context?: IOpenEvent<unknown>) {
const editorService = accessor.get(IEditorService);
const editorGroupsService = accessor.get(IEditorGroupsService);
const configurationService = accessor.get(IConfigurationService);

const [columnArg, optionsArg] = columnAndOptions ?? [];
const [options, column] = mixinContext(context, optionsArg, columnArg);

let label: string | undefined = undefined;
let description: string | undefined = undefined;
if (typeof labelAndOrDescription === 'string') {
label = labelAndOrDescription;
} else if (labelAndOrDescription) {
label = labelAndOrDescription.label;
description = labelAndOrDescription.description;
}
await openDiffEditor(accessor, originalResource, modifiedResource, labelAndOrDescription, columnAndOptions, context);
});

await editorService.openEditor({
original: { resource: URI.from(originalResource, true) },
modified: { resource: URI.from(modifiedResource, true) },
label,
description,
options
}, columnToEditorGroup(editorGroupsService, configurationService, column));
CommandsRegistry.registerCommand(API_OPEN_DIFF_EDITOR_IN_MODAL_COMMAND_ID, async function (accessor: ServicesAccessor, originalResource: UriComponents, modifiedResource: UriComponents, labelAndOrDescription?: string | { label: string; description: string }, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?], context?: IOpenEvent<unknown>) {
await openDiffEditor(accessor, originalResource, modifiedResource, labelAndOrDescription, columnAndOptions, context, MODAL_GROUP);
});

CommandsRegistry.registerCommand(API_OPEN_WITH_EDITOR_COMMAND_ID, async (accessor: ServicesAccessor, resource: UriComponents, id: string, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?]) => {
Expand Down
9 changes: 9 additions & 0 deletions src/vs/workbench/contrib/scm/browser/scm.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
type: 'boolean',
description: localize('scm.graph.showOutgoingChanges', "Controls whether to show outgoing changes in the Source Control Graph view."),
default: true
},
'scm.allowOpenInModalEditor': {
type: 'boolean',
description: localize('scm.allowOpenInModalEditor', "Controls whether Source Control diff editors open in a modal editor overlay."),
default: false,
tags: ['experimental'],
experiment: {
mode: 'auto'
}
}
}
});
Expand Down
5 changes: 3 additions & 2 deletions src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import { FileKind } from '../../../../platform/files/common/files.js';
import { WorkbenchToolBar } from '../../../../platform/actions/browser/toolbar.js';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
import { basename } from '../../../../base/common/path.js';
import { IEditorService } from '../../../services/editor/common/editorService.js';
import { IEditorService, MODAL_GROUP } from '../../../services/editor/common/editorService.js';
import { ScmHistoryItemResolver } from '../../multiDiffEditor/browser/scmMultiDiffSourceResolver.js';
import { IResourceNode, ResourceTree } from '../../../../base/common/resourceTree.js';
import { URI } from '../../../../base/common/uri.js';
Expand Down Expand Up @@ -2064,12 +2064,13 @@ export class SCMHistoryViewPane extends ViewPane {
const modifiedUriTitle = `${basename(historyItemChange.modifiedUri.fsPath)} (${historyItemDisplayId})`;

const title = `${originalUriTitle} \u2194 ${modifiedUriTitle}`;
const useModal = this.configurationService.getValue<boolean>('scm.allowOpenInModalEditor');
await this._editorService.openEditor({
label: title,
original: { resource: historyItemChange.originalUri },
modified: { resource: historyItemChange.modifiedUri },
options: e.editorOptions
});
}, useModal ? MODAL_GROUP : undefined);
} else if (historyItemChange.modifiedUri) {
await this._editorService.openEditor({
label: `${basename(historyItemChange.modifiedUri.fsPath)} (${historyItemDisplayId})`,
Expand Down
8 changes: 6 additions & 2 deletions src/vs/workbench/contrib/scm/browser/scmViewPane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import { RepositoryActionRunner, RepositoryRenderer } from './scmRepositoryRende
import { isDark } from '../../../../platform/theme/common/theme.js';
import { LabelFuzzyScore } from '../../../../base/browser/ui/tree/abstractTree.js';
import { Selection } from '../../../../editor/common/core/selection.js';
import { API_OPEN_DIFF_EDITOR_COMMAND_ID, API_OPEN_EDITOR_COMMAND_ID } from '../../../browser/parts/editor/editorCommands.js';
import { API_OPEN_DIFF_EDITOR_COMMAND_ID, API_OPEN_DIFF_EDITOR_IN_MODAL_COMMAND_ID, API_OPEN_EDITOR_COMMAND_ID } from '../../../browser/parts/editor/editorCommands.js';
import { getFlatContextMenuActions } from '../../../../platform/actions/browser/menuEntryActionViewItem.js';
import { Button, ButtonWithDescription, ButtonWithDropdown } from '../../../../base/browser/ui/button/button.js';
import { INotificationService } from '../../../../platform/notification/common/notification.js';
Expand Down Expand Up @@ -1723,7 +1723,11 @@ export class SCMViewPane extends ViewPane {
preserveFocus: true,
});
} else {
await this.commandService.executeCommand(e.element.command.id, ...(e.element.command.arguments || []), e);
if (e.element.command.id === API_OPEN_DIFF_EDITOR_COMMAND_ID && this.configurationService.getValue<boolean>('scm.allowOpenInModalEditor')) {
await this.commandService.executeCommand(API_OPEN_DIFF_EDITOR_IN_MODAL_COMMAND_ID, ...(e.element.command.arguments || []), e);
} else {
await this.commandService.executeCommand(e.element.command.id, ...(e.element.command.arguments || []), e);
}
}
} else {
await e.element.open(!!e.editorOptions.preserveFocus);
Expand Down
Loading