Implement join editors command#22389
Conversation
|
@initialshl, thanks for your PR! By analyzing the history of the files in this pull request, we identified @egamma and @bpasero to be potential reviewers. |
|
@initialshl, |
bpasero
left a comment
There was a problem hiding this comment.
Good start, added some feedback.
This makes me think: do we want more commands that allow to "Split Editors"? Like the inverse operation of "Join Editors" which would basically mean to start a new group starting with the current active editor and move all editors to the right to a new group. Would be pretty cool :)
| 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); |
There was a problem hiding this comment.
Should this maybe be more descriptive to what it actually does? Join Editors of two Groups?
| @IWorkbenchEditorService private editorService: IWorkbenchEditorService, | ||
| @IEditorGroupService private editorGroupService: IEditorGroupService | ||
| ) { | ||
| super(id, label, 'join-editors-action'); |
There was a problem hiding this comment.
You do not need the CSS class here unless it would show up as icon, so I suggest to remove it.
| } | ||
|
|
||
| public run(context?: IEditorContext): TPromise<any> { | ||
| let editorToJoin: IEditor; |
There was a problem hiding this comment.
It looks like you only need position and input from the IEditor. If so, I suggest to completley bypass the editorService API and do all of this from the stacks model that provides all you need (inputs, groups, a way to convert from a group to a position) from editor group service (there is a bit of overlap for historic reasons).
The stacks model is really the truth of what is going up in the 1-3 editor groups and you should be able to do everything with it. The more heavy IEditor is the actual instance of control that hosts inputs.
|
|
||
| // 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)); |
There was a problem hiding this comment.
This is a bit crazy to do because for each editor that gets moved it will be opened in the target group causing an editor switch. It would be much smoother if the move would happen with the editors opening inactive on the target group and only the last one would actually be active. There is an option that can be set when opening an editor called inactive that I think we should wire into the moveEditor call so that we can optimize for this (for the openEditor call here).
|
@bpasero Thanks for the review!
Indeed, |
bpasero
left a comment
There was a problem hiding this comment.
Awesome, just a minor comment left.
| 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, index?: number, inactive?: boolean): void; |
There was a problem hiding this comment.
I suggest to put index and inactive into a new optional options bag (IMoveOptions).
| */ | ||
| 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, index?: number, inactive?: boolean): void; |
bpasero
left a comment
There was a problem hiding this comment.
more feedback, almost there 👍
| const fromGroupTotalCount = fromGroupEditors.length; | ||
|
|
||
| // If an editor exists in both groups, only the editor in the joining group is kept | ||
| if (toPosition < fromPosition) { |
There was a problem hiding this comment.
We still need to improve this: Now we start to move editors from the group to another group starting with the first editor of that group, going to the last. This is bad when the first editor of the group is also the active editor because after each editor is moved, the group will show the next editor as active.
As such, please first move all the inactive editors of the group and only at last the active editor. This will again prevent many unwanted editor change events being fired.
|
@bpasero Thanks for the feedbacks. I overlooked the And regarding the possibility of adding a new command |
|
@initialshl yes, something like "View: Split Editors into Two Groups" 👍 . Ideally we could have a common base class of both actions to share some logic for both. This PR looks nice now, thanks. I will merge it in tomorrow. |
|
is there any key combination available? |
|
@kounelios13 just assign it via keybindings settings: |
|
Hello.I've noticed something.If I have more than 2 editors open when I execute this command it won't join all of them.Is there any way to achieve this behavior? |
|
Works for me, even with 3 editor groups open. |
|
@bpasero If I have 3 editors open it will merge two of them and then it leaves me with 2 editors open |
|
@kounelios13 what would you expect to happen? |
|
@bpasero I would expect that if I have let's say 5 editors open after executing the join command it would merge them all into 1. Isn't that the purpose of this command or have I misunderstood it? |
|
@kounelios13 as the name of that action implies, it will only merge the editors of 2 groups, not all groups. |
|
Sorry my mistake. |

Fixes #20279
This command joins the editor group with the previous group (except for the first group which joins with the next group).
The order of editors in the joining group is preserved when joining with the target group.
If an editor is opened in both the joining and target group, only one will be kept, in the same position as in the joining group.