提交 dd197f19 编写于 作者: B Benjamin Pasero 提交者: GitHub

Merge pull request #22389 from initialshl/join-editors-command

Implement join editors command
......@@ -30,7 +30,7 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes';
import {
CloseEditorsInGroupAction, CloseEditorsInOtherGroupsAction, CloseAllEditorsAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, KeepEditorAction, CloseOtherEditorsInGroupAction, OpenToSideAction, RevertAndCloseEditorAction,
CloseEditorsInGroupAction, CloseEditorsInOtherGroupsAction, CloseAllEditorsAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, JoinTwoGroupsAction, KeepEditorAction, CloseOtherEditorsInGroupAction, OpenToSideAction, RevertAndCloseEditorAction,
NavigateBetweenGroupsAction, FocusActiveGroupAction, FocusFirstGroupAction, FocusSecondGroupAction, FocusThirdGroupAction, EvenGroupWidthsAction, MaximizeGroupAction, MinimizeOtherGroupsAction, FocusPreviousGroup, FocusNextGroup, ShowEditorsInGroupOneAction,
toEditorQuickOpenEntry, CloseLeftEditorsInGroupAction, CloseRightEditorsInGroupAction, OpenNextEditor, OpenPreviousEditor, NavigateBackwardsAction, NavigateForwardAction, ReopenClosedEditorAction, OpenPreviousRecentlyUsedEditorInGroupAction, NAVIGATE_IN_GROUP_ONE_PREFIX,
OpenPreviousEditorFromHistoryAction, ShowAllEditorsAction, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, ClearEditorHistoryAction, ShowEditorsInGroupTwoAction, MoveEditorRightInGroupAction, OpenNextEditorInGroup, OpenPreviousEditorInGroup,
......@@ -331,6 +331,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(CloseEditorsInGroupAct
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseOtherEditorsInGroupAction, CloseOtherEditorsInGroupAction.ID, CloseOtherEditorsInGroupAction.LABEL, { primary: null, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_T } }), 'View: Close Other Editors', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseEditorsInOtherGroupsAction, CloseEditorsInOtherGroupsAction.ID, CloseEditorsInOtherGroupsAction.LABEL), 'View: Close Editors in Other Groups', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(SplitEditorAction, SplitEditorAction.ID, SplitEditorAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH }), 'View: Split Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(JoinTwoGroupsAction, JoinTwoGroupsAction.ID, JoinTwoGroupsAction.LABEL), 'View: Join Editors of Two Groups', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(NavigateBetweenGroupsAction, NavigateBetweenGroupsAction.ID, NavigateBetweenGroupsAction.LABEL), 'View: Navigate Between Editor Groups', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusActiveGroupAction, FocusActiveGroupAction.ID, FocusActiveGroupAction.LABEL), 'View: Focus Active Editor Group', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusFirstGroupAction, FocusFirstGroupAction.ID, FocusFirstGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_1 }), 'View: Focus First Editor Group', category);
......
......@@ -106,6 +106,71 @@ export class SplitEditorAction extends Action {
}
}
export class JoinTwoGroupsAction extends Action {
public static ID = 'workbench.action.joinTwoGroups';
public static LABEL = nls.localize('joinTwoGroups', "Join Editors of Two Groups");
constructor(
id: string,
label: string,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IEditorGroupService private editorGroupService: IEditorGroupService
) {
super(id, label);
}
public run(context?: IEditorContext): TPromise<any> {
const editorStacksModel = this.editorGroupService.getStacksModel();
// Return if has no other group to join to
if (editorStacksModel.groups.length < 2) {
return TPromise.as(true);
}
let fromPosition: number;
let toPosition: number;
// Joining group is from context, or the active group
if (context) {
fromPosition = editorStacksModel.positionOfGroup(context.group);
} else {
fromPosition = editorStacksModel.positionOfGroup(editorStacksModel.activeGroup);
}
// Target group is next group if joining from position one, otherwise it is the previous group
if (fromPosition === Position.ONE) {
toPosition = fromPosition + 1;
} else {
toPosition = fromPosition - 1;
}
const fromGroup = editorStacksModel.groupAt(fromPosition);
const toGroup = editorStacksModel.groupAt(toPosition);
const activeEditor = fromGroup.activeEditor;
const fromGroupEditors = fromGroup.getEditors();
// Insert the editors to the start if moving to the next group, otherwise insert to the end
// If an editor exists in both groups, its index is respected as in the joining group
const movingToNextGroup = fromPosition < toPosition;
let index = movingToNextGroup ? 0 : toGroup.count;
// Inactive and preserve focus options are used to prevent unnecessary switchings of active editor or group
fromGroupEditors.forEach(e => {
const inactive = e !== activeEditor;
this.editorGroupService.moveEditor(e, fromPosition, toPosition, { index, inactive, preserveFocus: inactive });
index = movingToNextGroup ? index + 1 : toGroup.count;
});
// Focus may be lost when the joining group is closed, regain focus on the target group
this.editorGroupService.focusGroup(toGroup);
return TPromise.as(true);
}
}
export class NavigateBetweenGroupsAction extends Action {
public static ID = 'workbench.action.navigateEditorGroups';
......
......@@ -115,7 +115,7 @@ function moveActiveTab(args: ActiveEditorMoveArguments, activeEditor: IEditor, a
}
index = index < 0 ? 0 : index >= editorGroup.count ? editorGroup.count - 1 : index;
editorGroupsService.moveEditor(activeEditor.input, editorGroup, editorGroup, index);
editorGroupsService.moveEditor(activeEditor.input, editorGroup, editorGroup, { index });
}
function moveActiveEditorToGroup(args: ActiveEditorMoveArguments, activeEditor: IEditor, accessor: ServicesAccessor): void {
......
......@@ -24,7 +24,7 @@ import { BaseEditor, EditorDescriptor } from 'vs/workbench/browser/parts/editor/
import { IEditorRegistry, Extensions as EditorExtensions, EditorInput, EditorOptions, ConfirmResult, IWorkbenchEditorConfiguration, IEditorDescriptor, TextEditorOptions, SideBySideEditorInput, TextCompareEditorVisible, TEXT_DIFF_EDITOR_ID } from 'vs/workbench/common/editor';
import { EditorGroupsControl, Rochade, IEditorGroupsControl, ProgressState } from 'vs/workbench/browser/parts/editor/editorGroupsControl';
import { WorkbenchProgressService } from 'vs/workbench/services/progress/browser/progressService';
import { IEditorGroupService, GroupOrientation, GroupArrangement, ITabOptions } from 'vs/workbench/services/group/common/groupService';
import { IEditorGroupService, GroupOrientation, GroupArrangement, ITabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEditorPart } from 'vs/workbench/services/editor/browser/editorService';
import { IPartService } from 'vs/workbench/services/part/common/partService';
......@@ -808,9 +808,9 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
this._onEditorsMoved.fire();
}
public moveEditor(input: EditorInput, from: EditorGroup, to: EditorGroup, index?: number): void;
public moveEditor(input: EditorInput, from: Position, to: Position, index?: number): void;
public moveEditor(input: EditorInput, arg2: any, arg3: any, index?: number): void {
public moveEditor(input: EditorInput, from: EditorGroup, to: EditorGroup, moveOptions?: IMoveOptions): void;
public moveEditor(input: EditorInput, from: Position, to: Position, moveOptions?: IMoveOptions): void;
public moveEditor(input: EditorInput, arg2: any, arg3: any, moveOptions?: IMoveOptions): void {
const fromGroup = (typeof arg2 === 'number') ? this.stacks.groupAt(arg2) : arg2;
if (!fromGroup) {
return;
......@@ -818,18 +818,20 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
// Move within group
if (arg2 === arg3) {
this.doMoveEditorInsideGroups(input, fromGroup, index);
this.doMoveEditorInsideGroups(input, fromGroup, moveOptions);
}
// Move across groups
else {
const toPosition = (typeof arg3 === 'number') ? arg3 : this.stacks.positionOfGroup(arg3);
this.doMoveEditorAcrossGroups(input, fromGroup, toPosition, index);
this.doMoveEditorAcrossGroups(input, fromGroup, toPosition, moveOptions);
}
}
private doMoveEditorInsideGroups(input: EditorInput, group: EditorGroup, toIndex: number): void {
private doMoveEditorInsideGroups(input: EditorInput, group: EditorGroup, moveOptions?: IMoveOptions): void {
let toIndex = moveOptions && moveOptions.index;
if (typeof toIndex !== 'number') {
return; // do nothing if we move into same group without index
}
......@@ -844,7 +846,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
group.pin(input);
}
private doMoveEditorAcrossGroups(input: EditorInput, fromGroup: EditorGroup, to: Position, index?: number): void {
private doMoveEditorAcrossGroups(input: EditorInput, fromGroup: EditorGroup, to: Position, moveOptions?: IMoveOptions): void {
if (fromGroup.count === 1) {
const toGroup = this.stacks.groupAt(to);
if (!toGroup && this.stacks.positionOfGroup(fromGroup) < to) {
......@@ -852,13 +854,17 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
}
}
const index = moveOptions && moveOptions.index;
const inactive = moveOptions && moveOptions.inactive;
const preserveFocus = moveOptions && moveOptions.preserveFocus;
// When moving an editor, try to preserve as much view state as possible by checking
// for th editor to be a text editor and creating the options accordingly if so
let options = EditorOptions.create({ pinned: true, index });
// for the editor to be a text editor and creating the options accordingly if so
let options = EditorOptions.create({ pinned: true, index, inactive, preserveFocus });
const activeEditor = this.getActiveEditor();
const codeEditor = getCodeEditor(activeEditor);
if (codeEditor && activeEditor.position === this.stacks.positionOfGroup(fromGroup) && input.matches(activeEditor.input)) {
options = TextEditorOptions.create({ pinned: true, index });
options = TextEditorOptions.create({ pinned: true, index, inactive, preserveFocus });
(<TextEditorOptions>options).fromEditor(codeEditor);
}
......
......@@ -627,7 +627,7 @@ export class TabsTitleControl extends TitleControl {
// Move editor to target position and index
if (this.isMoveOperation(e, draggedEditor.group, group)) {
this.editorGroupService.moveEditor(draggedEditor.editor, draggedEditor.group, group, targetIndex);
this.editorGroupService.moveEditor(draggedEditor.editor, draggedEditor.group, group, { index: targetIndex });
}
// Copy: just open editor at target index
......
......@@ -642,6 +642,7 @@ export class TextEditorOptions extends EditorOptions {
options.revealIfVisible = settings.revealIfVisible;
options.pinned = settings.pinned;
options.index = settings.index;
options.inactive = settings.inactive;
if (settings.selection) {
options.startLineNumber = settings.selection.startLineNumber;
......
......@@ -491,7 +491,7 @@ export class DragAndDrop extends DefaultDragAndDrop {
if (draggedElement) {
if (draggedElement instanceof OpenEditor) {
this.editorGroupService.moveEditor(draggedElement.editorInput, model.positionOfGroup(draggedElement.editorGroup), positionOfTargetGroup, index);
this.editorGroupService.moveEditor(draggedElement.editorInput, model.positionOfGroup(draggedElement.editorGroup), positionOfTargetGroup, { index });
} else {
this.editorGroupService.moveGroup(model.positionOfGroup(draggedElement), positionOfTargetGroup);
}
......
......@@ -24,7 +24,13 @@ export interface ITabOptions {
tabCloseButton?: 'left' | 'right' | 'off';
showIcons?: boolean;
previewEditors?: boolean;
};
}
export interface IMoveOptions {
index?: number;
inactive?: boolean;
preserveFocus?: boolean;
}
/**
* The editor service allows to open editors and work on the active
......@@ -106,9 +112,10 @@ export interface IEditorGroupService {
/**
* Moves an editor from one group to another. The index in the group is optional.
* The inactive option is applied when moving across groups.
*/
moveEditor(input: IEditorInput, from: IEditorGroup, to: IEditorGroup, index?: number): void;
moveEditor(input: IEditorInput, from: Position, to: Position, index?: number): void;
moveEditor(input: IEditorInput, from: IEditorGroup, to: IEditorGroup, moveOptions?: IMoveOptions): void;
moveEditor(input: IEditorInput, from: Position, to: Position, moveOptions?: IMoveOptions): void;
/**
* Provides access to the editor stacks model
......
......@@ -32,7 +32,7 @@ import { ILifecycleService, ShutdownEvent, ShutdownReason } from 'vs/platform/li
import { EditorStacksModel } from 'vs/workbench/common/editor/editorStacksModel';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { IEditorGroupService, GroupArrangement, GroupOrientation, ITabOptions } from 'vs/workbench/services/group/common/groupService';
import { IEditorGroupService, GroupArrangement, GroupOrientation, ITabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService';
import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService';
import { FileOperationEvent, IFileService, IResolveContentOptions, IFileOperationResult, IFileStat, IImportResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent } from 'vs/platform/files/common/files';
import { IModelService } from 'vs/editor/common/services/modelService';
......@@ -449,9 +449,9 @@ export class TestEditorGroupService implements IEditorGroupService {
public unpinEditor(arg1: any, input: IEditorInput): void {
}
public moveEditor(input: IEditorInput, from: IEditorGroup, to: IEditorGroup, index?: number): void;
public moveEditor(input: IEditorInput, from: Position, to: Position, index?: number): void;
public moveEditor(input: IEditorInput, from: any, to: any, index?: number): void {
public moveEditor(input: IEditorInput, from: IEditorGroup, to: IEditorGroup, moveOptions?: IMoveOptions): void;
public moveEditor(input: IEditorInput, from: Position, to: Position, moveOptions?: IMoveOptions): void;
public moveEditor(input: IEditorInput, from: any, to: any, moveOptions?: IMoveOptions): void {
}
public getStacksModel(): EditorStacksModel {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册