
import { registerCss } from '../../../../../../../css.js';
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import '../../services/contribution.js';
import { DragAndDropObserver, getWindow, scheduleAtNextAnimationFrame } from '../../../../base/browser/dom.js';
import { onUnexpectedError } from '../../../../base/common/errors.js';
import { createEventDeliveryQueue, Emitter } from '../../../../base/common/event.js';
import { hash } from '../../../../base/common/hash.js';
import { Disposable, dispose } from '../../../../base/common/lifecycle.js';
import { Schemas } from '../../../../base/common/network.js';
import * as editor from './editor.css';
import { applyFontInfo } from '../../config/domFontInfo.js';
import { EditorConfiguration } from '../../config/editorConfiguration.js';
import { TabFocus } from '../../config/tabFocus.js';
import { EditorExtensionsRegistry } from '../../editorExtensions.js';
import { ICodeEditorService } from '../../services/codeEditorService.service.js';
import { View } from '../../view.js';
import { DOMLineBreaksComputerFactory } from '../../view/domLineBreaksComputer.js';
import { ViewUserInputEvents } from '../../view/viewUserInputEvents.js';
import { CodeEditorContributions } from './codeEditorContributions.js';
import { EditorOption, filterValidationDecorations, filterFontDecorations } from '../../../common/config/editorOptions.js';
import { CursorColumns } from '../../../common/core/cursorColumns.js';
import { editorUnnecessaryCodeOpacity } from '../../../common/core/editorColorRegistry.js';
import { Position } from '../../../common/core/position.js';
import { Range } from '../../../common/core/range.js';
import { Selection } from '../../../common/core/selection.js';
import { WordOperations } from '../../../common/cursor/cursorWordOperations.js';
import { CursorChangeReason } from '../../../common/cursorEvents.js';
import { InternalEditorAction } from '../../../common/editorAction.js';
import { EditorType, ScrollType, Handler } from '../../../common/editorCommon.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { ILanguageConfigurationService } from '../../../common/languages/languageConfigurationRegistry.service.js';
import { EndOfLinePreference } from '../../../common/model.js';
import { ClassName } from '../../../common/model/intervalTree.js';
import { ModelDecorationOptions } from '../../../common/model/textModel.js';
import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.service.js';
import { VerticalRevealType } from '../../../common/viewEvents.js';
import { MonospaceLineBreaksComputerFactory } from '../../../common/viewModel/monospaceLineBreaksComputer.js';
import { ViewModel } from '../../../common/viewModel/viewModelImpl.js';
import { OutgoingViewModelEventKind } from '../../../common/viewModelEventDispatcher.js';
import { localize } from '../../../../nls.js';
import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.service.js';
import { ICommandService } from '../../../../platform/commands/common/commands.service.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';
import '../../../../platform/notification/common/notification.js';
import { INotificationService } from '../../../../platform/notification/common/notification.service.js';
import '../../../../platform/theme/common/colorUtils.js';
import '../../../../platform/theme/common/colors/baseColors.js';
import '../../../../platform/theme/common/colors/chartsColors.js';
import { editorErrorForeground, editorWarningForeground, editorInfoForeground, editorHintForeground } from '../../../../platform/theme/common/colors/editorColors.js';
import '../../../../platform/theme/common/colors/inputColors.js';
import '../../../../platform/theme/common/colors/listColors.js';
import '../../../../platform/theme/common/colors/menuColors.js';
import '../../../../platform/theme/common/colors/minimapColors.js';
import '../../../../platform/theme/common/colors/miscColors.js';
import '../../../../platform/theme/common/colors/quickpickColors.js';
import '../../../../platform/theme/common/colors/searchColors.js';
import { registerThemingParticipant } from '../../../../platform/theme/common/themeService.js';
import { IThemeService } from '../../../../platform/theme/common/themeService.service.js';
import { MenuId } from '../../../../platform/actions/common/actions.js';
import { TextModelEditSource, EditSources } from '../../../common/textModelEditSource.js';
import { isObject } from '../../../../base/common/types.js';
import { IUserInteractionService } from '../../../../platform/userInteraction/browser/userInteractionService.service.js';
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.service.js';
import Severity$1 from '../../../../base/common/severity.js';

var CodeEditorWidget_1;
registerCss(editor);
let CodeEditorWidget = class CodeEditorWidget extends Disposable {
    static {
        CodeEditorWidget_1 = this;
    }
    static {
        this.dropIntoEditorDecorationOptions = ModelDecorationOptions.register({
            description: "workbench-dnd-target",
            className: "dnd-target"
        });
    }
    get isSimpleWidget() {
        return this._configuration.isSimpleWidget;
    }
    get contextMenuId() {
        return this._configuration.contextMenuId;
    }
    get contextKeyService() {
        return this._contextKeyService;
    }
    constructor(
        domElement,
        _options,
        codeEditorWidgetOptions,
        instantiationService,
        codeEditorService,
        commandService,
        contextKeyService,
        themeService,
        notificationService,
        accessibilityService,
        languageConfigurationService,
        languageFeaturesService,
        userInteractionService,
        keybindingService
    ) {
        super();
        this.languageConfigurationService = languageConfigurationService;
        this.keybindingService = keybindingService;
        this._deliveryQueue = createEventDeliveryQueue();
        this._contributions = this._register(( new CodeEditorContributions()));
        this._onDidDispose = this._register(( new Emitter()));
        this.onDidDispose = this._onDidDispose.event;
        this._onDidChangeModelContent = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeModelContent = this._onDidChangeModelContent.event;
        this._onDidChangeModelLanguage = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeModelLanguage = this._onDidChangeModelLanguage.event;
        this._onDidChangeModelLanguageConfiguration = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeModelLanguageConfiguration = this._onDidChangeModelLanguageConfiguration.event;
        this._onDidChangeModelOptions = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeModelOptions = this._onDidChangeModelOptions.event;
        this._onDidChangeModelDecorations = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeModelDecorations = this._onDidChangeModelDecorations.event;
        this._onDidChangeLineHeight = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeLineHeight = this._onDidChangeLineHeight.event;
        this._onDidChangeFont = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeFont = this._onDidChangeFont.event;
        this._onDidChangeModelTokens = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeModelTokens = this._onDidChangeModelTokens.event;
        this._onDidChangeConfiguration = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeConfiguration = this._onDidChangeConfiguration.event;
        this._onWillChangeModel = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onWillChangeModel = this._onWillChangeModel.event;
        this._onDidChangeModel = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeModel = this._onDidChangeModel.event;
        this._onDidChangeCursorPosition = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeCursorPosition = this._onDidChangeCursorPosition.event;
        this._onDidChangeCursorSelection = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeCursorSelection = this._onDidChangeCursorSelection.event;
        this._onDidAttemptReadOnlyEdit = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onDidAttemptReadOnlyEdit = this._onDidAttemptReadOnlyEdit.event;
        this._onDidLayoutChange = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidLayoutChange = this._onDidLayoutChange.event;
        this._editorTextFocus = this._register(( new BooleanEventEmitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidFocusEditorText = this._editorTextFocus.onDidChangeToTrue;
        this.onDidBlurEditorText = this._editorTextFocus.onDidChangeToFalse;
        this._editorWidgetFocus = this._register(( new BooleanEventEmitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidFocusEditorWidget = this._editorWidgetFocus.onDidChangeToTrue;
        this.onDidBlurEditorWidget = this._editorWidgetFocus.onDidChangeToFalse;
        this._onWillType = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onWillType = this._onWillType.event;
        this._onDidType = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onDidType = this._onDidType.event;
        this._onDidCompositionStart = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onDidCompositionStart = this._onDidCompositionStart.event;
        this._onDidCompositionEnd = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onDidCompositionEnd = this._onDidCompositionEnd.event;
        this._onDidPaste = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onDidPaste = this._onDidPaste.event;
        this._onWillCopy = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onWillCopy = this._onWillCopy.event;
        this._onWillCut = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onWillCut = this._onWillCut.event;
        this._onWillPaste = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onWillPaste = this._onWillPaste.event;
        this._onMouseUp = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseUp = this._onMouseUp.event;
        this._onMouseDown = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseDown = this._onMouseDown.event;
        this._onMouseDrag = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseDrag = this._onMouseDrag.event;
        this._onMouseDrop = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseDrop = this._onMouseDrop.event;
        this._onMouseDropCanceled = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseDropCanceled = this._onMouseDropCanceled.event;
        this._onDropIntoEditor = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onDropIntoEditor = this._onDropIntoEditor.event;
        this._onContextMenu = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onContextMenu = this._onContextMenu.event;
        this._onMouseMove = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseMove = this._onMouseMove.event;
        this._onMouseLeave = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseLeave = this._onMouseLeave.event;
        this._onMouseWheel = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onMouseWheel = this._onMouseWheel.event;
        this._onKeyUp = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onKeyUp = this._onKeyUp.event;
        this._onKeyDown = this._register(( new InteractionEmitter(this._contributions, this._deliveryQueue)));
        this.onKeyDown = this._onKeyDown.event;
        this._onDidContentSizeChange = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidContentSizeChange = this._onDidContentSizeChange.event;
        this._onDidScrollChange = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidScrollChange = this._onDidScrollChange.event;
        this._onDidChangeViewZones = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeViewZones = this._onDidChangeViewZones.event;
        this._onDidChangeHiddenAreas = this._register(( new Emitter({
            deliveryQueue: this._deliveryQueue
        })));
        this.onDidChangeHiddenAreas = this._onDidChangeHiddenAreas.event;
        this._updateCounter = 0;
        this._onWillTriggerEditorOperationEvent = this._register(( new Emitter()));
        this.onWillTriggerEditorOperationEvent = this._onWillTriggerEditorOperationEvent.event;
        this._onBeginUpdate = this._register(( new Emitter()));
        this.onBeginUpdate = this._onBeginUpdate.event;
        this._onEndUpdate = this._register(( new Emitter()));
        this.onEndUpdate = this._onEndUpdate.event;
        this._onBeforeExecuteEdit = this._register(( new Emitter()));
        this.onBeforeExecuteEdit = this._onBeforeExecuteEdit.event;
        this._actions = ( new Map());
        this._bannerDomNode = null;
        this._dropIntoEditorDecorations = this.createDecorationsCollection();
        this.inComposition = false;
        codeEditorService.willCreateCodeEditor();
        const options = {
            ..._options
        };
        this._domElement = domElement;
        this._userInteractionService = userInteractionService;
        this._overflowWidgetsDomNode = options.overflowWidgetsDomNode;
        delete options.overflowWidgetsDomNode;
        this._id = (++EDITOR_ID);
        this._decorationTypeKeysToIds = {};
        this._decorationTypeSubtypes = {};
        this._telemetryData = codeEditorWidgetOptions.telemetryData;
        this._configuration = this._register(this._createConfiguration(
            codeEditorWidgetOptions.isSimpleWidget || false,
            codeEditorWidgetOptions.contextMenuId ?? (codeEditorWidgetOptions.isSimpleWidget ? MenuId.SimpleEditorContext : MenuId.EditorContext),
            codeEditorWidgetOptions.isStandaloneEditor || false,
            options,
            accessibilityService
        ));
        this._domElement.style?.setProperty(
            "--editor-font-size",
            this._configuration.options.get(EditorOption.fontSize) + "px"
        );
        this._register(this._configuration.onDidChange(e => {
            this._onDidChangeConfiguration.fire(e);
            const options = this._configuration.options;
            if (e.hasChanged(EditorOption.layoutInfo)) {
                const layoutInfo = options.get(EditorOption.layoutInfo);
                this._onDidLayoutChange.fire(layoutInfo);
            }
            if (e.hasChanged(EditorOption.fontSize)) {
                this._domElement.style.setProperty("--editor-font-size", options.get(EditorOption.fontSize) + "px");
            }
        }));
        this._contextKeyService = this._register(contextKeyService.createScoped(this._domElement));
        if (codeEditorWidgetOptions.contextKeyValues) {
            for (const [key, value] of Object.entries(codeEditorWidgetOptions.contextKeyValues)) {
                this._contextKeyService.createKey(key, value);
            }
        }
        this._notificationService = notificationService;
        this._codeEditorService = codeEditorService;
        this._commandService = commandService;
        this._themeService = themeService;
        this._register(( new EditorContextKeysManager(this, this._contextKeyService)));
        this._register(( new EditorModeContext(this, this._contextKeyService, languageFeaturesService)));
        this._instantiationService = this._register(instantiationService.createChild(( new ServiceCollection([IContextKeyService, this._contextKeyService]))));
        this._modelData = null;
        this._contentWidgets = {};
        this._overlayWidgets = {};
        this._glyphMarginWidgets = {};
        let contributions;
        if (Array.isArray(codeEditorWidgetOptions.contributions)) {
            contributions = codeEditorWidgetOptions.contributions;
        } else {
            contributions = EditorExtensionsRegistry.getEditorContributions();
        }
        this._contributions.initialize(this, contributions, this._instantiationService);
        for (const action of EditorExtensionsRegistry.getEditorActions()) {
            if (( this._actions.has(action.id))) {
                onUnexpectedError(( new Error(`Cannot have two actions with the same id ${action.id}`)));
                continue;
            }
            const internalAction = ( new InternalEditorAction(
                action.id,
                action.label,
                action.alias,
                action.metadata,
                action.precondition ?? undefined,
                args => {
                    return this._instantiationService.invokeFunction(accessor => {
                        return Promise.resolve(action.runEditorCommand(accessor, this, args));
                    });
                },
                this._contextKeyService
            ));
            this._actions.set(internalAction.id, internalAction);
        }
        const isDropIntoEnabled = () => {
            return !this._configuration.options.get(EditorOption.readOnly) && this._configuration.options.get(EditorOption.dropIntoEditor).enabled;
        };
        this._register(new DragAndDropObserver(this._domElement, {
            onDragOver: e => {
                if (!isDropIntoEnabled()) {
                    return;
                }
                const target = this.getTargetAtClientPoint(e.clientX, e.clientY);
                if (target?.position) {
                    this.showDropIndicatorAt(target.position);
                }
            },
            onDrop: async e => {
                if (!isDropIntoEnabled()) {
                    return;
                }
                this.removeDropIndicator();
                if (!e.dataTransfer) {
                    return;
                }
                const target = this.getTargetAtClientPoint(e.clientX, e.clientY);
                if (target?.position) {
                    this._onDropIntoEditor.fire({
                        position: target.position,
                        event: e
                    });
                }
            },
            onDragLeave: () => {
                this.removeDropIndicator();
            },
            onDragEnd: () => {
                this.removeDropIndicator();
            }
        }));
        this._codeEditorService.addCodeEditor(this);
        if (!this.getOption(EditorOption.inDiffEditor)) {
            this._register(this.keybindingService.registerContainer(this.getContainerDomNode()));
        }
    }
    writeScreenReaderContent(reason) {
        this._modelData?.view.writeScreenReaderContent(reason);
    }
    _createConfiguration(
        isSimpleWidget,
        contextMenuId,
        isStandaloneEditor,
        options,
        accessibilityService
    ) {
        return ( new EditorConfiguration(
            isSimpleWidget,
            contextMenuId,
            isStandaloneEditor,
            options,
            this._domElement,
            accessibilityService
        ));
    }
    getId() {
        return this.getEditorType() + ":" + this._id;
    }
    getEditorType() {
        return EditorType.ICodeEditor;
    }
    dispose() {
        this._codeEditorService.removeCodeEditor(this);
        this._actions.clear();
        this._contentWidgets = {};
        this._overlayWidgets = {};
        this._removeDecorationTypes();
        this._postDetachModelCleanup(this._detachModel());
        this._onDidDispose.fire();
        super.dispose();
    }
    invokeWithinContext(fn) {
        return this._instantiationService.invokeFunction(fn);
    }
    updateOptions(newOptions) {
        this._configuration.updateOptions(newOptions || {});
    }
    getOptions() {
        return this._configuration.options;
    }
    getOption(id) {
        return this._configuration.options.get(id);
    }
    getRawOptions() {
        return this._configuration.getRawOptions();
    }
    getOverflowWidgetsDomNode() {
        return this._overflowWidgetsDomNode;
    }
    getConfiguredWordAtPosition(position) {
        if (!this._modelData) {
            return null;
        }
        return WordOperations.getWordAtPosition(
            this._modelData.model,
            this._configuration.options.get(EditorOption.wordSeparators),
            this._configuration.options.get(EditorOption.wordSegmenterLocales),
            position
        );
    }
    getValue(options = null) {
        if (!this._modelData) {
            return "";
        }
        const preserveBOM = (options && options.preserveBOM) ? true : false;
        let eolPreference = EndOfLinePreference.TextDefined;
        if (options && options.lineEnding && options.lineEnding === "\n") {
            eolPreference = EndOfLinePreference.LF;
        } else if (options && options.lineEnding && options.lineEnding === "\r\n") {
            eolPreference = EndOfLinePreference.CRLF;
        }
        return this._modelData.model.getValue(eolPreference, preserveBOM);
    }
    setValue(newValue) {
        try {
            this._beginUpdate();
            if (!this._modelData) {
                return;
            }
            this._modelData.model.setValue(newValue);
        } finally {
            this._endUpdate();
        }
    }
    getModel() {
        if (!this._modelData) {
            return null;
        }
        return this._modelData.model;
    }
    setModel(_model = null) {
        try {
            this._beginUpdate();
            const model = _model;
            if (this._modelData === null && model === null) {
                return;
            }
            if (this._modelData && this._modelData.model === model) {
                return;
            }
            const e = {
                oldModelUrl: this._modelData?.model.uri || null,
                newModelUrl: model?.uri || null
            };
            this._onWillChangeModel.fire(e);
            const hasTextFocus = this.hasTextFocus();
            const detachedModel = this._detachModel();
            this._attachModel(model);
            if (this.hasModel()) {
                if (hasTextFocus) {
                    this.focus();
                }
            } else {
                this._editorTextFocus.setValue(false);
                this._editorWidgetFocus.setValue(false);
            }
            this._removeDecorationTypes();
            this._onDidChangeModel.fire(e);
            this._postDetachModelCleanup(detachedModel);
            this._contributionsDisposable = this._contributions.onAfterModelAttached();
        } finally {
            this._endUpdate();
        }
    }
    _removeDecorationTypes() {
        this._decorationTypeKeysToIds = {};
        if (this._decorationTypeSubtypes) {
            for (const decorationType in this._decorationTypeSubtypes) {
                const subTypes = this._decorationTypeSubtypes[decorationType];
                for (const subType in subTypes) {
                    this._removeDecorationType(decorationType + "-" + subType);
                }
            }
            this._decorationTypeSubtypes = {};
        }
    }
    getVisibleRanges() {
        if (!this._modelData) {
            return [];
        }
        return this._modelData.viewModel.getVisibleRanges();
    }
    getVisibleRangesPlusViewportAboveBelow() {
        if (!this._modelData) {
            return [];
        }
        return this._modelData.viewModel.getVisibleRangesPlusViewportAboveBelow();
    }
    getWhitespaces() {
        if (!this._modelData) {
            return [];
        }
        return this._modelData.viewModel.viewLayout.getWhitespaces();
    }
    static _getVerticalOffsetAfterPosition(modelData, modelLineNumber, modelColumn, includeViewZones) {
        const modelPosition = modelData.model.validatePosition({
            lineNumber: modelLineNumber,
            column: modelColumn
        });
        const viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition);
        return modelData.viewModel.viewLayout.getVerticalOffsetAfterLineNumber(viewPosition.lineNumber, includeViewZones);
    }
    getTopForLineNumber(lineNumber, includeViewZones = false) {
        if (!this._modelData) {
            return -1;
        }
        return CodeEditorWidget_1._getVerticalOffsetForPosition(this._modelData, lineNumber, 1, includeViewZones);
    }
    getTopForPosition(lineNumber, column) {
        if (!this._modelData) {
            return -1;
        }
        return CodeEditorWidget_1._getVerticalOffsetForPosition(this._modelData, lineNumber, column, false);
    }
    static _getVerticalOffsetForPosition(modelData, modelLineNumber, modelColumn, includeViewZones = false) {
        const modelPosition = modelData.model.validatePosition({
            lineNumber: modelLineNumber,
            column: modelColumn
        });
        const viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition);
        return modelData.viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber, includeViewZones);
    }
    getBottomForLineNumber(lineNumber, includeViewZones = false) {
        if (!this._modelData) {
            return -1;
        }
        return CodeEditorWidget_1._getVerticalOffsetAfterPosition(this._modelData, lineNumber, Number.MAX_SAFE_INTEGER, includeViewZones);
    }
    getLineHeightForPosition(position) {
        if (!this._modelData) {
            return -1;
        }
        const viewModel = this._modelData.viewModel;
        const coordinatesConverter = viewModel.coordinatesConverter;
        const pos = Position.lift(position);
        if (coordinatesConverter.modelPositionIsVisible(pos)) {
            const viewPosition = coordinatesConverter.convertModelPositionToViewPosition(pos);
            return viewModel.viewLayout.getLineHeightForLineNumber(viewPosition.lineNumber);
        }
        return 0;
    }
    setHiddenAreas(ranges, source, forceUpdate) {
        this._modelData?.viewModel.setHiddenAreas(( ranges.map(r => Range.lift(r))), source, forceUpdate);
    }
    getVisibleColumnFromPosition(rawPosition) {
        if (!this._modelData) {
            return rawPosition.column;
        }
        const position = this._modelData.model.validatePosition(rawPosition);
        const tabSize = this._modelData.model.getOptions().tabSize;
        return CursorColumns.visibleColumnFromColumn(
            this._modelData.model.getLineContent(position.lineNumber),
            position.column,
            tabSize
        ) + 1;
    }
    getStatusbarColumn(rawPosition) {
        if (!this._modelData) {
            return rawPosition.column;
        }
        const position = this._modelData.model.validatePosition(rawPosition);
        const tabSize = this._modelData.model.getOptions().tabSize;
        return CursorColumns.toStatusbarColumn(
            this._modelData.model.getLineContent(position.lineNumber),
            position.column,
            tabSize
        );
    }
    getPosition() {
        if (!this._modelData) {
            return null;
        }
        return this._modelData.viewModel.getPosition();
    }
    setPosition(position, source = "api") {
        if (!this._modelData) {
            return;
        }
        if (!Position.isIPosition(position)) {
            throw ( new Error("Invalid arguments"));
        }
        this._modelData.viewModel.setSelections(source, [{
            selectionStartLineNumber: position.lineNumber,
            selectionStartColumn: position.column,
            positionLineNumber: position.lineNumber,
            positionColumn: position.column
        }]);
    }
    _sendRevealRange(modelRange, verticalType, revealHorizontal, scrollType) {
        if (!this._modelData) {
            return;
        }
        if (!Range.isIRange(modelRange)) {
            throw ( new Error("Invalid arguments"));
        }
        const validatedModelRange = this._modelData.model.validateRange(modelRange);
        const viewRange = this._modelData.viewModel.coordinatesConverter.convertModelRangeToViewRange(validatedModelRange);
        this._modelData.viewModel.revealRange("api", revealHorizontal, viewRange, verticalType, scrollType);
    }
    revealAllCursors(revealHorizontal, minimalReveal) {
        if (!this._modelData) {
            return;
        }
        this._modelData.viewModel.revealAllCursors("api", revealHorizontal, minimalReveal);
    }
    revealLine(lineNumber, scrollType = ScrollType.Smooth) {
        this._revealLine(lineNumber, VerticalRevealType.Simple, scrollType);
    }
    revealLineInCenter(lineNumber, scrollType = ScrollType.Smooth) {
        this._revealLine(lineNumber, VerticalRevealType.Center, scrollType);
    }
    revealLineInCenterIfOutsideViewport(lineNumber, scrollType = ScrollType.Smooth) {
        this._revealLine(lineNumber, VerticalRevealType.CenterIfOutsideViewport, scrollType);
    }
    revealLineNearTop(lineNumber, scrollType = ScrollType.Smooth) {
        this._revealLine(lineNumber, VerticalRevealType.NearTop, scrollType);
    }
    _revealLine(lineNumber, revealType, scrollType) {
        if (typeof lineNumber !== "number") {
            throw ( new Error("Invalid arguments"));
        }
        this._sendRevealRange(( new Range(lineNumber, 1, lineNumber, 1)), revealType, false, scrollType);
    }
    revealPosition(position, scrollType = ScrollType.Smooth) {
        this._revealPosition(position, VerticalRevealType.Simple, true, scrollType);
    }
    revealPositionInCenter(position, scrollType = ScrollType.Smooth) {
        this._revealPosition(position, VerticalRevealType.Center, true, scrollType);
    }
    revealPositionInCenterIfOutsideViewport(position, scrollType = ScrollType.Smooth) {
        this._revealPosition(position, VerticalRevealType.CenterIfOutsideViewport, true, scrollType);
    }
    revealPositionNearTop(position, scrollType = ScrollType.Smooth) {
        this._revealPosition(position, VerticalRevealType.NearTop, true, scrollType);
    }
    _revealPosition(position, verticalType, revealHorizontal, scrollType) {
        if (!Position.isIPosition(position)) {
            throw ( new Error("Invalid arguments"));
        }
        this._sendRevealRange(( new Range(position.lineNumber, position.column, position.lineNumber, position.column)), verticalType, revealHorizontal, scrollType);
    }
    getSelection() {
        if (!this._modelData) {
            return null;
        }
        return this._modelData.viewModel.getSelection();
    }
    getSelections() {
        if (!this._modelData) {
            return null;
        }
        return this._modelData.viewModel.getSelections();
    }
    setSelection(something, source = "api") {
        const isSelection = Selection.isISelection(something);
        const isRange = Range.isIRange(something);
        if (!isSelection && !isRange) {
            throw ( new Error("Invalid arguments"));
        }
        if (isSelection) {
            this._setSelectionImpl(something, source);
        } else if (isRange) {
            const selection = {
                selectionStartLineNumber: something.startLineNumber,
                selectionStartColumn: something.startColumn,
                positionLineNumber: something.endLineNumber,
                positionColumn: something.endColumn
            };
            this._setSelectionImpl(selection, source);
        }
    }
    _setSelectionImpl(sel, source) {
        if (!this._modelData) {
            return;
        }
        const selection = ( new Selection(
            sel.selectionStartLineNumber,
            sel.selectionStartColumn,
            sel.positionLineNumber,
            sel.positionColumn
        ));
        this._modelData.viewModel.setSelections(source, [selection]);
    }
    revealLines(
        startLineNumber,
        endLineNumber,
        scrollType = ScrollType.Smooth
    ) {
        this._revealLines(startLineNumber, endLineNumber, VerticalRevealType.Simple, scrollType);
    }
    revealLinesInCenter(
        startLineNumber,
        endLineNumber,
        scrollType = ScrollType.Smooth
    ) {
        this._revealLines(startLineNumber, endLineNumber, VerticalRevealType.Center, scrollType);
    }
    revealLinesInCenterIfOutsideViewport(
        startLineNumber,
        endLineNumber,
        scrollType = ScrollType.Smooth
    ) {
        this._revealLines(
            startLineNumber,
            endLineNumber,
            VerticalRevealType.CenterIfOutsideViewport,
            scrollType
        );
    }
    revealLinesNearTop(
        startLineNumber,
        endLineNumber,
        scrollType = ScrollType.Smooth
    ) {
        this._revealLines(startLineNumber, endLineNumber, VerticalRevealType.NearTop, scrollType);
    }
    _revealLines(startLineNumber, endLineNumber, verticalType, scrollType) {
        if (typeof startLineNumber !== "number" || typeof endLineNumber !== "number") {
            throw ( new Error("Invalid arguments"));
        }
        this._sendRevealRange(( new Range(startLineNumber, 1, endLineNumber, 1)), verticalType, false, scrollType);
    }
    revealRange(
        range,
        scrollType = ScrollType.Smooth,
        revealVerticalInCenter = false,
        revealHorizontal = true
    ) {
        this._revealRange(
            range,
            revealVerticalInCenter ? VerticalRevealType.Center : VerticalRevealType.Simple,
            revealHorizontal,
            scrollType
        );
    }
    revealRangeInCenter(range, scrollType = ScrollType.Smooth) {
        this._revealRange(range, VerticalRevealType.Center, true, scrollType);
    }
    revealRangeInCenterIfOutsideViewport(range, scrollType = ScrollType.Smooth) {
        this._revealRange(range, VerticalRevealType.CenterIfOutsideViewport, true, scrollType);
    }
    revealRangeNearTop(range, scrollType = ScrollType.Smooth) {
        this._revealRange(range, VerticalRevealType.NearTop, true, scrollType);
    }
    revealRangeNearTopIfOutsideViewport(range, scrollType = ScrollType.Smooth) {
        this._revealRange(range, VerticalRevealType.NearTopIfOutsideViewport, true, scrollType);
    }
    revealRangeAtTop(range, scrollType = ScrollType.Smooth) {
        this._revealRange(range, VerticalRevealType.Top, true, scrollType);
    }
    _revealRange(range, verticalType, revealHorizontal, scrollType) {
        if (!Range.isIRange(range)) {
            throw ( new Error("Invalid arguments"));
        }
        this._sendRevealRange(Range.lift(range), verticalType, revealHorizontal, scrollType);
    }
    setSelections(ranges, source = "api", reason = CursorChangeReason.NotSet) {
        if (!this._modelData) {
            return;
        }
        if (!ranges || ranges.length === 0) {
            throw ( new Error("Invalid arguments"));
        }
        for (let i = 0, len = ranges.length; i < len; i++) {
            if (!Selection.isISelection(ranges[i])) {
                throw ( new Error("Invalid arguments"));
            }
        }
        this._modelData.viewModel.setSelections(source, ranges, reason);
    }
    getContentWidth() {
        if (!this._modelData) {
            return -1;
        }
        return this._modelData.viewModel.viewLayout.getContentWidth();
    }
    getScrollWidth() {
        if (!this._modelData) {
            return -1;
        }
        return this._modelData.viewModel.viewLayout.getScrollWidth();
    }
    getScrollLeft() {
        if (!this._modelData) {
            return -1;
        }
        return this._modelData.viewModel.viewLayout.getCurrentScrollLeft();
    }
    getContentHeight() {
        if (!this._modelData) {
            return -1;
        }
        return this._modelData.viewModel.viewLayout.getContentHeight();
    }
    getScrollHeight() {
        if (!this._modelData) {
            return -1;
        }
        return this._modelData.viewModel.viewLayout.getScrollHeight();
    }
    getScrollTop() {
        if (!this._modelData) {
            return -1;
        }
        return this._modelData.viewModel.viewLayout.getCurrentScrollTop();
    }
    setScrollLeft(newScrollLeft, scrollType = ScrollType.Immediate) {
        if (!this._modelData) {
            return;
        }
        if (typeof newScrollLeft !== "number") {
            throw ( new Error("Invalid arguments"));
        }
        this._modelData.viewModel.viewLayout.setScrollPosition({
            scrollLeft: newScrollLeft
        }, scrollType);
    }
    setScrollTop(newScrollTop, scrollType = ScrollType.Immediate) {
        if (!this._modelData) {
            return;
        }
        if (typeof newScrollTop !== "number") {
            throw ( new Error("Invalid arguments"));
        }
        this._modelData.viewModel.viewLayout.setScrollPosition({
            scrollTop: newScrollTop
        }, scrollType);
    }
    setScrollPosition(position, scrollType = ScrollType.Immediate) {
        if (!this._modelData) {
            return;
        }
        this._modelData.viewModel.viewLayout.setScrollPosition(position, scrollType);
    }
    hasPendingScrollAnimation() {
        if (!this._modelData) {
            return false;
        }
        return this._modelData.viewModel.viewLayout.hasPendingScrollAnimation();
    }
    saveViewState() {
        if (!this._modelData) {
            return null;
        }
        const contributionsState = this._contributions.saveViewState();
        const cursorState = this._modelData.viewModel.saveCursorState();
        const viewState = this._modelData.viewModel.saveState();
        return {
            cursorState: cursorState,
            viewState: viewState,
            contributionsState: contributionsState
        };
    }
    restoreViewState(s) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        const codeEditorState = s;
        if (codeEditorState && codeEditorState.cursorState && codeEditorState.viewState) {
            const cursorState = codeEditorState.cursorState;
            if (Array.isArray(cursorState)) {
                if (cursorState.length > 0) {
                    this._modelData.viewModel.restoreCursorState(cursorState);
                }
            } else {
                this._modelData.viewModel.restoreCursorState([cursorState]);
            }
            this._contributions.restoreViewState(codeEditorState.contributionsState || {});
            const reducedState = this._modelData.viewModel.reduceRestoreState(codeEditorState.viewState);
            this._modelData.view.restoreState(reducedState);
        }
    }
    handleInitialized() {
        this._getViewModel()?.visibleLinesStabilized();
    }
    onVisible() {
        this._modelData?.view.refreshFocusState();
    }
    onHide() {
        this._modelData?.view.refreshFocusState();
    }
    getContribution(id) {
        return this._contributions.get(id);
    }
    getActions() {
        return Array.from(( this._actions.values()));
    }
    getSupportedActions() {
        let result = this.getActions();
        result = result.filter(action => action.isSupported());
        return result;
    }
    getAction(id) {
        return this._actions.get(id) || null;
    }
    trigger(source, handlerId, payload) {
        payload = payload || {};
        try {
            this._onWillTriggerEditorOperationEvent.fire({
                source: source,
                handlerId: handlerId,
                payload: payload
            });
            this._beginUpdate();
            switch (handlerId) {
            case Handler.CompositionStart:
                this._startComposition();
                return;
            case Handler.CompositionEnd:
                this._endComposition(source);
                return;
            case Handler.Type:
                {
                    const args = payload;
                    this._type(source, args.text || "");
                    return;
                }
            case Handler.ReplacePreviousChar:
                {
                    const args = payload;
                    this._compositionType(source, args.text || "", args.replaceCharCnt || 0, 0, 0);
                    return;
                }
            case Handler.CompositionType:
                {
                    const args = payload;
                    this._compositionType(
                        source,
                        args.text || "",
                        args.replacePrevCharCnt || 0,
                        args.replaceNextCharCnt || 0,
                        args.positionDelta || 0
                    );
                    return;
                }
            case Handler.Paste:
                {
                    const args = payload;
                    this._paste(
                        source,
                        args.text || "",
                        args.pasteOnNewLine || false,
                        args.multicursorText || null,
                        args.mode || null,
                        args.clipboardEvent
                    );
                    return;
                }
            case Handler.Cut:
                this._cut(source);
                return;
            }
            const action = this.getAction(handlerId);
            if (action) {
                Promise.resolve(action.run(payload)).then(undefined, onUnexpectedError);
                return;
            }
            if (!this._modelData) {
                return;
            }
            if (this._triggerEditorCommand(source, handlerId, payload)) {
                return;
            }
            this._triggerCommand(handlerId, payload);
        } finally {
            this._endUpdate();
        }
    }
    _triggerCommand(handlerId, payload) {
        this._commandService.executeCommand(handlerId, payload);
    }
    _startComposition() {
        if (!this._modelData) {
            return;
        }
        this.inComposition = true;
        this._modelData.viewModel.startComposition();
        this._onDidCompositionStart.fire();
    }
    _endComposition(source) {
        if (!this._modelData) {
            return;
        }
        this.inComposition = false;
        this._modelData.viewModel.endComposition(source);
        this._onDidCompositionEnd.fire();
    }
    _type(source, text) {
        if (!this._modelData || text.length === 0) {
            return;
        }
        if (source === "keyboard") {
            this._onWillType.fire(text);
        }
        this._modelData.viewModel.type(text, source);
        if (source === "keyboard") {
            this._onDidType.fire(text);
        }
    }
    _compositionType(source, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta) {
        if (!this._modelData) {
            return;
        }
        this._modelData.viewModel.compositionType(text, replacePrevCharCnt, replaceNextCharCnt, positionDelta, source);
    }
    _paste(source, text, pasteOnNewLine, multicursorText, mode, clipboardEvent) {
        if (!this._modelData) {
            return;
        }
        const viewModel = this._modelData.viewModel;
        const startPosition = viewModel.getSelection().getStartPosition();
        viewModel.paste(text, pasteOnNewLine, multicursorText, source);
        const endPosition = viewModel.getSelection().getStartPosition();
        if (source === "keyboard") {
            this._onDidPaste.fire({
                clipboardEvent,
                range: ( new Range(
                    startPosition.lineNumber,
                    startPosition.column,
                    endPosition.lineNumber,
                    endPosition.column
                )),
                languageId: mode
            });
        }
    }
    _cut(source) {
        if (!this._modelData) {
            return;
        }
        this._modelData.viewModel.cut(source);
    }
    _triggerEditorCommand(source, handlerId, payload) {
        const command = EditorExtensionsRegistry.getEditorCommand(handlerId);
        if (command) {
            payload = payload || {};
            if (isObject(payload)) {
                payload.source = source;
            }
            this._instantiationService.invokeFunction(accessor => {
                Promise.resolve(command.runEditorCommand(accessor, this, payload)).then(undefined, onUnexpectedError);
            });
            return true;
        }
        return false;
    }
    _getViewModel() {
        if (!this._modelData) {
            return null;
        }
        return this._modelData.viewModel;
    }
    pushUndoStop() {
        if (!this._modelData) {
            return false;
        }
        if (this._configuration.options.get(EditorOption.readOnly)) {
            return false;
        }
        this._modelData.model.pushStackElement();
        return true;
    }
    popUndoStop() {
        if (!this._modelData) {
            return false;
        }
        if (this._configuration.options.get(EditorOption.readOnly)) {
            return false;
        }
        this._modelData.model.popStackElement();
        return true;
    }
    edit(edit, reason) {
        return this.executeEdits(reason, ( edit.replacements.map(e => ({
            range: e.range,
            text: e.text
        }))), undefined);
    }
    executeEdits(source, edits, endCursorState) {
        if (!this._modelData) {
            return false;
        }
        if (this._configuration.options.get(EditorOption.readOnly)) {
            return false;
        }
        let cursorStateComputer;
        if (!endCursorState) {
            cursorStateComputer = () => null;
        } else if (Array.isArray(endCursorState)) {
            cursorStateComputer = () => endCursorState;
        } else {
            cursorStateComputer = endCursorState;
        }
        let sourceStr;
        let reason;
        if (source instanceof TextModelEditSource) {
            reason = source;
            sourceStr = source.metadata.source;
        } else {
            reason = EditSources.unknown({
                name: source
            });
            sourceStr = source;
        }
        this._onBeforeExecuteEdit.fire({
            source: sourceStr ?? undefined
        });
        this._modelData.viewModel.executeEdits(sourceStr, edits, cursorStateComputer, reason);
        return true;
    }
    executeCommand(source, command) {
        if (!this._modelData) {
            return;
        }
        this._modelData.viewModel.executeCommand(command, source);
    }
    executeCommands(source, commands) {
        if (!this._modelData) {
            return;
        }
        this._modelData.viewModel.executeCommands(commands, source);
    }
    createDecorationsCollection(decorations) {
        return ( new EditorDecorationsCollection(this, decorations));
    }
    changeDecorations(callback) {
        if (!this._modelData) {
            return null;
        }
        return this._modelData.model.changeDecorations(callback, this._id);
    }
    getLineDecorations(lineNumber) {
        if (!this._modelData) {
            return null;
        }
        const options = this._configuration.options;
        return this._modelData.model.getLineDecorations(
            lineNumber,
            this._id,
            filterValidationDecorations(options),
            filterFontDecorations(options)
        );
    }
    getDecorationsInRange(range) {
        if (!this._modelData) {
            return null;
        }
        const options = this._configuration.options;
        return this._modelData.model.getDecorationsInRange(
            range,
            this._id,
            filterValidationDecorations(options),
            filterFontDecorations(options)
        );
    }
    getFontSizeAtPosition(position) {
        if (!this._modelData) {
            return null;
        }
        return this._modelData.viewModel.getFontSizeAtPosition(position);
    }
    deltaDecorations(oldDecorations, newDecorations) {
        if (!this._modelData) {
            return [];
        }
        if (oldDecorations.length === 0 && newDecorations.length === 0) {
            return oldDecorations;
        }
        return this._modelData.model.deltaDecorations(oldDecorations, newDecorations, this._id);
    }
    removeDecorations(decorationIds) {
        if (!this._modelData || decorationIds.length === 0) {
            return;
        }
        this._modelData.model.changeDecorations(changeAccessor => {
            changeAccessor.deltaDecorations(decorationIds, []);
        });
    }
    setDecorationsByType(description, decorationTypeKey, decorationOptions) {
        const newDecorationsSubTypes = {};
        const oldDecorationsSubTypes = this._decorationTypeSubtypes[decorationTypeKey] || {};
        this._decorationTypeSubtypes[decorationTypeKey] = newDecorationsSubTypes;
        const newModelDecorations = [];
        for (const decorationOption of decorationOptions) {
            let typeKey = decorationTypeKey;
            if (decorationOption.renderOptions) {
                const subType = ( hash(decorationOption.renderOptions).toString(16));
                typeKey = decorationTypeKey + "-" + subType;
                if (!oldDecorationsSubTypes[subType] && !newDecorationsSubTypes[subType]) {
                    this._registerDecorationType(description, typeKey, decorationOption.renderOptions, decorationTypeKey);
                }
                newDecorationsSubTypes[subType] = true;
            }
            const opts = this._resolveDecorationOptions(typeKey, !!decorationOption.hoverMessage);
            if (decorationOption.hoverMessage) {
                opts.hoverMessage = decorationOption.hoverMessage;
            }
            newModelDecorations.push({
                range: decorationOption.range,
                options: opts
            });
        }
        for (const subType in oldDecorationsSubTypes) {
            if (!newDecorationsSubTypes[subType]) {
                this._removeDecorationType(decorationTypeKey + "-" + subType);
            }
        }
        const oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey] || [];
        this.changeDecorations(
            accessor => this._decorationTypeKeysToIds[decorationTypeKey] = accessor.deltaDecorations(oldDecorationsIds, newModelDecorations)
        );
        return this._decorationTypeKeysToIds[decorationTypeKey] || [];
    }
    setDecorationsByTypeFast(decorationTypeKey, ranges) {
        const oldDecorationsSubTypes = this._decorationTypeSubtypes[decorationTypeKey] || {};
        for (const subType in oldDecorationsSubTypes) {
            this._removeDecorationType(decorationTypeKey + "-" + subType);
        }
        this._decorationTypeSubtypes[decorationTypeKey] = {};
        const opts = ModelDecorationOptions.createDynamic(this._resolveDecorationOptions(decorationTypeKey, false));
        const newModelDecorations = ( new Array(ranges.length));
        for (let i = 0, len = ranges.length; i < len; i++) {
            newModelDecorations[i] = {
                range: ranges[i],
                options: opts
            };
        }
        const oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey] || [];
        this.changeDecorations(
            accessor => this._decorationTypeKeysToIds[decorationTypeKey] = accessor.deltaDecorations(oldDecorationsIds, newModelDecorations)
        );
    }
    removeDecorationsByType(decorationTypeKey) {
        const oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey];
        if (oldDecorationsIds) {
            this.changeDecorations(accessor => accessor.deltaDecorations(oldDecorationsIds, []));
        }
        if (this._decorationTypeKeysToIds.hasOwnProperty(decorationTypeKey)) {
            delete this._decorationTypeKeysToIds[decorationTypeKey];
        }
        if (this._decorationTypeSubtypes.hasOwnProperty(decorationTypeKey)) {
            const items = this._decorationTypeSubtypes[decorationTypeKey];
            for (const subType of ( Object.keys(items))) {
                this._removeDecorationType(decorationTypeKey + "-" + subType);
            }
            delete this._decorationTypeSubtypes[decorationTypeKey];
        }
    }
    getLayoutInfo() {
        const options = this._configuration.options;
        const layoutInfo = options.get(EditorOption.layoutInfo);
        return layoutInfo;
    }
    createOverviewRuler(cssClassName) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return null;
        }
        return this._modelData.view.createOverviewRuler(cssClassName);
    }
    getContainerDomNode() {
        return this._domElement;
    }
    getDomNode() {
        if (!this._modelData || !this._modelData.hasRealView) {
            return null;
        }
        return this._modelData.view.domNode.domNode;
    }
    delegateVerticalScrollbarPointerDown(browserEvent) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.view.delegateVerticalScrollbarPointerDown(browserEvent);
    }
    delegateScrollFromMouseWheelEvent(browserEvent) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.view.delegateScrollFromMouseWheelEvent(browserEvent);
    }
    layout(dimension, postponeRendering = false) {
        this._configuration.observeContainer(dimension);
        if (!postponeRendering) {
            this.render();
        }
    }
    focus() {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.view.focus();
    }
    hasTextFocus() {
        if (!this._modelData || !this._modelData.hasRealView) {
            return false;
        }
        return this._modelData.view.isFocused();
    }
    hasWidgetFocus() {
        if (!this._modelData || !this._modelData.hasRealView) {
            return false;
        }
        return this._modelData.view.isWidgetFocused();
    }
    addContentWidget(widget) {
        const widgetData = {
            widget: widget,
            position: widget.getPosition()
        };
        if (this._contentWidgets.hasOwnProperty(widget.getId())) {
            console.warn("Overwriting a content widget with the same id:" + widget.getId());
        }
        this._contentWidgets[widget.getId()] = widgetData;
        if (this._modelData && this._modelData.hasRealView) {
            this._modelData.view.addContentWidget(widgetData);
        }
    }
    layoutContentWidget(widget) {
        const widgetId = widget.getId();
        if (this._contentWidgets.hasOwnProperty(widgetId)) {
            const widgetData = this._contentWidgets[widgetId];
            widgetData.position = widget.getPosition();
            if (this._modelData && this._modelData.hasRealView) {
                this._modelData.view.layoutContentWidget(widgetData);
            }
        }
    }
    removeContentWidget(widget) {
        const widgetId = widget.getId();
        if (this._contentWidgets.hasOwnProperty(widgetId)) {
            const widgetData = this._contentWidgets[widgetId];
            delete this._contentWidgets[widgetId];
            if (this._modelData && this._modelData.hasRealView) {
                this._modelData.view.removeContentWidget(widgetData);
            }
        }
    }
    addOverlayWidget(widget) {
        const widgetData = {
            widget: widget,
            position: widget.getPosition()
        };
        if (this._overlayWidgets.hasOwnProperty(widget.getId())) {
            console.warn("Overwriting an overlay widget with the same id.");
        }
        this._overlayWidgets[widget.getId()] = widgetData;
        if (this._modelData && this._modelData.hasRealView) {
            this._modelData.view.addOverlayWidget(widgetData);
        }
    }
    layoutOverlayWidget(widget) {
        const widgetId = widget.getId();
        if (this._overlayWidgets.hasOwnProperty(widgetId)) {
            const widgetData = this._overlayWidgets[widgetId];
            widgetData.position = widget.getPosition();
            if (this._modelData && this._modelData.hasRealView) {
                this._modelData.view.layoutOverlayWidget(widgetData);
            }
        }
    }
    removeOverlayWidget(widget) {
        const widgetId = widget.getId();
        if (this._overlayWidgets.hasOwnProperty(widgetId)) {
            const widgetData = this._overlayWidgets[widgetId];
            delete this._overlayWidgets[widgetId];
            if (this._modelData && this._modelData.hasRealView) {
                this._modelData.view.removeOverlayWidget(widgetData);
            }
        }
    }
    addGlyphMarginWidget(widget) {
        const widgetData = {
            widget: widget,
            position: widget.getPosition()
        };
        if (this._glyphMarginWidgets.hasOwnProperty(widget.getId())) {
            console.warn("Overwriting a glyph margin widget with the same id.");
        }
        this._glyphMarginWidgets[widget.getId()] = widgetData;
        if (this._modelData && this._modelData.hasRealView) {
            this._modelData.view.addGlyphMarginWidget(widgetData);
        }
    }
    layoutGlyphMarginWidget(widget) {
        const widgetId = widget.getId();
        if (this._glyphMarginWidgets.hasOwnProperty(widgetId)) {
            const widgetData = this._glyphMarginWidgets[widgetId];
            widgetData.position = widget.getPosition();
            if (this._modelData && this._modelData.hasRealView) {
                this._modelData.view.layoutGlyphMarginWidget(widgetData);
            }
        }
    }
    removeGlyphMarginWidget(widget) {
        const widgetId = widget.getId();
        if (this._glyphMarginWidgets.hasOwnProperty(widgetId)) {
            const widgetData = this._glyphMarginWidgets[widgetId];
            delete this._glyphMarginWidgets[widgetId];
            if (this._modelData && this._modelData.hasRealView) {
                this._modelData.view.removeGlyphMarginWidget(widgetData);
            }
        }
    }
    changeViewZones(callback) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.view.change(callback);
    }
    getTargetAtClientPoint(clientX, clientY) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return null;
        }
        return this._modelData.view.getTargetAtClientPoint(clientX, clientY);
    }
    getScrolledVisiblePosition(rawPosition) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return null;
        }
        const position = this._modelData.model.validatePosition(rawPosition);
        const options = this._configuration.options;
        const layoutInfo = options.get(EditorOption.layoutInfo);
        const top = CodeEditorWidget_1._getVerticalOffsetForPosition(this._modelData, position.lineNumber, position.column) - this.getScrollTop();
        const left = this._modelData.view.getOffsetForColumn(position.lineNumber, position.column) + layoutInfo.glyphMarginWidth + layoutInfo.lineNumbersWidth + layoutInfo.decorationsWidth - this.getScrollLeft();
        const height = this.getLineHeightForPosition(position);
        return {
            top: top,
            left: left,
            height
        };
    }
    getOffsetForColumn(lineNumber, column) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return -1;
        }
        return this._modelData.view.getOffsetForColumn(lineNumber, column);
    }
    getWidthOfLine(lineNumber) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return -1;
        }
        return this._modelData.view.getLineWidth(lineNumber);
    }
    resetLineWidthCaches() {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.view.resetLineWidthCaches();
    }
    render(forceRedraw = false) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.viewModel.batchEvents(() => {
            this._modelData.view.render(true, forceRedraw);
        });
    }
    renderAsync(forceRedraw = false) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.viewModel.batchEvents(() => {
            this._modelData.view.render(false, forceRedraw);
        });
    }
    setAriaOptions(options) {
        if (!this._modelData || !this._modelData.hasRealView) {
            return;
        }
        this._modelData.view.setAriaOptions(options);
    }
    applyFontInfo(target) {
        applyFontInfo(target, this._configuration.options.get(EditorOption.fontInfo));
    }
    setBanner(domNode, domNodeHeight) {
        if (this._bannerDomNode && this._domElement.contains(this._bannerDomNode)) {
            this._bannerDomNode.remove();
        }
        this._bannerDomNode = domNode;
        this._configuration.setReservedHeight(domNode ? domNodeHeight : 0);
        if (this._bannerDomNode) {
            this._domElement.prepend(this._bannerDomNode);
        }
    }
    _attachModel(model) {
        if (!model) {
            this._modelData = null;
            return;
        }
        const listenersToRemove = [];
        this._domElement.setAttribute("data-mode-id", model.getLanguageId());
        this._configuration.setIsDominatedByLongLines(model.isDominatedByLongLines());
        this._configuration.setModelLineCount(model.getLineCount());
        const attachedView = model.onBeforeAttached();
        const viewModel = ( new ViewModel(
            this._id,
            this._configuration,
            model,
            DOMLineBreaksComputerFactory.create(getWindow(this._domElement)),
            MonospaceLineBreaksComputerFactory.create(this._configuration.options),
            callback => scheduleAtNextAnimationFrame(getWindow(this._domElement), callback),
            this.languageConfigurationService,
            this._themeService,
            attachedView,
            {
                batchChanges: cb => {
                    try {
                        this._beginUpdate();
                        return cb();
                    } finally {
                        this._endUpdate();
                    }
                }
            }
        ));
        listenersToRemove.push(model.onWillDispose(() => this.setModel(null)));
        listenersToRemove.push(viewModel.onEvent(e => {
            switch (e.kind) {
            case OutgoingViewModelEventKind.ContentSizeChanged:
                this._onDidContentSizeChange.fire(e);
                break;
            case OutgoingViewModelEventKind.FocusChanged:
                this._editorTextFocus.setValue(e.hasFocus);
                break;
            case OutgoingViewModelEventKind.WidgetFocusChanged:
                this._editorWidgetFocus.setValue(e.hasFocus);
                break;
            case OutgoingViewModelEventKind.ScrollChanged:
                this._onDidScrollChange.fire(e);
                break;
            case OutgoingViewModelEventKind.ViewZonesChanged:
                this._onDidChangeViewZones.fire();
                break;
            case OutgoingViewModelEventKind.HiddenAreasChanged:
                this._onDidChangeHiddenAreas.fire();
                break;
            case OutgoingViewModelEventKind.ReadOnlyEditAttempt:
                this._onDidAttemptReadOnlyEdit.fire();
                break;
            case OutgoingViewModelEventKind.CursorStateChanged:
                {
                    if (e.reachedMaxCursorCount) {
                        const multiCursorLimit = this.getOption(EditorOption.multiCursorLimit);
                        const message = ( localize(
                            177,
                            "The number of cursors has been limited to {0}. Consider using [find and replace](https://code.visualstudio.com/docs/editor/codebasics#_find-and-replace) for larger changes or increase the editor multi cursor limit setting.",
                            multiCursorLimit
                        ));
                        this._notificationService.prompt(Severity$1.Warning, message, [{
                            label: "Find and Replace",
                            run: () => {
                                this._commandService.executeCommand("editor.action.startFindReplaceAction");
                            }
                        }, {
                            label: ( localize(178, "Increase Multi Cursor Limit")),
                            run: () => {
                                this._commandService.executeCommand("workbench.action.openSettings2", {
                                    query: "editor.multiCursorLimit"
                                });
                            }
                        }]);
                    }
                    const positions = [];
                    for (let i = 0, len = e.selections.length; i < len; i++) {
                        positions[i] = e.selections[i].getPosition();
                    }
                    const e1 = {
                        position: positions[0],
                        secondaryPositions: positions.slice(1),
                        reason: e.reason,
                        source: e.source
                    };
                    this._onDidChangeCursorPosition.fire(e1);
                    const e2 = {
                        selection: e.selections[0],
                        secondarySelections: e.selections.slice(1),
                        modelVersionId: e.modelVersionId,
                        oldSelections: e.oldSelections,
                        oldModelVersionId: e.oldModelVersionId,
                        source: e.source,
                        reason: e.reason
                    };
                    this._onDidChangeCursorSelection.fire(e2);
                    break;
                }
            case OutgoingViewModelEventKind.ModelDecorationsChanged:
                this._onDidChangeModelDecorations.fire(e.event);
                break;
            case OutgoingViewModelEventKind.ModelLanguageChanged:
                this._domElement.setAttribute("data-mode-id", model.getLanguageId());
                this._onDidChangeModelLanguage.fire(e.event);
                break;
            case OutgoingViewModelEventKind.ModelLanguageConfigurationChanged:
                this._onDidChangeModelLanguageConfiguration.fire(e.event);
                break;
            case OutgoingViewModelEventKind.ModelContentChanged:
                this._onDidChangeModelContent.fire(e.event);
                break;
            case OutgoingViewModelEventKind.ModelOptionsChanged:
                this._onDidChangeModelOptions.fire(e.event);
                break;
            case OutgoingViewModelEventKind.ModelTokensChanged:
                this._onDidChangeModelTokens.fire(e.event);
                break;
            case OutgoingViewModelEventKind.ModelLineHeightChanged:
                this._onDidChangeLineHeight.fire(e.event);
                break;
            case OutgoingViewModelEventKind.ModelFontChangedEvent:
                this._onDidChangeFont.fire(e.event);
                break;
            }
        }));
        const [view, hasRealView] = this._createView(viewModel);
        if (hasRealView) {
            this._domElement.appendChild(view.domNode.domNode);
            let keys = ( Object.keys(this._contentWidgets));
            for (let i = 0, len = keys.length; i < len; i++) {
                const widgetId = keys[i];
                view.addContentWidget(this._contentWidgets[widgetId]);
            }
            keys = ( Object.keys(this._overlayWidgets));
            for (let i = 0, len = keys.length; i < len; i++) {
                const widgetId = keys[i];
                view.addOverlayWidget(this._overlayWidgets[widgetId]);
            }
            keys = ( Object.keys(this._glyphMarginWidgets));
            for (let i = 0, len = keys.length; i < len; i++) {
                const widgetId = keys[i];
                view.addGlyphMarginWidget(this._glyphMarginWidgets[widgetId]);
            }
            view.render(false, true);
            view.domNode.domNode.setAttribute("data-uri", ( model.uri.toString()));
            listenersToRemove.push(view.onWillCopy(e => this._onWillCopy.fire(e)));
            listenersToRemove.push(view.onWillCut(e => this._onWillCut.fire(e)));
            listenersToRemove.push(view.onWillPaste(e => this._onWillPaste.fire(e)));
        }
        this._modelData = ( new ModelData(model, viewModel, view, hasRealView, listenersToRemove, attachedView));
    }
    _createView(viewModel) {
        let commandDelegate;
        if (this.isSimpleWidget) {
            commandDelegate = {
                paste: (text, pasteOnNewLine, multicursorText, mode) => {
                    this._paste("keyboard", text, pasteOnNewLine, multicursorText, mode);
                },
                type: text => {
                    this._type("keyboard", text);
                },
                compositionType: (text, replacePrevCharCnt, replaceNextCharCnt, positionDelta) => {
                    this._compositionType("keyboard", text, replacePrevCharCnt, replaceNextCharCnt, positionDelta);
                },
                startComposition: () => {
                    this._startComposition();
                },
                endComposition: () => {
                    this._endComposition("keyboard");
                },
                cut: () => {
                    this._cut("keyboard");
                }
            };
        } else {
            commandDelegate = {
                paste: (text, pasteOnNewLine, multicursorText, mode) => {
                    const payload = {
                        text,
                        pasteOnNewLine,
                        multicursorText,
                        mode
                    };
                    this._commandService.executeCommand(Handler.Paste, payload);
                },
                type: text => {
                    const payload = {
                        text
                    };
                    this._commandService.executeCommand(Handler.Type, payload);
                },
                compositionType: (text, replacePrevCharCnt, replaceNextCharCnt, positionDelta) => {
                    if (replaceNextCharCnt || positionDelta) {
                        const payload = {
                            text,
                            replacePrevCharCnt,
                            replaceNextCharCnt,
                            positionDelta
                        };
                        this._commandService.executeCommand(Handler.CompositionType, payload);
                    } else {
                        const payload = {
                            text,
                            replaceCharCnt: replacePrevCharCnt
                        };
                        this._commandService.executeCommand(Handler.ReplacePreviousChar, payload);
                    }
                },
                startComposition: () => {
                    this._commandService.executeCommand(Handler.CompositionStart, {});
                },
                endComposition: () => {
                    this._commandService.executeCommand(Handler.CompositionEnd, {});
                },
                cut: () => {
                    this._commandService.executeCommand(Handler.Cut, {});
                }
            };
        }
        const viewUserInputEvents = ( new ViewUserInputEvents(viewModel.coordinatesConverter));
        viewUserInputEvents.onKeyDown = e => this._onKeyDown.fire(e);
        viewUserInputEvents.onKeyUp = e => this._onKeyUp.fire(e);
        viewUserInputEvents.onContextMenu = e => this._onContextMenu.fire(e);
        viewUserInputEvents.onMouseMove = e => this._onMouseMove.fire(e);
        viewUserInputEvents.onMouseLeave = e => this._onMouseLeave.fire(e);
        viewUserInputEvents.onMouseDown = e => this._onMouseDown.fire(e);
        viewUserInputEvents.onMouseUp = e => this._onMouseUp.fire(e);
        viewUserInputEvents.onMouseDrag = e => this._onMouseDrag.fire(e);
        viewUserInputEvents.onMouseDrop = e => this._onMouseDrop.fire(e);
        viewUserInputEvents.onMouseDropCanceled = e => this._onMouseDropCanceled.fire(e);
        viewUserInputEvents.onMouseWheel = e => this._onMouseWheel.fire(e);
        const view = ( new View(
            this._domElement,
            this.getId(),
            commandDelegate,
            this._configuration,
            this._themeService.getColorTheme(),
            viewModel,
            viewUserInputEvents,
            this._overflowWidgetsDomNode,
            this._instantiationService,
            this._userInteractionService
        ));
        return [view, true];
    }
    _postDetachModelCleanup(detachedModel) {
        detachedModel?.removeAllDecorationsWithOwnerId(this._id);
    }
    _detachModel() {
        this._contributionsDisposable?.dispose();
        this._contributionsDisposable = undefined;
        if (!this._modelData) {
            return null;
        }
        const model = this._modelData.model;
        const removeDomNode = this._modelData.hasRealView ? this._modelData.view.domNode.domNode : null;
        this._modelData.dispose();
        this._modelData = null;
        this._domElement.removeAttribute("data-mode-id");
        if (removeDomNode && this._domElement.contains(removeDomNode)) {
            removeDomNode.remove();
        }
        if (this._bannerDomNode && this._domElement.contains(this._bannerDomNode)) {
            this._bannerDomNode.remove();
        }
        return model;
    }
    _registerDecorationType(description, key, options, parentTypeKey) {
        this._codeEditorService.registerDecorationType(description, key, options, parentTypeKey, this);
    }
    _removeDecorationType(key) {
        this._codeEditorService.removeDecorationType(key);
    }
    _resolveDecorationOptions(typeKey, writable) {
        return this._codeEditorService.resolveDecorationOptions(typeKey, writable);
    }
    getTelemetryData() {
        return this._telemetryData;
    }
    hasModel() {
        return (this._modelData !== null);
    }
    showDropIndicatorAt(position) {
        const newDecorations = [{
            range: ( new Range(position.lineNumber, position.column, position.lineNumber, position.column)),
            options: CodeEditorWidget_1.dropIntoEditorDecorationOptions
        }];
        this._dropIntoEditorDecorations.set(newDecorations);
        this.revealPosition(position, ScrollType.Immediate);
    }
    removeDropIndicator() {
        this._dropIntoEditorDecorations.clear();
    }
    setContextValue(key, value) {
        this._contextKeyService.createKey(key, value);
    }
    _beginUpdate() {
        this._updateCounter++;
        if (this._updateCounter === 1) {
            this._onBeginUpdate.fire();
        }
    }
    _endUpdate() {
        this._updateCounter--;
        if (this._updateCounter === 0) {
            this._onEndUpdate.fire();
        }
    }
};
CodeEditorWidget = CodeEditorWidget_1 = ( __decorate([( __param(3, IInstantiationService)), ( __param(4, ICodeEditorService)), ( __param(5, ICommandService)), ( __param(6, IContextKeyService)), ( __param(7, IThemeService)), ( __param(8, INotificationService)), ( __param(9, IAccessibilityService)), ( __param(10, ILanguageConfigurationService)), ( __param(11, ILanguageFeaturesService)), ( __param(12, IUserInteractionService)), ( __param(13, IKeybindingService))], CodeEditorWidget));
let EDITOR_ID = 0;
class ModelData {
    constructor(model, viewModel, view, hasRealView, listenersToRemove, attachedView) {
        this.model = model;
        this.viewModel = viewModel;
        this.view = view;
        this.hasRealView = hasRealView;
        this.listenersToRemove = listenersToRemove;
        this.attachedView = attachedView;
    }
    dispose() {
        dispose(this.listenersToRemove);
        this.model.onBeforeDetached(this.attachedView);
        if (this.hasRealView) {
            this.view.dispose();
        }
        this.viewModel.dispose();
    }
}
var BooleanEventValue;
(function(BooleanEventValue) {
    BooleanEventValue[BooleanEventValue["NotSet"] = 0] = "NotSet";
    BooleanEventValue[BooleanEventValue["False"] = 1] = "False";
    BooleanEventValue[BooleanEventValue["True"] = 2] = "True";
})(BooleanEventValue || (BooleanEventValue = {}));
class BooleanEventEmitter extends Disposable {
    constructor(_emitterOptions) {
        super();
        this._emitterOptions = _emitterOptions;
        this._onDidChangeToTrue = this._register(( new Emitter(this._emitterOptions)));
        this.onDidChangeToTrue = this._onDidChangeToTrue.event;
        this._onDidChangeToFalse = this._register(( new Emitter(this._emitterOptions)));
        this.onDidChangeToFalse = this._onDidChangeToFalse.event;
        this._value = BooleanEventValue.NotSet;
    }
    setValue(_value) {
        const value = (_value ? BooleanEventValue.True : BooleanEventValue.False);
        if (this._value === value) {
            return;
        }
        this._value = value;
        if (this._value === BooleanEventValue.True) {
            this._onDidChangeToTrue.fire();
        } else if (this._value === BooleanEventValue.False) {
            this._onDidChangeToFalse.fire();
        }
    }
}
class InteractionEmitter extends Emitter {
    constructor(_contributions, deliveryQueue) {
        super({
            deliveryQueue
        });
        this._contributions = _contributions;
    }
    fire(event) {
        this._contributions.onBeforeInteractionEvent();
        super.fire(event);
    }
}
class EditorContextKeysManager extends Disposable {
    constructor(editor, contextKeyService) {
        super();
        this._editor = editor;
        contextKeyService.createKey("editorId", editor.getId());
        this._editorSimpleInput = EditorContextKeys.editorSimpleInput.bindTo(contextKeyService);
        this._editorFocus = EditorContextKeys.focus.bindTo(contextKeyService);
        this._textInputFocus = EditorContextKeys.textInputFocus.bindTo(contextKeyService);
        this._editorTextFocus = EditorContextKeys.editorTextFocus.bindTo(contextKeyService);
        this._tabMovesFocus = EditorContextKeys.tabMovesFocus.bindTo(contextKeyService);
        this._editorReadonly = EditorContextKeys.readOnly.bindTo(contextKeyService);
        this._inDiffEditor = EditorContextKeys.inDiffEditor.bindTo(contextKeyService);
        this._editorColumnSelection = EditorContextKeys.columnSelection.bindTo(contextKeyService);
        this._hasMultipleSelections = EditorContextKeys.hasMultipleSelections.bindTo(contextKeyService);
        this._hasNonEmptySelection = EditorContextKeys.hasNonEmptySelection.bindTo(contextKeyService);
        this._canUndo = EditorContextKeys.canUndo.bindTo(contextKeyService);
        this._canRedo = EditorContextKeys.canRedo.bindTo(contextKeyService);
        this._register(this._editor.onDidChangeConfiguration(() => this._updateFromConfig()));
        this._register(this._editor.onDidChangeCursorSelection(() => this._updateFromSelection()));
        this._register(this._editor.onDidFocusEditorWidget(() => this._updateFromFocus()));
        this._register(this._editor.onDidBlurEditorWidget(() => this._updateFromFocus()));
        this._register(this._editor.onDidFocusEditorText(() => this._updateFromFocus()));
        this._register(this._editor.onDidBlurEditorText(() => this._updateFromFocus()));
        this._register(this._editor.onDidChangeModel(() => this._updateFromModel()));
        this._register(this._editor.onDidChangeConfiguration(() => this._updateFromModel()));
        this._register(
            TabFocus.onDidChangeTabFocus(tabFocusMode => this._tabMovesFocus.set(tabFocusMode))
        );
        this._updateFromConfig();
        this._updateFromSelection();
        this._updateFromFocus();
        this._updateFromModel();
        this._editorSimpleInput.set(this._editor.isSimpleWidget);
    }
    _updateFromConfig() {
        const options = this._editor.getOptions();
        this._tabMovesFocus.set(options.get(EditorOption.tabFocusMode) || TabFocus.getTabFocusMode());
        this._editorReadonly.set(options.get(EditorOption.readOnly));
        this._inDiffEditor.set(options.get(EditorOption.inDiffEditor));
        this._editorColumnSelection.set(options.get(EditorOption.columnSelection));
    }
    _updateFromSelection() {
        const selections = this._editor.getSelections();
        if (!selections) {
            this._hasMultipleSelections.reset();
            this._hasNonEmptySelection.reset();
        } else {
            this._hasMultipleSelections.set(selections.length > 1);
            this._hasNonEmptySelection.set(( selections.some(s => !s.isEmpty())));
        }
    }
    _updateFromFocus() {
        this._editorFocus.set(this._editor.hasWidgetFocus() && !this._editor.isSimpleWidget);
        this._editorTextFocus.set(this._editor.hasTextFocus() && !this._editor.isSimpleWidget);
        this._textInputFocus.set(this._editor.hasTextFocus());
    }
    _updateFromModel() {
        const model = this._editor.getModel();
        this._canUndo.set(Boolean(model && model.canUndo()));
        this._canRedo.set(Boolean(model && model.canRedo()));
    }
}
class EditorModeContext extends Disposable {
    constructor(_editor, _contextKeyService, _languageFeaturesService) {
        super();
        this._editor = _editor;
        this._contextKeyService = _contextKeyService;
        this._languageFeaturesService = _languageFeaturesService;
        this._langId = EditorContextKeys.languageId.bindTo(_contextKeyService);
        this._hasCompletionItemProvider = EditorContextKeys.hasCompletionItemProvider.bindTo(_contextKeyService);
        this._hasCodeActionsProvider = EditorContextKeys.hasCodeActionsProvider.bindTo(_contextKeyService);
        this._hasCodeLensProvider = EditorContextKeys.hasCodeLensProvider.bindTo(_contextKeyService);
        this._hasDefinitionProvider = EditorContextKeys.hasDefinitionProvider.bindTo(_contextKeyService);
        this._hasDeclarationProvider = EditorContextKeys.hasDeclarationProvider.bindTo(_contextKeyService);
        this._hasImplementationProvider = EditorContextKeys.hasImplementationProvider.bindTo(_contextKeyService);
        this._hasTypeDefinitionProvider = EditorContextKeys.hasTypeDefinitionProvider.bindTo(_contextKeyService);
        this._hasHoverProvider = EditorContextKeys.hasHoverProvider.bindTo(_contextKeyService);
        this._hasDocumentHighlightProvider = EditorContextKeys.hasDocumentHighlightProvider.bindTo(_contextKeyService);
        this._hasDocumentSymbolProvider = EditorContextKeys.hasDocumentSymbolProvider.bindTo(_contextKeyService);
        this._hasReferenceProvider = EditorContextKeys.hasReferenceProvider.bindTo(_contextKeyService);
        this._hasRenameProvider = EditorContextKeys.hasRenameProvider.bindTo(_contextKeyService);
        this._hasSignatureHelpProvider = EditorContextKeys.hasSignatureHelpProvider.bindTo(_contextKeyService);
        this._hasInlayHintsProvider = EditorContextKeys.hasInlayHintsProvider.bindTo(_contextKeyService);
        this._hasDocumentFormattingProvider = EditorContextKeys.hasDocumentFormattingProvider.bindTo(_contextKeyService);
        this._hasDocumentSelectionFormattingProvider = EditorContextKeys.hasDocumentSelectionFormattingProvider.bindTo(_contextKeyService);
        this._hasMultipleDocumentFormattingProvider = EditorContextKeys.hasMultipleDocumentFormattingProvider.bindTo(_contextKeyService);
        this._hasMultipleDocumentSelectionFormattingProvider = EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider.bindTo(_contextKeyService);
        this._isInEmbeddedEditor = EditorContextKeys.isInEmbeddedEditor.bindTo(_contextKeyService);
        const update = () => this._update();
        this._register(_editor.onDidChangeModel(update));
        this._register(_editor.onDidChangeModelLanguage(update));
        this._register(_languageFeaturesService.completionProvider.onDidChange(update));
        this._register(_languageFeaturesService.codeActionProvider.onDidChange(update));
        this._register(_languageFeaturesService.codeLensProvider.onDidChange(update));
        this._register(_languageFeaturesService.definitionProvider.onDidChange(update));
        this._register(_languageFeaturesService.declarationProvider.onDidChange(update));
        this._register(_languageFeaturesService.implementationProvider.onDidChange(update));
        this._register(_languageFeaturesService.typeDefinitionProvider.onDidChange(update));
        this._register(_languageFeaturesService.hoverProvider.onDidChange(update));
        this._register(_languageFeaturesService.documentHighlightProvider.onDidChange(update));
        this._register(_languageFeaturesService.documentSymbolProvider.onDidChange(update));
        this._register(_languageFeaturesService.referenceProvider.onDidChange(update));
        this._register(_languageFeaturesService.renameProvider.onDidChange(update));
        this._register(
            _languageFeaturesService.documentFormattingEditProvider.onDidChange(update)
        );
        this._register(
            _languageFeaturesService.documentRangeFormattingEditProvider.onDidChange(update)
        );
        this._register(_languageFeaturesService.signatureHelpProvider.onDidChange(update));
        this._register(_languageFeaturesService.inlayHintsProvider.onDidChange(update));
        update();
    }
    dispose() {
        super.dispose();
    }
    reset() {
        this._contextKeyService.bufferChangeEvents(() => {
            this._langId.reset();
            this._hasCompletionItemProvider.reset();
            this._hasCodeActionsProvider.reset();
            this._hasCodeLensProvider.reset();
            this._hasDefinitionProvider.reset();
            this._hasDeclarationProvider.reset();
            this._hasImplementationProvider.reset();
            this._hasTypeDefinitionProvider.reset();
            this._hasHoverProvider.reset();
            this._hasDocumentHighlightProvider.reset();
            this._hasDocumentSymbolProvider.reset();
            this._hasReferenceProvider.reset();
            this._hasRenameProvider.reset();
            this._hasDocumentFormattingProvider.reset();
            this._hasDocumentSelectionFormattingProvider.reset();
            this._hasSignatureHelpProvider.reset();
            this._isInEmbeddedEditor.reset();
        });
    }
    _update() {
        const model = this._editor.getModel();
        if (!model) {
            this.reset();
            return;
        }
        this._contextKeyService.bufferChangeEvents(() => {
            this._langId.set(model.getLanguageId());
            this._hasCompletionItemProvider.set(( this._languageFeaturesService.completionProvider.has(model)));
            this._hasCodeActionsProvider.set(( this._languageFeaturesService.codeActionProvider.has(model)));
            this._hasCodeLensProvider.set(( this._languageFeaturesService.codeLensProvider.has(model)));
            this._hasDefinitionProvider.set(( this._languageFeaturesService.definitionProvider.has(model)));
            this._hasDeclarationProvider.set(( this._languageFeaturesService.declarationProvider.has(model)));
            this._hasImplementationProvider.set(( this._languageFeaturesService.implementationProvider.has(model)));
            this._hasTypeDefinitionProvider.set(( this._languageFeaturesService.typeDefinitionProvider.has(model)));
            this._hasHoverProvider.set(( this._languageFeaturesService.hoverProvider.has(model)));
            this._hasDocumentHighlightProvider.set(( this._languageFeaturesService.documentHighlightProvider.has(model)));
            this._hasDocumentSymbolProvider.set(( this._languageFeaturesService.documentSymbolProvider.has(model)));
            this._hasReferenceProvider.set(( this._languageFeaturesService.referenceProvider.has(model)));
            this._hasRenameProvider.set(( this._languageFeaturesService.renameProvider.has(model)));
            this._hasSignatureHelpProvider.set(( this._languageFeaturesService.signatureHelpProvider.has(model)));
            this._hasInlayHintsProvider.set(( this._languageFeaturesService.inlayHintsProvider.has(model)));
            this._hasDocumentFormattingProvider.set(( this._languageFeaturesService.documentFormattingEditProvider.has(model)) || ( this._languageFeaturesService.documentRangeFormattingEditProvider.has(model)));
            this._hasDocumentSelectionFormattingProvider.set(( this._languageFeaturesService.documentRangeFormattingEditProvider.has(model)));
            this._hasMultipleDocumentFormattingProvider.set(
                this._languageFeaturesService.documentFormattingEditProvider.all(model).length + this._languageFeaturesService.documentRangeFormattingEditProvider.all(model).length > 1
            );
            this._hasMultipleDocumentSelectionFormattingProvider.set(
                this._languageFeaturesService.documentRangeFormattingEditProvider.all(model).length > 1
            );
            this._isInEmbeddedEditor.set(
                model.uri.scheme === Schemas.walkThroughSnippet || model.uri.scheme === Schemas.vscodeChatCodeBlock
            );
        });
    }
}
class EditorDecorationsCollection {
    get length() {
        return this._decorationIds.length;
    }
    constructor(_editor, decorations) {
        this._editor = _editor;
        this._decorationIds = [];
        this._isChangingDecorations = false;
        if (Array.isArray(decorations) && decorations.length > 0) {
            this.set(decorations);
        }
    }
    onDidChange(listener, thisArgs, disposables) {
        return this._editor.onDidChangeModelDecorations(e => {
            if (this._isChangingDecorations) {
                return;
            }
            listener.call(thisArgs, e);
        }, disposables);
    }
    getRange(index) {
        if (!this._editor.hasModel()) {
            return null;
        }
        if (index >= this._decorationIds.length) {
            return null;
        }
        return this._editor.getModel().getDecorationRange(this._decorationIds[index]);
    }
    getRanges() {
        if (!this._editor.hasModel()) {
            return [];
        }
        const model = this._editor.getModel();
        const result = [];
        for (const decorationId of this._decorationIds) {
            const range = model.getDecorationRange(decorationId);
            if (range) {
                result.push(range);
            }
        }
        return result;
    }
    has(decoration) {
        return this._decorationIds.includes(decoration.id);
    }
    clear() {
        if (this._decorationIds.length === 0) {
            return;
        }
        this.set([]);
    }
    set(newDecorations) {
        try {
            this._isChangingDecorations = true;
            this._editor.changeDecorations(accessor => {
                this._decorationIds = accessor.deltaDecorations(this._decorationIds, newDecorations);
            });
        } finally {
            this._isChangingDecorations = false;
        }
        return this._decorationIds;
    }
    append(newDecorations) {
        let newDecorationIds = [];
        try {
            this._isChangingDecorations = true;
            this._editor.changeDecorations(accessor => {
                newDecorationIds = accessor.deltaDecorations([], newDecorations);
                this._decorationIds = this._decorationIds.concat(newDecorationIds);
            });
        } finally {
            this._isChangingDecorations = false;
        }
        return newDecorationIds;
    }
}
const squigglyStart = encodeURIComponent(
    `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 3' enable-background='new 0 0 6 3' height='3' width='6'><g fill='`
);
const squigglyEnd = encodeURIComponent(
    `'><polygon points='5.5,0 2.5,3 1.1,3 4.1,0'/><polygon points='4,0 6,2 6,0.6 5.4,0'/><polygon points='0,2 1,3 2.4,3 0,0.6'/></g></svg>`
);
function getSquigglySVGData(color) {
    return squigglyStart + encodeURIComponent(( color.toString())) + squigglyEnd;
}
const dotdotdotStart = encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" height="3" width="12"><g fill="`);
const dotdotdotEnd = encodeURIComponent(
    `"><circle cx="1" cy="1" r="1"/><circle cx="5" cy="1" r="1"/><circle cx="9" cy="1" r="1"/></g></svg>`
);
function getDotDotDotSVGData(color) {
    return dotdotdotStart + encodeURIComponent(( color.toString())) + dotdotdotEnd;
}
registerThemingParticipant((theme, collector) => {
    const errorForeground = theme.getColor(editorErrorForeground);
    if (errorForeground) {
        collector.addRule(
            `.monaco-editor .${ClassName.EditorErrorDecoration} { background: url("data:image/svg+xml,${getSquigglySVGData(errorForeground)}") repeat-x bottom left; }`
        );
        collector.addRule(
            `:root { --monaco-editor-error-decoration: url("data:image/svg+xml,${getSquigglySVGData(errorForeground)}"); }`
        );
    }
    const warningForeground = theme.getColor(editorWarningForeground);
    if (warningForeground) {
        collector.addRule(
            `.monaco-editor .${ClassName.EditorWarningDecoration} { background: url("data:image/svg+xml,${getSquigglySVGData(warningForeground)}") repeat-x bottom left; }`
        );
        collector.addRule(
            `:root { --monaco-editor-warning-decoration: url("data:image/svg+xml,${getSquigglySVGData(warningForeground)}"); }`
        );
    }
    const infoForeground = theme.getColor(editorInfoForeground);
    if (infoForeground) {
        collector.addRule(
            `.monaco-editor .${ClassName.EditorInfoDecoration} { background: url("data:image/svg+xml,${getSquigglySVGData(infoForeground)}") repeat-x bottom left; }`
        );
        collector.addRule(
            `:root { --monaco-editor-info-decoration: url("data:image/svg+xml,${getSquigglySVGData(infoForeground)}"); }`
        );
    }
    const hintForeground = theme.getColor(editorHintForeground);
    if (hintForeground) {
        collector.addRule(
            `.monaco-editor .${ClassName.EditorHintDecoration} { background: url("data:image/svg+xml,${getDotDotDotSVGData(hintForeground)}") no-repeat bottom left; }`
        );
        collector.addRule(
            `:root { --monaco-editor-hint-decoration: url("data:image/svg+xml,${getDotDotDotSVGData(hintForeground)}"); }`
        );
    }
    const unnecessaryForeground = theme.getColor(editorUnnecessaryCodeOpacity);
    if (unnecessaryForeground) {
        collector.addRule(
            `.monaco-editor.showUnused .${ClassName.EditorUnnecessaryInlineDecoration} { opacity: ${unnecessaryForeground.rgba.a}; }`
        );
        collector.addRule(
            `:root { --monaco-editor-unnecessary-decoration-opacity: ${unnecessaryForeground.rgba.a}; }`
        );
    }
});

export { BooleanEventEmitter, CodeEditorWidget, EditorModeContext };
