Path: blob/main/src/vs/workbench/browser/contextkeys.ts
5221 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Disposable } from '../../base/common/lifecycle.js';6import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from '../../platform/contextkey/common/contextkey.js';7import { IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from '../../platform/contextkey/common/contextkeys.js';8import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, AuxiliaryBarMaximizedContext, InAutomationContext, IsAgentSessionsWorkspaceContext, WorkbenchModeContext } from '../common/contextkeys.js';9import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';10import { IConfigurationService } from '../../platform/configuration/common/configuration.js';11import { IWorkbenchEnvironmentService } from '../services/environment/common/environmentService.js';12import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from '../../platform/workspace/common/workspace.js';13import { IWorkbenchLayoutService, Parts, positionToString } from '../services/layout/browser/layoutService.js';14import { getRemoteName } from '../../platform/remote/common/remoteHosts.js';15import { getVirtualWorkspaceScheme } from '../../platform/workspace/common/virtualWorkspace.js';16import { IWorkingCopyService } from '../services/workingCopy/common/workingCopyService.js';17import { isNative } from '../../base/common/platform.js';18import { IPaneCompositePartService } from '../services/panecomposite/browser/panecomposite.js';19import { WebFileSystemAccess } from '../../platform/files/browser/webFileSystemAccess.js';20import { IProductService } from '../../platform/product/common/productService.js';21import { getTitleBarStyle } from '../../platform/window/common/window.js';22import { mainWindow } from '../../base/browser/window.js';23import { isFullscreen, onDidChangeFullscreen } from '../../base/browser/browser.js';24import { IEditorService } from '../services/editor/common/editorService.js';25import { IWorkbenchModeService } from '../services/layout/common/workbenchModeService.js';2627export class WorkbenchContextKeysHandler extends Disposable {2829private dirtyWorkingCopiesContext: IContextKey<boolean>;3031private activeEditorGroupEmpty: IContextKey<boolean>;32private activeEditorGroupIndex: IContextKey<number>;33private activeEditorGroupLast: IContextKey<boolean>;34private activeEditorGroupLocked: IContextKey<boolean>;35private multipleEditorGroupsContext: IContextKey<boolean>;3637private editorsVisibleContext: IContextKey<boolean>;3839private splitEditorsVerticallyContext: IContextKey<boolean>;4041private workbenchStateContext: IContextKey<string>;42private workspaceFolderCountContext: IContextKey<number>;4344private openFolderWorkspaceSupportContext: IContextKey<boolean>;45private enterMultiRootWorkspaceSupportContext: IContextKey<boolean>;46private emptyWorkspaceSupportContext: IContextKey<boolean>;4748private virtualWorkspaceContext: IContextKey<string>;49private temporaryWorkspaceContext: IContextKey<boolean>;50private isAgentSessionsWorkspaceContext: IContextKey<boolean>;51private workbenchModeContext: IContextKey<string>;52private inAutomationContext: IContextKey<boolean>;5354private inZenModeContext: IContextKey<boolean>;55private isMainWindowFullscreenContext: IContextKey<boolean>;56private isAuxiliaryWindowFocusedContext: IContextKey<boolean>;57private isMainEditorCenteredLayoutContext: IContextKey<boolean>;58private sideBarVisibleContext: IContextKey<boolean>;59private mainEditorAreaVisibleContext: IContextKey<boolean>;60private panelPositionContext: IContextKey<string>;61private panelVisibleContext: IContextKey<boolean>;62private panelAlignmentContext: IContextKey<string>;63private panelMaximizedContext: IContextKey<boolean>;64private auxiliaryBarVisibleContext: IContextKey<boolean>;65private auxiliaryBarMaximizedContext: IContextKey<boolean>;66private editorTabsVisibleContext: IContextKey<boolean>;67private titleAreaVisibleContext: IContextKey<boolean>;68private titleBarStyleContext: IContextKey<string>;6970constructor(71@IContextKeyService private readonly contextKeyService: IContextKeyService,72@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,73@IConfigurationService private readonly configurationService: IConfigurationService,74@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,75@IProductService private readonly productService: IProductService,76@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,77@IEditorService private readonly editorService: IEditorService,78@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,79@IPaneCompositePartService private readonly paneCompositeService: IPaneCompositePartService,80@IWorkingCopyService private readonly workingCopyService: IWorkingCopyService,81@IWorkbenchModeService private readonly workbenchModeService: IWorkbenchModeService,82) {83super();8485// Platform86IsMacContext.bindTo(this.contextKeyService);87IsLinuxContext.bindTo(this.contextKeyService);88IsWindowsContext.bindTo(this.contextKeyService);8990IsWebContext.bindTo(this.contextKeyService);91IsMacNativeContext.bindTo(this.contextKeyService);92IsIOSContext.bindTo(this.contextKeyService);93IsMobileContext.bindTo(this.contextKeyService);9495RemoteNameContext.bindTo(this.contextKeyService).set(getRemoteName(this.environmentService.remoteAuthority) || '');9697this.virtualWorkspaceContext = VirtualWorkspaceContext.bindTo(this.contextKeyService);98this.temporaryWorkspaceContext = TemporaryWorkspaceContext.bindTo(this.contextKeyService);99this.isAgentSessionsWorkspaceContext = IsAgentSessionsWorkspaceContext.bindTo(this.contextKeyService);100this.isAgentSessionsWorkspaceContext.set(!!this.contextService.getWorkspace().isAgentSessionsWorkspace);101this.workbenchModeContext = WorkbenchModeContext.bindTo(this.contextKeyService);102this.workbenchModeContext.set(this.workbenchModeService.workbenchMode ?? '');103this.updateWorkspaceContextKeys();104105// Capabilities106HasWebFileSystemAccess.bindTo(this.contextKeyService).set(WebFileSystemAccess.supported(mainWindow));107108// Development109const isDevelopment = !this.environmentService.isBuilt || this.environmentService.isExtensionDevelopment;110IsDevelopmentContext.bindTo(this.contextKeyService).set(isDevelopment);111setConstantContextKey(IsDevelopmentContext.key, isDevelopment);112113// Product Service114ProductQualityContext.bindTo(this.contextKeyService).set(this.productService.quality || '');115EmbedderIdentifierContext.bindTo(this.contextKeyService).set(productService.embedderIdentifier);116117// Automation118this.inAutomationContext = InAutomationContext.bindTo(this.contextKeyService);119this.inAutomationContext.set(!!this.environmentService.enableSmokeTestDriver);120121// Editor Groups122this.activeEditorGroupEmpty = ActiveEditorGroupEmptyContext.bindTo(this.contextKeyService);123this.activeEditorGroupIndex = ActiveEditorGroupIndexContext.bindTo(this.contextKeyService);124this.activeEditorGroupLast = ActiveEditorGroupLastContext.bindTo(this.contextKeyService);125this.activeEditorGroupLocked = ActiveEditorGroupLockedContext.bindTo(this.contextKeyService);126this.multipleEditorGroupsContext = MultipleEditorGroupsContext.bindTo(this.contextKeyService);127128// Editors129this.editorsVisibleContext = EditorsVisibleContext.bindTo(this.contextKeyService);130131// Working Copies132this.dirtyWorkingCopiesContext = DirtyWorkingCopiesContext.bindTo(this.contextKeyService);133this.dirtyWorkingCopiesContext.set(this.workingCopyService.hasDirty);134135// Workbench State136this.workbenchStateContext = WorkbenchStateContext.bindTo(this.contextKeyService);137this.updateWorkbenchStateContextKey();138139// Workspace Folder Count140this.workspaceFolderCountContext = WorkspaceFolderCountContext.bindTo(this.contextKeyService);141this.updateWorkspaceFolderCountContextKey();142143// Opening folder support: support for opening a folder workspace144// (e.g. "Open Folder...") is limited in web when not connected145// to a remote.146this.openFolderWorkspaceSupportContext = OpenFolderWorkspaceSupportContext.bindTo(this.contextKeyService);147this.openFolderWorkspaceSupportContext.set(isNative || typeof this.environmentService.remoteAuthority === 'string');148149// Empty workspace support: empty workspaces require built-in file system150// providers to be available that allow to enter a workspace or open loose151// files. This condition is met:152// - desktop: always153// - web: only when connected to a remote154this.emptyWorkspaceSupportContext = EmptyWorkspaceSupportContext.bindTo(this.contextKeyService);155this.emptyWorkspaceSupportContext.set(isNative || typeof this.environmentService.remoteAuthority === 'string');156157// Entering a multi root workspace support: support for entering a multi-root158// workspace (e.g. "Open Workspace from File...", "Duplicate Workspace", "Save Workspace")159// is driven by the ability to resolve a workspace configuration file (*.code-workspace)160// with a built-in file system provider.161// This condition is met:162// - desktop: always163// - web: only when connected to a remote164this.enterMultiRootWorkspaceSupportContext = EnterMultiRootWorkspaceSupportContext.bindTo(this.contextKeyService);165this.enterMultiRootWorkspaceSupportContext.set(isNative || typeof this.environmentService.remoteAuthority === 'string');166167// Editor Layout168this.splitEditorsVerticallyContext = SplitEditorsVertically.bindTo(this.contextKeyService);169this.updateSplitEditorsVerticallyContext();170171// Window172this.isMainWindowFullscreenContext = IsMainWindowFullscreenContext.bindTo(this.contextKeyService);173this.isAuxiliaryWindowFocusedContext = IsAuxiliaryWindowFocusedContext.bindTo(this.contextKeyService);174175// Zen Mode176this.inZenModeContext = InEditorZenModeContext.bindTo(this.contextKeyService);177178// Centered Layout (Main Editor)179this.isMainEditorCenteredLayoutContext = IsMainEditorCenteredLayoutContext.bindTo(this.contextKeyService);180181// Editor Area182this.mainEditorAreaVisibleContext = MainEditorAreaVisibleContext.bindTo(this.contextKeyService);183this.editorTabsVisibleContext = EditorTabsVisibleContext.bindTo(this.contextKeyService);184185// Sidebar186this.sideBarVisibleContext = SideBarVisibleContext.bindTo(this.contextKeyService);187188// Title Bar189this.titleAreaVisibleContext = TitleBarVisibleContext.bindTo(this.contextKeyService);190this.titleBarStyleContext = TitleBarStyleContext.bindTo(this.contextKeyService);191this.updateTitleBarContextKeys();192193// Panel194this.panelPositionContext = PanelPositionContext.bindTo(this.contextKeyService);195this.panelPositionContext.set(positionToString(this.layoutService.getPanelPosition()));196this.panelVisibleContext = PanelVisibleContext.bindTo(this.contextKeyService);197this.panelVisibleContext.set(this.layoutService.isVisible(Parts.PANEL_PART));198this.panelMaximizedContext = PanelMaximizedContext.bindTo(this.contextKeyService);199this.panelMaximizedContext.set(this.layoutService.isPanelMaximized());200this.panelAlignmentContext = PanelAlignmentContext.bindTo(this.contextKeyService);201this.panelAlignmentContext.set(this.layoutService.getPanelAlignment());202203// Auxiliary Bar204this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService);205this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));206this.auxiliaryBarMaximizedContext = AuxiliaryBarMaximizedContext.bindTo(this.contextKeyService);207this.auxiliaryBarMaximizedContext.set(this.layoutService.isAuxiliaryBarMaximized());208209this.registerListeners();210}211212private registerListeners(): void {213this.editorGroupService.whenReady.then(() => {214this.updateEditorAreaContextKeys();215this.updateActiveEditorGroupContextKeys();216this.updateVisiblePanesContextKeys();217});218219this._register(this.editorService.onDidActiveEditorChange(() => this.updateActiveEditorGroupContextKeys()));220this._register(this.editorService.onDidVisibleEditorsChange(() => this.updateVisiblePanesContextKeys()));221this._register(this.editorGroupService.onDidAddGroup(() => this.updateEditorGroupsContextKeys()));222this._register(this.editorGroupService.onDidRemoveGroup(() => this.updateEditorGroupsContextKeys()));223this._register(this.editorGroupService.onDidChangeGroupIndex(() => this.updateActiveEditorGroupContextKeys()));224this._register(this.editorGroupService.onDidChangeGroupLocked(() => this.updateActiveEditorGroupContextKeys()));225226this._register(this.editorGroupService.onDidChangeEditorPartOptions(() => this.updateEditorAreaContextKeys()));227228this._register(this.contextService.onDidChangeWorkbenchState(() => this.updateWorkbenchStateContextKey()));229this._register(this.contextService.onDidChangeWorkspaceFolders(() => {230this.updateWorkspaceFolderCountContextKey();231this.updateWorkspaceContextKeys();232}));233234this._register(this.workbenchModeService.onDidChangeWorkbenchMode(mode => this.workbenchModeContext.set(mode ?? '')));235236this._register(this.configurationService.onDidChangeConfiguration(e => {237if (e.affectsConfiguration('workbench.editor.openSideBySideDirection')) {238this.updateSplitEditorsVerticallyContext();239}240}));241242this._register(this.layoutService.onDidChangeZenMode(enabled => this.inZenModeContext.set(enabled)));243this._register(this.layoutService.onDidChangeActiveContainer(() => this.isAuxiliaryWindowFocusedContext.set(this.layoutService.activeContainer !== this.layoutService.mainContainer)));244this._register(onDidChangeFullscreen(windowId => {245if (windowId === mainWindow.vscodeWindowId) {246this.isMainWindowFullscreenContext.set(isFullscreen(mainWindow));247}248}));249this._register(this.layoutService.onDidChangeMainEditorCenteredLayout(centered => this.isMainEditorCenteredLayoutContext.set(centered)));250this._register(this.layoutService.onDidChangePanelPosition(position => this.panelPositionContext.set(position)));251252this._register(this.layoutService.onDidChangePanelAlignment(alignment => this.panelAlignmentContext.set(alignment)));253254this._register(this.paneCompositeService.onDidPaneCompositeClose(() => this.updateSideBarContextKeys()));255this._register(this.paneCompositeService.onDidPaneCompositeOpen(() => this.updateSideBarContextKeys()));256257this._register(this.layoutService.onDidChangePartVisibility(() => {258this.mainEditorAreaVisibleContext.set(this.layoutService.isVisible(Parts.EDITOR_PART, mainWindow));259this.panelVisibleContext.set(this.layoutService.isVisible(Parts.PANEL_PART));260this.panelMaximizedContext.set(this.layoutService.isPanelMaximized());261this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));262263this.updateTitleBarContextKeys();264}));265266this._register(this.layoutService.onDidChangeAuxiliaryBarMaximized(() => {267this.auxiliaryBarMaximizedContext.set(this.layoutService.isAuxiliaryBarMaximized());268}));269270this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.dirtyWorkingCopiesContext.set(workingCopy.isDirty() || this.workingCopyService.hasDirty)));271}272273private updateVisiblePanesContextKeys(): void {274const visibleEditorPanes = this.editorService.visibleEditorPanes;275if (visibleEditorPanes.length > 0) {276this.editorsVisibleContext.set(true);277} else {278this.editorsVisibleContext.reset();279}280}281282// Context keys depending on the state of the editor group itself283private updateActiveEditorGroupContextKeys(): void {284if (!this.editorService.activeEditor) {285this.activeEditorGroupEmpty.set(true);286} else {287this.activeEditorGroupEmpty.reset();288}289290const activeGroup = this.editorGroupService.activeGroup;291this.activeEditorGroupIndex.set(activeGroup.index + 1); // not zero-indexed292this.activeEditorGroupLocked.set(activeGroup.isLocked);293294this.updateEditorGroupsContextKeys();295}296297// Context keys depending on the state of other editor groups298private updateEditorGroupsContextKeys(): void {299const groupCount = this.editorGroupService.count;300if (groupCount > 1) {301this.multipleEditorGroupsContext.set(true);302} else {303this.multipleEditorGroupsContext.reset();304}305306const activeGroup = this.editorGroupService.activeGroup;307this.activeEditorGroupLast.set(activeGroup.index === groupCount - 1);308}309310private updateEditorAreaContextKeys(): void {311this.editorTabsVisibleContext.set(this.editorGroupService.partOptions.showTabs === 'multiple');312}313314private updateWorkbenchStateContextKey(): void {315this.workbenchStateContext.set(this.getWorkbenchStateString());316}317318private updateWorkspaceFolderCountContextKey(): void {319this.workspaceFolderCountContext.set(this.contextService.getWorkspace().folders.length);320}321322private updateSplitEditorsVerticallyContext(): void {323const direction = preferredSideBySideGroupDirection(this.configurationService);324this.splitEditorsVerticallyContext.set(direction === GroupDirection.DOWN);325}326327private getWorkbenchStateString(): string {328switch (this.contextService.getWorkbenchState()) {329case WorkbenchState.EMPTY: return 'empty';330case WorkbenchState.FOLDER: return 'folder';331case WorkbenchState.WORKSPACE: return 'workspace';332}333}334335private updateSideBarContextKeys(): void {336this.sideBarVisibleContext.set(this.layoutService.isVisible(Parts.SIDEBAR_PART));337}338339private updateTitleBarContextKeys(): void {340this.titleAreaVisibleContext.set(this.layoutService.isVisible(Parts.TITLEBAR_PART, mainWindow));341this.titleBarStyleContext.set(getTitleBarStyle(this.configurationService));342}343344private updateWorkspaceContextKeys(): void {345this.virtualWorkspaceContext.set(getVirtualWorkspaceScheme(this.contextService.getWorkspace()) || '');346this.temporaryWorkspaceContext.set(isTemporaryWorkspace(this.contextService.getWorkspace()));347}348}349350351