Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/standalone/browser/standaloneServices.ts
3294 views
1
/*---------------------------------------------------------------------------------------------
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 './standaloneCodeEditorService.js';
7
import './standaloneLayoutService.js';
8
import '../../../platform/undoRedo/common/undoRedoService.js';
9
import '../../common/services/languageFeatureDebounce.js';
10
import '../../common/services/semanticTokensStylingService.js';
11
import '../../common/services/languageFeaturesService.js';
12
import '../../browser/services/hoverService/hoverService.js';
13
import '../../browser/services/inlineCompletionsService.js';
14
15
import * as strings from '../../../base/common/strings.js';
16
import * as dom from '../../../base/browser/dom.js';
17
import { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js';
18
import { Emitter, Event, IValueWithChangeEvent, ValueWithChangeEvent } from '../../../base/common/event.js';
19
import { ResolvedKeybinding, KeyCodeChord, Keybinding, decodeKeybinding } from '../../../base/common/keybindings.js';
20
import { IDisposable, IReference, ImmortalReference, toDisposable, DisposableStore, Disposable, combinedDisposable } from '../../../base/common/lifecycle.js';
21
import { OS, isLinux, isMacintosh } from '../../../base/common/platform.js';
22
import Severity from '../../../base/common/severity.js';
23
import { URI } from '../../../base/common/uri.js';
24
import { IBulkEditOptions, IBulkEditResult, IBulkEditService, ResourceEdit, ResourceTextEdit } from '../../browser/services/bulkEditService.js';
25
import { isDiffEditorConfigurationKey, isEditorConfigurationKey } from '../../common/config/editorConfigurationSchema.js';
26
import { EditOperation, ISingleEditOperation } from '../../common/core/editOperation.js';
27
import { IPosition, Position as Pos } from '../../common/core/position.js';
28
import { Range } from '../../common/core/range.js';
29
import { ITextModel, ITextSnapshot } from '../../common/model.js';
30
import { IModelService } from '../../common/services/model.js';
31
import { IResolvedTextEditorModel, ITextModelContentProvider, ITextModelService } from '../../common/services/resolverService.js';
32
import { ITextResourceConfigurationService, ITextResourcePropertiesService, ITextResourceConfigurationChangeEvent } from '../../common/services/textResourceConfiguration.js';
33
import { CommandsRegistry, ICommandEvent, ICommandHandler, ICommandService } from '../../../platform/commands/common/commands.js';
34
import { IConfigurationChangeEvent, IConfigurationData, IConfigurationOverrides, IConfigurationService, IConfigurationModel, IConfigurationValue, ConfigurationTarget } from '../../../platform/configuration/common/configuration.js';
35
import { Configuration, ConfigurationModel, ConfigurationChangeEvent } from '../../../platform/configuration/common/configurationModels.js';
36
import { IContextKeyService, ContextKeyExpression } from '../../../platform/contextkey/common/contextkey.js';
37
import { IConfirmation, IConfirmationResult, IDialogService, IInputResult, IPrompt, IPromptResult, IPromptWithCustomCancel, IPromptResultWithCancel, IPromptWithDefaultCancel, IPromptBaseButton } from '../../../platform/dialogs/common/dialogs.js';
38
import { createDecorator, IInstantiationService, ServiceIdentifier } from '../../../platform/instantiation/common/instantiation.js';
39
import { AbstractKeybindingService } from '../../../platform/keybinding/common/abstractKeybindingService.js';
40
import { IKeybindingService, IKeyboardEvent, KeybindingsSchemaContribution } from '../../../platform/keybinding/common/keybinding.js';
41
import { KeybindingResolver } from '../../../platform/keybinding/common/keybindingResolver.js';
42
import { IKeybindingItem, KeybindingsRegistry } from '../../../platform/keybinding/common/keybindingsRegistry.js';
43
import { ResolvedKeybindingItem } from '../../../platform/keybinding/common/resolvedKeybindingItem.js';
44
import { USLayoutResolvedKeybinding } from '../../../platform/keybinding/common/usLayoutResolvedKeybinding.js';
45
import { ILabelService, ResourceLabelFormatter, IFormatterChangeEvent, Verbosity } from '../../../platform/label/common/label.js';
46
import { INotification, INotificationHandle, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification, IStatusMessageOptions, INotificationSource, INotificationSourceFilter, NotificationsFilter, IStatusHandle } from '../../../platform/notification/common/notification.js';
47
import { IProgressRunner, IEditorProgressService, IProgressService, IProgress, IProgressCompositeOptions, IProgressDialogOptions, IProgressNotificationOptions, IProgressOptions, IProgressStep, IProgressWindowOptions } from '../../../platform/progress/common/progress.js';
48
import { ITelemetryService, TelemetryLevel } from '../../../platform/telemetry/common/telemetry.js';
49
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, WorkbenchState, WorkspaceFolder, STANDALONE_EDITOR_WORKSPACE_ID } from '../../../platform/workspace/common/workspace.js';
50
import { ILayoutService } from '../../../platform/layout/browser/layoutService.js';
51
import { StandaloneServicesNLS } from '../../common/standaloneStrings.js';
52
import { basename } from '../../../base/common/resources.js';
53
import { ICodeEditorService } from '../../browser/services/codeEditorService.js';
54
import { ConsoleLogger, ILoggerService, ILogService, NullLoggerService } from '../../../platform/log/common/log.js';
55
import { IWorkspaceTrustManagementService, IWorkspaceTrustTransitionParticipant, IWorkspaceTrustUriInfo } from '../../../platform/workspace/common/workspaceTrust.js';
56
import { EditorOption } from '../../common/config/editorOptions.js';
57
import { ICodeEditor, IDiffEditor } from '../../browser/editorBrowser.js';
58
import { IContextMenuService, IContextViewDelegate, IContextViewService, IOpenContextView } from '../../../platform/contextview/browser/contextView.js';
59
import { ContextViewService } from '../../../platform/contextview/browser/contextViewService.js';
60
import { LanguageService } from '../../common/services/languageService.js';
61
import { ContextMenuService } from '../../../platform/contextview/browser/contextMenuService.js';
62
import { getSingletonServiceDescriptors, InstantiationType, registerSingleton } from '../../../platform/instantiation/common/extensions.js';
63
import { OpenerService } from '../../browser/services/openerService.js';
64
import { IEditorWorkerService } from '../../common/services/editorWorker.js';
65
import { EditorWorkerService } from '../../browser/services/editorWorkerService.js';
66
import { ILanguageService } from '../../common/languages/language.js';
67
import { MarkerDecorationsService } from '../../common/services/markerDecorationsService.js';
68
import { IMarkerDecorationsService } from '../../common/services/markerDecorations.js';
69
import { ModelService } from '../../common/services/modelService.js';
70
import { StandaloneQuickInputService } from './quickInput/standaloneQuickInputService.js';
71
import { StandaloneThemeService } from './standaloneThemeService.js';
72
import { IStandaloneThemeService } from '../common/standaloneTheme.js';
73
import { AccessibilityService } from '../../../platform/accessibility/browser/accessibilityService.js';
74
import { IAccessibilityService } from '../../../platform/accessibility/common/accessibility.js';
75
import { IMenuService } from '../../../platform/actions/common/actions.js';
76
import { MenuService } from '../../../platform/actions/common/menuService.js';
77
import { BrowserClipboardService } from '../../../platform/clipboard/browser/clipboardService.js';
78
import { IClipboardService } from '../../../platform/clipboard/common/clipboardService.js';
79
import { ContextKeyService } from '../../../platform/contextkey/browser/contextKeyService.js';
80
import { SyncDescriptor } from '../../../platform/instantiation/common/descriptors.js';
81
import { InstantiationService } from '../../../platform/instantiation/common/instantiationService.js';
82
import { ServiceCollection } from '../../../platform/instantiation/common/serviceCollection.js';
83
import { IListService, ListService } from '../../../platform/list/browser/listService.js';
84
import { IMarkerService } from '../../../platform/markers/common/markers.js';
85
import { MarkerService } from '../../../platform/markers/common/markerService.js';
86
import { IOpenerService } from '../../../platform/opener/common/opener.js';
87
import { IQuickInputService } from '../../../platform/quickinput/common/quickInput.js';
88
import { IStorageService, InMemoryStorageService } from '../../../platform/storage/common/storage.js';
89
import { DefaultConfiguration } from '../../../platform/configuration/common/configurations.js';
90
import { WorkspaceEdit } from '../../common/languages.js';
91
import { AccessibilitySignal, AccessibilityModality, IAccessibilitySignalService, Sound } from '../../../platform/accessibilitySignal/browser/accessibilitySignalService.js';
92
import { ILanguageFeaturesService } from '../../common/services/languageFeatures.js';
93
import { ILanguageConfigurationService } from '../../common/languages/languageConfigurationRegistry.js';
94
import { LogService } from '../../../platform/log/common/logService.js';
95
import { getEditorFeatures } from '../../common/editorFeatures.js';
96
import { onUnexpectedError } from '../../../base/common/errors.js';
97
import { ExtensionKind, IEnvironmentService, IExtensionHostDebugParams } from '../../../platform/environment/common/environment.js';
98
import { mainWindow } from '../../../base/browser/window.js';
99
import { ResourceMap } from '../../../base/common/map.js';
100
import { IWebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js';
101
import { ITreeSitterLibraryService } from '../../common/services/treeSitter/treeSitterLibraryService.js';
102
import { StandaloneTreeSitterLibraryService } from './standaloneTreeSitterLibraryService.js';
103
import { IDataChannelService, NullDataChannelService } from '../../../platform/dataChannel/common/dataChannel.js';
104
105
class SimpleModel implements IResolvedTextEditorModel {
106
107
private readonly model: ITextModel;
108
private readonly _onWillDispose: Emitter<void>;
109
110
constructor(model: ITextModel) {
111
this.model = model;
112
this._onWillDispose = new Emitter<void>();
113
}
114
115
public get onWillDispose(): Event<void> {
116
return this._onWillDispose.event;
117
}
118
119
public resolve(): Promise<void> {
120
return Promise.resolve();
121
}
122
123
public get textEditorModel(): ITextModel {
124
return this.model;
125
}
126
127
public createSnapshot(): ITextSnapshot {
128
return this.model.createSnapshot();
129
}
130
131
public isReadonly(): boolean {
132
return false;
133
}
134
135
private disposed = false;
136
public dispose(): void {
137
this.disposed = true;
138
139
this._onWillDispose.fire();
140
}
141
142
public isDisposed(): boolean {
143
return this.disposed;
144
}
145
146
public isResolved(): boolean {
147
return true;
148
}
149
150
public getLanguageId(): string | undefined {
151
return this.model.getLanguageId();
152
}
153
}
154
155
class StandaloneTextModelService implements ITextModelService {
156
public _serviceBrand: undefined;
157
158
constructor(
159
@IModelService private readonly modelService: IModelService
160
) { }
161
162
public createModelReference(resource: URI): Promise<IReference<IResolvedTextEditorModel>> {
163
const model = this.modelService.getModel(resource);
164
165
if (!model) {
166
return Promise.reject(new Error(`Model not found`));
167
}
168
169
return Promise.resolve(new ImmortalReference(new SimpleModel(model)));
170
}
171
172
public registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): IDisposable {
173
return {
174
dispose: function () { /* no op */ }
175
};
176
}
177
178
public canHandleResource(resource: URI): boolean {
179
return false;
180
}
181
}
182
183
class StandaloneEditorProgressService implements IEditorProgressService {
184
declare readonly _serviceBrand: undefined;
185
186
private static NULL_PROGRESS_RUNNER: IProgressRunner = {
187
done: () => { },
188
total: () => { },
189
worked: () => { }
190
};
191
192
show(infinite: true, delay?: number): IProgressRunner;
193
show(total: number, delay?: number): IProgressRunner;
194
show(): IProgressRunner {
195
return StandaloneEditorProgressService.NULL_PROGRESS_RUNNER;
196
}
197
198
async showWhile(promise: Promise<any>, delay?: number): Promise<void> {
199
await promise;
200
}
201
}
202
203
class StandaloneProgressService implements IProgressService {
204
205
declare readonly _serviceBrand: undefined;
206
207
withProgress<R>(_options: IProgressOptions | IProgressDialogOptions | IProgressNotificationOptions | IProgressWindowOptions | IProgressCompositeOptions, task: (progress: IProgress<IProgressStep>) => Promise<R>, onDidCancel?: ((choice?: number | undefined) => void) | undefined): Promise<R> {
208
return task({
209
report: () => { },
210
});
211
}
212
}
213
214
class StandaloneEnvironmentService implements IEnvironmentService {
215
216
declare readonly _serviceBrand: undefined;
217
218
readonly stateResource: URI = URI.from({ scheme: 'monaco', authority: 'stateResource' });
219
readonly userRoamingDataHome: URI = URI.from({ scheme: 'monaco', authority: 'userRoamingDataHome' });
220
readonly keyboardLayoutResource: URI = URI.from({ scheme: 'monaco', authority: 'keyboardLayoutResource' });
221
readonly argvResource: URI = URI.from({ scheme: 'monaco', authority: 'argvResource' });
222
readonly untitledWorkspacesHome: URI = URI.from({ scheme: 'monaco', authority: 'untitledWorkspacesHome' });
223
readonly workspaceStorageHome: URI = URI.from({ scheme: 'monaco', authority: 'workspaceStorageHome' });
224
readonly localHistoryHome: URI = URI.from({ scheme: 'monaco', authority: 'localHistoryHome' });
225
readonly cacheHome: URI = URI.from({ scheme: 'monaco', authority: 'cacheHome' });
226
readonly userDataSyncHome: URI = URI.from({ scheme: 'monaco', authority: 'userDataSyncHome' });
227
readonly sync: 'on' | 'off' | undefined = undefined;
228
readonly continueOn?: string | undefined = undefined;
229
readonly editSessionId?: string | undefined = undefined;
230
readonly debugExtensionHost: IExtensionHostDebugParams = { port: null, break: false };
231
readonly isExtensionDevelopment: boolean = false;
232
readonly disableExtensions: boolean | string[] = false;
233
readonly disableExperiments: boolean = false;
234
readonly enableExtensions?: readonly string[] | undefined = undefined;
235
readonly extensionDevelopmentLocationURI?: URI[] | undefined = undefined;
236
readonly extensionDevelopmentKind?: ExtensionKind[] | undefined = undefined;
237
readonly extensionTestsLocationURI?: URI | undefined = undefined;
238
readonly logsHome: URI = URI.from({ scheme: 'monaco', authority: 'logsHome' });
239
readonly logLevel?: string | undefined = undefined;
240
readonly extensionLogLevel?: [string, string][] | undefined = undefined;
241
readonly verbose: boolean = false;
242
readonly isBuilt: boolean = false;
243
readonly disableTelemetry: boolean = false;
244
readonly serviceMachineIdResource: URI = URI.from({ scheme: 'monaco', authority: 'serviceMachineIdResource' });
245
readonly policyFile?: URI | undefined = undefined;
246
readonly isSimulation: boolean | undefined = undefined;
247
}
248
249
class StandaloneDialogService implements IDialogService {
250
251
_serviceBrand: undefined;
252
253
readonly onWillShowDialog = Event.None;
254
readonly onDidShowDialog = Event.None;
255
256
async confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {
257
const confirmed = this.doConfirm(confirmation.message, confirmation.detail);
258
259
return {
260
confirmed,
261
checkboxChecked: false // unsupported
262
};
263
}
264
265
private doConfirm(message: string, detail?: string): boolean {
266
let messageText = message;
267
if (detail) {
268
messageText = messageText + '\n\n' + detail;
269
}
270
271
return mainWindow.confirm(messageText);
272
}
273
274
prompt<T>(prompt: IPromptWithCustomCancel<T>): Promise<IPromptResultWithCancel<T>>;
275
prompt<T>(prompt: IPrompt<T>): Promise<IPromptResult<T>>;
276
prompt<T>(prompt: IPromptWithDefaultCancel<T>): Promise<IPromptResult<T>>;
277
async prompt<T>(prompt: IPrompt<T> | IPromptWithCustomCancel<T>): Promise<IPromptResult<T> | IPromptResultWithCancel<T>> {
278
let result: T | undefined = undefined;
279
const confirmed = this.doConfirm(prompt.message, prompt.detail);
280
if (confirmed) {
281
const promptButtons: IPromptBaseButton<T>[] = [...(prompt.buttons ?? [])];
282
if (prompt.cancelButton && typeof prompt.cancelButton !== 'string' && typeof prompt.cancelButton !== 'boolean') {
283
promptButtons.push(prompt.cancelButton);
284
}
285
286
result = await promptButtons[0]?.run({ checkboxChecked: false });
287
}
288
289
return { result };
290
}
291
292
async info(message: string, detail?: string): Promise<void> {
293
await this.prompt({ type: Severity.Info, message, detail });
294
}
295
296
async warn(message: string, detail?: string): Promise<void> {
297
await this.prompt({ type: Severity.Warning, message, detail });
298
}
299
300
async error(message: string, detail?: string): Promise<void> {
301
await this.prompt({ type: Severity.Error, message, detail });
302
}
303
304
input(): Promise<IInputResult> {
305
return Promise.resolve({ confirmed: false }); // unsupported
306
}
307
308
about(): Promise<void> {
309
return Promise.resolve(undefined);
310
}
311
}
312
313
export class StandaloneNotificationService implements INotificationService {
314
315
readonly onDidChangeFilter: Event<void> = Event.None;
316
317
public _serviceBrand: undefined;
318
319
private static readonly NO_OP: INotificationHandle = new NoOpNotification();
320
321
public info(message: string): INotificationHandle {
322
return this.notify({ severity: Severity.Info, message });
323
}
324
325
public warn(message: string): INotificationHandle {
326
return this.notify({ severity: Severity.Warning, message });
327
}
328
329
public error(error: string | Error): INotificationHandle {
330
return this.notify({ severity: Severity.Error, message: error });
331
}
332
333
public notify(notification: INotification): INotificationHandle {
334
switch (notification.severity) {
335
case Severity.Error:
336
console.error(notification.message);
337
break;
338
case Severity.Warning:
339
console.warn(notification.message);
340
break;
341
default:
342
console.log(notification.message);
343
break;
344
}
345
346
return StandaloneNotificationService.NO_OP;
347
}
348
349
public prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {
350
return StandaloneNotificationService.NO_OP;
351
}
352
353
public status(message: string | Error, options?: IStatusMessageOptions): IStatusHandle {
354
return { close: () => { } };
355
}
356
357
public setFilter(filter: NotificationsFilter | INotificationSourceFilter): void { }
358
359
public getFilter(source?: INotificationSource): NotificationsFilter {
360
return NotificationsFilter.OFF;
361
}
362
363
public getFilters(): INotificationSourceFilter[] {
364
return [];
365
}
366
367
public removeFilter(sourceId: string): void { }
368
}
369
370
export class StandaloneCommandService implements ICommandService {
371
declare readonly _serviceBrand: undefined;
372
373
private readonly _instantiationService: IInstantiationService;
374
375
private readonly _onWillExecuteCommand = new Emitter<ICommandEvent>();
376
private readonly _onDidExecuteCommand = new Emitter<ICommandEvent>();
377
public readonly onWillExecuteCommand: Event<ICommandEvent> = this._onWillExecuteCommand.event;
378
public readonly onDidExecuteCommand: Event<ICommandEvent> = this._onDidExecuteCommand.event;
379
380
constructor(
381
@IInstantiationService instantiationService: IInstantiationService
382
) {
383
this._instantiationService = instantiationService;
384
}
385
386
public executeCommand<T>(id: string, ...args: any[]): Promise<T> {
387
const command = CommandsRegistry.getCommand(id);
388
if (!command) {
389
return Promise.reject(new Error(`command '${id}' not found`));
390
}
391
392
try {
393
this._onWillExecuteCommand.fire({ commandId: id, args });
394
const result = this._instantiationService.invokeFunction.apply(this._instantiationService, [command.handler, ...args]) as T;
395
396
this._onDidExecuteCommand.fire({ commandId: id, args });
397
return Promise.resolve(result);
398
} catch (err) {
399
return Promise.reject(err);
400
}
401
}
402
}
403
404
export interface IKeybindingRule {
405
keybinding: number;
406
command?: string | null;
407
commandArgs?: any;
408
when?: ContextKeyExpression | null;
409
}
410
411
export class StandaloneKeybindingService extends AbstractKeybindingService {
412
private _cachedResolver: KeybindingResolver | null;
413
private _dynamicKeybindings: IKeybindingItem[];
414
private readonly _domNodeListeners: DomNodeListeners[];
415
416
constructor(
417
@IContextKeyService contextKeyService: IContextKeyService,
418
@ICommandService commandService: ICommandService,
419
@ITelemetryService telemetryService: ITelemetryService,
420
@INotificationService notificationService: INotificationService,
421
@ILogService logService: ILogService,
422
@ICodeEditorService codeEditorService: ICodeEditorService
423
) {
424
super(contextKeyService, commandService, telemetryService, notificationService, logService);
425
426
this._cachedResolver = null;
427
this._dynamicKeybindings = [];
428
this._domNodeListeners = [];
429
430
const addContainer = (domNode: HTMLElement) => {
431
const disposables = new DisposableStore();
432
433
// for standard keybindings
434
disposables.add(dom.addDisposableListener(domNode, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
435
const keyEvent = new StandardKeyboardEvent(e);
436
const shouldPreventDefault = this._dispatch(keyEvent, keyEvent.target);
437
if (shouldPreventDefault) {
438
keyEvent.preventDefault();
439
keyEvent.stopPropagation();
440
}
441
}));
442
443
// for single modifier chord keybindings (e.g. shift shift)
444
disposables.add(dom.addDisposableListener(domNode, dom.EventType.KEY_UP, (e: KeyboardEvent) => {
445
const keyEvent = new StandardKeyboardEvent(e);
446
const shouldPreventDefault = this._singleModifierDispatch(keyEvent, keyEvent.target);
447
if (shouldPreventDefault) {
448
keyEvent.preventDefault();
449
}
450
}));
451
452
this._domNodeListeners.push(new DomNodeListeners(domNode, disposables));
453
};
454
const removeContainer = (domNode: HTMLElement) => {
455
for (let i = 0; i < this._domNodeListeners.length; i++) {
456
const domNodeListeners = this._domNodeListeners[i];
457
if (domNodeListeners.domNode === domNode) {
458
this._domNodeListeners.splice(i, 1);
459
domNodeListeners.dispose();
460
}
461
}
462
};
463
464
const addCodeEditor = (codeEditor: ICodeEditor) => {
465
if (codeEditor.getOption(EditorOption.inDiffEditor)) {
466
return;
467
}
468
addContainer(codeEditor.getContainerDomNode());
469
};
470
const removeCodeEditor = (codeEditor: ICodeEditor) => {
471
if (codeEditor.getOption(EditorOption.inDiffEditor)) {
472
return;
473
}
474
removeContainer(codeEditor.getContainerDomNode());
475
};
476
this._register(codeEditorService.onCodeEditorAdd(addCodeEditor));
477
this._register(codeEditorService.onCodeEditorRemove(removeCodeEditor));
478
codeEditorService.listCodeEditors().forEach(addCodeEditor);
479
480
const addDiffEditor = (diffEditor: IDiffEditor) => {
481
addContainer(diffEditor.getContainerDomNode());
482
};
483
const removeDiffEditor = (diffEditor: IDiffEditor) => {
484
removeContainer(diffEditor.getContainerDomNode());
485
};
486
this._register(codeEditorService.onDiffEditorAdd(addDiffEditor));
487
this._register(codeEditorService.onDiffEditorRemove(removeDiffEditor));
488
codeEditorService.listDiffEditors().forEach(addDiffEditor);
489
}
490
491
public addDynamicKeybinding(command: string, keybinding: number, handler: ICommandHandler, when: ContextKeyExpression | undefined): IDisposable {
492
return combinedDisposable(
493
CommandsRegistry.registerCommand(command, handler),
494
this.addDynamicKeybindings([{
495
keybinding,
496
command,
497
when
498
}])
499
);
500
}
501
502
public addDynamicKeybindings(rules: IKeybindingRule[]): IDisposable {
503
const entries: IKeybindingItem[] = rules.map((rule) => {
504
const keybinding = decodeKeybinding(rule.keybinding, OS);
505
return {
506
keybinding,
507
command: rule.command ?? null,
508
commandArgs: rule.commandArgs,
509
when: rule.when,
510
weight1: 1000,
511
weight2: 0,
512
extensionId: null,
513
isBuiltinExtension: false
514
};
515
});
516
this._dynamicKeybindings = this._dynamicKeybindings.concat(entries);
517
518
this.updateResolver();
519
520
return toDisposable(() => {
521
// Search the first entry and remove them all since they will be contiguous
522
for (let i = 0; i < this._dynamicKeybindings.length; i++) {
523
if (this._dynamicKeybindings[i] === entries[0]) {
524
this._dynamicKeybindings.splice(i, entries.length);
525
this.updateResolver();
526
return;
527
}
528
}
529
});
530
}
531
532
private updateResolver(): void {
533
this._cachedResolver = null;
534
this._onDidUpdateKeybindings.fire();
535
}
536
537
protected _getResolver(): KeybindingResolver {
538
if (!this._cachedResolver) {
539
const defaults = this._toNormalizedKeybindingItems(KeybindingsRegistry.getDefaultKeybindings(), true);
540
const overrides = this._toNormalizedKeybindingItems(this._dynamicKeybindings, false);
541
this._cachedResolver = new KeybindingResolver(defaults, overrides, (str) => this._log(str));
542
}
543
return this._cachedResolver;
544
}
545
546
protected _documentHasFocus(): boolean {
547
return mainWindow.document.hasFocus();
548
}
549
550
private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
551
const result: ResolvedKeybindingItem[] = [];
552
let resultLen = 0;
553
for (const item of items) {
554
const when = item.when || undefined;
555
const keybinding = item.keybinding;
556
557
if (!keybinding) {
558
// This might be a removal keybinding item in user settings => accept it
559
result[resultLen++] = new ResolvedKeybindingItem(undefined, item.command, item.commandArgs, when, isDefault, null, false);
560
} else {
561
const resolvedKeybindings = USLayoutResolvedKeybinding.resolveKeybinding(keybinding, OS);
562
for (const resolvedKeybinding of resolvedKeybindings) {
563
result[resultLen++] = new ResolvedKeybindingItem(resolvedKeybinding, item.command, item.commandArgs, when, isDefault, null, false);
564
}
565
}
566
}
567
568
return result;
569
}
570
571
public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[] {
572
return USLayoutResolvedKeybinding.resolveKeybinding(keybinding, OS);
573
}
574
575
public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding {
576
const chord = new KeyCodeChord(
577
keyboardEvent.ctrlKey,
578
keyboardEvent.shiftKey,
579
keyboardEvent.altKey,
580
keyboardEvent.metaKey,
581
keyboardEvent.keyCode
582
);
583
return new USLayoutResolvedKeybinding([chord], OS);
584
}
585
586
public resolveUserBinding(userBinding: string): ResolvedKeybinding[] {
587
return [];
588
}
589
590
public _dumpDebugInfo(): string {
591
return '';
592
}
593
594
public _dumpDebugInfoJSON(): string {
595
return '';
596
}
597
598
public registerSchemaContribution(contribution: KeybindingsSchemaContribution): IDisposable {
599
return Disposable.None;
600
}
601
602
/**
603
* not yet supported
604
*/
605
public override enableKeybindingHoldMode(commandId: string): Promise<void> | undefined {
606
return undefined;
607
}
608
}
609
610
class DomNodeListeners extends Disposable {
611
constructor(
612
public readonly domNode: HTMLElement,
613
disposables: DisposableStore
614
) {
615
super();
616
this._register(disposables);
617
}
618
}
619
620
function isConfigurationOverrides(thing: any): thing is IConfigurationOverrides {
621
return thing
622
&& typeof thing === 'object'
623
&& (!thing.overrideIdentifier || typeof thing.overrideIdentifier === 'string')
624
&& (!thing.resource || thing.resource instanceof URI);
625
}
626
627
export class StandaloneConfigurationService implements IConfigurationService {
628
629
declare readonly _serviceBrand: undefined;
630
631
private readonly _onDidChangeConfiguration = new Emitter<IConfigurationChangeEvent>();
632
public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
633
634
private readonly _configuration: Configuration;
635
636
constructor(
637
@ILogService private readonly logService: ILogService,
638
) {
639
const defaultConfiguration = new DefaultConfiguration(logService);
640
this._configuration = new Configuration(
641
defaultConfiguration.reload(),
642
ConfigurationModel.createEmptyModel(logService),
643
ConfigurationModel.createEmptyModel(logService),
644
ConfigurationModel.createEmptyModel(logService),
645
ConfigurationModel.createEmptyModel(logService),
646
ConfigurationModel.createEmptyModel(logService),
647
new ResourceMap<ConfigurationModel>(),
648
ConfigurationModel.createEmptyModel(logService),
649
new ResourceMap<ConfigurationModel>(),
650
logService
651
);
652
defaultConfiguration.dispose();
653
}
654
655
getValue<T>(): T;
656
getValue<T>(section: string): T;
657
getValue<T>(overrides: IConfigurationOverrides): T;
658
getValue<T>(section: string, overrides: IConfigurationOverrides): T;
659
getValue(arg1?: any, arg2?: any): any {
660
const section = typeof arg1 === 'string' ? arg1 : undefined;
661
const overrides = isConfigurationOverrides(arg1) ? arg1 : isConfigurationOverrides(arg2) ? arg2 : {};
662
return this._configuration.getValue(section, overrides, undefined);
663
}
664
665
public updateValues(values: [string, any][]): Promise<void> {
666
const previous = { data: this._configuration.toData() };
667
668
const changedKeys: string[] = [];
669
670
for (const entry of values) {
671
const [key, value] = entry;
672
if (this.getValue(key) === value) {
673
continue;
674
}
675
this._configuration.updateValue(key, value);
676
changedKeys.push(key);
677
}
678
679
if (changedKeys.length > 0) {
680
const configurationChangeEvent = new ConfigurationChangeEvent({ keys: changedKeys, overrides: [] }, previous, this._configuration, undefined, this.logService);
681
configurationChangeEvent.source = ConfigurationTarget.MEMORY;
682
this._onDidChangeConfiguration.fire(configurationChangeEvent);
683
}
684
685
return Promise.resolve();
686
}
687
688
public updateValue(key: string, value: any, arg3?: any, arg4?: any): Promise<void> {
689
return this.updateValues([[key, value]]);
690
}
691
692
public inspect<C>(key: string, options: IConfigurationOverrides = {}): IConfigurationValue<C> {
693
return this._configuration.inspect<C>(key, options, undefined);
694
}
695
696
public keys() {
697
return this._configuration.keys(undefined);
698
}
699
700
public reloadConfiguration(): Promise<void> {
701
return Promise.resolve(undefined);
702
}
703
704
public getConfigurationData(): IConfigurationData | null {
705
const emptyModel: IConfigurationModel = {
706
contents: {},
707
keys: [],
708
overrides: []
709
};
710
return {
711
defaults: emptyModel,
712
policy: emptyModel,
713
application: emptyModel,
714
userLocal: emptyModel,
715
userRemote: emptyModel,
716
workspace: emptyModel,
717
folders: []
718
};
719
}
720
}
721
722
class StandaloneResourceConfigurationService implements ITextResourceConfigurationService {
723
724
declare readonly _serviceBrand: undefined;
725
726
private readonly _onDidChangeConfiguration = new Emitter<ITextResourceConfigurationChangeEvent>();
727
public readonly onDidChangeConfiguration = this._onDidChangeConfiguration.event;
728
729
constructor(
730
@IConfigurationService private readonly configurationService: StandaloneConfigurationService,
731
@IModelService private readonly modelService: IModelService,
732
@ILanguageService private readonly languageService: ILanguageService
733
) {
734
this.configurationService.onDidChangeConfiguration((e) => {
735
this._onDidChangeConfiguration.fire({ affectedKeys: e.affectedKeys, affectsConfiguration: (resource: URI, configuration: string) => e.affectsConfiguration(configuration) });
736
});
737
}
738
739
getValue<T>(resource: URI, section?: string): T;
740
getValue<T>(resource: URI, position?: IPosition, section?: string): T;
741
getValue<T>(resource: URI | undefined, arg2?: any, arg3?: any) {
742
const position: IPosition | null = Pos.isIPosition(arg2) ? arg2 : null;
743
const section: string | undefined = position ? (typeof arg3 === 'string' ? arg3 : undefined) : (typeof arg2 === 'string' ? arg2 : undefined);
744
const language = resource ? this.getLanguage(resource, position) : undefined;
745
if (typeof section === 'undefined') {
746
return this.configurationService.getValue<T>({
747
resource,
748
overrideIdentifier: language
749
});
750
}
751
return this.configurationService.getValue<T>(section, {
752
resource,
753
overrideIdentifier: language
754
});
755
}
756
757
inspect<T>(resource: URI | undefined, position: IPosition | null, section: string): IConfigurationValue<Readonly<T>> {
758
const language = resource ? this.getLanguage(resource, position) : undefined;
759
return this.configurationService.inspect<T>(section, { resource, overrideIdentifier: language });
760
}
761
762
private getLanguage(resource: URI, position: IPosition | null): string | null {
763
const model = this.modelService.getModel(resource);
764
if (model) {
765
return position ? model.getLanguageIdAtPosition(position.lineNumber, position.column) : model.getLanguageId();
766
}
767
return this.languageService.guessLanguageIdByFilepathOrFirstLine(resource);
768
}
769
770
updateValue(resource: URI, key: string, value: any, configurationTarget?: ConfigurationTarget): Promise<void> {
771
return this.configurationService.updateValue(key, value, { resource }, configurationTarget);
772
}
773
}
774
775
class StandaloneResourcePropertiesService implements ITextResourcePropertiesService {
776
777
declare readonly _serviceBrand: undefined;
778
779
constructor(
780
@IConfigurationService private readonly configurationService: IConfigurationService,
781
) {
782
}
783
784
getEOL(resource: URI, language?: string): string {
785
const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource });
786
if (eol && typeof eol === 'string' && eol !== 'auto') {
787
return eol;
788
}
789
return (isLinux || isMacintosh) ? '\n' : '\r\n';
790
}
791
}
792
793
class StandaloneTelemetryService implements ITelemetryService {
794
declare readonly _serviceBrand: undefined;
795
readonly telemetryLevel = TelemetryLevel.NONE;
796
readonly sessionId = 'someValue.sessionId';
797
readonly machineId = 'someValue.machineId';
798
readonly sqmId = 'someValue.sqmId';
799
readonly devDeviceId = 'someValue.devDeviceId';
800
readonly firstSessionDate = 'someValue.firstSessionDate';
801
readonly sendErrorTelemetry = false;
802
setEnabled(): void { }
803
setExperimentProperty(): void { }
804
publicLog() { }
805
publicLog2() { }
806
publicLogError() { }
807
publicLogError2() { }
808
}
809
810
class StandaloneWorkspaceContextService implements IWorkspaceContextService {
811
812
public _serviceBrand: undefined;
813
814
private static readonly SCHEME = 'inmemory';
815
816
private readonly _onDidChangeWorkspaceName = new Emitter<void>();
817
public readonly onDidChangeWorkspaceName: Event<void> = this._onDidChangeWorkspaceName.event;
818
819
private readonly _onWillChangeWorkspaceFolders = new Emitter<IWorkspaceFoldersWillChangeEvent>();
820
public readonly onWillChangeWorkspaceFolders: Event<IWorkspaceFoldersWillChangeEvent> = this._onWillChangeWorkspaceFolders.event;
821
822
private readonly _onDidChangeWorkspaceFolders = new Emitter<IWorkspaceFoldersChangeEvent>();
823
public readonly onDidChangeWorkspaceFolders: Event<IWorkspaceFoldersChangeEvent> = this._onDidChangeWorkspaceFolders.event;
824
825
private readonly _onDidChangeWorkbenchState = new Emitter<WorkbenchState>();
826
public readonly onDidChangeWorkbenchState: Event<WorkbenchState> = this._onDidChangeWorkbenchState.event;
827
828
private readonly workspace: IWorkspace;
829
830
constructor() {
831
const resource = URI.from({ scheme: StandaloneWorkspaceContextService.SCHEME, authority: 'model', path: '/' });
832
this.workspace = { id: STANDALONE_EDITOR_WORKSPACE_ID, folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })] };
833
}
834
835
getCompleteWorkspace(): Promise<IWorkspace> {
836
return Promise.resolve(this.getWorkspace());
837
}
838
839
public getWorkspace(): IWorkspace {
840
return this.workspace;
841
}
842
843
public getWorkbenchState(): WorkbenchState {
844
if (this.workspace) {
845
if (this.workspace.configuration) {
846
return WorkbenchState.WORKSPACE;
847
}
848
return WorkbenchState.FOLDER;
849
}
850
return WorkbenchState.EMPTY;
851
}
852
853
public getWorkspaceFolder(resource: URI): IWorkspaceFolder | null {
854
return resource && resource.scheme === StandaloneWorkspaceContextService.SCHEME ? this.workspace.folders[0] : null;
855
}
856
857
public isInsideWorkspace(resource: URI): boolean {
858
return resource && resource.scheme === StandaloneWorkspaceContextService.SCHEME;
859
}
860
861
public isCurrentWorkspace(workspaceIdOrFolder: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI): boolean {
862
return true;
863
}
864
}
865
866
export function updateConfigurationService(configurationService: IConfigurationService, source: any, isDiffEditor: boolean): void {
867
if (!source) {
868
return;
869
}
870
if (!(configurationService instanceof StandaloneConfigurationService)) {
871
return;
872
}
873
const toUpdate: [string, any][] = [];
874
Object.keys(source).forEach((key) => {
875
if (isEditorConfigurationKey(key)) {
876
toUpdate.push([`editor.${key}`, source[key]]);
877
}
878
if (isDiffEditor && isDiffEditorConfigurationKey(key)) {
879
toUpdate.push([`diffEditor.${key}`, source[key]]);
880
}
881
});
882
if (toUpdate.length > 0) {
883
configurationService.updateValues(toUpdate);
884
}
885
}
886
887
class StandaloneBulkEditService implements IBulkEditService {
888
declare readonly _serviceBrand: undefined;
889
890
constructor(
891
@IModelService private readonly _modelService: IModelService
892
) {
893
//
894
}
895
896
hasPreviewHandler(): false {
897
return false;
898
}
899
900
setPreviewHandler(): IDisposable {
901
return Disposable.None;
902
}
903
904
async apply(editsIn: ResourceEdit[] | WorkspaceEdit, _options?: IBulkEditOptions): Promise<IBulkEditResult> {
905
const edits = Array.isArray(editsIn) ? editsIn : ResourceEdit.convert(editsIn);
906
const textEdits = new Map<ITextModel, ISingleEditOperation[]>();
907
908
for (const edit of edits) {
909
if (!(edit instanceof ResourceTextEdit)) {
910
throw new Error('bad edit - only text edits are supported');
911
}
912
const model = this._modelService.getModel(edit.resource);
913
if (!model) {
914
throw new Error('bad edit - model not found');
915
}
916
if (typeof edit.versionId === 'number' && model.getVersionId() !== edit.versionId) {
917
throw new Error('bad state - model changed in the meantime');
918
}
919
let array = textEdits.get(model);
920
if (!array) {
921
array = [];
922
textEdits.set(model, array);
923
}
924
array.push(EditOperation.replaceMove(Range.lift(edit.textEdit.range), edit.textEdit.text));
925
}
926
927
928
let totalEdits = 0;
929
let totalFiles = 0;
930
for (const [model, edits] of textEdits) {
931
model.pushStackElement();
932
model.pushEditOperations([], edits, () => []);
933
model.pushStackElement();
934
totalFiles += 1;
935
totalEdits += edits.length;
936
}
937
938
return {
939
ariaSummary: strings.format(StandaloneServicesNLS.bulkEditServiceSummary, totalEdits, totalFiles),
940
isApplied: totalEdits > 0
941
};
942
}
943
}
944
945
class StandaloneUriLabelService implements ILabelService {
946
947
declare readonly _serviceBrand: undefined;
948
949
public readonly onDidChangeFormatters: Event<IFormatterChangeEvent> = Event.None;
950
951
public getUriLabel(resource: URI, options?: { relative?: boolean; forceNoTildify?: boolean }): string {
952
if (resource.scheme === 'file') {
953
return resource.fsPath;
954
}
955
return resource.path;
956
}
957
958
getUriBasenameLabel(resource: URI): string {
959
return basename(resource);
960
}
961
962
public getWorkspaceLabel(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | IWorkspace, options?: { verbose: Verbosity }): string {
963
return '';
964
}
965
966
public getSeparator(scheme: string, authority?: string): '/' | '\\' {
967
return '/';
968
}
969
970
public registerFormatter(formatter: ResourceLabelFormatter): IDisposable {
971
throw new Error('Not implemented');
972
}
973
974
public registerCachedFormatter(formatter: ResourceLabelFormatter): IDisposable {
975
return this.registerFormatter(formatter);
976
}
977
978
public getHostLabel(): string {
979
return '';
980
}
981
982
public getHostTooltip(): string | undefined {
983
return undefined;
984
}
985
}
986
987
988
class StandaloneContextViewService extends ContextViewService {
989
990
constructor(
991
@ILayoutService layoutService: ILayoutService,
992
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
993
) {
994
super(layoutService);
995
}
996
997
override showContextView(delegate: IContextViewDelegate, container?: HTMLElement, shadowRoot?: boolean): IOpenContextView {
998
if (!container) {
999
const codeEditor = this._codeEditorService.getFocusedCodeEditor() || this._codeEditorService.getActiveCodeEditor();
1000
if (codeEditor) {
1001
container = codeEditor.getContainerDomNode();
1002
}
1003
}
1004
return super.showContextView(delegate, container, shadowRoot);
1005
}
1006
}
1007
1008
class StandaloneWorkspaceTrustManagementService implements IWorkspaceTrustManagementService {
1009
_serviceBrand: undefined;
1010
1011
private _neverEmitter = new Emitter<never>();
1012
public readonly onDidChangeTrust: Event<boolean> = this._neverEmitter.event;
1013
onDidChangeTrustedFolders: Event<void> = this._neverEmitter.event;
1014
public readonly workspaceResolved = Promise.resolve();
1015
public readonly workspaceTrustInitialized = Promise.resolve();
1016
public readonly acceptsOutOfWorkspaceFiles = true;
1017
1018
isWorkspaceTrusted(): boolean {
1019
return true;
1020
}
1021
isWorkspaceTrustForced(): boolean {
1022
return false;
1023
}
1024
canSetParentFolderTrust(): boolean {
1025
return false;
1026
}
1027
async setParentFolderTrust(trusted: boolean): Promise<void> {
1028
// noop
1029
}
1030
canSetWorkspaceTrust(): boolean {
1031
return false;
1032
}
1033
async setWorkspaceTrust(trusted: boolean): Promise<void> {
1034
// noop
1035
}
1036
getUriTrustInfo(uri: URI): Promise<IWorkspaceTrustUriInfo> {
1037
throw new Error('Method not supported.');
1038
}
1039
async setUrisTrust(uri: URI[], trusted: boolean): Promise<void> {
1040
// noop
1041
}
1042
getTrustedUris(): URI[] {
1043
return [];
1044
}
1045
async setTrustedUris(uris: URI[]): Promise<void> {
1046
// noop
1047
}
1048
addWorkspaceTrustTransitionParticipant(participant: IWorkspaceTrustTransitionParticipant): IDisposable {
1049
throw new Error('Method not supported.');
1050
}
1051
}
1052
1053
class StandaloneLanguageService extends LanguageService {
1054
constructor() {
1055
super();
1056
}
1057
}
1058
1059
class StandaloneLogService extends LogService {
1060
constructor() {
1061
super(new ConsoleLogger());
1062
}
1063
}
1064
1065
class StandaloneContextMenuService extends ContextMenuService {
1066
constructor(
1067
@ITelemetryService telemetryService: ITelemetryService,
1068
@INotificationService notificationService: INotificationService,
1069
@IContextViewService contextViewService: IContextViewService,
1070
@IKeybindingService keybindingService: IKeybindingService,
1071
@IMenuService menuService: IMenuService,
1072
@IContextKeyService contextKeyService: IContextKeyService,
1073
) {
1074
super(telemetryService, notificationService, contextViewService, keybindingService, menuService, contextKeyService);
1075
this.configure({ blockMouse: false }); // we do not want that in the standalone editor
1076
}
1077
}
1078
1079
const standaloneEditorWorkerDescriptor: IWebWorkerDescriptor = {
1080
esmModuleLocation: undefined,
1081
label: 'editorWorkerService'
1082
};
1083
1084
class StandaloneEditorWorkerService extends EditorWorkerService {
1085
constructor(
1086
@IModelService modelService: IModelService,
1087
@ITextResourceConfigurationService configurationService: ITextResourceConfigurationService,
1088
@ILogService logService: ILogService,
1089
@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService,
1090
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
1091
) {
1092
super(standaloneEditorWorkerDescriptor, modelService, configurationService, logService, languageConfigurationService, languageFeaturesService);
1093
}
1094
}
1095
1096
class StandaloneAccessbilitySignalService implements IAccessibilitySignalService {
1097
_serviceBrand: undefined;
1098
async playSignal(cue: AccessibilitySignal, options: {}): Promise<void> {
1099
}
1100
1101
async playSignals(cues: AccessibilitySignal[]): Promise<void> {
1102
}
1103
1104
getEnabledState(signal: AccessibilitySignal, userGesture: boolean, modality?: AccessibilityModality | undefined): IValueWithChangeEvent<boolean> {
1105
return ValueWithChangeEvent.const(false);
1106
}
1107
1108
getDelayMs(signal: AccessibilitySignal, modality: AccessibilityModality): number {
1109
return 0;
1110
}
1111
1112
isSoundEnabled(cue: AccessibilitySignal): boolean {
1113
return false;
1114
}
1115
1116
isAnnouncementEnabled(cue: AccessibilitySignal): boolean {
1117
return false;
1118
}
1119
1120
onSoundEnabledChanged(cue: AccessibilitySignal): Event<void> {
1121
return Event.None;
1122
}
1123
1124
async playSound(cue: Sound, allowManyInParallel?: boolean | undefined): Promise<void> {
1125
}
1126
playSignalLoop(cue: AccessibilitySignal): IDisposable {
1127
return toDisposable(() => { });
1128
}
1129
}
1130
1131
export interface IEditorOverrideServices {
1132
[index: string]: any;
1133
}
1134
1135
1136
registerSingleton(ILogService, StandaloneLogService, InstantiationType.Eager);
1137
registerSingleton(IConfigurationService, StandaloneConfigurationService, InstantiationType.Eager);
1138
registerSingleton(ITextResourceConfigurationService, StandaloneResourceConfigurationService, InstantiationType.Eager);
1139
registerSingleton(ITextResourcePropertiesService, StandaloneResourcePropertiesService, InstantiationType.Eager);
1140
registerSingleton(IWorkspaceContextService, StandaloneWorkspaceContextService, InstantiationType.Eager);
1141
registerSingleton(ILabelService, StandaloneUriLabelService, InstantiationType.Eager);
1142
registerSingleton(ITelemetryService, StandaloneTelemetryService, InstantiationType.Eager);
1143
registerSingleton(IDialogService, StandaloneDialogService, InstantiationType.Eager);
1144
registerSingleton(IEnvironmentService, StandaloneEnvironmentService, InstantiationType.Eager);
1145
registerSingleton(INotificationService, StandaloneNotificationService, InstantiationType.Eager);
1146
registerSingleton(IMarkerService, MarkerService, InstantiationType.Eager);
1147
registerSingleton(ILanguageService, StandaloneLanguageService, InstantiationType.Eager);
1148
registerSingleton(IStandaloneThemeService, StandaloneThemeService, InstantiationType.Eager);
1149
registerSingleton(IModelService, ModelService, InstantiationType.Eager);
1150
registerSingleton(IMarkerDecorationsService, MarkerDecorationsService, InstantiationType.Eager);
1151
registerSingleton(IContextKeyService, ContextKeyService, InstantiationType.Eager);
1152
registerSingleton(IProgressService, StandaloneProgressService, InstantiationType.Eager);
1153
registerSingleton(IEditorProgressService, StandaloneEditorProgressService, InstantiationType.Eager);
1154
registerSingleton(IStorageService, InMemoryStorageService, InstantiationType.Eager);
1155
registerSingleton(IEditorWorkerService, StandaloneEditorWorkerService, InstantiationType.Eager);
1156
registerSingleton(IBulkEditService, StandaloneBulkEditService, InstantiationType.Eager);
1157
registerSingleton(IWorkspaceTrustManagementService, StandaloneWorkspaceTrustManagementService, InstantiationType.Eager);
1158
registerSingleton(ITextModelService, StandaloneTextModelService, InstantiationType.Eager);
1159
registerSingleton(IAccessibilityService, AccessibilityService, InstantiationType.Eager);
1160
registerSingleton(IListService, ListService, InstantiationType.Eager);
1161
registerSingleton(ICommandService, StandaloneCommandService, InstantiationType.Eager);
1162
registerSingleton(IKeybindingService, StandaloneKeybindingService, InstantiationType.Eager);
1163
registerSingleton(IQuickInputService, StandaloneQuickInputService, InstantiationType.Eager);
1164
registerSingleton(IContextViewService, StandaloneContextViewService, InstantiationType.Eager);
1165
registerSingleton(IOpenerService, OpenerService, InstantiationType.Eager);
1166
registerSingleton(IClipboardService, BrowserClipboardService, InstantiationType.Eager);
1167
registerSingleton(IContextMenuService, StandaloneContextMenuService, InstantiationType.Eager);
1168
registerSingleton(IMenuService, MenuService, InstantiationType.Eager);
1169
registerSingleton(IAccessibilitySignalService, StandaloneAccessbilitySignalService, InstantiationType.Eager);
1170
registerSingleton(ITreeSitterLibraryService, StandaloneTreeSitterLibraryService, InstantiationType.Eager);
1171
registerSingleton(ILoggerService, NullLoggerService, InstantiationType.Eager);
1172
registerSingleton(IDataChannelService, NullDataChannelService, InstantiationType.Eager);
1173
1174
/**
1175
* We don't want to eagerly instantiate services because embedders get a one time chance
1176
* to override services when they create the first editor.
1177
*/
1178
export module StandaloneServices {
1179
1180
const serviceCollection = new ServiceCollection();
1181
for (const [id, descriptor] of getSingletonServiceDescriptors()) {
1182
serviceCollection.set(id, descriptor);
1183
}
1184
1185
const instantiationService = new InstantiationService(serviceCollection, true);
1186
serviceCollection.set(IInstantiationService, instantiationService);
1187
1188
export function get<T>(serviceId: ServiceIdentifier<T>): T {
1189
if (!initialized) {
1190
initialize({});
1191
}
1192
const r = serviceCollection.get(serviceId);
1193
if (!r) {
1194
throw new Error('Missing service ' + serviceId);
1195
}
1196
if (r instanceof SyncDescriptor) {
1197
return instantiationService.invokeFunction((accessor) => accessor.get(serviceId));
1198
} else {
1199
return r;
1200
}
1201
}
1202
1203
let initialized = false;
1204
const onDidInitialize = new Emitter<void>();
1205
export function initialize(overrides: IEditorOverrideServices): IInstantiationService {
1206
if (initialized) {
1207
return instantiationService;
1208
}
1209
initialized = true;
1210
1211
// Add singletons that were registered after this module loaded
1212
for (const [id, descriptor] of getSingletonServiceDescriptors()) {
1213
if (!serviceCollection.get(id)) {
1214
serviceCollection.set(id, descriptor);
1215
}
1216
}
1217
1218
// Initialize the service collection with the overrides, but only if the
1219
// service was not instantiated in the meantime.
1220
for (const serviceId in overrides) {
1221
if (overrides.hasOwnProperty(serviceId)) {
1222
const serviceIdentifier = createDecorator(serviceId);
1223
const r = serviceCollection.get(serviceIdentifier);
1224
if (r instanceof SyncDescriptor) {
1225
serviceCollection.set(serviceIdentifier, overrides[serviceId]);
1226
}
1227
}
1228
}
1229
1230
// Instantiate all editor features
1231
const editorFeatures = getEditorFeatures();
1232
for (const feature of editorFeatures) {
1233
try {
1234
instantiationService.createInstance(feature);
1235
} catch (err) {
1236
onUnexpectedError(err);
1237
}
1238
}
1239
1240
onDidInitialize.fire();
1241
1242
return instantiationService;
1243
}
1244
1245
/**
1246
* Executes callback once services are initialized.
1247
*/
1248
export function withServices(callback: () => IDisposable): IDisposable {
1249
if (initialized) {
1250
return callback();
1251
}
1252
1253
const disposable = new DisposableStore();
1254
1255
const listener = disposable.add(onDidInitialize.event(() => {
1256
listener.dispose();
1257
disposable.add(callback());
1258
}));
1259
1260
return disposable;
1261
}
1262
1263
}
1264
1265