Path: blob/main/src/vs/editor/standalone/browser/standaloneServices.ts
3294 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 './standaloneCodeEditorService.js';6import './standaloneLayoutService.js';7import '../../../platform/undoRedo/common/undoRedoService.js';8import '../../common/services/languageFeatureDebounce.js';9import '../../common/services/semanticTokensStylingService.js';10import '../../common/services/languageFeaturesService.js';11import '../../browser/services/hoverService/hoverService.js';12import '../../browser/services/inlineCompletionsService.js';1314import * as strings from '../../../base/common/strings.js';15import * as dom from '../../../base/browser/dom.js';16import { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js';17import { Emitter, Event, IValueWithChangeEvent, ValueWithChangeEvent } from '../../../base/common/event.js';18import { ResolvedKeybinding, KeyCodeChord, Keybinding, decodeKeybinding } from '../../../base/common/keybindings.js';19import { IDisposable, IReference, ImmortalReference, toDisposable, DisposableStore, Disposable, combinedDisposable } from '../../../base/common/lifecycle.js';20import { OS, isLinux, isMacintosh } from '../../../base/common/platform.js';21import Severity from '../../../base/common/severity.js';22import { URI } from '../../../base/common/uri.js';23import { IBulkEditOptions, IBulkEditResult, IBulkEditService, ResourceEdit, ResourceTextEdit } from '../../browser/services/bulkEditService.js';24import { isDiffEditorConfigurationKey, isEditorConfigurationKey } from '../../common/config/editorConfigurationSchema.js';25import { EditOperation, ISingleEditOperation } from '../../common/core/editOperation.js';26import { IPosition, Position as Pos } from '../../common/core/position.js';27import { Range } from '../../common/core/range.js';28import { ITextModel, ITextSnapshot } from '../../common/model.js';29import { IModelService } from '../../common/services/model.js';30import { IResolvedTextEditorModel, ITextModelContentProvider, ITextModelService } from '../../common/services/resolverService.js';31import { ITextResourceConfigurationService, ITextResourcePropertiesService, ITextResourceConfigurationChangeEvent } from '../../common/services/textResourceConfiguration.js';32import { CommandsRegistry, ICommandEvent, ICommandHandler, ICommandService } from '../../../platform/commands/common/commands.js';33import { IConfigurationChangeEvent, IConfigurationData, IConfigurationOverrides, IConfigurationService, IConfigurationModel, IConfigurationValue, ConfigurationTarget } from '../../../platform/configuration/common/configuration.js';34import { Configuration, ConfigurationModel, ConfigurationChangeEvent } from '../../../platform/configuration/common/configurationModels.js';35import { IContextKeyService, ContextKeyExpression } from '../../../platform/contextkey/common/contextkey.js';36import { IConfirmation, IConfirmationResult, IDialogService, IInputResult, IPrompt, IPromptResult, IPromptWithCustomCancel, IPromptResultWithCancel, IPromptWithDefaultCancel, IPromptBaseButton } from '../../../platform/dialogs/common/dialogs.js';37import { createDecorator, IInstantiationService, ServiceIdentifier } from '../../../platform/instantiation/common/instantiation.js';38import { AbstractKeybindingService } from '../../../platform/keybinding/common/abstractKeybindingService.js';39import { IKeybindingService, IKeyboardEvent, KeybindingsSchemaContribution } from '../../../platform/keybinding/common/keybinding.js';40import { KeybindingResolver } from '../../../platform/keybinding/common/keybindingResolver.js';41import { IKeybindingItem, KeybindingsRegistry } from '../../../platform/keybinding/common/keybindingsRegistry.js';42import { ResolvedKeybindingItem } from '../../../platform/keybinding/common/resolvedKeybindingItem.js';43import { USLayoutResolvedKeybinding } from '../../../platform/keybinding/common/usLayoutResolvedKeybinding.js';44import { ILabelService, ResourceLabelFormatter, IFormatterChangeEvent, Verbosity } from '../../../platform/label/common/label.js';45import { INotification, INotificationHandle, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification, IStatusMessageOptions, INotificationSource, INotificationSourceFilter, NotificationsFilter, IStatusHandle } from '../../../platform/notification/common/notification.js';46import { IProgressRunner, IEditorProgressService, IProgressService, IProgress, IProgressCompositeOptions, IProgressDialogOptions, IProgressNotificationOptions, IProgressOptions, IProgressStep, IProgressWindowOptions } from '../../../platform/progress/common/progress.js';47import { ITelemetryService, TelemetryLevel } from '../../../platform/telemetry/common/telemetry.js';48import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, WorkbenchState, WorkspaceFolder, STANDALONE_EDITOR_WORKSPACE_ID } from '../../../platform/workspace/common/workspace.js';49import { ILayoutService } from '../../../platform/layout/browser/layoutService.js';50import { StandaloneServicesNLS } from '../../common/standaloneStrings.js';51import { basename } from '../../../base/common/resources.js';52import { ICodeEditorService } from '../../browser/services/codeEditorService.js';53import { ConsoleLogger, ILoggerService, ILogService, NullLoggerService } from '../../../platform/log/common/log.js';54import { IWorkspaceTrustManagementService, IWorkspaceTrustTransitionParticipant, IWorkspaceTrustUriInfo } from '../../../platform/workspace/common/workspaceTrust.js';55import { EditorOption } from '../../common/config/editorOptions.js';56import { ICodeEditor, IDiffEditor } from '../../browser/editorBrowser.js';57import { IContextMenuService, IContextViewDelegate, IContextViewService, IOpenContextView } from '../../../platform/contextview/browser/contextView.js';58import { ContextViewService } from '../../../platform/contextview/browser/contextViewService.js';59import { LanguageService } from '../../common/services/languageService.js';60import { ContextMenuService } from '../../../platform/contextview/browser/contextMenuService.js';61import { getSingletonServiceDescriptors, InstantiationType, registerSingleton } from '../../../platform/instantiation/common/extensions.js';62import { OpenerService } from '../../browser/services/openerService.js';63import { IEditorWorkerService } from '../../common/services/editorWorker.js';64import { EditorWorkerService } from '../../browser/services/editorWorkerService.js';65import { ILanguageService } from '../../common/languages/language.js';66import { MarkerDecorationsService } from '../../common/services/markerDecorationsService.js';67import { IMarkerDecorationsService } from '../../common/services/markerDecorations.js';68import { ModelService } from '../../common/services/modelService.js';69import { StandaloneQuickInputService } from './quickInput/standaloneQuickInputService.js';70import { StandaloneThemeService } from './standaloneThemeService.js';71import { IStandaloneThemeService } from '../common/standaloneTheme.js';72import { AccessibilityService } from '../../../platform/accessibility/browser/accessibilityService.js';73import { IAccessibilityService } from '../../../platform/accessibility/common/accessibility.js';74import { IMenuService } from '../../../platform/actions/common/actions.js';75import { MenuService } from '../../../platform/actions/common/menuService.js';76import { BrowserClipboardService } from '../../../platform/clipboard/browser/clipboardService.js';77import { IClipboardService } from '../../../platform/clipboard/common/clipboardService.js';78import { ContextKeyService } from '../../../platform/contextkey/browser/contextKeyService.js';79import { SyncDescriptor } from '../../../platform/instantiation/common/descriptors.js';80import { InstantiationService } from '../../../platform/instantiation/common/instantiationService.js';81import { ServiceCollection } from '../../../platform/instantiation/common/serviceCollection.js';82import { IListService, ListService } from '../../../platform/list/browser/listService.js';83import { IMarkerService } from '../../../platform/markers/common/markers.js';84import { MarkerService } from '../../../platform/markers/common/markerService.js';85import { IOpenerService } from '../../../platform/opener/common/opener.js';86import { IQuickInputService } from '../../../platform/quickinput/common/quickInput.js';87import { IStorageService, InMemoryStorageService } from '../../../platform/storage/common/storage.js';88import { DefaultConfiguration } from '../../../platform/configuration/common/configurations.js';89import { WorkspaceEdit } from '../../common/languages.js';90import { AccessibilitySignal, AccessibilityModality, IAccessibilitySignalService, Sound } from '../../../platform/accessibilitySignal/browser/accessibilitySignalService.js';91import { ILanguageFeaturesService } from '../../common/services/languageFeatures.js';92import { ILanguageConfigurationService } from '../../common/languages/languageConfigurationRegistry.js';93import { LogService } from '../../../platform/log/common/logService.js';94import { getEditorFeatures } from '../../common/editorFeatures.js';95import { onUnexpectedError } from '../../../base/common/errors.js';96import { ExtensionKind, IEnvironmentService, IExtensionHostDebugParams } from '../../../platform/environment/common/environment.js';97import { mainWindow } from '../../../base/browser/window.js';98import { ResourceMap } from '../../../base/common/map.js';99import { IWebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js';100import { ITreeSitterLibraryService } from '../../common/services/treeSitter/treeSitterLibraryService.js';101import { StandaloneTreeSitterLibraryService } from './standaloneTreeSitterLibraryService.js';102import { IDataChannelService, NullDataChannelService } from '../../../platform/dataChannel/common/dataChannel.js';103104class SimpleModel implements IResolvedTextEditorModel {105106private readonly model: ITextModel;107private readonly _onWillDispose: Emitter<void>;108109constructor(model: ITextModel) {110this.model = model;111this._onWillDispose = new Emitter<void>();112}113114public get onWillDispose(): Event<void> {115return this._onWillDispose.event;116}117118public resolve(): Promise<void> {119return Promise.resolve();120}121122public get textEditorModel(): ITextModel {123return this.model;124}125126public createSnapshot(): ITextSnapshot {127return this.model.createSnapshot();128}129130public isReadonly(): boolean {131return false;132}133134private disposed = false;135public dispose(): void {136this.disposed = true;137138this._onWillDispose.fire();139}140141public isDisposed(): boolean {142return this.disposed;143}144145public isResolved(): boolean {146return true;147}148149public getLanguageId(): string | undefined {150return this.model.getLanguageId();151}152}153154class StandaloneTextModelService implements ITextModelService {155public _serviceBrand: undefined;156157constructor(158@IModelService private readonly modelService: IModelService159) { }160161public createModelReference(resource: URI): Promise<IReference<IResolvedTextEditorModel>> {162const model = this.modelService.getModel(resource);163164if (!model) {165return Promise.reject(new Error(`Model not found`));166}167168return Promise.resolve(new ImmortalReference(new SimpleModel(model)));169}170171public registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): IDisposable {172return {173dispose: function () { /* no op */ }174};175}176177public canHandleResource(resource: URI): boolean {178return false;179}180}181182class StandaloneEditorProgressService implements IEditorProgressService {183declare readonly _serviceBrand: undefined;184185private static NULL_PROGRESS_RUNNER: IProgressRunner = {186done: () => { },187total: () => { },188worked: () => { }189};190191show(infinite: true, delay?: number): IProgressRunner;192show(total: number, delay?: number): IProgressRunner;193show(): IProgressRunner {194return StandaloneEditorProgressService.NULL_PROGRESS_RUNNER;195}196197async showWhile(promise: Promise<any>, delay?: number): Promise<void> {198await promise;199}200}201202class StandaloneProgressService implements IProgressService {203204declare readonly _serviceBrand: undefined;205206withProgress<R>(_options: IProgressOptions | IProgressDialogOptions | IProgressNotificationOptions | IProgressWindowOptions | IProgressCompositeOptions, task: (progress: IProgress<IProgressStep>) => Promise<R>, onDidCancel?: ((choice?: number | undefined) => void) | undefined): Promise<R> {207return task({208report: () => { },209});210}211}212213class StandaloneEnvironmentService implements IEnvironmentService {214215declare readonly _serviceBrand: undefined;216217readonly stateResource: URI = URI.from({ scheme: 'monaco', authority: 'stateResource' });218readonly userRoamingDataHome: URI = URI.from({ scheme: 'monaco', authority: 'userRoamingDataHome' });219readonly keyboardLayoutResource: URI = URI.from({ scheme: 'monaco', authority: 'keyboardLayoutResource' });220readonly argvResource: URI = URI.from({ scheme: 'monaco', authority: 'argvResource' });221readonly untitledWorkspacesHome: URI = URI.from({ scheme: 'monaco', authority: 'untitledWorkspacesHome' });222readonly workspaceStorageHome: URI = URI.from({ scheme: 'monaco', authority: 'workspaceStorageHome' });223readonly localHistoryHome: URI = URI.from({ scheme: 'monaco', authority: 'localHistoryHome' });224readonly cacheHome: URI = URI.from({ scheme: 'monaco', authority: 'cacheHome' });225readonly userDataSyncHome: URI = URI.from({ scheme: 'monaco', authority: 'userDataSyncHome' });226readonly sync: 'on' | 'off' | undefined = undefined;227readonly continueOn?: string | undefined = undefined;228readonly editSessionId?: string | undefined = undefined;229readonly debugExtensionHost: IExtensionHostDebugParams = { port: null, break: false };230readonly isExtensionDevelopment: boolean = false;231readonly disableExtensions: boolean | string[] = false;232readonly disableExperiments: boolean = false;233readonly enableExtensions?: readonly string[] | undefined = undefined;234readonly extensionDevelopmentLocationURI?: URI[] | undefined = undefined;235readonly extensionDevelopmentKind?: ExtensionKind[] | undefined = undefined;236readonly extensionTestsLocationURI?: URI | undefined = undefined;237readonly logsHome: URI = URI.from({ scheme: 'monaco', authority: 'logsHome' });238readonly logLevel?: string | undefined = undefined;239readonly extensionLogLevel?: [string, string][] | undefined = undefined;240readonly verbose: boolean = false;241readonly isBuilt: boolean = false;242readonly disableTelemetry: boolean = false;243readonly serviceMachineIdResource: URI = URI.from({ scheme: 'monaco', authority: 'serviceMachineIdResource' });244readonly policyFile?: URI | undefined = undefined;245readonly isSimulation: boolean | undefined = undefined;246}247248class StandaloneDialogService implements IDialogService {249250_serviceBrand: undefined;251252readonly onWillShowDialog = Event.None;253readonly onDidShowDialog = Event.None;254255async confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {256const confirmed = this.doConfirm(confirmation.message, confirmation.detail);257258return {259confirmed,260checkboxChecked: false // unsupported261};262}263264private doConfirm(message: string, detail?: string): boolean {265let messageText = message;266if (detail) {267messageText = messageText + '\n\n' + detail;268}269270return mainWindow.confirm(messageText);271}272273prompt<T>(prompt: IPromptWithCustomCancel<T>): Promise<IPromptResultWithCancel<T>>;274prompt<T>(prompt: IPrompt<T>): Promise<IPromptResult<T>>;275prompt<T>(prompt: IPromptWithDefaultCancel<T>): Promise<IPromptResult<T>>;276async prompt<T>(prompt: IPrompt<T> | IPromptWithCustomCancel<T>): Promise<IPromptResult<T> | IPromptResultWithCancel<T>> {277let result: T | undefined = undefined;278const confirmed = this.doConfirm(prompt.message, prompt.detail);279if (confirmed) {280const promptButtons: IPromptBaseButton<T>[] = [...(prompt.buttons ?? [])];281if (prompt.cancelButton && typeof prompt.cancelButton !== 'string' && typeof prompt.cancelButton !== 'boolean') {282promptButtons.push(prompt.cancelButton);283}284285result = await promptButtons[0]?.run({ checkboxChecked: false });286}287288return { result };289}290291async info(message: string, detail?: string): Promise<void> {292await this.prompt({ type: Severity.Info, message, detail });293}294295async warn(message: string, detail?: string): Promise<void> {296await this.prompt({ type: Severity.Warning, message, detail });297}298299async error(message: string, detail?: string): Promise<void> {300await this.prompt({ type: Severity.Error, message, detail });301}302303input(): Promise<IInputResult> {304return Promise.resolve({ confirmed: false }); // unsupported305}306307about(): Promise<void> {308return Promise.resolve(undefined);309}310}311312export class StandaloneNotificationService implements INotificationService {313314readonly onDidChangeFilter: Event<void> = Event.None;315316public _serviceBrand: undefined;317318private static readonly NO_OP: INotificationHandle = new NoOpNotification();319320public info(message: string): INotificationHandle {321return this.notify({ severity: Severity.Info, message });322}323324public warn(message: string): INotificationHandle {325return this.notify({ severity: Severity.Warning, message });326}327328public error(error: string | Error): INotificationHandle {329return this.notify({ severity: Severity.Error, message: error });330}331332public notify(notification: INotification): INotificationHandle {333switch (notification.severity) {334case Severity.Error:335console.error(notification.message);336break;337case Severity.Warning:338console.warn(notification.message);339break;340default:341console.log(notification.message);342break;343}344345return StandaloneNotificationService.NO_OP;346}347348public prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {349return StandaloneNotificationService.NO_OP;350}351352public status(message: string | Error, options?: IStatusMessageOptions): IStatusHandle {353return { close: () => { } };354}355356public setFilter(filter: NotificationsFilter | INotificationSourceFilter): void { }357358public getFilter(source?: INotificationSource): NotificationsFilter {359return NotificationsFilter.OFF;360}361362public getFilters(): INotificationSourceFilter[] {363return [];364}365366public removeFilter(sourceId: string): void { }367}368369export class StandaloneCommandService implements ICommandService {370declare readonly _serviceBrand: undefined;371372private readonly _instantiationService: IInstantiationService;373374private readonly _onWillExecuteCommand = new Emitter<ICommandEvent>();375private readonly _onDidExecuteCommand = new Emitter<ICommandEvent>();376public readonly onWillExecuteCommand: Event<ICommandEvent> = this._onWillExecuteCommand.event;377public readonly onDidExecuteCommand: Event<ICommandEvent> = this._onDidExecuteCommand.event;378379constructor(380@IInstantiationService instantiationService: IInstantiationService381) {382this._instantiationService = instantiationService;383}384385public executeCommand<T>(id: string, ...args: any[]): Promise<T> {386const command = CommandsRegistry.getCommand(id);387if (!command) {388return Promise.reject(new Error(`command '${id}' not found`));389}390391try {392this._onWillExecuteCommand.fire({ commandId: id, args });393const result = this._instantiationService.invokeFunction.apply(this._instantiationService, [command.handler, ...args]) as T;394395this._onDidExecuteCommand.fire({ commandId: id, args });396return Promise.resolve(result);397} catch (err) {398return Promise.reject(err);399}400}401}402403export interface IKeybindingRule {404keybinding: number;405command?: string | null;406commandArgs?: any;407when?: ContextKeyExpression | null;408}409410export class StandaloneKeybindingService extends AbstractKeybindingService {411private _cachedResolver: KeybindingResolver | null;412private _dynamicKeybindings: IKeybindingItem[];413private readonly _domNodeListeners: DomNodeListeners[];414415constructor(416@IContextKeyService contextKeyService: IContextKeyService,417@ICommandService commandService: ICommandService,418@ITelemetryService telemetryService: ITelemetryService,419@INotificationService notificationService: INotificationService,420@ILogService logService: ILogService,421@ICodeEditorService codeEditorService: ICodeEditorService422) {423super(contextKeyService, commandService, telemetryService, notificationService, logService);424425this._cachedResolver = null;426this._dynamicKeybindings = [];427this._domNodeListeners = [];428429const addContainer = (domNode: HTMLElement) => {430const disposables = new DisposableStore();431432// for standard keybindings433disposables.add(dom.addDisposableListener(domNode, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {434const keyEvent = new StandardKeyboardEvent(e);435const shouldPreventDefault = this._dispatch(keyEvent, keyEvent.target);436if (shouldPreventDefault) {437keyEvent.preventDefault();438keyEvent.stopPropagation();439}440}));441442// for single modifier chord keybindings (e.g. shift shift)443disposables.add(dom.addDisposableListener(domNode, dom.EventType.KEY_UP, (e: KeyboardEvent) => {444const keyEvent = new StandardKeyboardEvent(e);445const shouldPreventDefault = this._singleModifierDispatch(keyEvent, keyEvent.target);446if (shouldPreventDefault) {447keyEvent.preventDefault();448}449}));450451this._domNodeListeners.push(new DomNodeListeners(domNode, disposables));452};453const removeContainer = (domNode: HTMLElement) => {454for (let i = 0; i < this._domNodeListeners.length; i++) {455const domNodeListeners = this._domNodeListeners[i];456if (domNodeListeners.domNode === domNode) {457this._domNodeListeners.splice(i, 1);458domNodeListeners.dispose();459}460}461};462463const addCodeEditor = (codeEditor: ICodeEditor) => {464if (codeEditor.getOption(EditorOption.inDiffEditor)) {465return;466}467addContainer(codeEditor.getContainerDomNode());468};469const removeCodeEditor = (codeEditor: ICodeEditor) => {470if (codeEditor.getOption(EditorOption.inDiffEditor)) {471return;472}473removeContainer(codeEditor.getContainerDomNode());474};475this._register(codeEditorService.onCodeEditorAdd(addCodeEditor));476this._register(codeEditorService.onCodeEditorRemove(removeCodeEditor));477codeEditorService.listCodeEditors().forEach(addCodeEditor);478479const addDiffEditor = (diffEditor: IDiffEditor) => {480addContainer(diffEditor.getContainerDomNode());481};482const removeDiffEditor = (diffEditor: IDiffEditor) => {483removeContainer(diffEditor.getContainerDomNode());484};485this._register(codeEditorService.onDiffEditorAdd(addDiffEditor));486this._register(codeEditorService.onDiffEditorRemove(removeDiffEditor));487codeEditorService.listDiffEditors().forEach(addDiffEditor);488}489490public addDynamicKeybinding(command: string, keybinding: number, handler: ICommandHandler, when: ContextKeyExpression | undefined): IDisposable {491return combinedDisposable(492CommandsRegistry.registerCommand(command, handler),493this.addDynamicKeybindings([{494keybinding,495command,496when497}])498);499}500501public addDynamicKeybindings(rules: IKeybindingRule[]): IDisposable {502const entries: IKeybindingItem[] = rules.map((rule) => {503const keybinding = decodeKeybinding(rule.keybinding, OS);504return {505keybinding,506command: rule.command ?? null,507commandArgs: rule.commandArgs,508when: rule.when,509weight1: 1000,510weight2: 0,511extensionId: null,512isBuiltinExtension: false513};514});515this._dynamicKeybindings = this._dynamicKeybindings.concat(entries);516517this.updateResolver();518519return toDisposable(() => {520// Search the first entry and remove them all since they will be contiguous521for (let i = 0; i < this._dynamicKeybindings.length; i++) {522if (this._dynamicKeybindings[i] === entries[0]) {523this._dynamicKeybindings.splice(i, entries.length);524this.updateResolver();525return;526}527}528});529}530531private updateResolver(): void {532this._cachedResolver = null;533this._onDidUpdateKeybindings.fire();534}535536protected _getResolver(): KeybindingResolver {537if (!this._cachedResolver) {538const defaults = this._toNormalizedKeybindingItems(KeybindingsRegistry.getDefaultKeybindings(), true);539const overrides = this._toNormalizedKeybindingItems(this._dynamicKeybindings, false);540this._cachedResolver = new KeybindingResolver(defaults, overrides, (str) => this._log(str));541}542return this._cachedResolver;543}544545protected _documentHasFocus(): boolean {546return mainWindow.document.hasFocus();547}548549private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {550const result: ResolvedKeybindingItem[] = [];551let resultLen = 0;552for (const item of items) {553const when = item.when || undefined;554const keybinding = item.keybinding;555556if (!keybinding) {557// This might be a removal keybinding item in user settings => accept it558result[resultLen++] = new ResolvedKeybindingItem(undefined, item.command, item.commandArgs, when, isDefault, null, false);559} else {560const resolvedKeybindings = USLayoutResolvedKeybinding.resolveKeybinding(keybinding, OS);561for (const resolvedKeybinding of resolvedKeybindings) {562result[resultLen++] = new ResolvedKeybindingItem(resolvedKeybinding, item.command, item.commandArgs, when, isDefault, null, false);563}564}565}566567return result;568}569570public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[] {571return USLayoutResolvedKeybinding.resolveKeybinding(keybinding, OS);572}573574public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding {575const chord = new KeyCodeChord(576keyboardEvent.ctrlKey,577keyboardEvent.shiftKey,578keyboardEvent.altKey,579keyboardEvent.metaKey,580keyboardEvent.keyCode581);582return new USLayoutResolvedKeybinding([chord], OS);583}584585public resolveUserBinding(userBinding: string): ResolvedKeybinding[] {586return [];587}588589public _dumpDebugInfo(): string {590return '';591}592593public _dumpDebugInfoJSON(): string {594return '';595}596597public registerSchemaContribution(contribution: KeybindingsSchemaContribution): IDisposable {598return Disposable.None;599}600601/**602* not yet supported603*/604public override enableKeybindingHoldMode(commandId: string): Promise<void> | undefined {605return undefined;606}607}608609class DomNodeListeners extends Disposable {610constructor(611public readonly domNode: HTMLElement,612disposables: DisposableStore613) {614super();615this._register(disposables);616}617}618619function isConfigurationOverrides(thing: any): thing is IConfigurationOverrides {620return thing621&& typeof thing === 'object'622&& (!thing.overrideIdentifier || typeof thing.overrideIdentifier === 'string')623&& (!thing.resource || thing.resource instanceof URI);624}625626export class StandaloneConfigurationService implements IConfigurationService {627628declare readonly _serviceBrand: undefined;629630private readonly _onDidChangeConfiguration = new Emitter<IConfigurationChangeEvent>();631public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;632633private readonly _configuration: Configuration;634635constructor(636@ILogService private readonly logService: ILogService,637) {638const defaultConfiguration = new DefaultConfiguration(logService);639this._configuration = new Configuration(640defaultConfiguration.reload(),641ConfigurationModel.createEmptyModel(logService),642ConfigurationModel.createEmptyModel(logService),643ConfigurationModel.createEmptyModel(logService),644ConfigurationModel.createEmptyModel(logService),645ConfigurationModel.createEmptyModel(logService),646new ResourceMap<ConfigurationModel>(),647ConfigurationModel.createEmptyModel(logService),648new ResourceMap<ConfigurationModel>(),649logService650);651defaultConfiguration.dispose();652}653654getValue<T>(): T;655getValue<T>(section: string): T;656getValue<T>(overrides: IConfigurationOverrides): T;657getValue<T>(section: string, overrides: IConfigurationOverrides): T;658getValue(arg1?: any, arg2?: any): any {659const section = typeof arg1 === 'string' ? arg1 : undefined;660const overrides = isConfigurationOverrides(arg1) ? arg1 : isConfigurationOverrides(arg2) ? arg2 : {};661return this._configuration.getValue(section, overrides, undefined);662}663664public updateValues(values: [string, any][]): Promise<void> {665const previous = { data: this._configuration.toData() };666667const changedKeys: string[] = [];668669for (const entry of values) {670const [key, value] = entry;671if (this.getValue(key) === value) {672continue;673}674this._configuration.updateValue(key, value);675changedKeys.push(key);676}677678if (changedKeys.length > 0) {679const configurationChangeEvent = new ConfigurationChangeEvent({ keys: changedKeys, overrides: [] }, previous, this._configuration, undefined, this.logService);680configurationChangeEvent.source = ConfigurationTarget.MEMORY;681this._onDidChangeConfiguration.fire(configurationChangeEvent);682}683684return Promise.resolve();685}686687public updateValue(key: string, value: any, arg3?: any, arg4?: any): Promise<void> {688return this.updateValues([[key, value]]);689}690691public inspect<C>(key: string, options: IConfigurationOverrides = {}): IConfigurationValue<C> {692return this._configuration.inspect<C>(key, options, undefined);693}694695public keys() {696return this._configuration.keys(undefined);697}698699public reloadConfiguration(): Promise<void> {700return Promise.resolve(undefined);701}702703public getConfigurationData(): IConfigurationData | null {704const emptyModel: IConfigurationModel = {705contents: {},706keys: [],707overrides: []708};709return {710defaults: emptyModel,711policy: emptyModel,712application: emptyModel,713userLocal: emptyModel,714userRemote: emptyModel,715workspace: emptyModel,716folders: []717};718}719}720721class StandaloneResourceConfigurationService implements ITextResourceConfigurationService {722723declare readonly _serviceBrand: undefined;724725private readonly _onDidChangeConfiguration = new Emitter<ITextResourceConfigurationChangeEvent>();726public readonly onDidChangeConfiguration = this._onDidChangeConfiguration.event;727728constructor(729@IConfigurationService private readonly configurationService: StandaloneConfigurationService,730@IModelService private readonly modelService: IModelService,731@ILanguageService private readonly languageService: ILanguageService732) {733this.configurationService.onDidChangeConfiguration((e) => {734this._onDidChangeConfiguration.fire({ affectedKeys: e.affectedKeys, affectsConfiguration: (resource: URI, configuration: string) => e.affectsConfiguration(configuration) });735});736}737738getValue<T>(resource: URI, section?: string): T;739getValue<T>(resource: URI, position?: IPosition, section?: string): T;740getValue<T>(resource: URI | undefined, arg2?: any, arg3?: any) {741const position: IPosition | null = Pos.isIPosition(arg2) ? arg2 : null;742const section: string | undefined = position ? (typeof arg3 === 'string' ? arg3 : undefined) : (typeof arg2 === 'string' ? arg2 : undefined);743const language = resource ? this.getLanguage(resource, position) : undefined;744if (typeof section === 'undefined') {745return this.configurationService.getValue<T>({746resource,747overrideIdentifier: language748});749}750return this.configurationService.getValue<T>(section, {751resource,752overrideIdentifier: language753});754}755756inspect<T>(resource: URI | undefined, position: IPosition | null, section: string): IConfigurationValue<Readonly<T>> {757const language = resource ? this.getLanguage(resource, position) : undefined;758return this.configurationService.inspect<T>(section, { resource, overrideIdentifier: language });759}760761private getLanguage(resource: URI, position: IPosition | null): string | null {762const model = this.modelService.getModel(resource);763if (model) {764return position ? model.getLanguageIdAtPosition(position.lineNumber, position.column) : model.getLanguageId();765}766return this.languageService.guessLanguageIdByFilepathOrFirstLine(resource);767}768769updateValue(resource: URI, key: string, value: any, configurationTarget?: ConfigurationTarget): Promise<void> {770return this.configurationService.updateValue(key, value, { resource }, configurationTarget);771}772}773774class StandaloneResourcePropertiesService implements ITextResourcePropertiesService {775776declare readonly _serviceBrand: undefined;777778constructor(779@IConfigurationService private readonly configurationService: IConfigurationService,780) {781}782783getEOL(resource: URI, language?: string): string {784const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource });785if (eol && typeof eol === 'string' && eol !== 'auto') {786return eol;787}788return (isLinux || isMacintosh) ? '\n' : '\r\n';789}790}791792class StandaloneTelemetryService implements ITelemetryService {793declare readonly _serviceBrand: undefined;794readonly telemetryLevel = TelemetryLevel.NONE;795readonly sessionId = 'someValue.sessionId';796readonly machineId = 'someValue.machineId';797readonly sqmId = 'someValue.sqmId';798readonly devDeviceId = 'someValue.devDeviceId';799readonly firstSessionDate = 'someValue.firstSessionDate';800readonly sendErrorTelemetry = false;801setEnabled(): void { }802setExperimentProperty(): void { }803publicLog() { }804publicLog2() { }805publicLogError() { }806publicLogError2() { }807}808809class StandaloneWorkspaceContextService implements IWorkspaceContextService {810811public _serviceBrand: undefined;812813private static readonly SCHEME = 'inmemory';814815private readonly _onDidChangeWorkspaceName = new Emitter<void>();816public readonly onDidChangeWorkspaceName: Event<void> = this._onDidChangeWorkspaceName.event;817818private readonly _onWillChangeWorkspaceFolders = new Emitter<IWorkspaceFoldersWillChangeEvent>();819public readonly onWillChangeWorkspaceFolders: Event<IWorkspaceFoldersWillChangeEvent> = this._onWillChangeWorkspaceFolders.event;820821private readonly _onDidChangeWorkspaceFolders = new Emitter<IWorkspaceFoldersChangeEvent>();822public readonly onDidChangeWorkspaceFolders: Event<IWorkspaceFoldersChangeEvent> = this._onDidChangeWorkspaceFolders.event;823824private readonly _onDidChangeWorkbenchState = new Emitter<WorkbenchState>();825public readonly onDidChangeWorkbenchState: Event<WorkbenchState> = this._onDidChangeWorkbenchState.event;826827private readonly workspace: IWorkspace;828829constructor() {830const resource = URI.from({ scheme: StandaloneWorkspaceContextService.SCHEME, authority: 'model', path: '/' });831this.workspace = { id: STANDALONE_EDITOR_WORKSPACE_ID, folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })] };832}833834getCompleteWorkspace(): Promise<IWorkspace> {835return Promise.resolve(this.getWorkspace());836}837838public getWorkspace(): IWorkspace {839return this.workspace;840}841842public getWorkbenchState(): WorkbenchState {843if (this.workspace) {844if (this.workspace.configuration) {845return WorkbenchState.WORKSPACE;846}847return WorkbenchState.FOLDER;848}849return WorkbenchState.EMPTY;850}851852public getWorkspaceFolder(resource: URI): IWorkspaceFolder | null {853return resource && resource.scheme === StandaloneWorkspaceContextService.SCHEME ? this.workspace.folders[0] : null;854}855856public isInsideWorkspace(resource: URI): boolean {857return resource && resource.scheme === StandaloneWorkspaceContextService.SCHEME;858}859860public isCurrentWorkspace(workspaceIdOrFolder: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI): boolean {861return true;862}863}864865export function updateConfigurationService(configurationService: IConfigurationService, source: any, isDiffEditor: boolean): void {866if (!source) {867return;868}869if (!(configurationService instanceof StandaloneConfigurationService)) {870return;871}872const toUpdate: [string, any][] = [];873Object.keys(source).forEach((key) => {874if (isEditorConfigurationKey(key)) {875toUpdate.push([`editor.${key}`, source[key]]);876}877if (isDiffEditor && isDiffEditorConfigurationKey(key)) {878toUpdate.push([`diffEditor.${key}`, source[key]]);879}880});881if (toUpdate.length > 0) {882configurationService.updateValues(toUpdate);883}884}885886class StandaloneBulkEditService implements IBulkEditService {887declare readonly _serviceBrand: undefined;888889constructor(890@IModelService private readonly _modelService: IModelService891) {892//893}894895hasPreviewHandler(): false {896return false;897}898899setPreviewHandler(): IDisposable {900return Disposable.None;901}902903async apply(editsIn: ResourceEdit[] | WorkspaceEdit, _options?: IBulkEditOptions): Promise<IBulkEditResult> {904const edits = Array.isArray(editsIn) ? editsIn : ResourceEdit.convert(editsIn);905const textEdits = new Map<ITextModel, ISingleEditOperation[]>();906907for (const edit of edits) {908if (!(edit instanceof ResourceTextEdit)) {909throw new Error('bad edit - only text edits are supported');910}911const model = this._modelService.getModel(edit.resource);912if (!model) {913throw new Error('bad edit - model not found');914}915if (typeof edit.versionId === 'number' && model.getVersionId() !== edit.versionId) {916throw new Error('bad state - model changed in the meantime');917}918let array = textEdits.get(model);919if (!array) {920array = [];921textEdits.set(model, array);922}923array.push(EditOperation.replaceMove(Range.lift(edit.textEdit.range), edit.textEdit.text));924}925926927let totalEdits = 0;928let totalFiles = 0;929for (const [model, edits] of textEdits) {930model.pushStackElement();931model.pushEditOperations([], edits, () => []);932model.pushStackElement();933totalFiles += 1;934totalEdits += edits.length;935}936937return {938ariaSummary: strings.format(StandaloneServicesNLS.bulkEditServiceSummary, totalEdits, totalFiles),939isApplied: totalEdits > 0940};941}942}943944class StandaloneUriLabelService implements ILabelService {945946declare readonly _serviceBrand: undefined;947948public readonly onDidChangeFormatters: Event<IFormatterChangeEvent> = Event.None;949950public getUriLabel(resource: URI, options?: { relative?: boolean; forceNoTildify?: boolean }): string {951if (resource.scheme === 'file') {952return resource.fsPath;953}954return resource.path;955}956957getUriBasenameLabel(resource: URI): string {958return basename(resource);959}960961public getWorkspaceLabel(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI | IWorkspace, options?: { verbose: Verbosity }): string {962return '';963}964965public getSeparator(scheme: string, authority?: string): '/' | '\\' {966return '/';967}968969public registerFormatter(formatter: ResourceLabelFormatter): IDisposable {970throw new Error('Not implemented');971}972973public registerCachedFormatter(formatter: ResourceLabelFormatter): IDisposable {974return this.registerFormatter(formatter);975}976977public getHostLabel(): string {978return '';979}980981public getHostTooltip(): string | undefined {982return undefined;983}984}985986987class StandaloneContextViewService extends ContextViewService {988989constructor(990@ILayoutService layoutService: ILayoutService,991@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,992) {993super(layoutService);994}995996override showContextView(delegate: IContextViewDelegate, container?: HTMLElement, shadowRoot?: boolean): IOpenContextView {997if (!container) {998const codeEditor = this._codeEditorService.getFocusedCodeEditor() || this._codeEditorService.getActiveCodeEditor();999if (codeEditor) {1000container = codeEditor.getContainerDomNode();1001}1002}1003return super.showContextView(delegate, container, shadowRoot);1004}1005}10061007class StandaloneWorkspaceTrustManagementService implements IWorkspaceTrustManagementService {1008_serviceBrand: undefined;10091010private _neverEmitter = new Emitter<never>();1011public readonly onDidChangeTrust: Event<boolean> = this._neverEmitter.event;1012onDidChangeTrustedFolders: Event<void> = this._neverEmitter.event;1013public readonly workspaceResolved = Promise.resolve();1014public readonly workspaceTrustInitialized = Promise.resolve();1015public readonly acceptsOutOfWorkspaceFiles = true;10161017isWorkspaceTrusted(): boolean {1018return true;1019}1020isWorkspaceTrustForced(): boolean {1021return false;1022}1023canSetParentFolderTrust(): boolean {1024return false;1025}1026async setParentFolderTrust(trusted: boolean): Promise<void> {1027// noop1028}1029canSetWorkspaceTrust(): boolean {1030return false;1031}1032async setWorkspaceTrust(trusted: boolean): Promise<void> {1033// noop1034}1035getUriTrustInfo(uri: URI): Promise<IWorkspaceTrustUriInfo> {1036throw new Error('Method not supported.');1037}1038async setUrisTrust(uri: URI[], trusted: boolean): Promise<void> {1039// noop1040}1041getTrustedUris(): URI[] {1042return [];1043}1044async setTrustedUris(uris: URI[]): Promise<void> {1045// noop1046}1047addWorkspaceTrustTransitionParticipant(participant: IWorkspaceTrustTransitionParticipant): IDisposable {1048throw new Error('Method not supported.');1049}1050}10511052class StandaloneLanguageService extends LanguageService {1053constructor() {1054super();1055}1056}10571058class StandaloneLogService extends LogService {1059constructor() {1060super(new ConsoleLogger());1061}1062}10631064class StandaloneContextMenuService extends ContextMenuService {1065constructor(1066@ITelemetryService telemetryService: ITelemetryService,1067@INotificationService notificationService: INotificationService,1068@IContextViewService contextViewService: IContextViewService,1069@IKeybindingService keybindingService: IKeybindingService,1070@IMenuService menuService: IMenuService,1071@IContextKeyService contextKeyService: IContextKeyService,1072) {1073super(telemetryService, notificationService, contextViewService, keybindingService, menuService, contextKeyService);1074this.configure({ blockMouse: false }); // we do not want that in the standalone editor1075}1076}10771078const standaloneEditorWorkerDescriptor: IWebWorkerDescriptor = {1079esmModuleLocation: undefined,1080label: 'editorWorkerService'1081};10821083class StandaloneEditorWorkerService extends EditorWorkerService {1084constructor(1085@IModelService modelService: IModelService,1086@ITextResourceConfigurationService configurationService: ITextResourceConfigurationService,1087@ILogService logService: ILogService,1088@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService,1089@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,1090) {1091super(standaloneEditorWorkerDescriptor, modelService, configurationService, logService, languageConfigurationService, languageFeaturesService);1092}1093}10941095class StandaloneAccessbilitySignalService implements IAccessibilitySignalService {1096_serviceBrand: undefined;1097async playSignal(cue: AccessibilitySignal, options: {}): Promise<void> {1098}10991100async playSignals(cues: AccessibilitySignal[]): Promise<void> {1101}11021103getEnabledState(signal: AccessibilitySignal, userGesture: boolean, modality?: AccessibilityModality | undefined): IValueWithChangeEvent<boolean> {1104return ValueWithChangeEvent.const(false);1105}11061107getDelayMs(signal: AccessibilitySignal, modality: AccessibilityModality): number {1108return 0;1109}11101111isSoundEnabled(cue: AccessibilitySignal): boolean {1112return false;1113}11141115isAnnouncementEnabled(cue: AccessibilitySignal): boolean {1116return false;1117}11181119onSoundEnabledChanged(cue: AccessibilitySignal): Event<void> {1120return Event.None;1121}11221123async playSound(cue: Sound, allowManyInParallel?: boolean | undefined): Promise<void> {1124}1125playSignalLoop(cue: AccessibilitySignal): IDisposable {1126return toDisposable(() => { });1127}1128}11291130export interface IEditorOverrideServices {1131[index: string]: any;1132}113311341135registerSingleton(ILogService, StandaloneLogService, InstantiationType.Eager);1136registerSingleton(IConfigurationService, StandaloneConfigurationService, InstantiationType.Eager);1137registerSingleton(ITextResourceConfigurationService, StandaloneResourceConfigurationService, InstantiationType.Eager);1138registerSingleton(ITextResourcePropertiesService, StandaloneResourcePropertiesService, InstantiationType.Eager);1139registerSingleton(IWorkspaceContextService, StandaloneWorkspaceContextService, InstantiationType.Eager);1140registerSingleton(ILabelService, StandaloneUriLabelService, InstantiationType.Eager);1141registerSingleton(ITelemetryService, StandaloneTelemetryService, InstantiationType.Eager);1142registerSingleton(IDialogService, StandaloneDialogService, InstantiationType.Eager);1143registerSingleton(IEnvironmentService, StandaloneEnvironmentService, InstantiationType.Eager);1144registerSingleton(INotificationService, StandaloneNotificationService, InstantiationType.Eager);1145registerSingleton(IMarkerService, MarkerService, InstantiationType.Eager);1146registerSingleton(ILanguageService, StandaloneLanguageService, InstantiationType.Eager);1147registerSingleton(IStandaloneThemeService, StandaloneThemeService, InstantiationType.Eager);1148registerSingleton(IModelService, ModelService, InstantiationType.Eager);1149registerSingleton(IMarkerDecorationsService, MarkerDecorationsService, InstantiationType.Eager);1150registerSingleton(IContextKeyService, ContextKeyService, InstantiationType.Eager);1151registerSingleton(IProgressService, StandaloneProgressService, InstantiationType.Eager);1152registerSingleton(IEditorProgressService, StandaloneEditorProgressService, InstantiationType.Eager);1153registerSingleton(IStorageService, InMemoryStorageService, InstantiationType.Eager);1154registerSingleton(IEditorWorkerService, StandaloneEditorWorkerService, InstantiationType.Eager);1155registerSingleton(IBulkEditService, StandaloneBulkEditService, InstantiationType.Eager);1156registerSingleton(IWorkspaceTrustManagementService, StandaloneWorkspaceTrustManagementService, InstantiationType.Eager);1157registerSingleton(ITextModelService, StandaloneTextModelService, InstantiationType.Eager);1158registerSingleton(IAccessibilityService, AccessibilityService, InstantiationType.Eager);1159registerSingleton(IListService, ListService, InstantiationType.Eager);1160registerSingleton(ICommandService, StandaloneCommandService, InstantiationType.Eager);1161registerSingleton(IKeybindingService, StandaloneKeybindingService, InstantiationType.Eager);1162registerSingleton(IQuickInputService, StandaloneQuickInputService, InstantiationType.Eager);1163registerSingleton(IContextViewService, StandaloneContextViewService, InstantiationType.Eager);1164registerSingleton(IOpenerService, OpenerService, InstantiationType.Eager);1165registerSingleton(IClipboardService, BrowserClipboardService, InstantiationType.Eager);1166registerSingleton(IContextMenuService, StandaloneContextMenuService, InstantiationType.Eager);1167registerSingleton(IMenuService, MenuService, InstantiationType.Eager);1168registerSingleton(IAccessibilitySignalService, StandaloneAccessbilitySignalService, InstantiationType.Eager);1169registerSingleton(ITreeSitterLibraryService, StandaloneTreeSitterLibraryService, InstantiationType.Eager);1170registerSingleton(ILoggerService, NullLoggerService, InstantiationType.Eager);1171registerSingleton(IDataChannelService, NullDataChannelService, InstantiationType.Eager);11721173/**1174* We don't want to eagerly instantiate services because embedders get a one time chance1175* to override services when they create the first editor.1176*/1177export module StandaloneServices {11781179const serviceCollection = new ServiceCollection();1180for (const [id, descriptor] of getSingletonServiceDescriptors()) {1181serviceCollection.set(id, descriptor);1182}11831184const instantiationService = new InstantiationService(serviceCollection, true);1185serviceCollection.set(IInstantiationService, instantiationService);11861187export function get<T>(serviceId: ServiceIdentifier<T>): T {1188if (!initialized) {1189initialize({});1190}1191const r = serviceCollection.get(serviceId);1192if (!r) {1193throw new Error('Missing service ' + serviceId);1194}1195if (r instanceof SyncDescriptor) {1196return instantiationService.invokeFunction((accessor) => accessor.get(serviceId));1197} else {1198return r;1199}1200}12011202let initialized = false;1203const onDidInitialize = new Emitter<void>();1204export function initialize(overrides: IEditorOverrideServices): IInstantiationService {1205if (initialized) {1206return instantiationService;1207}1208initialized = true;12091210// Add singletons that were registered after this module loaded1211for (const [id, descriptor] of getSingletonServiceDescriptors()) {1212if (!serviceCollection.get(id)) {1213serviceCollection.set(id, descriptor);1214}1215}12161217// Initialize the service collection with the overrides, but only if the1218// service was not instantiated in the meantime.1219for (const serviceId in overrides) {1220if (overrides.hasOwnProperty(serviceId)) {1221const serviceIdentifier = createDecorator(serviceId);1222const r = serviceCollection.get(serviceIdentifier);1223if (r instanceof SyncDescriptor) {1224serviceCollection.set(serviceIdentifier, overrides[serviceId]);1225}1226}1227}12281229// Instantiate all editor features1230const editorFeatures = getEditorFeatures();1231for (const feature of editorFeatures) {1232try {1233instantiationService.createInstance(feature);1234} catch (err) {1235onUnexpectedError(err);1236}1237}12381239onDidInitialize.fire();12401241return instantiationService;1242}12431244/**1245* Executes callback once services are initialized.1246*/1247export function withServices(callback: () => IDisposable): IDisposable {1248if (initialized) {1249return callback();1250}12511252const disposable = new DisposableStore();12531254const listener = disposable.add(onDidInitialize.event(() => {1255listener.dispose();1256disposable.add(callback());1257}));12581259return disposable;1260}12611262}126312641265