editorGroupsService.ts ×4

Frontier kind: Code frontier

unlabeled · c_60de9fe2fa3b

204 tests · 11407 LOC · 41 files · introduces 0 tests · 1075 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
4 ranges1075 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1286 ranges11407 lines · 41 files · Browse complete extent
All tests (intent)
204 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 1075 introduced LOC across 4 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/workbench/services/editor/common/editorGroupsService.ts 1075 introduced LOC · 4 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- editorGroupsService.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { Event } from '../../../../base/common/event.js';
7 > import { IInstantiationService, createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
8 > import { IEditorPane, GroupIdentifier, EditorInputWithOptions, CloseDirection, IEditorPartOptions, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, IEditorCloseEvent, IUntypedEditorInput, isEditorInput, IEditorWillMoveEvent, IMatchEditorOptions, IActiveEditorChangeEvent, IFindEditorOptions, IToolbarActions } from '../../../common/editor.js';
9 > import { EditorInput } from '../../../common/editor/editorInput.js';
10 > import { IEditorOptions, IModalEditorNavigation, IModalEditorPartOptions } from '../../../../platform/editor/common/editor.js';
11 > import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
12 > import { IDimension } from '../../../../editor/common/core/2d/dimension.js';
13 > import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
14 > import { ContextKeyValue, IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
15 > import { URI } from '../../../../base/common/uri.js';
16 > import { IGroupModelChangeEvent } from '../../../common/editor/editorGroupModel.js';
17 > import { IRectangle } from '../../../../platform/window/common/window.js';
18 > import { IMenuChangeEvent, MenuId } from '../../../../platform/actions/common/actions.js';
19 > import { DeepPartial } from '../../../../base/common/types.js';
20 >
21 > export const IEditorGroupsService = createDecorator<IEditorGroupsService>('editorGroupsService');
22 >
23 > export const enum GroupActivationReason {
24 >
25 > /**
26 > * Group was activated explicitly by user or programmatic action.
27 > */
28 > DEFAULT = 0,
29 >
30 > /**
31 > * Group was activated because a modal or auxiliary editor part was closing.
32 > */
33 > PART_CLOSE = 1
34 > }
35 >
36 > export interface IEditorGroupActivationEvent {
37 > readonly group: IEditorGroup;
38 > readonly reason: GroupActivationReason;
39 > }
40 >
41 > export const enum GroupDirection {
42 > UP,
43 > DOWN,
44 > LEFT,
45 > RIGHT
46 > }
47 >
48 > export const enum GroupOrientation {
49 > HORIZONTAL,
50 > VERTICAL
51 > }
52 >
53 > export const enum GroupLocation {
54 > FIRST,
55 > LAST,
56 > NEXT,
57 > PREVIOUS
58 > }
59 >
60 > export interface IFindGroupScope {
61 > readonly direction?: GroupDirection;
62 > readonly location?: GroupLocation;
63 > }
64 >
65 > export const enum GroupsArrangement {
66 > /**
67 > * Make the current active group consume the entire
68 > * editor area.
69 > */
70 > MAXIMIZE,
71 >
72 > /**
73 > * Make the current active group consume the maximum
74 > * amount of space possible.
75 > */
76 > EXPAND,
77 >
78 > /**
79 > * Size all groups evenly.
80 > */
81 > EVEN
82 > }
83 >
84 > export interface GroupLayoutArgument {
85 >
86 > /**
87 > * Only applies when there are multiple groups
88 > * arranged next to each other in a row or column.
89 > * If provided, their sum must be 1 to be applied
90 > * per row or column.
91 > */
92 > readonly size?: number;
93 >
94 > /**
95 > * Editor groups will be laid out orthogonal to the
96 > * parent orientation.
97 > */
98 > readonly groups?: GroupLayoutArgument[];
99 > }
100 >
101 > export interface EditorGroupLayout {
102 >
103 > /**
104 > * The initial orientation of the editor groups at the root.
105 > */
106 > readonly orientation: GroupOrientation;
107 >
108 > /**
109 > * The editor groups at the root of the layout.
110 > */
111 > readonly groups: GroupLayoutArgument[];
112 > }
113 >
114 > export const enum MergeGroupMode {
115 > COPY_EDITORS,
116 > MOVE_EDITORS
117 > }
118 >
119 > export interface IMergeGroupOptions {
120 > mode?: MergeGroupMode;
121 > readonly index?: number;
122 >
123 > /**
124 > * Set this to prevent editors already present in the
125 > * target group from moving to a different index as
126 > * they are in the source group.
127 > */
128 > readonly preserveExistingIndex?: boolean;
129 > }
130 >
131 > export interface ICloseEditorOptions {
132 > readonly preserveFocus?: boolean;
133 > }
134 >
135 > export type ICloseEditorsFilter = {
136 > readonly except?: EditorInput;
137 > readonly direction?: CloseDirection;
138 > readonly savedOnly?: boolean;
139 > readonly excludeSticky?: boolean;
140 > };
141 >
142 > export interface ICloseAllEditorsOptions {
143 > readonly excludeSticky?: boolean;
144 > readonly excludeConfirming?: boolean;
145 > }
146 >
147 > export interface IEditorReplacement {
148 > readonly editor: EditorInput;
149 > readonly replacement: EditorInput;
150 > readonly options?: IEditorOptions;
151 >
152 > /**
153 > * Skips asking the user for confirmation and doesn't
154 > * save the document. Only use this if you really need to!
155 > */
156 > readonly forceReplaceDirty?: boolean;
157 > }
158 >
159 > export function isEditorReplacement(replacement: unknown): replacement is IEditorReplacement {
160 const candidate = replacement as IEditorReplacement | undefined;
161
162 return isEditorInput(candidate?.editor) && isEditorInput(candidate?.replacement);
163 }
165 > export const enum GroupsOrder {
166 >
167 > /**
168 > * Groups sorted by creation order (oldest one first)
169 > */
170 > CREATION_TIME,
171 >
172 > /**
173 > * Groups sorted by most recent activity (most recent active first)
174 > */
175 > MOST_RECENTLY_ACTIVE,
176 >
177 > /**
178 > * Groups sorted by grid widget order
179 > */
180 > GRID_APPEARANCE
181 > }
182 >
183 > export interface IEditorSideGroup {
184 >
185 > /**
186 > * Open an editor in this group.
187 > *
188 > * @returns a promise that resolves around an IEditor instance unless
189 > * the call failed, or the editor was not opened as active editor.
190 > */
191 > openEditor(editor: EditorInput, options?: IEditorOptions): Promise<IEditorPane | undefined>;
192 > }
193 >
194 > export interface IEditorDropTargetDelegate {
195 >
196 > /**
197 > * A helper to figure out if the drop target contains the provided group.
198 > */
199 > containsGroup?(groupView: IEditorGroup): boolean;
200 > }
201 >
202 > /**
203 > * The basic primitive to work with editor groups. This interface is both implemented
204 > * by editor part component as well as the editor groups service that operates across
205 > * all opened editor parts.
206 > */
207 > export interface IEditorGroupsContainer {
208 >
209 > /**
210 > * An event for when the active editor group changes. The active editor
211 > * group is the default location for new editors to open.
212 > */
213 > readonly onDidChangeActiveGroup: Event<IEditorGroup>;
214 >
215 > /**
216 > * An event for when a new group was added.
217 > */
218 > readonly onDidAddGroup: Event<IEditorGroup>;
219 >
220 > /**
221 > * An event for when a group was removed.
222 > */
223 > readonly onDidRemoveGroup: Event<IEditorGroup>;
224 >
225 > /**
226 > * An event for when a group was moved.
227 > */
228 > readonly onDidMoveGroup: Event<IEditorGroup>;
229 >
230 > /**
231 > * An event for when a group gets activated.
232 > */
233 > readonly onDidActivateGroup: Event<IEditorGroupActivationEvent>;
234 >
235 > /**
236 > * An event for when the index of a group changes.
237 > */
238 > readonly onDidChangeGroupIndex: Event<IEditorGroup>;
239 >
240 > /**
241 > * An event for when the locked state of a group changes.
242 > */
243 > readonly onDidChangeGroupLocked: Event<IEditorGroup>;
244 >
245 > /**
246 > * An event for when the maximized state of a group changes.
247 > */
248 > readonly onDidChangeGroupMaximized: Event<boolean>;
249 >
250 > /**
251 > * An event that notifies when container options change.
252 > */
253 > readonly onDidChangeEditorPartOptions: Event<IEditorPartOptionsChangeEvent>;
254 >
255 > /**
256 > * A property that indicates when groups have been created
257 > * and are ready to be used in the container.
258 > */
259 > readonly isReady: boolean;
260 >
261 > /**
262 > * A promise that resolves when groups have been created
263 > * and are ready to be used in the container.
264 > *
265 > * Await this promise to safely work on the editor groups model
266 > * (for example, install editor group listeners).
267 > *
268 > * Use the `whenRestored` property to await visible editors
269 > * having fully resolved.
270 > */
271 > readonly whenReady: Promise<void>;
272 >
273 > /**
274 > * A promise that resolves when groups have been restored in
275 > * the container.
276 > *
277 > * For groups with active editor, the promise will resolve
278 > * when the visible editor has finished to resolve.
279 > *
280 > * Use the `whenReady` property to not await editors to
281 > * resolve.
282 > */
283 > readonly whenRestored: Promise<void>;
284 >
285 > /**
286 > * Find out if the container has UI state to restore
287 > * from a previous session.
288 > */
289 > readonly hasRestorableState: boolean;
290 >
291 > /**
292 > * An active group is the default location for new editors to open.
293 > */
294 > readonly activeGroup: IEditorGroup;
295 >
296 > /**
297 > * A side group allows a subset of methods on a group that is either
298 > * created to the side or picked if already there.
299 > */
300 > readonly sideGroup: IEditorSideGroup;
301 >
302 > /**
303 > * All groups that are currently visible in the container in the order
304 > * of their creation (oldest first).
305 > */
306 > readonly groups: readonly IEditorGroup[];
307 >
308 > /**
309 > * The number of editor groups that are currently opened in the
310 > * container.
311 > */
312 > readonly count: number;
313 >
314 > /**
315 > * The current layout orientation of the root group.
316 > */
317 > readonly orientation: GroupOrientation;
318 >
319 > /**
320 > * Access the options of the container.
321 > */
322 > readonly partOptions: IEditorPartOptions;
323 >
324 > /**
325 > * Enforce container options temporarily.
326 > */
327 > enforcePartOptions(options: DeepPartial<IEditorPartOptions>): IDisposable;
328 >
329 > /**
330 > * Get all groups that are currently visible in the container.
331 > *
332 > * @param order the order of the editors to use
333 > */
334 > getGroups(order: GroupsOrder): readonly IEditorGroup[];
335 >
336 > /**
337 > * Allows to convert a group identifier to a group.
338 > */
339 > getGroup(identifier: GroupIdentifier): IEditorGroup | undefined;
340 >
341 > /**
342 > * Set a group as active. An active group is the default location for new editors to open.
343 > */
344 > activateGroup(group: IEditorGroup | GroupIdentifier): IEditorGroup;
345 >
346 > /**
347 > * Returns the size of a group.
348 > */
349 > getSize(group: IEditorGroup | GroupIdentifier): { width: number; height: number };
350 >
351 > /**
352 > * Sets the size of a group.
353 > */
354 > setSize(group: IEditorGroup | GroupIdentifier, size: { width: number; height: number }): void;
355 >
356 > /**
357 > * Arrange all groups in the container according to the provided arrangement.
358 > */
359 > arrangeGroups(arrangement: GroupsArrangement, target?: IEditorGroup | GroupIdentifier): void;
360 >
361 > /**
362 > * Toggles the target goup size to maximize/unmaximize.
363 > */
364 > toggleMaximizeGroup(group?: IEditorGroup | GroupIdentifier): void;
365 >
366 > /**
367 > * Toggles the target goup size to expand/distribute even.
368 > */
369 > toggleExpandGroup(group?: IEditorGroup | GroupIdentifier): void;
370 >
371 > /**
372 > * Applies the provided layout by either moving existing groups or creating new groups.
373 > */
374 > applyLayout(layout: EditorGroupLayout): void;
375 >
376 > /**
377 > * Returns an editor layout of the container.
378 > */
379 > getLayout(): EditorGroupLayout;
380 >
381 > /**
382 > * Sets the orientation of the root group to be either vertical or horizontal.
383 > */
384 > setGroupOrientation(orientation: GroupOrientation): void;
385 >
386 > /**
387 > * Find a group in a specific scope:
388 > * * `GroupLocation.FIRST`: the first group
389 > * * `GroupLocation.LAST`: the last group
390 > * * `GroupLocation.NEXT`: the next group from either the active one or `source`
391 > * * `GroupLocation.PREVIOUS`: the previous group from either the active one or `source`
392 > * * `GroupDirection.UP`: the next group above the active one or `source`
393 > * * `GroupDirection.DOWN`: the next group below the active one or `source`
394 > * * `GroupDirection.LEFT`: the next group to the left of the active one or `source`
395 > * * `GroupDirection.RIGHT`: the next group to the right of the active one or `source`
396 > *
397 > * @param scope the scope of the group to search in
398 > * @param source optional source to search from
399 > * @param wrap optionally wrap around if reaching the edge of groups
400 > */
401 > findGroup(scope: IFindGroupScope, source?: IEditorGroup | GroupIdentifier, wrap?: boolean): IEditorGroup | undefined;
402 >
403 > /**
404 > * Add a new group to the container. A new group is added by splitting a provided one in
405 > * one of the four directions.
406 > *
407 > * @param location the group from which to split to add a new group
408 > * @param direction the direction of where to split to
409 > */
410 > addGroup(location: IEditorGroup | GroupIdentifier, direction: GroupDirection): IEditorGroup;
411 >
412 > /**
413 > * Remove a group from the container.
414 > */
415 > removeGroup(group: IEditorGroup | GroupIdentifier): void;
416 >
417 > /**
418 > * Move a group to a new group in the container.
419 > *
420 > * @param group the group to move
421 > * @param location the group from which to split to add the moved group
422 > * @param direction the direction of where to split to
423 > */
424 > moveGroup(group: IEditorGroup | GroupIdentifier, location: IEditorGroup | GroupIdentifier, direction: GroupDirection): IEditorGroup;
425 >
426 > /**
427 > * Merge the editors of a group into a target group. By default, all editors will
428 > * move and the source group will close. This behaviour can be configured via the
429 > * `IMergeGroupOptions` options.
430 > *
431 > * @param group the group to merge
432 > * @param target the target group to merge into
433 > * @param options controls how the merge should be performed. by default all editors
434 > * will be moved over to the target and the source group will close. Configure to
435 > * `MOVE_EDITORS_KEEP_GROUP` to prevent the source group from closing. Set to
436 > * `COPY_EDITORS` to copy the editors into the target instead of moding them.
437 > *
438 > * @returns if merging was successful
439 > */
440 > mergeGroup(group: IEditorGroup | GroupIdentifier, target: IEditorGroup | GroupIdentifier, options?: IMergeGroupOptions): boolean;
441 >
442 > /**
443 > * Merge all editor groups into the target one.
444 > *
445 > * @returns if merging was successful
446 > */
447 > mergeAllGroups(target: IEditorGroup | GroupIdentifier): boolean;
448 >
449 > /**
450 > * Copy a group to a new group in the container.
451 > *
452 > * @param group the group to copy
453 > * @param location the group from which to split to add the copied group
454 > * @param direction the direction of where to split to
455 > */
456 > copyGroup(group: IEditorGroup | GroupIdentifier, location: IEditorGroup | GroupIdentifier, direction: GroupDirection): IEditorGroup;
457 >
458 > /**
459 > * Allows to register a drag and drop target for editors
460 > * on the provided `container`.
461 > */
462 > createEditorDropTarget(container: unknown /* HTMLElement */, delegate: IEditorDropTargetDelegate): IDisposable;
463 > }
464 >
465 > /**
466 > * An editor part is a viewer of editor groups. There can be multiple editor
467 > * parts opened in multiple windows.
468 > */
469 > export interface IEditorPart extends IEditorGroupsContainer {
470 >
471 > /**
472 > * An event for when the editor part is layed out.
473 > */
474 > readonly onDidLayout: Event<IDimension>;
475 >
476 > /**
477 > * An event for when the editor part is scrolled.
478 > */
479 > readonly onDidScroll: Event<void>;
480 >
481 > /**
482 > * An event for when the editor part is disposed.
483 > */
484 > readonly onWillDispose: Event<void>;
485 >
486 > /**
487 > * The identifier of the window the editor part is contained in.
488 > */
489 > readonly windowId: number;
490 >
491 > /**
492 > * The size of the editor part.
493 > */
494 > readonly contentDimension: IDimension;
495 >
496 > /**
497 > * Find out if an editor group is currently maximized.
498 > */
499 > hasMaximizedGroup(): boolean;
500 >
501 > /**
502 > * Enable or disable centered editor layout.
503 > */
504 > centerLayout(active: boolean): void;
505 >
506 > /**
507 > * Find out if the editor layout is currently centered.
508 > */
509 > isLayoutCentered(): boolean;
510 > }
511 >
512 > export interface IAuxiliaryEditorPart extends IEditorPart {
513 >
514 > /**
515 > * Close this auxiliary editor part after moving all
516 > * dirty editors of all groups back to the main editor
517 > * part.
518 > *
519 > * @returns `false` if an editor could not be moved back.
520 > */
521 > close(): boolean;
522 > }
523 >
524 > export interface IModalEditorPart extends IEditorPart {
525 >
526 > /**
527 > * Modal container of the editor part.
528 > */
529 > readonly modalElement: unknown /* HTMLElement */;
530 >
531 > /**
532 > * Whether the modal editor part is currently maximized.
533 > */
534 > readonly maximized: boolean;
535 >
536 > /**
537 > * Fired when the maximized state changes.
538 > */
539 > readonly onDidChangeMaximized: Event<boolean>;
540 >
541 > /**
542 > * Toggle between default and maximized size.
543 > */
544 > toggleMaximized(): void;
545 >
546 > /**
547 > * Size set by the user via resizing, if any.
548 > */
549 > readonly size: IDimension | undefined;
550 >
551 > /**
552 > * Position set by the user via dragging, if any.
553 > */
554 > readonly position: { left: number; top: number } | undefined;
555 >
556 > /**
557 > * Whether the modal editor part has a sidebar.
558 > */
559 > readonly hasSidebar: boolean;
560 >
561 > /**
562 > * Sidebar width set by the user via resizing, if any.
563 > */
564 > readonly sidebarWidth: number | undefined;
565 >
566 > /**
567 > * Whether the sidebar is hidden.
568 > */
569 > readonly sidebarHidden: boolean;
570 >
571 > /**
572 > * Toggle sidebar visibility.
573 > */
574 > toggleSidebar(): void;
575 >
576 > /**
577 > * The current navigation context, if any.
578 > */
579 > readonly navigation: IModalEditorNavigation | undefined;
580 >
581 > /**
582 > * Update options for the modal editor part.
583 > */
584 > updateOptions(options?: IModalEditorPartOptions): void;
585 >
586 > /**
587 > * Fired when this modal editor part is about to close.
588 > */
589 > readonly onWillClose: Event<void>;
590 >
591 > /**
592 > * Close this modal editor part after closing all
593 > * editors of all groups. Dirty editors will trigger
594 > * a confirmation dialog asking the user to save.
595 > *
596 > * The option `mergeAllEditorsToMainPart` can be used
597 > * to first move all editors from this modal editor part
598 > * back to the main editor part, where they remain open.
599 > * This avoids the confirmation dialog because the editors
600 > * are not closed as part of this operation.
601 > *
602 > * @returns `false` if the close was cancelled.
603 > */
604 > close(options?: { mergeAllEditorsToMainPart?: boolean }): Promise<boolean>;
605 > }
606 >
607 > export interface IEditorWorkingSet {
608 > readonly id: string;
609 > readonly name: string;
610 > }
611 >
612 > export interface IEditorWorkingSetOptions {
613 > readonly preserveFocus?: boolean;
614 > }
615 >
616 > export interface IEditorGroupContextKeyProvider<T extends ContextKeyValue> {
617 >
618 > /**
619 > * The context key that needs to be set for each editor group context and the global context.
620 > */
621 > readonly contextKey: RawContextKey<T>;
622 >
623 > /**
624 > * Retrieves the context key value for the given editor group.
625 > */
626 > readonly getGroupContextKeyValue: (group: IEditorGroup) => T;
627 >
628 > /**
629 > * An event that is fired when there was a change leading to the context key value to be re-evaluated.
630 > */
631 > readonly onDidChange?: Event<void>;
632 > }
633 >
634 > /**
635 > * The main service to interact with editor groups across all opened editor parts.
636 > */
637 > export interface IEditorGroupsService extends IEditorGroupsContainer {
638 >
639 > readonly _serviceBrand: undefined;
640 >
641 > /**
642 > * An event for when a new auxiliary editor part is created.
643 > */
644 > readonly onDidCreateAuxiliaryEditorPart: Event<IAuxiliaryEditorPart>;
645 >
646 > /**
647 > * Provides access to the main window editor part.
648 > */
649 > readonly mainPart: IEditorPart;
650 >
651 > /**
652 > * Provides access to all editor parts.
653 > */
654 > readonly parts: ReadonlyArray<IEditorPart>;
655 >
656 > /**
657 > * Get the editor part that contains the group with the provided identifier.
658 > */
659 > getPart(group: IEditorGroup | GroupIdentifier): IEditorPart;
660 >
661 > /**
662 > * Get the editor part that is rooted in the provided container.
663 > */
664 > getPart(container: unknown /* HTMLElement */): IEditorPart;
665 >
666 > /**
667 > * Opens a new window with a full editor part instantiated
668 > * in there at the optional position and size on screen.
669 > */
670 > createAuxiliaryEditorPart(options?: { bounds?: Partial<IRectangle>; compact?: boolean; alwaysOnTop?: boolean }): Promise<IAuxiliaryEditorPart>;
671 >
672 > /**
673 > * Creates a modal editor part that shows in a modal overlay
674 > * on top of the main workbench window.
675 > *
676 > * If a modal part already exists, it will be returned
677 > * instead of creating a new one.
678 > */
679 > createModalEditorPart(options?: IModalEditorPartOptions): Promise<IModalEditorPart>;
680 >
681 > /**
682 > * The currently active modal editor part, if any.
683 > */
684 > readonly activeModalEditorPart: IModalEditorPart | undefined;
685 >
686 > /**
687 > * Returns the instantiation service that is scoped to the
688 > * provided editor part. Use this method when building UI
689 > * that contributes to auxiliary editor parts to ensure the
690 > * UI is scoped to that part.
691 > */
692 > getScopedInstantiationService(part: IEditorPart): IInstantiationService;
693 >
694 > /**
695 > * Save a new editor working set from the currently opened
696 > * editors and group layout.
697 > */
698 > saveWorkingSet(name: string): IEditorWorkingSet;
699 >
700 > /**
701 > * Returns all known editor working sets.
702 > */
703 > getWorkingSets(): IEditorWorkingSet[];
704 >
705 > /**
706 > * Applies the working set. Use `empty` to apply an empty working set.
707 > *
708 > * @returns `true` when the working set as applied.
709 > */
710 > applyWorkingSet(workingSet: IEditorWorkingSet | 'empty', options?: IEditorWorkingSetOptions): Promise<boolean>;
711 >
712 > /**
713 > * Deletes a working set.
714 > */
715 > deleteWorkingSet(workingSet: IEditorWorkingSet): void;
716 >
717 > /**
718 > * Registers a context key provider. This provider sets a context key for each scoped editor group context and the global context.
719 > *
720 > * @param provider - The context key provider to be registered.
721 > * @returns - A disposable object to unregister the provider.
722 > */
723 > registerContextKeyProvider<T extends ContextKeyValue>(provider: IEditorGroupContextKeyProvider<T>): IDisposable;
724 > }
725 >
726 > export const enum OpenEditorContext {
727 > NEW_EDITOR = 1,
728 > MOVE_EDITOR = 2,
729 > COPY_EDITOR = 3
730 > }
731 >
732 > export interface IActiveEditorActions {
733 > readonly actions: IToolbarActions;
734 > readonly onDidChange: Event<IMenuChangeEvent | void>;
735 > }
736 >
737 > export interface IEditorGroup {
738 >
739 > /**
740 > * An event which fires whenever the underlying group model changes.
741 > */
742 > readonly onDidModelChange: Event<IGroupModelChangeEvent>;
743 >
744 > /**
745 > * An event that is fired when the group gets disposed.
746 > */
747 > readonly onWillDispose: Event<void>;
748 >
749 > /**
750 > * An event that is fired when the active editor in the group changed.
751 > */
752 > readonly onDidActiveEditorChange: Event<IActiveEditorChangeEvent>;
753 >
754 > /**
755 > * An event that is fired when an editor is about to close.
756 > */
757 > readonly onWillCloseEditor: Event<IEditorCloseEvent>;
758 >
759 > /**
760 > * An event that is fired when an editor is closed.
761 > */
762 > readonly onDidCloseEditor: Event<IEditorCloseEvent>;
763 >
764 > /**
765 > * An event that is fired when an editor is about to move to
766 > * a different group.
767 > */
768 > readonly onWillMoveEditor: Event<IEditorWillMoveEvent>;
769 >
770 > /**
771 > * A unique identifier of this group that remains identical even if the
772 > * group is moved to different locations.
773 > */
774 > readonly id: GroupIdentifier;
775 >
776 > /**
777 > * The identifier of the window this editor group is part of.
778 > */
779 > readonly windowId: number;
780 >
781 > /**
782 > * A number that indicates the position of this group in the visual
783 > * order of groups from left to right and top to bottom. The lowest
784 > * index will likely be top-left while the largest index in most
785 > * cases should be bottom-right, but that depends on the grid.
786 > */
787 > readonly index: number;
788 >
789 > /**
790 > * A human readable label for the group. This label can change depending
791 > * on the layout of all editor groups. Clients should listen on the
792 > * `onDidGroupModelChange` event to react to that.
793 > */
794 > readonly label: string;
795 >
796 > /**
797 > * A human readable label for the group to be used by screen readers.
798 > */
799 > readonly ariaLabel: string;
800 >
801 > /**
802 > * The active editor pane is the currently visible editor pane of the group.
803 > */
804 > readonly activeEditorPane: IVisibleEditorPane | undefined;
805 >
806 > /**
807 > * The active editor is the currently visible editor of the group
808 > * within the current active editor pane.
809 > */
810 > readonly activeEditor: EditorInput | null;
811 >
812 > /**
813 > * All selected editor in this group in sequential order.
814 > * The active editor is always part of the selection.
815 > */
816 > readonly selectedEditors: EditorInput[];
817 >
818 > /**
819 > * The editor in the group that is in preview mode if any. There can
820 > * only ever be one editor in preview mode.
821 > */
822 > readonly previewEditor: EditorInput | null;
823 >
824 > /**
825 > * The number of opened editors in this group.
826 > */
827 > readonly count: number;
828 >
829 > /**
830 > * Whether the group has editors or not.
831 > */
832 > readonly isEmpty: boolean;
833 >
834 > /**
835 > * Whether this editor group is locked or not. Locked editor groups
836 > * will only be considered for editors to open in when the group is
837 > * explicitly provided for the editor.
838 > *
839 > * Note: editor group locking only applies when more than one group
840 > * is opened.
841 > */
842 > readonly isLocked: boolean;
843 >
844 > /**
845 > * The number of sticky editors in this group.
846 > */
847 > readonly stickyCount: number;
848 >
849 > /**
850 > * All opened editors in the group in sequential order of their appearance.
851 > */
852 > readonly editors: readonly EditorInput[];
853 >
854 > /**
855 > * The scoped context key service for this group.
856 > */
857 > readonly scopedContextKeyService: IContextKeyService;
858 >
859 > /**
860 > * Get all editors that are currently opened in the group.
861 > *
862 > * @param order the order of the editors to use
863 > * @param options options to select only specific editors as instructed
864 > */
865 > getEditors(order: EditorsOrder, options?: { excludeSticky?: boolean }): readonly EditorInput[];
866 >
867 > /**
868 > * Finds all editors for the given resource that are currently
869 > * opened in the group. This method will return an entry for
870 > * each editor that reports a `resource` that matches the
871 > * provided one.
872 > *
873 > * @param resource the resource of the editor to find
874 > * @param options whether to support side by side editors or not
875 > */
876 > findEditors(resource: URI, options?: IFindEditorOptions): readonly EditorInput[];
877 >
878 > /**
879 > * Returns the editor at a specific index of the group.
880 > */
881 > getEditorByIndex(index: number): EditorInput | undefined;
882 >
883 > /**
884 > * Returns the index of the editor in the group or -1 if not opened.
885 > */
886 > getIndexOfEditor(editor: EditorInput): number;
887 >
888 > /**
889 > * Whether the editor is the first in the group.
890 > */
891 > isFirst(editor: EditorInput): boolean;
892 >
893 > /**
894 > * Whether the editor is the last in the group.
895 > */
896 > isLast(editor: EditorInput): boolean;
897 >
898 > /**
899 > * Open an editor in this group.
900 > *
901 > * @returns a promise that resolves around an IEditor instance unless
902 > * the call failed, or the editor was not opened as active editor.
903 > */
904 > openEditor(editor: EditorInput, options?: IEditorOptions): Promise<IEditorPane | undefined>;
905 >
906 > /**
907 > * Opens editors in this group.
908 > *
909 > * @returns a promise that resolves around an IEditor instance unless
910 > * the call failed, or the editor was not opened as active editor. Since
911 > * a group can only ever have one active editor, even if many editors are
912 > * opened, the result will only be one editor.
913 > */
914 > openEditors(editors: EditorInputWithOptions[]): Promise<IEditorPane | undefined>;
915 >
916 > /**
917 > * Find out if the provided editor is pinned in the group.
918 > */
919 > isPinned(editorOrIndex: EditorInput | number): boolean;
920 >
921 > /**
922 > * Find out if the provided editor or index of editor is sticky in the group.
923 > */
924 > isSticky(editorOrIndex: EditorInput | number): boolean;
925 >
926 > /**
927 > * Find out if the provided editor or index of editor is transient in the group.
928 > */
929 > isTransient(editorOrIndex: EditorInput | number): boolean;
930 >
931 > /**
932 > * Find out if the provided editor is active in the group.
933 > */
934 > isActive(editor: EditorInput | IUntypedEditorInput): boolean;
935 >
936 > /**
937 > * Whether the editor is selected in the group.
938 > */
939 > isSelected(editor: EditorInput): boolean;
940 >
941 > /**
942 > * Set a new selection for this group. This will replace the current
943 > * selection with the new selection.
944 > *
945 > * @param activeSelectedEditor the editor to set as active selected editor
946 > * @param inactiveSelectedEditors the inactive editors to set as selected
947 > */
948 > setSelection(activeSelectedEditor: EditorInput, inactiveSelectedEditors: EditorInput[]): Promise<void>;
949 >
950 > /**
951 > * Find out if a certain editor is included in the group.
952 > *
953 > * @param candidate the editor to find
954 > * @param options fine tune how to match editors
955 > */
956 > contains(candidate: EditorInput | IUntypedEditorInput, options?: IMatchEditorOptions): boolean;
957 >
958 > /**
959 > * Move an editor from this group either within this group or to another group.
960 > *
961 > * @returns whether the editor was moved or not.
962 > */
963 > moveEditor(editor: EditorInput, target: IEditorGroup, options?: IEditorOptions): boolean;
964 >
965 > /**
966 > * Move editors from this group either within this group or to another group.
967 > *
968 > * @returns whether all editors were moved or not.
969 > */
970 > moveEditors(editors: EditorInputWithOptions[], target: IEditorGroup): boolean;
971 >
972 > /**
973 > * Copy an editor from this group to another group.
974 > *
975 > * Note: It is currently not supported to show the same editor more than once in the same group.
976 > */
977 > copyEditor(editor: EditorInput, target: IEditorGroup, options?: IEditorOptions): void;
978 >
979 > /**
980 > * Copy editors from this group to another group.
981 > *
982 > * Note: It is currently not supported to show the same editor more than once in the same group.
983 > */
984 > copyEditors(editors: EditorInputWithOptions[], target: IEditorGroup): void;
985 >
986 > /**
987 > * Close an editor from the group. This may trigger a confirmation dialog if
988 > * the editor is dirty and thus returns a promise as value.
989 > *
990 > * @param editor the editor to close, or the currently active editor
991 > * if unspecified.
992 > *
993 > * @returns a promise when the editor is closed or not. If `true`, the editor
994 > * is closed and if `false` there was a veto closing the editor, e.g. when it
995 > * is dirty.
996 > */
997 > closeEditor(editor?: EditorInput, options?: ICloseEditorOptions): Promise<boolean>;
998 >
999 > /**
1000 > * Closes specific editors in this group. This may trigger a confirmation dialog if
1001 > * there are dirty editors and thus returns a promise as value.
1002 > *
1003 > * @returns a promise whether the editors were closed or not. If `true`, the editors
1004 > * were closed and if `false` there was a veto closing the editors, e.g. when one
1005 > * is dirty.
1006 > */
1007 > closeEditors(editors: EditorInput[] | ICloseEditorsFilter, options?: ICloseEditorOptions): Promise<boolean>;
1008 >
1009 > /**
1010 > * Closes all editors from the group. This may trigger a confirmation dialog if
1011 > * there are dirty editors and thus returns a promise as value.
1012 > *
1013 > * @returns a promise if confirmation is needed when all editors are closed.
1014 > */
1015 > closeAllEditors(options: { excludeConfirming: true }): boolean;
1016 > closeAllEditors(options?: ICloseAllEditorsOptions): Promise<boolean>;
1017 >
1018 > /**
1019 > * Replaces editors in this group with the provided replacement.
1020 > *
1021 > * @param editors the editors to replace
1022 > *
1023 > * @returns a promise that is resolved when the replaced active
1024 > * editor (if any) has finished loading.
1025 > */
1026 > replaceEditors(editors: IEditorReplacement[]): Promise<void>;
1027 >
1028 > /**
1029 > * Set an editor to be pinned. A pinned editor is not replaced
1030 > * when another editor opens at the same location.
1031 > *
1032 > * @param editor the editor to pin, or the currently active editor
1033 > * if unspecified.
1034 > */
1035 > pinEditor(editor?: EditorInput): void;
1036 >
1037 > /**
1038 > * Set an editor to be sticky. A sticky editor is showing in the beginning
1039 > * of the tab stripe and will not be impacted by close operations.
1040 > *
1041 > * @param editor the editor to make sticky, or the currently active editor
1042 > * if unspecified.
1043 > */
1044 > stickEditor(editor?: EditorInput): void;
1045 >
1046 > /**
1047 > * Set an editor to be non-sticky and thus moves back to a location after
1048 > * sticky editors and can be closed normally.
1049 > *
1050 > * @param editor the editor to make unsticky, or the currently active editor
1051 > * if unspecified.
1052 > */
1053 > unstickEditor(editor?: EditorInput): void;
1054 >
1055 > /**
1056 > * Whether this editor group should be locked or not.
1057 > *
1058 > * See {@linkcode IEditorGroup.isLocked `isLocked`}
1059 > */
1060 > lock(locked: boolean): void;
1061 >
1062 > /**
1063 > * Move keyboard focus into the group.
1064 > */
1065 > focus(): void;
1066 >
1067 > /**
1068 > * Create the editor actions for the current active editor.
1069 > */
1070 > createEditorActions(disposables: DisposableStore, menuId?: MenuId): IActiveEditorActions;
1071 > }
1072 >
1073 > export function isEditorGroup(obj: unknown): obj is IEditorGroup {
1074 const group = obj as IEditorGroup | undefined;
1075
1076 return !!group && typeof group.id === 'number' && Array.isArray(group.editors);
1077 }
1079 > //#region Editor Group Helpers
1080 >
1081 > export function preferredSideBySideGroupDirection(configurationService: IConfigurationService): GroupDirection.DOWN | GroupDirection.RIGHT {
1082 const openSideBySideDirection = configurationService.getValue('workbench.editor.openSideBySideDirection');
1083