提交 b7996ed7 编写于 作者: B Benjamin Pasero

editors - tweak options around group activation more

上级 61c52d0d
...@@ -82,17 +82,33 @@ export interface IResourceInput extends IBaseResourceInput { ...@@ -82,17 +82,33 @@ export interface IResourceInput extends IBaseResourceInput {
export interface IEditorOptions { export interface IEditorOptions {
/** /**
* Tells the editor to not receive keyboard focus when the editor is being opened. This * Tells the editor to not receive keyboard focus when the editor is being opened.
* will also prevent the group the editor opens in to become active. This can be overridden
* via the `forceActive` option.
* *
* By default, the editor will receive keyboard focus on open. * Will also not activate the group the editor opens in unless the group is already the active one.
* This behaviour can be overridden via the `forceActive` option.
*/ */
readonly preserveFocus?: boolean; readonly preserveFocus?: boolean;
/** /**
* Tells the group the editor opens in to become active even if either `preserveFocus: true` * This option is only relevant if an editor is opened into a group that is not active. In
* or `inactive: true` are specified. * most cases opening an editor into an inactive group will cause it to become active. With
* `preserveActive: true` in combination with `preserveFocus: true` an editor can be opened
* while keeping the current group active.
*
* Other options like `preserveFocus`, `inactive` and `forceActive` can have an impact on
* whether a group gets activated or not.
*
* Note: `forceActive: true` will always win over `preserveActive: true`.
*/
readonly preserveActive?: boolean;
/**
* This option is only relevant if an editor is opened into a group that is not active. In
* most cases opening an editor into an inactive group will cause it to become active. With
* `forceActive` the inactive group will become active independent of other options such as
* `preserveFocus` or `inactive`.
*
* Note: `forceActive: true` will always win over `preserveActive: true`.
*/ */
readonly forceActive?: boolean; readonly forceActive?: boolean;
...@@ -132,8 +148,10 @@ export interface IEditorOptions { ...@@ -132,8 +148,10 @@ export interface IEditorOptions {
/** /**
* An active editor that is opened will show its contents directly. Set to true to open an editor * An active editor that is opened will show its contents directly. Set to true to open an editor
* in the background. This will also prevent the group the editor opens in to become active. This * in the background without loading its contents.
* can be overridden via the `forceActive` option. *
* Will also not activate the group the editor opens in unless the group is already the active one.
* This behaviour can be overridden via the `forceActive` option.
*/ */
readonly inactive?: boolean; readonly inactive?: boolean;
......
...@@ -835,10 +835,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView { ...@@ -835,10 +835,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
let restoreGroup = false; let restoreGroup = false;
if (options && options.forceActive) { if (options && options.forceActive) {
// Always respect option to force activate an editor group. // First, respect option to force activate an editor group.
activateGroup = true; activateGroup = true;
} else if (options && options.preserveActive) {
// Second, respect option to preserve active editor group.
activateGroup = false;
} else if (openEditorOptions.active) { } else if (openEditorOptions.active) {
// Otherwise, we only activate/restore an editor which is // Third, we only activate/restore an editor which is
// opening as active editor. // opening as active editor.
// If preserveFocus is enabled, we only restore but never // If preserveFocus is enabled, we only restore but never
// activate the group. // activate the group.
......
...@@ -172,6 +172,12 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { ...@@ -172,6 +172,12 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
modifiedInput.setForceOpenAsBinary(); modifiedInput.setForceOpenAsBinary();
} }
// Make sure to not steal away the currently active group
// because we are triggering another openEditor() call
// and do not control the initial intent that resulted
// in us now opening as binary.
options.overwrite({ preserveActive: true, forceActive: false });
this.editorService.openEditor(binaryDiffInput, options, this.group); this.editorService.openEditor(binaryDiffInput, options, this.group);
return true; return true;
......
...@@ -713,17 +713,33 @@ export class EditorOptions implements IEditorOptions { ...@@ -713,17 +713,33 @@ export class EditorOptions implements IEditorOptions {
} }
/** /**
* Tells the editor to not receive keyboard focus when the editor is being opened. This * Tells the editor to not receive keyboard focus when the editor is being opened.
* will also prevent the group the editor opens in to become active. This can be overridden
* via the `forceActive` option.
* *
* By default, the editor will receive keyboard focus on open. * Will also not activate the group the editor opens in unless the group is already the active one.
* This behaviour can be overridden via the `forceActive` option.
*/ */
preserveFocus: boolean | undefined; preserveFocus: boolean | undefined;
/** /**
* Tells the group the editor opens in to become active even if either `preserveFocus: true` * This option is only relevant if an editor is opened into a group that is not active. In
* or `inactive: true` are specified. * most cases opening an editor into an inactive group will cause it to become active. With
* `preserveActive: true` in combination with `preserveFocus: true` an editor can be opened
* while keeping the current group active.
*
* Other options like `preserveFocus`, `inactive` and `forceActive` can have an impact on
* whether a group gets activated or not.
*
* Note: `forceActive: true` will always win over `preserveActive: true`.
*/
preserveActive: boolean | undefined;
/**
* This option is only relevant if an editor is opened into a group that is not active. In
* most cases opening an editor into an inactive group will cause it to become active. With
* `forceActive` the inactive group will become active independent of other options such as
* `preserveFocus` or `inactive`.
*
* Note: `forceActive: true` will always win over `preserveActive: true`.
*/ */
forceActive: boolean | undefined; forceActive: boolean | undefined;
...@@ -757,8 +773,10 @@ export class EditorOptions implements IEditorOptions { ...@@ -757,8 +773,10 @@ export class EditorOptions implements IEditorOptions {
/** /**
* An active editor that is opened will show its contents directly. Set to true to open an editor * An active editor that is opened will show its contents directly. Set to true to open an editor
* in the background. This will also prevent the group the editor opens in to become active. This * in the background without loading its contents.
* can be overridden via the `forceActive` option. *
* Will also not activate the group the editor opens in unless the group is already the active one.
* This behaviour can be overridden via the `forceActive` option.
*/ */
inactive: boolean | undefined; inactive: boolean | undefined;
...@@ -788,6 +806,10 @@ export class EditorOptions implements IEditorOptions { ...@@ -788,6 +806,10 @@ export class EditorOptions implements IEditorOptions {
this.preserveFocus = options.preserveFocus; this.preserveFocus = options.preserveFocus;
} }
if (typeof options.preserveActive === 'boolean') {
this.preserveActive = options.preserveActive;
}
if (typeof options.forceActive === 'boolean') { if (typeof options.forceActive === 'boolean') {
this.forceActive = options.forceActive; this.forceActive = options.forceActive;
} }
......
...@@ -326,7 +326,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut ...@@ -326,7 +326,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
// Binary editor that should reload from event // Binary editor that should reload from event
if (resource && editor.input && isBinaryEditor && (e.contains(resource, FileChangeType.UPDATED) || e.contains(resource, FileChangeType.ADDED))) { if (resource && editor.input && isBinaryEditor && (e.contains(resource, FileChangeType.UPDATED) || e.contains(resource, FileChangeType.ADDED))) {
this.editorService.openEditor(editor.input, { forceReload: true, preserveFocus: true }, editor.group); this.editorService.openEditor(editor.input, { forceReload: true, preserveFocus: true, preserveActive: true }, editor.group);
} }
}); });
} }
......
...@@ -225,6 +225,13 @@ export class TextFileEditor extends BaseTextEditor { ...@@ -225,6 +225,13 @@ export class TextFileEditor extends BaseTextEditor {
private openAsBinary(input: FileEditorInput, options: EditorOptions): void { private openAsBinary(input: FileEditorInput, options: EditorOptions): void {
input.setForceOpenAsBinary(); input.setForceOpenAsBinary();
// Make sure to not steal away the currently active group
// because we are triggering another openEditor() call
// and do not control the initial intent that resulted
// in us now opening as binary.
options.overwrite({ preserveActive: true, forceActive: false });
this.editorService.openEditor(input, options, this.group); this.editorService.openEditor(input, options, this.group);
} }
......
...@@ -225,23 +225,23 @@ async function saveAll(saveAllArguments: any, editorService: IEditorService, unt ...@@ -225,23 +225,23 @@ async function saveAll(saveAllArguments: any, editorService: IEditorService, unt
// Store some properties per untitled file to restore later after save is completed // Store some properties per untitled file to restore later after save is completed
const groupIdToUntitledResourceInput = new Map<number, IResourceInput[]>(); const groupIdToUntitledResourceInput = new Map<number, IResourceInput[]>();
editorGroupService.groups.forEach(g => { editorGroupService.groups.forEach(group => {
const activeEditorResource = g.activeEditor && g.activeEditor.getResource(); const activeEditorResource = group.activeEditor && group.activeEditor.getResource();
g.editors.forEach(e => { group.editors.forEach(e => {
const resource = e.getResource(); const resource = e.getResource();
if (resource && untitledEditorService.isDirty(resource)) { if (resource && untitledEditorService.isDirty(resource)) {
if (!groupIdToUntitledResourceInput.has(g.id)) { if (!groupIdToUntitledResourceInput.has(group.id)) {
groupIdToUntitledResourceInput.set(g.id, []); groupIdToUntitledResourceInput.set(group.id, []);
} }
groupIdToUntitledResourceInput.get(g.id)!.push({ groupIdToUntitledResourceInput.get(group.id)!.push({
encoding: untitledEditorService.getEncoding(resource), encoding: untitledEditorService.getEncoding(resource),
resource, resource,
options: { options: {
inactive: activeEditorResource ? activeEditorResource.toString() !== resource.toString() : true, inactive: activeEditorResource ? activeEditorResource.toString() !== resource.toString() : true,
pinned: true, pinned: true,
preserveFocus: true, preserveFocus: true,
index: g.getIndexOfEditor(e) index: group.getIndexOfEditor(e)
} }
}); });
} }
......
...@@ -241,8 +241,7 @@ export class ExplorerView extends ViewletPanel { ...@@ -241,8 +241,7 @@ export class ExplorerView extends ViewletPanel {
const activeFile = this.getActiveFile(); const activeFile = this.getActiveFile();
if (!activeFile && !focused[0].isDirectory) { if (!activeFile && !focused[0].isDirectory) {
// Open the focused element in the editor if there is currently no file opened #67708 // Open the focused element in the editor if there is currently no file opened #67708
this.editorService.openEditor({ resource: focused[0].resource, options: { preserveFocus: true, revealIfVisible: true } }) this.editorService.openEditor({ resource: focused[0].resource, options: { preserveFocus: true, revealIfVisible: true } });
.then(undefined, onUnexpectedError);
} }
} }
} }
......
...@@ -15,7 +15,7 @@ import { URI } from 'vs/base/common/uri'; ...@@ -15,7 +15,7 @@ import { URI } from 'vs/base/common/uri';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import * as arrays from 'vs/base/common/arrays'; import * as arrays from 'vs/base/common/arrays';
import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
export class DirtyFilesTracker extends Disposable implements IWorkbenchContribution { export class DirtyFilesTracker extends Disposable implements IWorkbenchContribution {
private isDocumentedEdited: boolean; private isDocumentedEdited: boolean;
...@@ -88,7 +88,6 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut ...@@ -88,7 +88,6 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut
} }
private doOpenDirtyResources(resources: URI[]): void { private doOpenDirtyResources(resources: URI[]): void {
const activeEditor = this.editorService.activeControl;
// Open // Open
this.editorService.openEditors(resources.map(resource => { this.editorService.openEditors(resources.map(resource => {
...@@ -96,7 +95,7 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut ...@@ -96,7 +95,7 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut
resource, resource,
options: { inactive: true, pinned: true, preserveFocus: true } options: { inactive: true, pinned: true, preserveFocus: true }
}; };
}), activeEditor ? activeEditor.group : ACTIVE_GROUP); }));
} }
private onTextFilesSaved(e: TextFileModelChangeEvent[]): void { private onTextFilesSaved(e: TextFileModelChangeEvent[]): void {
......
...@@ -250,18 +250,23 @@ export class EditorService extends Disposable implements EditorServiceImpl { ...@@ -250,18 +250,23 @@ export class EditorService extends Disposable implements EditorServiceImpl {
} }
if (typedEditor && resolvedGroup) { if (typedEditor && resolvedGroup) {
// Unless the editor opens as inactive editor or we are instructed to open a side group,
// ensure that the group gets activated even if preserveFocus: true.
//
// Not enforcing this for side groups supports a historic scenario we have: repeated
// Alt-clicking of files in the explorer always open into the same side group and not
// cause a group to be created each time.
if ( if (
typedOptions && !typedOptions.inactive && // never for inactive editors this.editorGroupService.activeGroup !== resolvedGroup && // only if target group is not already active
typedOptions.preserveFocus && // only if preserveFocus typedOptions && !typedOptions.inactive && // never for inactive editors
typeof typedOptions.forceActive !== 'boolean' && // only if forceActive is not already defined (either true or false) typedOptions.preserveFocus && // only if preserveFocus
candidateGroup !== SIDE_GROUP // never for the SIDE_GROUP typeof typedOptions.forceActive !== 'boolean' && // only if forceActive is not already defined (either true or false)
typeof typedOptions.preserveActive !== 'boolean' && // only if preserveActive is not already defined (either true or false)
candidateGroup !== SIDE_GROUP // never for the SIDE_GROUP
) { ) {
// If the resolved group is not the active one, we typically
// want the group to become active. There are a few cases
// where we stay away from encorcing this, e.g. if the caller
// is already providing `forceActive` or `preserveActive`.
//
// Specifically for historic reasons we do not activate a
// group is it is opened as `SIDE_GROUP` with `preserveFocus:true`.
// repeated Alt-clicking of files in the explorer always open
// into the same side group and not cause a group to be created each time.
typedOptions.overwrite({ forceActive: true }); typedOptions.overwrite({ forceActive: true });
} }
......
...@@ -364,7 +364,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic ...@@ -364,7 +364,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
const activeEditorGroup = this.editorGroupService.activeGroup; const activeEditorGroup = this.editorGroupService.activeGroup;
const sideEditorGroup = this.editorGroupService.addGroup(activeEditorGroup.id, GroupDirection.RIGHT); const sideEditorGroup = this.editorGroupService.addGroup(activeEditorGroup.id, GroupDirection.RIGHT);
return Promise.all([ return Promise.all([
this.editorService.openEditor({ resource: this.defaultSettingsRawResource, options: { pinned: true, preserveFocus: true, revealIfOpened: true }, label: nls.localize('defaultSettings', "Default Settings"), description: '' }), this.editorService.openEditor({ resource: this.defaultSettingsRawResource, options: { pinned: true, preserveFocus: true, preserveActive: true, revealIfOpened: true }, label: nls.localize('defaultSettings', "Default Settings"), description: '' }),
this.editorService.openEditor(editableSettingsEditorInput, { pinned: true, revealIfOpened: true }, sideEditorGroup.id) this.editorService.openEditor(editableSettingsEditorInput, { pinned: true, revealIfOpened: true }, sideEditorGroup.id)
]).then(([defaultEditor, editor]) => withNullAsUndefined(editor)); ]).then(([defaultEditor, editor]) => withNullAsUndefined(editor));
} else { } else {
......
...@@ -685,7 +685,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer ...@@ -685,7 +685,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
protected async promptForPath(resource: URI, defaultUri: URI, availableFileSystems?: string[]): Promise<URI | undefined> { protected async promptForPath(resource: URI, defaultUri: URI, availableFileSystems?: string[]): Promise<URI | undefined> {
// Help user to find a name for the file by opening it first // Help user to find a name for the file by opening it first
await this.editorService.openEditor({ resource, options: { revealIfOpened: true, preserveFocus: true, } }); await this.editorService.openEditor({ resource, options: { revealIfOpened: true, preserveFocus: true } });
return this.fileDialogService.pickFileToSave(this.getSaveDialogOptions(defaultUri, availableFileSystems)); return this.fileDialogService.pickFileToSave(this.getSaveDialogOptions(defaultUri, availableFileSystems));
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册