UNPKG

monaco-editor

Version:
1,063 lines (1,061 loc) • 90.3 kB
import '../../services/markerDecorations.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 { Disposable, dispose } from '../../../../base/common/lifecycle.js'; import { Schemas } from '../../../../base/common/network.js'; import './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.js'; import { View } from '../../view.js'; import { DOMLineBreaksComputerFactory } from '../../view/domLineBreaksComputer.js'; import { ViewUserInputEvents } from '../../view/viewUserInputEvents.js'; import { CodeEditorContributions } from './codeEditorContributions.js'; import { 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 { InternalEditorAction } from '../../../common/editorAction.js'; import { EditorType } from '../../../common/editorCommon.js'; import { EditorContextKeys } from '../../../common/editorContextKeys.js'; import { ILanguageConfigurationService } from '../../../common/languages/languageConfigurationRegistry.js'; import { ModelDecorationOptions } from '../../../common/model/textModel.js'; import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js'; import { MonospaceLineBreaksComputerFactory } from '../../../common/viewModel/monospaceLineBreaksComputer.js'; import { ViewModel } from '../../../common/viewModel/viewModelImpl.js'; import { localize } from '../../../../nls.js'; import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.js'; import { ICommandService } from '../../../../platform/commands/common/commands.js'; import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js'; import { Severity, INotificationService } from '../../../../platform/notification/common/notification.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 { IThemeService, registerThemingParticipant } from '../../../../platform/theme/common/themeService.js'; import { MenuId } from '../../../../platform/actions/common/actions.js'; import { TextModelEditSource, EditSources } from '../../../common/textModelEditSource.js'; import { isObject } from '../../../../base/common/types.js'; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (undefined && undefined.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var CodeEditorWidget_1; let CodeEditorWidget = class CodeEditorWidget extends Disposable { static { CodeEditorWidget_1 = this; } static { this.dropIntoEditorDecorationOptions = ModelDecorationOptions.register({ description: 'workbench-dnd-target', className: 'dnd-target' }); } //#endregion 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) { super(); this.languageConfigurationService = languageConfigurationService; //#region Eventing 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._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._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._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), options, accessibilityService)); this._register(this._configuration.onDidChange((e) => { this._onDidChangeConfiguration.fire(e); const options = this._configuration.options; if (e.hasChanged(165 /* EditorOption.layoutInfo */)) { const layoutInfo = options.get(165 /* EditorOption.layoutInfo */); this._onDidLayoutChange.fire(layoutInfo); } })); 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(104 /* EditorOption.readOnly */) && this._configuration.options.get(43 /* 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); } writeScreenReaderContent(reason) { this._modelData?.view.writeScreenReaderContent(reason); } _createConfiguration(isSimpleWidget, contextMenuId, options, accessibilityService) { return new EditorConfiguration(isSimpleWidget, contextMenuId, 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(148 /* EditorOption.wordSeparators */), this._configuration.options.get(147 /* EditorOption.wordSegmenterLocales */), position); } getValue(options = null) { if (!this._modelData) { return ''; } const preserveBOM = (options && options.preserveBOM) ? true : false; let eolPreference = 0 /* EndOfLinePreference.TextDefined */; if (options && options.lineEnding && options.lineEnding === '\n') { eolPreference = 1 /* EndOfLinePreference.LF */; } else if (options && options.lineEnding && options.lineEnding === '\r\n') { eolPreference = 2 /* 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) { // Current model is the new model return; } if (this._modelData && this._modelData.model === model) { // Current model is the new 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()) { // we have a new model (with a new view)! if (hasTextFocus) { this.focus(); } } else { // we have no model (and no view) anymore // make sure the outside world knows we are not focused 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; } const maxCol = this._modelData.model.getLineMaxColumn(lineNumber); return CodeEditorWidget_1._getVerticalOffsetAfterPosition(this._modelData, lineNumber, maxCol, 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; } 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); } revealLine(lineNumber, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLine(lineNumber, 0 /* VerticalRevealType.Simple */, scrollType); } revealLineInCenter(lineNumber, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLine(lineNumber, 1 /* VerticalRevealType.Center */, scrollType); } revealLineInCenterIfOutsideViewport(lineNumber, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLine(lineNumber, 2 /* VerticalRevealType.CenterIfOutsideViewport */, scrollType); } revealLineNearTop(lineNumber, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLine(lineNumber, 5 /* 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 = 0 /* editorCommon.ScrollType.Smooth */) { this._revealPosition(position, 0 /* VerticalRevealType.Simple */, true, scrollType); } revealPositionInCenter(position, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealPosition(position, 1 /* VerticalRevealType.Center */, true, scrollType); } revealPositionInCenterIfOutsideViewport(position, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealPosition(position, 2 /* VerticalRevealType.CenterIfOutsideViewport */, true, scrollType); } revealPositionNearTop(position, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealPosition(position, 5 /* 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) { // act as if it was an IRange 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 = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLines(startLineNumber, endLineNumber, 0 /* VerticalRevealType.Simple */, scrollType); } revealLinesInCenter(startLineNumber, endLineNumber, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLines(startLineNumber, endLineNumber, 1 /* VerticalRevealType.Center */, scrollType); } revealLinesInCenterIfOutsideViewport(startLineNumber, endLineNumber, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLines(startLineNumber, endLineNumber, 2 /* VerticalRevealType.CenterIfOutsideViewport */, scrollType); } revealLinesNearTop(startLineNumber, endLineNumber, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealLines(startLineNumber, endLineNumber, 5 /* 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 = 0 /* editorCommon.ScrollType.Smooth */, revealVerticalInCenter = false, revealHorizontal = true) { this._revealRange(range, revealVerticalInCenter ? 1 /* VerticalRevealType.Center */ : 0 /* VerticalRevealType.Simple */, revealHorizontal, scrollType); } revealRangeInCenter(range, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealRange(range, 1 /* VerticalRevealType.Center */, true, scrollType); } revealRangeInCenterIfOutsideViewport(range, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealRange(range, 2 /* VerticalRevealType.CenterIfOutsideViewport */, true, scrollType); } revealRangeNearTop(range, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealRange(range, 5 /* VerticalRevealType.NearTop */, true, scrollType); } revealRangeNearTopIfOutsideViewport(range, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealRange(range, 6 /* VerticalRevealType.NearTopIfOutsideViewport */, true, scrollType); } revealRangeAtTop(range, scrollType = 0 /* editorCommon.ScrollType.Smooth */) { this._revealRange(range, 3 /* 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 = 0 /* 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 = 1 /* editorCommon.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 = 1 /* editorCommon.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 = 1 /* editorCommon.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 { // Backwards compatibility 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(); } 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 "compositionStart" /* editorCommon.Handler.CompositionStart */: this._startComposition(); return; case "compositionEnd" /* editorCommon.Handler.CompositionEnd */: this._endComposition(source); return; case "type" /* editorCommon.Handler.Type */: { const args = payload; this._type(source, args.text || ''); return; } case "replacePreviousChar" /* editorCommon.Handler.ReplacePreviousChar */: { const args = payload; this._compositionType(source, args.text || '', args.replaceCharCnt || 0, 0, 0); return; } case "compositionType" /* editorCommon.Handler.CompositionType */: { const args = payload; this._compositionType(source, args.text || '', args.replacePrevCharCnt || 0, args.replaceNextCharCnt || 0, args.positionDelta || 0); return; } case "paste" /* editorCommon.Handler.Paste */: { const args = payload; this._paste(source, args.text || '', args.pasteOnNewLine || false, args.multicursorText || null, args.mode || null, args.clipboardEvent); return; } case "cut" /* editorCommon.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(104 /* EditorOption.readOnly */)) { // read only editor => sorry! return false; } this._modelData.model.pushStackElement(); return true; } popUndoStop() { if (!this._modelData) { return false; } if (this._configuration.options.get(104 /* EditorOption.readOnly */)) { // read only editor => sorry! 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(104 /* EditorOption.readOnly */)) { // read only editor => sorry! 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: sourceStr }); 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) { // callback will not be called 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); } /** * @deprecated */ 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, []); }); } removeDecorationsByType(decorationTypeKey) { // remove decorations for type and sub type 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)) { delete this._decorationTypeSubtypes[decorationTypeKey]; } } getLayoutInfo() { const options = this._configuration.options; const layoutInfo = options.get(165 /* 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();