From b9dc1b6a96f2b6ef228f310b380921d0b1e0b856 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Mon, 9 Oct 2023 12:05:52 +0200 Subject: [PATCH 01/11] turn setting into enum --- src/vs/workbench/browser/contextkeys.ts | 2 +- src/vs/workbench/browser/layout.ts | 4 +- .../workbench/browser/parts/editor/editor.ts | 2 +- .../browser/parts/editor/editorDropTarget.ts | 2 +- .../browser/parts/editor/editorGroupView.ts | 6 +- .../browser/parts/editor/editorTabsControl.ts | 4 +- .../parts/editor/editorTitleControl.ts | 27 ++++---- .../parts/editor/noEditorTabsControl.ts | 62 +++++++++++++++++++ .../browser/workbench.contribution.ts | 21 ++++--- src/vs/workbench/common/editor.ts | 2 +- src/vs/workbench/common/theme.ts | 2 +- .../test/browser/editorGroupsService.test.ts | 6 +- 12 files changed, 104 insertions(+), 36 deletions(-) create mode 100644 src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts diff --git a/src/vs/workbench/browser/contextkeys.ts b/src/vs/workbench/browser/contextkeys.ts index feca5c8da5825..205f570c15f26 100644 --- a/src/vs/workbench/browser/contextkeys.ts +++ b/src/vs/workbench/browser/contextkeys.ts @@ -265,7 +265,7 @@ export class WorkbenchContextKeysHandler extends Disposable { } private updateEditorAreaContextKeys(): void { - this.editorTabsVisibleContext.set(!!this.editorGroupService.partOptions.showTabs); + this.editorTabsVisibleContext.set(this.editorGroupService.partOptions.showTabs === 'multiple'); } private updateEditorContextKeys(): void { diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 1ccffa5770e83..01d611d63a413 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -1227,8 +1227,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.state.runtime.zenMode.transitionDisposables.add(this.editorService.onDidVisibleEditorsChange(() => setLineNumbers('off'))); } - if (config.hideTabs && this.editorGroupService.partOptions.showTabs) { - this.state.runtime.zenMode.transitionDisposables.add(this.editorGroupService.enforcePartOptions({ showTabs: false })); + if (config.hideTabs && this.editorGroupService.partOptions.showTabs === 'multiple') { + this.state.runtime.zenMode.transitionDisposables.add(this.editorGroupService.enforcePartOptions({ showTabs: 'single' })); } if (config.silentNotifications && zenModeExitInfo.handleNotificationsDoNotDisturbMode) { diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index a2a26d6f7ad15..a0edbc678d6c8 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -25,7 +25,7 @@ export const DEFAULT_EDITOR_MIN_DIMENSIONS = new Dimension(220, 70); export const DEFAULT_EDITOR_MAX_DIMENSIONS = new Dimension(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); export const DEFAULT_EDITOR_PART_OPTIONS: IEditorPartOptions = { - showTabs: true, + showTabs: 'multiple', highlightModifiedTabs: false, tabCloseButton: 'right', tabSizing: 'fit', diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index db792c89da9fe..6ba5020526d9f 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -530,7 +530,7 @@ class DropOverlay extends Themable { private getOverlayOffsetHeight(): number { // With tabs and opened editors: use the area below tabs as drop target - if (!this.groupView.isEmpty && this.editorGroupService.partOptions.showTabs) { + if (!this.groupView.isEmpty && this.editorGroupService.partOptions.showTabs === 'multiple') { return this.groupView.titleHeight.offset; } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 495b28c268487..4ebd1ae2571cd 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -463,7 +463,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } private updateTitleContainer(): void { - this.titleContainer.classList.toggle('tabs', this.groupsView.partOptions.showTabs); + this.titleContainer.classList.toggle('tabs', this.groupsView.partOptions.showTabs === 'multiple'); this.titleContainer.classList.toggle('show-file-icons', this.groupsView.partOptions.showIcons); } @@ -699,7 +699,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Title control switch between singleEditorTabs, multiEditorTabs and multiRowEditorTabs if ( event.oldPartOptions.showTabs !== event.newPartOptions.showTabs || - (event.oldPartOptions.showTabs && event.oldPartOptions.pinnedTabsOnSeparateRow !== event.newPartOptions.pinnedTabsOnSeparateRow) + (event.oldPartOptions.showTabs === 'multiple' && event.oldPartOptions.pinnedTabsOnSeparateRow !== event.newPartOptions.pinnedTabsOnSeparateRow) ) { // Re-layout @@ -1885,7 +1885,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } const { showTabs } = this.groupsView.partOptions; - this.titleContainer.style.backgroundColor = this.getColor(showTabs ? EDITOR_GROUP_HEADER_TABS_BACKGROUND : EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND) || ''; + this.titleContainer.style.backgroundColor = this.getColor(showTabs === 'multiple' ? EDITOR_GROUP_HEADER_TABS_BACKGROUND : EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND) || ''; // Editor container this.editorContainer.style.backgroundColor = this.getColor(editorBackground) || ''; diff --git a/src/vs/workbench/browser/parts/editor/editorTabsControl.ts b/src/vs/workbench/browser/parts/editor/editorTabsControl.ts index e862a4017653f..fc75ae4bfdef2 100644 --- a/src/vs/workbench/browser/parts/editor/editorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/editorTabsControl.ts @@ -290,7 +290,7 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC // Drag all tabs of the group if tabs are enabled let hasDataTransfer = false; - if (this.groupsView.partOptions.showTabs) { + if (this.groupsView.partOptions.showTabs === 'multiple') { hasDataTransfer = this.doFillResourceDataTransfers(this.groupView.getEditors(EditorsOrder.SEQUENTIAL), e); } @@ -309,7 +309,7 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC // Drag Image if (this.groupView.activeEditor) { let label = this.groupView.activeEditor.getName(); - if (this.groupsView.partOptions.showTabs && this.groupView.count > 1) { + if (this.groupsView.partOptions.showTabs === 'multiple' && this.groupView.count > 1) { label = localize('draggedEditorGroup', "{0} (+{1})", label, this.groupView.count - 1); } diff --git a/src/vs/workbench/browser/parts/editor/editorTitleControl.ts b/src/vs/workbench/browser/parts/editor/editorTitleControl.ts index 69aa10b14b7c6..38ea136a2a0c7 100644 --- a/src/vs/workbench/browser/parts/editor/editorTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/editorTitleControl.ts @@ -17,6 +17,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { MultiRowEditorControl } from 'vs/workbench/browser/parts/editor/multiRowEditorTabsControl'; import { IReadonlyEditorGroupModel } from 'vs/workbench/common/editor/editorGroupModel'; +import { NoEditorTabsControl } from 'vs/workbench/browser/parts/editor/noEditorTabsControl'; export interface IEditorTitleControlDimensions { @@ -57,22 +58,26 @@ export class EditorTitleControl extends Themable { } private createEditorTabsControl(): IEditorTabsControl { - let control: IEditorTabsControl; - if (this.groupsView.partOptions.showTabs) { - if (this.groupsView.partOptions.pinnedTabsOnSeparateRow) { - control = this.instantiationService.createInstance(MultiRowEditorControl, this.parent, this.editorPartsView, this.groupsView, this.groupView, this.model); - } else { - control = this.instantiationService.createInstance(MultiEditorTabsControl, this.parent, this.editorPartsView, this.groupsView, this.groupView, this.model); - } - } else { - control = this.instantiationService.createInstance(SingleEditorTabsControl, this.parent, this.editorPartsView, this.groupsView, this.groupView, this.model); + let tabsControlType; + switch (this.groupsView.partOptions.showTabs) { + case 'none': + tabsControlType = NoEditorTabsControl; + break; + case 'single': + tabsControlType = SingleEditorTabsControl; + break; + case 'multiple': + default: + tabsControlType = this.groupsView.partOptions.pinnedTabsOnSeparateRow ? MultiRowEditorControl : MultiEditorTabsControl; + break; } + const control = this.instantiationService.createInstance(tabsControlType, this.parent, this.editorPartsView, this.groupsView, this.groupView, this.model); return this.editorTabsControlDisposable.add(control); } private createBreadcrumbsControl(): BreadcrumbsControlFactory | undefined { - if (!this.groupsView.partOptions.showTabs) { + if (this.groupsView.partOptions.showTabs !== 'multiple') { return undefined; // single tabs have breadcrumbs inlined } @@ -170,7 +175,7 @@ export class EditorTitleControl extends Themable { // Update editor tabs control if options changed if ( oldOptions.showTabs !== newOptions.showTabs || - (newOptions.showTabs && oldOptions.pinnedTabsOnSeparateRow !== newOptions.pinnedTabsOnSeparateRow) + (newOptions.showTabs === 'multiple' && oldOptions.pinnedTabsOnSeparateRow !== newOptions.pinnedTabsOnSeparateRow) ) { // Clear old this.editorTabsControlDisposable.clear(); diff --git a/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts new file mode 100644 index 0000000000000..4d426dcf52ffb --- /dev/null +++ b/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./media/singleeditortabscontrol'; +import { EditorInput } from 'vs/workbench/common/editor/editorInput'; +import { EditorTabsControl, IToolbarActions } from 'vs/workbench/browser/parts/editor/editorTabsControl'; +import { Dimension } from 'vs/base/browser/dom'; +import { IEditorTitleControlDimensions } from 'vs/workbench/browser/parts/editor/editorTitleControl'; + +export class NoEditorTabsControl extends EditorTabsControl { + + protected override create(parent: HTMLElement): void { + super.create(parent); + } + + protected override prepareEditorActions(editorActions: IToolbarActions): IToolbarActions { + return { + primary: [], + secondary: [] + }; + } + + openEditor(editor: EditorInput): boolean { + return false; + } + + openEditors(editors: EditorInput[]): boolean { + return false; + } + + beforeCloseEditor(editor: EditorInput): void { } + + closeEditor(editor: EditorInput): void { } + + closeEditors(editors: EditorInput[]): void { } + + moveEditor(editor: EditorInput, fromIndex: number, targetIndex: number): void { } + + pinEditor(editor: EditorInput): void { } + + stickEditor(editor: EditorInput): void { } + + unstickEditor(editor: EditorInput): void { } + + setActive(isActive: boolean): void { } + + updateEditorLabel(editor: EditorInput): void { } + + updateEditorDirty(editor: EditorInput): void { } + + override updateStyles(): void { } + + getHeight(): number { + return 0; + } + + layout(dimensions: IEditorTitleControlDimensions): Dimension { + return new Dimension(dimensions.container.width, this.getHeight()); + } +} diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 2017f37c3b973..c4c8f6f8895d3 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -38,23 +38,24 @@ const registry = Registry.as(ConfigurationExtensions.Con default: 'default', }, 'workbench.editor.showTabs': { - 'type': 'boolean', + 'type': 'string', + 'enum': ['multiple', 'single', 'none'], 'description': localize('showEditorTabs', "Controls whether opened editors should show in tabs or not."), - 'default': true + 'default': 'multiple' }, 'workbench.editor.wrapTabs': { 'type': 'boolean', - 'markdownDescription': localize('wrapTabs', "Controls whether tabs should be wrapped over multiple lines when exceeding available space or whether a scrollbar should appear instead. This value is ignored when `#workbench.editor.showTabs#` is disabled."), + 'markdownDescription': localize('wrapTabs', "Controls whether tabs should be wrapped over multiple lines when exceeding available space or whether a scrollbar should appear instead. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`."), 'default': false }, 'workbench.editor.scrollToSwitchTabs': { 'type': 'boolean', - 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'scrollToSwitchTabs' }, "Controls whether scrolling over tabs will open them or not. By default tabs will only reveal upon scrolling, but not open. You can press and hold the Shift-key while scrolling to change this behavior for that duration. This value is ignored when `#workbench.editor.showTabs#` is disabled."), + 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'scrollToSwitchTabs' }, "Controls whether scrolling over tabs will open them or not. By default tabs will only reveal upon scrolling, but not open. You can press and hold the Shift-key while scrolling to change this behavior for that duration. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`."), 'default': false }, 'workbench.editor.highlightModifiedTabs': { 'type': 'boolean', - 'markdownDescription': localize('highlightModifiedTabs', "Controls whether a top border is drawn on tabs for editors that have unsaved changes. This value is ignored when `#workbench.editor.showTabs#` is disabled."), + 'markdownDescription': localize('highlightModifiedTabs', "Controls whether a top border is drawn on tabs for editors that have unsaved changes. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`."), 'default': false }, 'workbench.editor.decorations.badges': { @@ -140,7 +141,7 @@ const registry = Registry.as(ConfigurationExtensions.Con 'type': 'string', 'enum': ['left', 'right', 'off'], 'default': 'right', - 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorTabCloseButton' }, "Controls the position of the editor's tabs close buttons, or disables them when set to 'off'. This value is ignored when `#workbench.editor.showTabs#` is disabled.") + 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'editorTabCloseButton' }, "Controls the position of the editor's tabs close buttons, or disables them when set to 'off'. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`.") }, 'workbench.editor.tabSizing': { 'type': 'string', @@ -151,7 +152,7 @@ const registry = Registry.as(ConfigurationExtensions.Con localize('workbench.editor.tabSizing.shrink', "Allow tabs to get smaller when the available space is not enough to show all tabs at once."), localize('workbench.editor.tabSizing.fixed', "Make all tabs the same size, while allowing them to get smaller when the available space is not enough to show all tabs at once.") ], - 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'tabSizing' }, "Controls the size of editor tabs. This value is ignored when `#workbench.editor.showTabs#` is disabled.") + 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'tabSizing' }, "Controls the size of editor tabs. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`.") }, 'workbench.editor.tabSizingFixedMinWidth': { 'type': 'number', @@ -169,7 +170,7 @@ const registry = Registry.as(ConfigurationExtensions.Con 'type': 'string', 'enum': ['default', 'compact'], 'default': 'default', - 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.editor.tabHeight' }, "Controls the height of editor tabs. Also applies to the title control bar when `#workbench.editor.showTabs#` is disabled.") + 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'workbench.editor.tabHeight' }, "Controls the height of editor tabs. Also applies to the title control bar when `#workbench.editor.showTabs#` is not set to `multiple`.") }, 'workbench.editor.pinnedTabSizing': { 'type': 'string', @@ -180,7 +181,7 @@ const registry = Registry.as(ConfigurationExtensions.Con localize('workbench.editor.pinnedTabSizing.compact', "A pinned tab will show in a compact form with only icon or first letter of the editor name."), localize('workbench.editor.pinnedTabSizing.shrink', "A pinned tab shrinks to a compact fixed size showing parts of the editor name.") ], - 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'pinnedTabSizing' }, "Controls the size of pinned editor tabs. Pinned tabs are sorted to the beginning of all opened tabs and typically do not close until unpinned. This value is ignored when `#workbench.editor.showTabs#` is disabled.") + 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'pinnedTabSizing' }, "Controls the size of pinned editor tabs. Pinned tabs are sorted to the beginning of all opened tabs and typically do not close until unpinned. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`.") }, 'workbench.editor.pinnedTabsOnSeparateRow': { 'type': 'boolean', @@ -317,7 +318,7 @@ const registry = Registry.as(ConfigurationExtensions.Con 'workbench.editor.doubleClickTabToToggleEditorGroupSizes': { 'type': 'boolean', 'default': true, - 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'doubleClickTabToToggleEditorGroupSizes' }, "Controls whether to maximize/restore the editor group when double clicking on a tab. This value is ignored when `#workbench.editor.showTabs#` is disabled.") + 'markdownDescription': localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'doubleClickTabToToggleEditorGroupSizes' }, "Controls whether to maximize/restore the editor group when double clicking on a tab. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`.") }, 'workbench.editor.limit.enabled': { 'type': 'boolean', diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 41664fd79f8a3..5c3e8230881e8 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -1090,7 +1090,7 @@ export interface IWorkbenchEditorConfiguration { } interface IEditorPartConfiguration { - showTabs?: boolean; + showTabs?: 'multiple' | 'single' | 'none'; wrapTabs?: boolean; scrollToSwitchTabs?: boolean; highlightModifiedTabs?: boolean; diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 9d31beaefc272..9de1bf36c1b1a 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -256,7 +256,7 @@ export const EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND = registerColor('editorGroup light: editorBackground, hcDark: editorBackground, hcLight: editorBackground -}, localize('editorGroupHeaderBackground', "Background color of the editor group title header when tabs are disabled (`\"workbench.editor.showTabs\": false`). Editor groups are the containers of editors.")); +}, localize('editorGroupHeaderBackground', "Background color of the editor group title header when `workbench.editor.showTabs` is not set to multiple. Editor groups are the containers of editors.")); export const EDITOR_GROUP_HEADER_BORDER = registerColor('editorGroupHeader.border', { dark: null, diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index 200a6e33a424a..02d63db45ad32 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -408,9 +408,9 @@ suite('EditorGroupsService', () => { const currentOptions = part.partOptions; assert.ok(currentOptions); - disposables.add(part.enforcePartOptions({ showTabs: false })); - assert.strictEqual(part.partOptions.showTabs, false); - assert.strictEqual(newOptions.showTabs, false); + disposables.add(part.enforcePartOptions({ showTabs: 'single' })); + assert.strictEqual(part.partOptions.showTabs, 'single'); + assert.strictEqual(newOptions.showTabs, 'single'); assert.strictEqual(oldOptions, currentOptions); }); From 2e04ce400a4664e7c162a831c1cfa0f9c1405b52 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Mon, 9 Oct 2023 14:45:07 +0200 Subject: [PATCH 02/11] Migration support --- src/vs/workbench/browser/parts/editor/editor.ts | 8 ++++++++ src/vs/workbench/browser/workbench.contribution.ts | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index a0edbc678d6c8..6a4624900908a 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -80,6 +80,14 @@ export function getEditorPartOptions(configurationService: IConfigurationService } } + // showTabs ensure correct enum value + if (typeof options.showTabs === 'boolean') { + // Migration service kicks in very late and can cause a flicker otherwise + options.showTabs = options.showTabs ? 'multiple' : 'single'; + } else if (options.showTabs !== 'multiple' && options.showTabs !== 'single' && options.showTabs !== 'none') { + options.showTabs = 'multiple'; + } + const windowConfig = configurationService.getValue(); if (windowConfig?.window?.density?.editorTabHeight) { options.tabHeight = windowConfig.window.density.editorTabHeight; diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index de682c9af5379..6cc79eea67178 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -766,3 +766,14 @@ Registry.as(Extensions.ConfigurationMigration) return result; } }]); + +Registry.as(Extensions.ConfigurationMigration) + .registerConfigurationMigrations([{ + key: 'workbench.editor.showTabs', migrateFn: (value: any) => { + const result: ConfigurationKeyValuePairs = [['workbench.editor.showTabs', { value: value }]]; + if (value === false) { + result.push(['workbench.editor.showTabs', { value: 'single' }]); + } + return result; + } + }]); From 30871cbe2dae534e2ff85a2bb97c2345d16a3c6d Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Tue, 10 Oct 2023 09:25:49 +0200 Subject: [PATCH 03/11] :lipstick: --- .../browser/parts/editor/media/singleeditortabscontrol.css | 2 +- .../workbench/browser/parts/editor/singleEditorTabsControl.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css b/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css index 893920c71c580..f3a7d7b2484b7 100644 --- a/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css @@ -28,7 +28,7 @@ /* Breadcrumbs (inline next to single editor tab) */ -.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .no-tabs.title-label { +.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .single-tab.title-label { flex: none; } diff --git a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts index 8efda41b36d40..0ea58b717d2c7 100644 --- a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts @@ -317,7 +317,7 @@ export class SingleEditorTabsControl extends EditorTabsControl { { title, italic: !isEditorPinned, - extraClasses: ['no-tabs', 'title-label'].concat(editor.getLabelExtraClasses()), + extraClasses: ['single-tab', 'title-label'].concat(editor.getLabelExtraClasses()), fileDecorations: { colors: Boolean(options.decorations?.colors), badges: Boolean(options.decorations?.badges) From 5c9a261b6adbc284ab62a02117fd25eb6c75cbf8 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Tue, 10 Oct 2023 09:48:04 +0200 Subject: [PATCH 04/11] :lipstick: --- .../workbench/browser/parts/editor/editor.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 6a4624900908a..2d0ce727b054b 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -80,6 +80,17 @@ export function getEditorPartOptions(configurationService: IConfigurationService } } + const windowConfig = configurationService.getValue(); + if (windowConfig?.window?.density?.editorTabHeight) { + options.tabHeight = windowConfig.window.density.editorTabHeight; + } + + validateEditorPartOptions(options); + + return options; +} + +function validateEditorPartOptions(options: IEditorPartOptions) { // showTabs ensure correct enum value if (typeof options.showTabs === 'boolean') { // Migration service kicks in very late and can cause a flicker otherwise @@ -87,13 +98,6 @@ export function getEditorPartOptions(configurationService: IConfigurationService } else if (options.showTabs !== 'multiple' && options.showTabs !== 'single' && options.showTabs !== 'none') { options.showTabs = 'multiple'; } - - const windowConfig = configurationService.getValue(); - if (windowConfig?.window?.density?.editorTabHeight) { - options.tabHeight = windowConfig.window.density.editorTabHeight; - } - - return options; } /** From 6a0b43656e6c0e18b637d5c7dbb460658aee5f58 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Tue, 10 Oct 2023 10:00:26 +0200 Subject: [PATCH 05/11] :lipstick: --- src/vs/workbench/common/theme.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 9de1bf36c1b1a..a2d462a28c77a 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -256,7 +256,7 @@ export const EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND = registerColor('editorGroup light: editorBackground, hcDark: editorBackground, hcLight: editorBackground -}, localize('editorGroupHeaderBackground', "Background color of the editor group title header when `workbench.editor.showTabs` is not set to multiple. Editor groups are the containers of editors.")); +}, localize('editorGroupHeaderBackground', "Background color of the editor group title header when (`\"workbench.editor.showTabs\": \"single\"`). Editor groups are the containers of editors.")); export const EDITOR_GROUP_HEADER_BORDER = registerColor('editorGroupHeader.border', { dark: null, From 2fdc60de8f2426495903f18b373e68438dc4d3c7 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 15 Oct 2023 17:36:44 +0200 Subject: [PATCH 06/11] zen mode show tabs --- src/vs/workbench/browser/layout.ts | 6 +-- .../parts/editor/editorTitleControl.ts | 2 +- .../browser/workbench.contribution.ts | 39 ++++++++++++++----- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 91394f798dc95..e21aabd3fb255 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -1232,8 +1232,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.state.runtime.zenMode.transitionDisposables.add(this.editorService.onDidVisibleEditorsChange(() => setLineNumbers('off'))); } - if (config.hideTabs && this.editorGroupService.partOptions.showTabs === 'multiple') { - this.state.runtime.zenMode.transitionDisposables.add(this.editorGroupService.enforcePartOptions({ showTabs: 'single' })); + if (config.showTabs !== this.editorGroupService.partOptions.showTabs) { + this.state.runtime.zenMode.transitionDisposables.add(this.editorGroupService.enforcePartOptions({ showTabs: config.showTabs })); } if (config.silentNotifications && zenModeExitInfo.handleNotificationsDoNotDisturbMode) { @@ -2305,7 +2305,7 @@ type ZenModeConfiguration = { hideActivityBar: boolean; hideLineNumbers: boolean; hideStatusBar: boolean; - hideTabs: boolean; + showTabs: 'multiple' | 'single' | 'none'; restore: boolean; silentNotifications: boolean; }; diff --git a/src/vs/workbench/browser/parts/editor/editorTitleControl.ts b/src/vs/workbench/browser/parts/editor/editorTitleControl.ts index 38ea136a2a0c7..6330c3e814a93 100644 --- a/src/vs/workbench/browser/parts/editor/editorTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/editorTitleControl.ts @@ -78,7 +78,7 @@ export class EditorTitleControl extends Themable { private createBreadcrumbsControl(): BreadcrumbsControlFactory | undefined { if (this.groupsView.partOptions.showTabs !== 'multiple') { - return undefined; // single tabs have breadcrumbs inlined + return undefined; // Single tabs have breadcrumbs inlined. No tabs have no breadcrumbs. } // Breadcrumbs container diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 6cc79eea67178..c3b83193950ed 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -41,7 +41,12 @@ const registry = Registry.as(ConfigurationExtensions.Con 'workbench.editor.showTabs': { 'type': 'string', 'enum': ['multiple', 'single', 'none'], - 'description': localize('showEditorTabs', "Controls whether opened editors should show in tabs or not."), + 'enumDescriptions': [ + localize('workbench.editor.showTabs.multiple', "Each editor is displayed as a tab in the editor title area."), + localize('workbench.editor.showTabs.single', "The active editor is displayed as a single large tab in the editor title area."), + localize('workbench.editor.showTabs.none', "The editor title area is not displayed."), + ], + 'description': localize('showEditorTabs', "Controls whether opened editors should show as individual tabs, one single large tab or if the title area should not be shown."), 'default': 'multiple' }, 'workbench.editor.wrapTabs': { @@ -187,7 +192,7 @@ const registry = Registry.as(ConfigurationExtensions.Con 'workbench.editor.pinnedTabsOnSeparateRow': { 'type': 'boolean', 'default': false, - 'markdownDescription': localize('workbench.editor.pinnedTabsOnSeparateRow', "When enabled, displays pinned tabs in a separate row above all other tabs. This value is ignored when `#workbench.editor.showTabs#` is disabled."), + 'markdownDescription': localize('workbench.editor.pinnedTabsOnSeparateRow', "When enabled, displays pinned tabs in a separate row above all other tabs. This value is ignored when `#workbench.editor.showTabs#` is not set to `multiple`."), }, 'workbench.editor.preventPinnedEditorClose': { 'type': 'string', @@ -722,10 +727,16 @@ const registry = Registry.as(ConfigurationExtensions.Con 'default': true, 'description': localize('zenMode.centerLayout', "Controls whether turning on Zen Mode also centers the layout.") }, - 'zenMode.hideTabs': { - 'type': 'boolean', - 'default': true, - 'description': localize('zenMode.hideTabs', "Controls whether turning on Zen Mode also hides workbench tabs.") + 'zenMode.showTabs': { + 'type': 'string', + 'enum': ['multiple', 'single', 'none'], + 'description': localize('zenMode.showTabs', "Controls whether turning on Zen Mode should show muötiple editor tabs, a single editor tab or hide the editor title area completely."), + 'enumDescriptions': [ + localize('zenMode.showTabs.multiple', "Each editor is displayed as a tab in the editor title area."), + localize('zenMode.showTabs.single', "The active editor is displayed as a single large tab in the editor title area."), + localize('zenMode.showTabs.none', "The editor title area is not displayed."), + ], + 'default': 'multiple' }, 'zenMode.hideStatusBar': { 'type': 'boolean', @@ -770,9 +781,19 @@ Registry.as(Extensions.ConfigurationMigration) Registry.as(Extensions.ConfigurationMigration) .registerConfigurationMigrations([{ key: 'workbench.editor.showTabs', migrateFn: (value: any) => { - const result: ConfigurationKeyValuePairs = [['workbench.editor.showTabs', { value: value }]]; - if (value === false) { - result.push(['workbench.editor.showTabs', { value: 'single' }]); + if (typeof value === 'boolean') { + value = value ? 'multiple' : 'single'; + } + return [['workbench.editor.showTabs', { value: value }]]; + } + }]); + +Registry.as(Extensions.ConfigurationMigration) + .registerConfigurationMigrations([{ + key: 'zenMode.hideTabs', migrateFn: (value: any) => { + const result: ConfigurationKeyValuePairs = [['zenMode.hideTabs', { value: undefined }]]; + if (value === true) { + result.push(['zenMode.showTabs', { value: 'single' }]); } return result; } From df912eeb56acfb3b6a2fd519451168228bb4edee Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 15 Oct 2023 17:48:13 +0200 Subject: [PATCH 07/11] contextkey has --- src/vs/workbench/browser/actions/layoutActions.ts | 4 ++-- src/vs/workbench/browser/parts/editor/editor.contribution.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index 7dd8459f9aa9e..d4387fb9ea573 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -470,7 +470,7 @@ export class ToggleStatusbarVisibilityAction extends Action2 { registerAction2(ToggleStatusbarVisibilityAction); -// --- Bse Class Toggle Boolean Setting Action +// --- Base Class Toggle Boolean Setting Action abstract class BaseToggleBooleanSettingAction extends Action2 { @@ -524,7 +524,7 @@ export class ToggleSeparatePinnedTabsAction extends BaseToggleBooleanSettingActi original: 'Separate Pinned Editor Tabs' }, category: Categories.View, - precondition: ContextKeyExpr.has('config.workbench.editor.showTabs'), + precondition: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple'), f1: true }); } diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 7289ba1aca655..18cbd10b7d3f4 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -355,7 +355,7 @@ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_DOWN, title: localize('splitDown', "Split Down") }, group: '2_split', order: 20 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_LEFT, title: localize('splitLeft', "Split Left") }, group: '2_split', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '2_split', order: 40 }); -MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ToggleTabsVisibilityAction.ID, title: localize('toggleTabs', "Editor Tabs"), toggled: ContextKeyExpr.has('config.workbench.editor.showTabs') }, group: '3_config', order: 10 }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ToggleTabsVisibilityAction.ID, title: localize('toggleTabs', "Editor Tabs"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }, group: '3_config', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ToggleSeparatePinnedTabsAction.ID, title: localize('toggleSeparatePinnedEditorTabs', "Separate Pinned Editor Tabs"), toggled: ContextKeyExpr.has('config.workbench.editor.pinnedTabsOnSeparateRow') }, when: EditorPinnedAndUnpinnedTabsContext, group: '3_config', order: 20 }); // Editor Title Context Menu From e859dc6a999d5b5b6cf26a09e07dc5f71ec0bb46 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 15 Oct 2023 18:39:33 +0200 Subject: [PATCH 08/11] :lipstick: --- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index c3b83193950ed..c6c287adb4d0e 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -730,7 +730,7 @@ const registry = Registry.as(ConfigurationExtensions.Con 'zenMode.showTabs': { 'type': 'string', 'enum': ['multiple', 'single', 'none'], - 'description': localize('zenMode.showTabs', "Controls whether turning on Zen Mode should show muötiple editor tabs, a single editor tab or hide the editor title area completely."), + 'description': localize('zenMode.showTabs', "Controls whether turning on Zen Mode should show multiple editor tabs, a single editor tab or hide the editor title area completely."), 'enumDescriptions': [ localize('zenMode.showTabs.multiple', "Each editor is displayed as a tab in the editor title area."), localize('zenMode.showTabs.single', "The active editor is displayed as a single large tab in the editor title area."), From e47adcbf4bfdbe76aa6240d7186f2723d236d066 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Wed, 18 Oct 2023 12:07:15 +0200 Subject: [PATCH 09/11] Adapt context menu and commands --- .../browser/actions/layoutActions.ts | 79 ++++++++++++++----- .../parts/editor/editor.contribution.ts | 7 +- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index d4387fb9ea573..a1024ebff978f 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -470,49 +470,87 @@ export class ToggleStatusbarVisibilityAction extends Action2 { registerAction2(ToggleStatusbarVisibilityAction); -// --- Base Class Toggle Boolean Setting Action +// --- Hide Editor Tabs -abstract class BaseToggleBooleanSettingAction extends Action2 { +export class HideEditorTabsAction extends Action2 { - protected abstract get settingId(): string; + static readonly ID = 'workbench.action.hideEditorTabs'; + + constructor() { + super({ + id: HideEditorTabsAction.ID, + title: { + value: localize('hideEditorTabs', "Hide Editor Tabs"), + original: 'Hide Editor Tabs' + }, + category: Categories.View, + precondition: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate(), + f1: true + }); + } override run(accessor: ServicesAccessor): Promise { const configurationService = accessor.get(IConfigurationService); + return configurationService.updateValue('workbench.editor.showTabs', 'none'); + } +} +registerAction2(HideEditorTabsAction); - const oldettingValue = configurationService.getValue(this.settingId); - const newSettingValue = !oldettingValue; +// --- Show Multiple Editor Tabs + +export class ShowMultipleEditorTabsAction extends Action2 { + + static readonly ID = 'workbench.action.showMultipleEditorTabs'; + + constructor() { + super({ + id: ShowMultipleEditorTabsAction.ID, + title: { + value: localize('showMultipleEditorTabs', "Show Multiple Editor Tabs"), + original: 'Show Multiple Editor Tabs' + }, + category: Categories.View, + precondition: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple').negate(), + f1: true + }); + } - return configurationService.updateValue(this.settingId, newSettingValue); + override run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + return configurationService.updateValue('workbench.editor.showTabs', 'multiple'); } } +registerAction2(ShowMultipleEditorTabsAction); -// --- Toggle Tabs Visibility +// --- Show Single Editor Tab -export class ToggleTabsVisibilityAction extends BaseToggleBooleanSettingAction { +export class ShowSingleEditorTabAction extends Action2 { - static readonly ID = 'workbench.action.toggleTabsVisibility'; + static readonly ID = 'workbench.action.showEditorTab'; constructor() { super({ - id: ToggleTabsVisibilityAction.ID, + id: ShowSingleEditorTabAction.ID, title: { - value: localize('toggleTabs', "Toggle Editor Tab Visibility"), - original: 'Toggle Editor Tab Visibility' + value: localize('showSingleEditorTab', "Show Single Editor Tab"), + original: 'Show Single Editor Tab' }, category: Categories.View, + precondition: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'single').negate(), f1: true }); } - protected override get settingId(): string { - return 'workbench.editor.showTabs'; + override run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + return configurationService.updateValue('workbench.editor.showTabs', 'single'); } } -registerAction2(ToggleTabsVisibilityAction); +registerAction2(ShowSingleEditorTabAction); // --- Toggle Pinned Tabs On Separate Row -export class ToggleSeparatePinnedTabsAction extends BaseToggleBooleanSettingAction { +export class ToggleSeparatePinnedTabsAction extends Action2 { static readonly ID = 'workbench.action.toggleSeparatePinnedEditorTabs'; @@ -529,8 +567,13 @@ export class ToggleSeparatePinnedTabsAction extends BaseToggleBooleanSettingActi }); } - protected override get settingId(): string { - return 'workbench.editor.pinnedTabsOnSeparateRow'; + override run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + + const oldettingValue = configurationService.getValue('workbench.editor.pinnedTabsOnSeparateRow'); + const newSettingValue = !oldettingValue; + + return configurationService.updateValue('workbench.editor.pinnedTabsOnSeparateRow', newSettingValue); } } registerAction2(ToggleSeparatePinnedTabsAction); diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 18cbd10b7d3f4..cca074fe5692e 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -66,7 +66,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { UntitledTextEditorInputSerializer, UntitledTextEditorWorkingCopyEditorHandler } from 'vs/workbench/services/untitled/common/untitledTextEditorHandler'; import { DynamicEditorConfigurations } from 'vs/workbench/browser/parts/editor/editorConfiguration'; -import { ToggleSeparatePinnedTabsAction, ToggleTabsVisibilityAction } from 'vs/workbench/browser/actions/layoutActions'; +import { HideEditorTabsAction, ShowMultipleEditorTabsAction, ShowSingleEditorTabAction, ToggleSeparatePinnedTabsAction } from 'vs/workbench/browser/actions/layoutActions'; import product from 'vs/platform/product/common/product'; //#region Editor Registrations @@ -355,7 +355,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_DOWN, title: localize('splitDown', "Split Down") }, group: '2_split', order: 20 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_LEFT, title: localize('splitLeft', "Split Left") }, group: '2_split', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '2_split', order: 40 }); -MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ToggleTabsVisibilityAction.ID, title: localize('toggleTabs', "Editor Tabs"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }, group: '3_config', order: 10 }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ShowSingleEditorTabAction.ID, title: localize('showSingleTab', "Show Single Tab") }, group: '3_config', order: 10, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: HideEditorTabsAction.ID, title: localize('hideTabBar', "Hide Tab Bar") }, group: '3_config', order: 15, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate() }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ToggleSeparatePinnedTabsAction.ID, title: localize('toggleSeparatePinnedEditorTabs', "Separate Pinned Editor Tabs"), toggled: ContextKeyExpr.has('config.workbench.editor.pinnedTabsOnSeparateRow') }, when: EditorPinnedAndUnpinnedTabsContext, group: '3_config', order: 20 }); // Editor Title Context Menu @@ -374,6 +375,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: SPLIT_ED MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '5_split', order: 40 }); MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: SPLIT_EDITOR_IN_GROUP, title: localize('splitInGroup', "Split in Group") }, group: '6_split_in_group', order: 10, when: ActiveEditorCanSplitInGroupContext }); MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: JOIN_EDITOR_IN_GROUP, title: localize('joinInGroup', "Join in Group") }, group: '6_split_in_group', order: 10, when: SideBySideEditorActiveContext }); +MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: ShowMultipleEditorTabsAction.ID, title: localize('showMultipleTabs', "Show Multiple Tabs") }, group: '7_config', order: 10, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'single') }); +MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: HideEditorTabsAction.ID, title: localize('hideTabBar', "Hide Tab Bar") }, group: '7_config', order: 20, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate() }); // Editor Title Menu MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: TOGGLE_DIFF_SIDE_BY_SIDE, title: localize('inlineView', "Inline View"), toggled: ContextKeyExpr.equals('config.diffEditor.renderSideBySide', false) }, group: '1_diff', order: 10, when: ContextKeyExpr.has('isInDiffEditor') }); From 970cc6eaa530f35bd14baba649d3c82c9d05be9f Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Wed, 18 Oct 2023 15:21:17 +0200 Subject: [PATCH 10/11] Add show tabs submenu to editor tabs bar --- src/vs/platform/actions/common/actions.ts | 1 + .../workbench/browser/parts/editor/editor.contribution.ts | 8 ++++---- .../workbench/browser/parts/editor/noEditorTabsControl.ts | 8 +------- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 10a31c9853127..081100f852820 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -69,6 +69,7 @@ export class MenuId { static readonly EmptyEditorGroup = new MenuId('EmptyEditorGroup'); static readonly EmptyEditorGroupContext = new MenuId('EmptyEditorGroupContext'); static readonly EditorTabsBarContext = new MenuId('EditorTabsBarContext'); + static readonly EditorTabsBarShowTabsSubmenu = new MenuId('EditorTabsBarShowTabsSubmenu'); static readonly ExplorerContext = new MenuId('ExplorerContext'); static readonly ExplorerContextShare = new MenuId('ExplorerContextShare'); static readonly ExtensionContext = new MenuId('ExtensionContext'); diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index cca074fe5692e..71003f0f7d4be 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -355,8 +355,10 @@ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_DOWN, title: localize('splitDown', "Split Down") }, group: '2_split', order: 20 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_LEFT, title: localize('splitLeft', "Split Left") }, group: '2_split', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '2_split', order: 40 }); -MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ShowSingleEditorTabAction.ID, title: localize('showSingleTab', "Show Single Tab") }, group: '3_config', order: 10, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }); -MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: HideEditorTabsAction.ID, title: localize('hideTabBar', "Hide Tab Bar") }, group: '3_config', order: 15, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate() }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { submenu: MenuId.EditorTabsBarShowTabsSubmenu, title: localize('showTabs', "Show Tabs"), group: '3_config', order: 10 }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: ShowMultipleEditorTabsAction.ID, title: localize('multipleTabs', "Multiple Tab"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }, group: '1_config', order: 10 }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: ShowSingleEditorTabAction.ID, title: localize('singleTab', "Single Tab"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'single') }, group: '1_config', order: 20 }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: HideEditorTabsAction.ID, title: localize('hideTabBar', "Hide Tab Bar"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none') }, group: '1_config', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ToggleSeparatePinnedTabsAction.ID, title: localize('toggleSeparatePinnedEditorTabs', "Separate Pinned Editor Tabs"), toggled: ContextKeyExpr.has('config.workbench.editor.pinnedTabsOnSeparateRow') }, when: EditorPinnedAndUnpinnedTabsContext, group: '3_config', order: 20 }); // Editor Title Context Menu @@ -375,8 +377,6 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: SPLIT_ED MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '5_split', order: 40 }); MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: SPLIT_EDITOR_IN_GROUP, title: localize('splitInGroup', "Split in Group") }, group: '6_split_in_group', order: 10, when: ActiveEditorCanSplitInGroupContext }); MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: JOIN_EDITOR_IN_GROUP, title: localize('joinInGroup', "Join in Group") }, group: '6_split_in_group', order: 10, when: SideBySideEditorActiveContext }); -MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: ShowMultipleEditorTabsAction.ID, title: localize('showMultipleTabs', "Show Multiple Tabs") }, group: '7_config', order: 10, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'single') }); -MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id: HideEditorTabsAction.ID, title: localize('hideTabBar', "Hide Tab Bar") }, group: '7_config', order: 20, when: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none').negate() }); // Editor Title Menu MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: TOGGLE_DIFF_SIDE_BY_SIDE, title: localize('inlineView', "Inline View"), toggled: ContextKeyExpr.equals('config.diffEditor.renderSideBySide', false) }, group: '1_diff', order: 10, when: ContextKeyExpr.has('isInDiffEditor') }); diff --git a/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts index 4d426dcf52ffb..f265b1962129c 100644 --- a/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts @@ -11,11 +11,7 @@ import { IEditorTitleControlDimensions } from 'vs/workbench/browser/parts/editor export class NoEditorTabsControl extends EditorTabsControl { - protected override create(parent: HTMLElement): void { - super.create(parent); - } - - protected override prepareEditorActions(editorActions: IToolbarActions): IToolbarActions { + protected prepareEditorActions(editorActions: IToolbarActions): IToolbarActions { return { primary: [], secondary: [] @@ -50,8 +46,6 @@ export class NoEditorTabsControl extends EditorTabsControl { updateEditorDirty(editor: EditorInput): void { } - override updateStyles(): void { } - getHeight(): number { return 0; } From e26251254a3c4ad0ad7d426b3b72b40ebc76b646 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:20:00 +0200 Subject: [PATCH 11/11] Update src/vs/workbench/browser/parts/editor/editor.contribution.ts Co-authored-by: Benjamin Pasero --- src/vs/workbench/browser/parts/editor/editor.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 71003f0f7d4be..9e657431c9a48 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -356,7 +356,7 @@ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_ MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_LEFT, title: localize('splitLeft', "Split Left") }, group: '2_split', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '2_split', order: 40 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { submenu: MenuId.EditorTabsBarShowTabsSubmenu, title: localize('showTabs', "Show Tabs"), group: '3_config', order: 10 }); -MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: ShowMultipleEditorTabsAction.ID, title: localize('multipleTabs', "Multiple Tab"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }, group: '1_config', order: 10 }); +MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: ShowMultipleEditorTabsAction.ID, title: localize('multipleTabs', "Multiple Tabs"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'multiple') }, group: '1_config', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: ShowSingleEditorTabAction.ID, title: localize('singleTab', "Single Tab"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'single') }, group: '1_config', order: 20 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarShowTabsSubmenu, { command: { id: HideEditorTabsAction.ID, title: localize('hideTabBar', "Hide Tab Bar"), toggled: ContextKeyExpr.equals('config.workbench.editor.showTabs', 'none') }, group: '1_config', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EditorTabsBarContext, { command: { id: ToggleSeparatePinnedTabsAction.ID, title: localize('toggleSeparatePinnedEditorTabs', "Separate Pinned Editor Tabs"), toggled: ContextKeyExpr.has('config.workbench.editor.pinnedTabsOnSeparateRow') }, when: EditorPinnedAndUnpinnedTabsContext, group: '3_config', order: 20 });