diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 37061156a562..aee0fab76e1c 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -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, JoinEditorsAction, 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(JoinEditorsAction, JoinEditorsAction.ID, JoinEditorsAction.LABEL), 'View: Join Editors', 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); diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index c36ccc0d608c..f63ad52c7eb2 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -106,6 +106,71 @@ export class SplitEditorAction extends Action { } } +export class JoinEditorsAction extends Action { + + public static ID = 'workbench.action.joinEditors'; + public static LABEL = nls.localize('joinEditors', "Join Editors"); + + constructor( + id: string, + label: string, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, + @IEditorGroupService private editorGroupService: IEditorGroupService + ) { + super(id, label, 'join-editors-action'); + } + + public run(context?: IEditorContext): TPromise { + let editorToJoin: IEditor; + if (context) { + editorToJoin = this.editorService.getVisibleEditors()[this.editorGroupService.getStacksModel().positionOfGroup(context.group)]; + } else { + editorToJoin = this.editorService.getActiveEditor(); + } + + // Return if no editor to join + if (!editorToJoin) { + return TPromise.as(true); + } + + const visibleEditors = this.editorService.getVisibleEditors(); + + // Return if has no other group to join to + if (visibleEditors.length <= 1) { + return TPromise.as(true); + } + + const toJoinPosition = editorToJoin.position; + let targetPosition: number; + + // Join to next group if is position one, otherwise join to previous group + if (toJoinPosition === Position.ONE) { + targetPosition = toJoinPosition + 1; + } else { + targetPosition = toJoinPosition - 1; + } + + const toJoinEditorInput = editorToJoin.input; + const toJoinGroup = this.editorGroupService.getStacksModel().groupAt(toJoinPosition); + const targetGroup = this.editorGroupService.getStacksModel().groupAt(targetPosition); + + const toJoinEditors = toJoinGroup.getEditors(); + const toJoinEditorsTotalCount = toJoinEditors.length; + + // If an editor exists in joining group and target group, only the editor in the joining group is kept. + if (targetPosition < toJoinPosition) { + toJoinEditors.forEach(e => this.editorGroupService.moveEditor(e, toJoinPosition, targetPosition, targetGroup.count)); + } else { + toJoinEditors.forEach(e => this.editorGroupService.moveEditor(e, toJoinPosition, targetPosition, toJoinEditorsTotalCount - toJoinGroup.count)); + } + + // Re-activate the active editor + this.editorService.openEditor(toJoinEditorInput); + + return TPromise.as(true); + } +} + export class NavigateBetweenGroupsAction extends Action { public static ID = 'workbench.action.navigateEditorGroups';