src/vs/workbench/common/contextkeys.ts

364 LOC · 250 covered · 114 uncovered · 10 ranges · 1733 concepts · 1 introducers · 961 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

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 related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- constants.ts ×18
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 { DisposableStore } from '../../base/common/lifecycle.js';
7 > import { URI } from '../../base/common/uri.js';
8 > import { localize } from '../../nls.js';
9 > import { IContextKeyService, IContextKey, RawContextKey } from '../../platform/contextkey/common/contextkey.js';
10 > import { basename, dirname, extname, isEqual } from '../../base/common/resources.js';
11 > import { ILanguageService } from '../../editor/common/languages/language.js';
12 > import { IFileService } from '../../platform/files/common/files.js';
13 > import { IModelService } from '../../editor/common/services/model.js';
14 > import { Schemas } from '../../base/common/network.js';
15 > import { EditorInput } from './editor/editorInput.js';
16 > import { IEditorResolverService } from '../services/editor/common/editorResolverService.js';
17 > import { DEFAULT_EDITOR_ASSOCIATION, isDiffEditorInput } from './editor.js';
18 >
19 > //#region < --- Workbench --- >
20 >
21 > export const WorkbenchStateContext = new RawContextKey<string>('workbenchState', undefined, { type: 'string', description: localize('workbenchState', "The kind of workspace opened in the window, either 'empty' (no workspace), 'folder' (single folder) or 'workspace' (multi-root workspace)") });
22 > export const WorkspaceFolderCountContext = new RawContextKey<number>('workspaceFolderCount', 0, localize('workspaceFolderCount', "The number of root folders in the workspace"));
23 >
24 > export const OpenFolderWorkspaceSupportContext = new RawContextKey<boolean>('openFolderWorkspaceSupport', true, true);
25 > export const EnterMultiRootWorkspaceSupportContext = new RawContextKey<boolean>('enterMultiRootWorkspaceSupport', true, true);
26 > export const EmptyWorkspaceSupportContext = new RawContextKey<boolean>('emptyWorkspaceSupport', true, true);
27 >
28 > export const DirtyWorkingCopiesContext = new RawContextKey<boolean>('dirtyWorkingCopies', false, localize('dirtyWorkingCopies', "Whether there are any working copies with unsaved changes"));
29 >
30 > export const RemoteNameContext = new RawContextKey<string>('remoteName', '', localize('remoteName', "The name of the remote the window is connected to or an empty string if not connected to any remote"));
31 >
32 > export const VirtualWorkspaceContext = new RawContextKey<string>('virtualWorkspace', '', localize('virtualWorkspace', "The scheme of the current workspace is from a virtual file system or an empty string."));
33 > export const TemporaryWorkspaceContext = new RawContextKey<boolean>('temporaryWorkspace', false, localize('temporaryWorkspace', "The scheme of the current workspace is from a temporary file system."));
34 >
35 > export const IsSessionsWindowContext = new RawContextKey<boolean>('isSessionsWindow', false, localize('isSessionsWindow', "Whether the current window is a agent sessions window."));
36 >
37 > export const HasWebFileSystemAccess = new RawContextKey<boolean>('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access)
38 >
39 > export const EmbedderIdentifierContext = new RawContextKey<string | undefined>('embedderIdentifier', undefined, localize('embedderIdentifier', 'The identifier of the embedder according to the product service, if one is defined'));
40 >
41 > export const InAutomationContext = new RawContextKey<boolean>('inAutomation', false, localize('inAutomation', "Whether VS Code is running under automation/smoke test"));
42 >
43 > //#endregion
44 >
45 > //#region < --- Window --- >
46 >
47 > export const IsMainWindowFullscreenContext = new RawContextKey<boolean>('isFullscreen', false, localize('isFullscreen', "Whether the main window is in fullscreen mode"));
48 > export const IsAuxiliaryWindowFocusedContext = new RawContextKey<boolean>('isAuxiliaryWindowFocusedContext', false, localize('isAuxiliaryWindowFocusedContext', "Whether an auxiliary window is focused"));
49 >
50 > export const IsWindowAlwaysOnTopContext = new RawContextKey<boolean>('isWindowAlwaysOnTop', false, localize('isWindowAlwaysOnTop', "Whether the window is always on top"));
51 >
52 > export const IsAuxiliaryWindowContext = new RawContextKey<boolean>('isAuxiliaryWindow', false, localize('isAuxiliaryWindow', "Window is an auxiliary window"));
53 >
54 >
55 > //#endregion
56 >
57 >
58 > //#region < --- Editor --- >
59 >
60 > // Editor State Context Keys
61 > export const ActiveEditorDirtyContext = new RawContextKey<boolean>('activeEditorIsDirty', false, localize('activeEditorIsDirty', "Whether the active editor has unsaved changes"));
62 > export const ActiveEditorPinnedContext = new RawContextKey<boolean>('activeEditorIsNotPreview', false, localize('activeEditorIsNotPreview', "Whether the active editor is not in preview mode"));
63 > export const ActiveEditorFirstInGroupContext = new RawContextKey<boolean>('activeEditorIsFirstInGroup', false, localize('activeEditorIsFirstInGroup', "Whether the active editor is the first one in its group"));
64 > export const ActiveEditorLastInGroupContext = new RawContextKey<boolean>('activeEditorIsLastInGroup', false, localize('activeEditorIsLastInGroup', "Whether the active editor is the last one in its group"));
65 > export const ActiveEditorStickyContext = new RawContextKey<boolean>('activeEditorIsPinned', false, localize('activeEditorIsPinned', "Whether the active editor is pinned"));
66 > export const ActiveEditorReadonlyContext = new RawContextKey<boolean>('activeEditorIsReadonly', false, localize('activeEditorIsReadonly', "Whether the active editor is read-only"));
67 > export const ActiveCompareEditorCanSwapContext = new RawContextKey<boolean>('activeCompareEditorCanSwap', false, localize('activeCompareEditorCanSwap', "Whether the active compare editor can swap sides"));
68 > export const ActiveEditorCanToggleReadonlyContext = new RawContextKey<boolean>('activeEditorCanToggleReadonly', true, localize('activeEditorCanToggleReadonly', "Whether the active editor can toggle between being read-only or writeable"));
69 > export const ActiveEditorCanRevertContext = new RawContextKey<boolean>('activeEditorCanRevert', false, localize('activeEditorCanRevert', "Whether the active editor can revert"));
70 > export const ActiveEditorCanSplitInGroupContext = new RawContextKey<boolean>('activeEditorCanSplitInGroup', true);
71 >
72 > // Editor Kind Context Keys
73 > export const ActiveEditorContext = new RawContextKey<string | null>('activeEditor', null, { type: 'string', description: localize('activeEditor', "The identifier of the active editor") });
74 > export const ActiveEditorAvailableEditorIdsContext = new RawContextKey<string>('activeEditorAvailableEditorIds', '', localize('activeEditorAvailableEditorIds', "The available editor identifiers that are usable for the active editor"));
75 > export const TextCompareEditorVisibleContext = new RawContextKey<boolean>('textCompareEditorVisible', false, localize('textCompareEditorVisible', "Whether a text compare editor is visible"));
76 > export const TextCompareEditorActiveContext = new RawContextKey<boolean>('textCompareEditorActive', false, localize('textCompareEditorActive', "Whether a text compare editor is active"));
77 > export const SideBySideEditorActiveContext = new RawContextKey<boolean>('sideBySideEditorActive', false, localize('sideBySideEditorActive', "Whether a side by side editor is active"));
78 > export const ActiveCustomEditorDiffCanToggleLayoutContext = new RawContextKey<boolean>('activeCustomEditorDiffCanToggleLayout', false, localize('activeCustomEditorDiffCanToggleLayout', "Whether the active custom editor diff can toggle between inline and side by side layout"));
79 > export const ActiveCustomEditorTextDiffContext = new RawContextKey<boolean>('activeCustomEditorTextDiff', false, localize('activeCustomEditorTextDiff', "Whether the active custom editor diff is backed by text documents"));
80 >
81 > // Editor Group Context Keys
82 > export const EditorGroupEditorsCountContext = new RawContextKey<number>('groupEditorsCount', 0, localize('groupEditorsCount', "The number of opened editor groups"));
83 > export const IsTopRightEditorGroupContext = new RawContextKey<boolean>('isTopRightEditorGroup', false, localize('isTopRightEditorGroup', "Whether the editor group is the top right editor group in the editor part"));
84 > export const ActiveEditorGroupEmptyContext = new RawContextKey<boolean>('activeEditorGroupEmpty', false, localize('activeEditorGroupEmpty', "Whether the active editor group is empty"));
85 > export const ActiveEditorGroupIndexContext = new RawContextKey<number>('activeEditorGroupIndex', 0, localize('activeEditorGroupIndex', "The index of the active editor group"));
86 > export const ActiveEditorGroupLastContext = new RawContextKey<boolean>('activeEditorGroupLast', false, localize('activeEditorGroupLast', "Whether the active editor group is the last group"));
87 > export const ActiveEditorGroupLockedContext = new RawContextKey<boolean>('activeEditorGroupLocked', false, localize('activeEditorGroupLocked', "Whether the active editor group is locked"));
88 > export const MultipleEditorGroupsContext = new RawContextKey<boolean>('multipleEditorGroups', false, localize('multipleEditorGroups', "Whether there are multiple editor groups opened"));
89 > export const SingleEditorGroupsContext = MultipleEditorGroupsContext.toNegated();
90 > export const MultipleEditorsSelectedInGroupContext = new RawContextKey<boolean>('multipleEditorsSelectedInGroup', false, localize('multipleEditorsSelectedInGroup', "Whether multiple editors have been selected in an editor group"));
91 > export const TwoEditorsSelectedInGroupContext = new RawContextKey<boolean>('twoEditorsSelectedInGroup', false, localize('twoEditorsSelectedInGroup', "Whether exactly two editors have been selected in an editor group"));
92 > export const SelectedEditorsInGroupFileOrUntitledResourceContextKey = new RawContextKey<boolean>('SelectedEditorsInGroupFileOrUntitledResourceContextKey', true, localize('SelectedEditorsInGroupFileOrUntitledResourceContextKey', "Whether all selected editors in a group have a file or untitled resource associated"));
93 >
94 > // Editor Part Context Keys
95 > export const EditorPartMultipleEditorGroupsContext = new RawContextKey<boolean>('editorPartMultipleEditorGroups', false, localize('editorPartMultipleEditorGroups', "Whether there are multiple editor groups opened in an editor part"));
96 > export const EditorPartSingleEditorGroupsContext = EditorPartMultipleEditorGroupsContext.toNegated();
97 > export const EditorPartMaximizedEditorGroupContext = new RawContextKey<boolean>('editorPartMaximizedEditorGroup', false, localize('editorPartEditorGroupMaximized', "Editor Part has a maximized group"));
98 >
99 > export const EditorPartModalContext = new RawContextKey<boolean>('editorPartModal', false, localize('editorPartModal', "Whether focus is in a modal editor part"));
100 > export const EditorPartModalVisibleContext = new RawContextKey<boolean>('editorPartModalVisible', false, localize('editorPartModalVisible', "Whether a modal editor part is visible"));
101 > export const EditorPartModalMaximizedContext = new RawContextKey<boolean>('editorPartModalMaximized', false, localize('editorPartModalMaximized', "Whether the modal editor part is maximized"));
102 > export const EditorPartModalNavigationContext = new RawContextKey<boolean>('editorPartModalNavigation', false, localize('editorPartModalNavigation', "Whether the modal editor part has navigation context"));
103 > export const EditorPartModalSidebarContext = new RawContextKey<boolean>('editorPartModalSidebar', false, localize('editorPartModalSidebar', "Whether the modal editor part has a sidebar"));
104 > export const EditorPartModalSidebarVisibleContext = new RawContextKey<boolean>('editorPartModalSidebarVisible', false, localize('editorPartModalSidebarVisible', "Whether the modal editor part sidebar is visible"));
105 >
106 > // Editor Layout Context Keys
107 > export const EditorsVisibleContext = new RawContextKey<boolean>('editorIsOpen', false, localize('editorIsOpen', "Whether an editor is open"));
108 > export const EditorAreaFocusContext = new RawContextKey<boolean>('editorAreaFocus', false, localize('editorAreaFocus', "Whether the editor area (any editor part) has keyboard focus"));
109 > export const InEditorZenModeContext = new RawContextKey<boolean>('inZenMode', false, localize('inZenMode', "Whether Zen mode is enabled"));
110 > export const IsMainEditorCenteredLayoutContext = new RawContextKey<boolean>('isCenteredLayout', false, localize('isMainEditorCenteredLayout', "Whether centered layout is enabled for the main editor"));
111 > export const SplitEditorsVertically = new RawContextKey<boolean>('splitEditorsVertically', false, localize('splitEditorsVertically', "Whether editors split vertically"));
112 > export const MainEditorAreaVisibleContext = new RawContextKey<boolean>('mainEditorAreaVisible', true, localize('mainEditorAreaVisible', "Whether the editor area in the main window is visible"));
113 > export const EditorTabsVisibleContext = new RawContextKey<boolean>('editorTabsVisible', true, localize('editorTabsVisible', "Whether editor tabs are visible"));
114 >
115 > //#endregion
116 >
117 >
118 > //#region < --- Side Bar --- >
119 >
120 > export const SideBarVisibleContext = new RawContextKey<boolean>('sideBarVisible', false, localize('sideBarVisible', "Whether the sidebar is visible"));
121 > export const SidebarFocusContext = new RawContextKey<boolean>('sideBarFocus', false, localize('sideBarFocus', "Whether the sidebar has keyboard focus"));
122 > export const ActiveViewletContext = new RawContextKey<string>('activeViewlet', '', localize('activeViewlet', "The identifier of the active viewlet"));
123 >
124 > //#endregion
125 >
126 >
127 > //#region < --- Status Bar --- >
128 >
129 > export const StatusBarFocused = new RawContextKey<boolean>('statusBarFocused', false, localize('statusBarFocused', "Whether the status bar has keyboard focus"));
130 >
131 > //#endregion
132 >
133 > //#region < --- Title Bar --- >
134 >
135 > export const TitleBarStyleContext = new RawContextKey<string>('titleBarStyle', 'custom', localize('titleBarStyle', "Style of the window title bar"));
136 > export const TitleBarVisibleContext = new RawContextKey<boolean>('titleBarVisible', false, localize('titleBarVisible', "Whether the title bar is visible"));
137 > export const IsCompactTitleBarContext = new RawContextKey<boolean>('isCompactTitleBar', false, localize('isCompactTitleBar', "Title bar is in compact mode"));
138 >
139 > //#endregion
140 >
141 >
142 > //#region < --- Banner --- >
143 >
144 > export const BannerFocused = new RawContextKey<boolean>('bannerFocused', false, localize('bannerFocused', "Whether the banner has keyboard focus"));
145 >
146 > //#endregion
147 >
148 >
149 > //#region < --- Notifications --- >
150 >
151 > export const NotificationFocusedContext = new RawContextKey<boolean>('notificationFocus', true, localize('notificationFocus', "Whether a notification has keyboard focus"));
152 > export const NotificationsCenterVisibleContext = new RawContextKey<boolean>('notificationCenterVisible', false, localize('notificationCenterVisible', "Whether the notifications center is visible"));
153 > export const NotificationsToastsVisibleContext = new RawContextKey<boolean>('notificationToastsVisible', false, localize('notificationToastsVisible', "Whether a notification toast is visible"));
154 >
155 > //#endregion
156 >
157 >
158 > //#region < --- Auxiliary Bar --- >
159 >
160 > export const ActiveAuxiliaryContext = new RawContextKey<string>('activeAuxiliary', '', localize('activeAuxiliary', "The identifier of the active auxiliary panel"));
161 > export const AuxiliaryBarFocusContext = new RawContextKey<boolean>('auxiliaryBarFocus', false, localize('auxiliaryBarFocus', "Whether the auxiliary bar has keyboard focus"));
162 > export const AuxiliaryBarVisibleContext = new RawContextKey<boolean>('auxiliaryBarVisible', false, localize('auxiliaryBarVisible', "Whether the auxiliary bar is visible"));
163 > export const SecondarySideBarVisibleContext = new RawContextKey<boolean>('secondarySideBarVisible', false, localize('secondarySideBarVisible', "Whether the layout surface representing the secondary side bar is visible"));
164 > export const AuxiliaryBarMaximizedContext = new RawContextKey<boolean>('auxiliaryBarMaximized', false, localize('auxiliaryBarMaximized', "Whether the auxiliary bar is maximized"));
165 >
166 > //#endregion
167 >
168 >
169 > //#region < --- Panel --- >
170 >
171 > export const ActivePanelContext = new RawContextKey<string>('activePanel', '', localize('activePanel', "The identifier of the active panel"));
172 > export const PanelFocusContext = new RawContextKey<boolean>('panelFocus', false, localize('panelFocus', "Whether the panel has keyboard focus"));
173 > export const PanelPositionContext = new RawContextKey<string>('panelPosition', 'bottom', localize('panelPosition', "The position of the panel, always 'bottom'"));
174 > export const PanelAlignmentContext = new RawContextKey<string>('panelAlignment', 'center', localize('panelAlignment', "The alignment of the panel, either 'center', 'left', 'right' or 'justify'"));
175 > export const PanelVisibleContext = new RawContextKey<boolean>('panelVisible', false, localize('panelVisible', "Whether the panel is visible"));
176 > export const PanelMaximizedContext = new RawContextKey<boolean>('panelMaximized', false, localize('panelMaximized', "Whether the panel is maximized"));
177 >
178 > //#endregion
179 >
180 >
181 > //#region < --- Views --- >
182 >
183 > export const FocusedViewContext = new RawContextKey<string>('focusedView', '', localize('focusedView', "The identifier of the view that has keyboard focus"));
184 > export function getVisbileViewContextKey(viewId: string): string { return `view.${viewId}.visible`; }
185 >
186 > //#endregion
187 >
188 >
189 > //#region < --- Resources --- >
190 >
191 > abstract class AbstractResourceContextKey {
192 >
193 > // NOTE: DO NOT CHANGE THE DEFAULT VALUE TO ANYTHING BUT
194 > // UNDEFINED! IT IS IMPORTANT THAT DEFAULTS ARE INHERITED
195 > // FROM THE PARENT CONTEXT AND ONLY UNDEFINED DOES THIS
196 >
197 > static readonly Scheme = new RawContextKey<string>('resourceScheme', undefined, { type: 'string', description: localize('resourceScheme', "The scheme of the resource") });
198 > static readonly Filename = new RawContextKey<string>('resourceFilename', undefined, { type: 'string', description: localize('resourceFilename', "The file name of the resource") });
199 > static readonly Dirname = new RawContextKey<string>('resourceDirname', undefined, { type: 'string', description: localize('resourceDirname', "The folder name the resource is contained in") });
200 > static readonly Path = new RawContextKey<string>('resourcePath', undefined, { type: 'string', description: localize('resourcePath', "The full path of the resource") });
201 > static readonly LangId = new RawContextKey<string>('resourceLangId', undefined, { type: 'string', description: localize('resourceLangId', "The language identifier of the resource") });
202 > static readonly Resource = new RawContextKey<string>('resource', undefined, { type: 'URI', description: localize('resource', "The full value of the resource including scheme and path") });
203 > static readonly Extension = new RawContextKey<string>('resourceExtname', undefined, { type: 'string', description: localize('resourceExtname', "The extension name of the resource") });
204 > static readonly HasResource = new RawContextKey<boolean>('resourceSet', undefined, { type: 'boolean', description: localize('resourceSet', "Whether a resource is present or not") });
205 > static readonly IsFileSystemResource = new RawContextKey<boolean>('isFileSystemResource', undefined, { type: 'boolean', description: localize('isFileSystemResource', "Whether the resource is backed by a file system provider") });
206 >
207 > protected _value: URI | undefined;
208 > protected readonly _resourceKey: IContextKey<string | null>;
209 > protected readonly _schemeKey: IContextKey<string | null>;
210 > protected readonly _filenameKey: IContextKey<string | null>;
211 > protected readonly _dirnameKey: IContextKey<string | null>;
212 > protected readonly _pathKey: IContextKey<string | null>;
213 > protected readonly _langIdKey: IContextKey<string | null>;
214 > protected readonly _extensionKey: IContextKey<string | null>;
215 > protected readonly _hasResource: IContextKey<boolean>;
216 > protected readonly _isFileSystemResource: IContextKey<boolean>;
217 >
218 > constructor(
219 @IContextKeyService protected readonly _contextKeyService: IContextKeyService,
220 @IFileService protected readonly _fileService: IFileService,
221 @ILanguageService protected readonly _languageService: ILanguageService,
222 @IModelService protected readonly _modelService: IModelService
223 ) {
224 this._schemeKey = AbstractResourceContextKey.Scheme.bindTo(this._contextKeyService);
225 this._filenameKey = AbstractResourceContextKey.Filename.bindTo(this._contextKeyService);
226 this._dirnameKey = AbstractResourceContextKey.Dirname.bindTo(this._contextKeyService);
227 this._pathKey = AbstractResourceContextKey.Path.bindTo(this._contextKeyService);
228 this._langIdKey = AbstractResourceContextKey.LangId.bindTo(this._contextKeyService);
229 this._resourceKey = AbstractResourceContextKey.Resource.bindTo(this._contextKeyService);
230 this._extensionKey = AbstractResourceContextKey.Extension.bindTo(this._contextKeyService);
231 this._hasResource = AbstractResourceContextKey.HasResource.bindTo(this._contextKeyService);
232 this._isFileSystemResource = AbstractResourceContextKey.IsFileSystemResource.bindTo(this._contextKeyService);
233 }
235 > protected _setLangId(): void {
236 const value = this.get();
237 if (!value) {
238 this._langIdKey.set(null);
239 return;
240 }
241 const langId = this._modelService.getModel(value)?.getLanguageId() ?? this._languageService.guessLanguageIdByFilepathOrFirstLine(value);
242 this._langIdKey.set(langId);
243 }
245 > set(value: URI | null | undefined) {
246 value = value ?? undefined;
247 if (isEqual(this._value, value)) {
248 return;
249 }
250 this._value = value;
251 this._contextKeyService.bufferChangeEvents(() => {
252 this._resourceKey.set(value ? value.toString() : null);
253 this._schemeKey.set(value ? value.scheme : null);
254 this._filenameKey.set(value ? basename(value) : null);
255 this._dirnameKey.set(value ? this.uriToPath(dirname(value)) : null);
256 this._pathKey.set(value ? this.uriToPath(value) : null);
257 this._setLangId();
258 this._extensionKey.set(value ? extname(value) : null);
259 this._hasResource.set(Boolean(value));
260 this._isFileSystemResource.set(value ? this._fileService.hasProvider(value) : false);
261 });
262 }
264 > protected uriToPath(uri: URI): string {
265 if (uri.scheme === Schemas.file) {
266 return uri.fsPath;
267 }
268 return uri.path;
269 }
271 > reset(): void {
272 this._value = undefined;
273 this._contextKeyService.bufferChangeEvents(() => {
274 this._resourceKey.reset();
275 this._schemeKey.reset();
276 this._filenameKey.reset();
277 this._dirnameKey.reset();
278 this._pathKey.reset();
279 this._langIdKey.reset();
280 this._extensionKey.reset();
281 this._hasResource.reset();
282 this._isFileSystemResource.reset();
283 });
284 }
286 > get(): URI | undefined {
287 return this._value;
288 }
290 >
291 > export class ResourceContextKey extends AbstractResourceContextKey {
292 >
293 > private readonly _disposables = new DisposableStore();
294 >
295 > constructor(
296 @IContextKeyService contextKeyService: IContextKeyService,
297 @IFileService fileService: IFileService,
298 @ILanguageService languageService: ILanguageService,
299 @IModelService modelService: IModelService
300 ) {
301 super(contextKeyService, fileService, languageService, modelService);
302 this._disposables.add(fileService.onDidChangeFileSystemProviderRegistrations(() => {
303 const resource = this.get();
304 this._isFileSystemResource.set(Boolean(resource && fileService.hasProvider(resource)));
305 }));
306 this._disposables.add(modelService.onModelAdded(model => {
307 if (isEqual(model.uri, this.get())) {
308 this._setLangId();
309 }
310 }));
311 this._disposables.add(modelService.onModelLanguageChanged(e => {
312 if (isEqual(e.model.uri, this.get())) {
313 this._setLangId();
314 }
315 }));
316 }
318 > dispose(): void {
319 this._disposables.dispose();
320 }
322 >
323 > /**
324 > * This is a version of ResourceContextKey that is not disposable and has no listeners for model change events.
325 > * It will configure itself for the state/presence of a model only when created and not update.
326 > */
327 > export class StaticResourceContextKey extends AbstractResourceContextKey { }
328 >
329 >
330 > //#endregion
331 >
332 > export function applyAvailableEditorIds(contextKey: IContextKey<string>, editor: EditorInput | undefined | null, editorResolverService: IEditorResolverService): void {
333 if (!editor) {
334 contextKey.set('');
335 return;
336 }
337
338 const editors = getAvailableEditorIds(editor, editorResolverService);
339 contextKey.set(editors.join(','));
340 }
342 function getAvailableEditorIds(editor: EditorInput, editorResolverService: IEditorResolverService): string[] {
343 // Non text editor untitled files cannot be easily serialized between
344 // extensions so instead we disable this context key to prevent common
345 // commands that act on the active editor.
346 if (editor.resource?.scheme === Schemas.untitled && editor.editorId !== DEFAULT_EDITOR_ASSOCIATION.id) {
347 return [];
348 }
349
350 // Diff editors. The original and modified resources of a diff editor
351 // *should* be the same, but calculate the set intersection just to be safe.
352 if (isDiffEditorInput(editor)) {
353 const original = getAvailableEditorIds(editor.original, editorResolverService);
354 const modified = new Set(getAvailableEditorIds(editor.modified, editorResolverService));
355 return original.filter(editor => modified.has(editor));
356 }
357
358 // Normal editors.
359 if (editor.resource) {
360 return editorResolverService.getEditors(editor.resource).map(editor => editor.id);
361 }
362
363 return [];
364 }