monaco-editor
Version:
A browser based code editor
1,019 lines • 70.7 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __decorate = (this && this.__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 = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import './media/editor.css';
import './media/tokens.css';
import * as nls from '../../../nls.js';
import * as dom from '../../../base/browser/dom.js';
import { onUnexpectedError } from '../../../base/common/errors.js';
import { Emitter } from '../../../base/common/event.js';
import { Disposable, dispose } from '../../../base/common/lifecycle.js';
import { Schemas } from '../../../base/common/network.js';
import { Configuration } from '../config/configuration.js';
import { EditorExtensionsRegistry } from '../editorExtensions.js';
import { ICodeEditorService } from '../services/codeEditorService.js';
import { View } from '../view/viewImpl.js';
import { ViewOutgoingEvents } from '../view/viewOutgoingEvents.js';
import { Cursor } from '../../common/controller/cursor.js';
import { CursorColumns } from '../../common/controller/cursorCommon.js';
import { Position } from '../../common/core/position.js';
import { Range } from '../../common/core/range.js';
import { Selection } from '../../common/core/selection.js';
import { InternalEditorAction } from '../../common/editorAction.js';
import * as editorCommon from '../../common/editorCommon.js';
import { EditorContextKeys } from '../../common/editorContextKeys.js';
import * as modes from '../../common/modes.js';
import { editorErrorBorder, editorErrorForeground, editorHintBorder, editorHintForeground, editorInfoBorder, editorInfoForeground, editorUnnecessaryCodeBorder, editorUnnecessaryCodeOpacity, editorWarningBorder, editorWarningForeground } from '../../common/view/editorColorRegistry.js';
import { ViewModel } from '../../common/viewModel/viewModelImpl.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 { INotificationService } from '../../../platform/notification/common/notification.js';
import { IThemeService, registerThemingParticipant } from '../../../platform/theme/common/themeService.js';
var EDITOR_ID = 0;
var SHOW_UNUSED_ENABLED_CLASS = 'showUnused';
var ModelData = /** @class */ (function () {
function ModelData(model, viewModel, cursor, view, hasRealView, listenersToRemove) {
this.model = model;
this.viewModel = viewModel;
this.cursor = cursor;
this.view = view;
this.hasRealView = hasRealView;
this.listenersToRemove = listenersToRemove;
}
ModelData.prototype.dispose = function () {
dispose(this.listenersToRemove);
this.model.onBeforeDetached();
if (this.hasRealView) {
this.view.dispose();
}
this.cursor.dispose();
this.viewModel.dispose();
};
return ModelData;
}());
var CodeEditorWidget = /** @class */ (function (_super) {
__extends(CodeEditorWidget, _super);
function CodeEditorWidget(domElement, options, codeEditorWidgetOptions, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService) {
var _this = _super.call(this) || this;
//#region Eventing
_this._onDidDispose = _this._register(new Emitter());
_this.onDidDispose = _this._onDidDispose.event;
_this._onDidChangeModelContent = _this._register(new Emitter());
_this.onDidChangeModelContent = _this._onDidChangeModelContent.event;
_this._onDidChangeModelLanguage = _this._register(new Emitter());
_this.onDidChangeModelLanguage = _this._onDidChangeModelLanguage.event;
_this._onDidChangeModelLanguageConfiguration = _this._register(new Emitter());
_this.onDidChangeModelLanguageConfiguration = _this._onDidChangeModelLanguageConfiguration.event;
_this._onDidChangeModelOptions = _this._register(new Emitter());
_this.onDidChangeModelOptions = _this._onDidChangeModelOptions.event;
_this._onDidChangeModelDecorations = _this._register(new Emitter());
_this.onDidChangeModelDecorations = _this._onDidChangeModelDecorations.event;
_this._onDidChangeConfiguration = _this._register(new Emitter());
_this.onDidChangeConfiguration = _this._onDidChangeConfiguration.event;
_this._onDidChangeModel = _this._register(new Emitter());
_this.onDidChangeModel = _this._onDidChangeModel.event;
_this._onDidChangeCursorPosition = _this._register(new Emitter());
_this.onDidChangeCursorPosition = _this._onDidChangeCursorPosition.event;
_this._onDidChangeCursorSelection = _this._register(new Emitter());
_this.onDidChangeCursorSelection = _this._onDidChangeCursorSelection.event;
_this._onDidAttemptReadOnlyEdit = _this._register(new Emitter());
_this.onDidAttemptReadOnlyEdit = _this._onDidAttemptReadOnlyEdit.event;
_this._onDidLayoutChange = _this._register(new Emitter());
_this.onDidLayoutChange = _this._onDidLayoutChange.event;
_this._editorTextFocus = _this._register(new BooleanEventEmitter());
_this.onDidFocusEditorText = _this._editorTextFocus.onDidChangeToTrue;
_this.onDidBlurEditorText = _this._editorTextFocus.onDidChangeToFalse;
_this._editorWidgetFocus = _this._register(new BooleanEventEmitter());
_this.onDidFocusEditorWidget = _this._editorWidgetFocus.onDidChangeToTrue;
_this.onDidBlurEditorWidget = _this._editorWidgetFocus.onDidChangeToFalse;
_this._onWillType = _this._register(new Emitter());
_this.onWillType = _this._onWillType.event;
_this._onDidType = _this._register(new Emitter());
_this.onDidType = _this._onDidType.event;
_this._onCompositionStart = _this._register(new Emitter());
_this.onCompositionStart = _this._onCompositionStart.event;
_this._onCompositionEnd = _this._register(new Emitter());
_this.onCompositionEnd = _this._onCompositionEnd.event;
_this._onDidPaste = _this._register(new Emitter());
_this.onDidPaste = _this._onDidPaste.event;
_this._onMouseUp = _this._register(new Emitter());
_this.onMouseUp = _this._onMouseUp.event;
_this._onMouseDown = _this._register(new Emitter());
_this.onMouseDown = _this._onMouseDown.event;
_this._onMouseDrag = _this._register(new Emitter());
_this.onMouseDrag = _this._onMouseDrag.event;
_this._onMouseDrop = _this._register(new Emitter());
_this.onMouseDrop = _this._onMouseDrop.event;
_this._onContextMenu = _this._register(new Emitter());
_this.onContextMenu = _this._onContextMenu.event;
_this._onMouseMove = _this._register(new Emitter());
_this.onMouseMove = _this._onMouseMove.event;
_this._onMouseLeave = _this._register(new Emitter());
_this.onMouseLeave = _this._onMouseLeave.event;
_this._onKeyUp = _this._register(new Emitter());
_this.onKeyUp = _this._onKeyUp.event;
_this._onKeyDown = _this._register(new Emitter());
_this.onKeyDown = _this._onKeyDown.event;
_this._onDidScrollChange = _this._register(new Emitter());
_this.onDidScrollChange = _this._onDidScrollChange.event;
_this._onDidChangeViewZones = _this._register(new Emitter());
_this.onDidChangeViewZones = _this._onDidChangeViewZones.event;
_this._domElement = domElement;
_this._id = (++EDITOR_ID);
_this._decorationTypeKeysToIds = {};
_this._decorationTypeSubtypes = {};
_this.isSimpleWidget = codeEditorWidgetOptions.isSimpleWidget || false;
_this._telemetryData = codeEditorWidgetOptions.telemetryData || null;
options = options || {};
_this._configuration = _this._register(_this._createConfiguration(options));
_this._register(_this._configuration.onDidChange(function (e) {
_this._onDidChangeConfiguration.fire(e);
if (e.layoutInfo) {
_this._onDidLayoutChange.fire(_this._configuration.editor.layoutInfo);
}
if (_this._configuration.editor.showUnused) {
_this._domElement.classList.add(SHOW_UNUSED_ENABLED_CLASS);
}
else {
_this._domElement.classList.remove(SHOW_UNUSED_ENABLED_CLASS);
}
}));
_this._contextKeyService = _this._register(contextKeyService.createScoped(_this._domElement));
_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));
_this._instantiationService = instantiationService.createChild(new ServiceCollection([IContextKeyService, _this._contextKeyService]));
_this._attachModel(null);
_this._contributions = {};
_this._actions = {};
_this._focusTracker = new CodeEditorWidgetFocusTracker(domElement);
_this._focusTracker.onChange(function () {
_this._editorWidgetFocus.setValue(_this._focusTracker.hasFocus());
});
_this._contentWidgets = {};
_this._overlayWidgets = {};
var contributions;
if (Array.isArray(codeEditorWidgetOptions.contributions)) {
contributions = codeEditorWidgetOptions.contributions;
}
else {
contributions = EditorExtensionsRegistry.getEditorContributions();
}
for (var i = 0, len = contributions.length; i < len; i++) {
var ctor = contributions[i];
try {
var contribution = _this._instantiationService.createInstance(ctor, _this);
_this._contributions[contribution.getId()] = contribution;
}
catch (err) {
onUnexpectedError(err);
}
}
EditorExtensionsRegistry.getEditorActions().forEach(function (action) {
var internalAction = new InternalEditorAction(action.id, action.label, action.alias, action.precondition, function () {
return _this._instantiationService.invokeFunction(function (accessor) {
return Promise.resolve(action.runEditorCommand(accessor, _this, null));
});
}, _this._contextKeyService);
_this._actions[internalAction.id] = internalAction;
});
_this._codeEditorService.addCodeEditor(_this);
return _this;
}
CodeEditorWidget.prototype._createConfiguration = function (options) {
return new Configuration(options, this._domElement);
};
CodeEditorWidget.prototype.getId = function () {
return this.getEditorType() + ':' + this._id;
};
CodeEditorWidget.prototype.getEditorType = function () {
return editorCommon.EditorType.ICodeEditor;
};
CodeEditorWidget.prototype.dispose = function () {
this._codeEditorService.removeCodeEditor(this);
this._focusTracker.dispose();
var keys = Object.keys(this._contributions);
for (var i = 0, len = keys.length; i < len; i++) {
var contributionId = keys[i];
this._contributions[contributionId].dispose();
}
this._removeDecorationTypes();
this._postDetachModelCleanup(this._detachModel());
this._onDidDispose.fire();
_super.prototype.dispose.call(this);
};
CodeEditorWidget.prototype.invokeWithinContext = function (fn) {
return this._instantiationService.invokeFunction(fn);
};
CodeEditorWidget.prototype.updateOptions = function (newOptions) {
this._configuration.updateOptions(newOptions);
};
CodeEditorWidget.prototype.getConfiguration = function () {
return this._configuration.editor;
};
CodeEditorWidget.prototype.getRawConfiguration = function () {
return this._configuration.getRawOptions();
};
CodeEditorWidget.prototype.getValue = function (options) {
if (options === void 0) { options = null; }
if (!this._modelData) {
return '';
}
var preserveBOM = (options && options.preserveBOM) ? true : false;
var eolPreference = 0 /* TextDefined */;
if (options && options.lineEnding && options.lineEnding === '\n') {
eolPreference = 1 /* LF */;
}
else if (options && options.lineEnding && options.lineEnding === '\r\n') {
eolPreference = 2 /* CRLF */;
}
return this._modelData.model.getValue(eolPreference, preserveBOM);
};
CodeEditorWidget.prototype.setValue = function (newValue) {
if (!this._modelData) {
return;
}
this._modelData.model.setValue(newValue);
};
CodeEditorWidget.prototype.getModel = function () {
if (!this._modelData) {
return null;
}
return this._modelData.model;
};
CodeEditorWidget.prototype.setModel = function (model) {
if (model === void 0) { model = null; }
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;
}
var detachedModel = this._detachModel();
this._attachModel(model);
var e = {
oldModelUrl: detachedModel ? detachedModel.uri : null,
newModelUrl: model ? model.uri : null
};
this._removeDecorationTypes();
this._onDidChangeModel.fire(e);
this._postDetachModelCleanup(detachedModel);
};
CodeEditorWidget.prototype._removeDecorationTypes = function () {
this._decorationTypeKeysToIds = {};
if (this._decorationTypeSubtypes) {
for (var decorationType in this._decorationTypeSubtypes) {
var subTypes = this._decorationTypeSubtypes[decorationType];
for (var subType in subTypes) {
this._removeDecorationType(decorationType + '-' + subType);
}
}
this._decorationTypeSubtypes = {};
}
};
CodeEditorWidget.prototype.getVisibleRanges = function () {
if (!this._modelData) {
return [];
}
return this._modelData.viewModel.getVisibleRanges();
};
CodeEditorWidget.prototype.getWhitespaces = function () {
if (!this._modelData) {
return [];
}
return this._modelData.viewModel.viewLayout.getWhitespaces();
};
CodeEditorWidget._getVerticalOffsetForPosition = function (modelData, modelLineNumber, modelColumn) {
var modelPosition = modelData.model.validatePosition({
lineNumber: modelLineNumber,
column: modelColumn
});
var viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition);
return modelData.viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber);
};
CodeEditorWidget.prototype.getTopForLineNumber = function (lineNumber) {
if (!this._modelData) {
return -1;
}
return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, 1);
};
CodeEditorWidget.prototype.getTopForPosition = function (lineNumber, column) {
if (!this._modelData) {
return -1;
}
return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, column);
};
CodeEditorWidget.prototype.setHiddenAreas = function (ranges) {
if (this._modelData) {
this._modelData.viewModel.setHiddenAreas(ranges.map(function (r) { return Range.lift(r); }));
}
};
CodeEditorWidget.prototype.getVisibleColumnFromPosition = function (rawPosition) {
if (!this._modelData) {
return rawPosition.column;
}
var position = this._modelData.model.validatePosition(rawPosition);
var tabSize = this._modelData.model.getOptions().tabSize;
return CursorColumns.visibleColumnFromColumn(this._modelData.model.getLineContent(position.lineNumber), position.column, tabSize) + 1;
};
CodeEditorWidget.prototype.getPosition = function () {
if (!this._modelData) {
return null;
}
return this._modelData.cursor.getPosition();
};
CodeEditorWidget.prototype.setPosition = function (position) {
if (!this._modelData) {
return;
}
if (!Position.isIPosition(position)) {
throw new Error('Invalid arguments');
}
this._modelData.cursor.setSelections('api', [{
selectionStartLineNumber: position.lineNumber,
selectionStartColumn: position.column,
positionLineNumber: position.lineNumber,
positionColumn: position.column
}]);
};
CodeEditorWidget.prototype._sendRevealRange = function (modelRange, verticalType, revealHorizontal, scrollType) {
if (!this._modelData) {
return;
}
if (!Range.isIRange(modelRange)) {
throw new Error('Invalid arguments');
}
var validatedModelRange = this._modelData.model.validateRange(modelRange);
var viewRange = this._modelData.viewModel.coordinatesConverter.convertModelRangeToViewRange(validatedModelRange);
this._modelData.cursor.emitCursorRevealRange(viewRange, verticalType, revealHorizontal, scrollType);
};
CodeEditorWidget.prototype.revealLine = function (lineNumber, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealLine(lineNumber, 0 /* Simple */, scrollType);
};
CodeEditorWidget.prototype.revealLineInCenter = function (lineNumber, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealLine(lineNumber, 1 /* Center */, scrollType);
};
CodeEditorWidget.prototype.revealLineInCenterIfOutsideViewport = function (lineNumber, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealLine(lineNumber, 2 /* CenterIfOutsideViewport */, scrollType);
};
CodeEditorWidget.prototype._revealLine = function (lineNumber, revealType, scrollType) {
if (typeof lineNumber !== 'number') {
throw new Error('Invalid arguments');
}
this._sendRevealRange(new Range(lineNumber, 1, lineNumber, 1), revealType, false, scrollType);
};
CodeEditorWidget.prototype.revealPosition = function (position, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealPosition(position, 0 /* Simple */, true, scrollType);
};
CodeEditorWidget.prototype.revealPositionInCenter = function (position, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealPosition(position, 1 /* Center */, true, scrollType);
};
CodeEditorWidget.prototype.revealPositionInCenterIfOutsideViewport = function (position, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealPosition(position, 2 /* CenterIfOutsideViewport */, true, scrollType);
};
CodeEditorWidget.prototype._revealPosition = function (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);
};
CodeEditorWidget.prototype.getSelection = function () {
if (!this._modelData) {
return null;
}
return this._modelData.cursor.getSelection();
};
CodeEditorWidget.prototype.getSelections = function () {
if (!this._modelData) {
return null;
}
return this._modelData.cursor.getSelections();
};
CodeEditorWidget.prototype.setSelection = function (something) {
var isSelection = Selection.isISelection(something);
var isRange = Range.isIRange(something);
if (!isSelection && !isRange) {
throw new Error('Invalid arguments');
}
if (isSelection) {
this._setSelectionImpl(something);
}
else if (isRange) {
// act as if it was an IRange
var selection = {
selectionStartLineNumber: something.startLineNumber,
selectionStartColumn: something.startColumn,
positionLineNumber: something.endLineNumber,
positionColumn: something.endColumn
};
this._setSelectionImpl(selection);
}
};
CodeEditorWidget.prototype._setSelectionImpl = function (sel) {
if (!this._modelData) {
return;
}
var selection = new Selection(sel.selectionStartLineNumber, sel.selectionStartColumn, sel.positionLineNumber, sel.positionColumn);
this._modelData.cursor.setSelections('api', [selection]);
};
CodeEditorWidget.prototype.revealLines = function (startLineNumber, endLineNumber, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealLines(startLineNumber, endLineNumber, 0 /* Simple */, scrollType);
};
CodeEditorWidget.prototype.revealLinesInCenter = function (startLineNumber, endLineNumber, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealLines(startLineNumber, endLineNumber, 1 /* Center */, scrollType);
};
CodeEditorWidget.prototype.revealLinesInCenterIfOutsideViewport = function (startLineNumber, endLineNumber, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealLines(startLineNumber, endLineNumber, 2 /* CenterIfOutsideViewport */, scrollType);
};
CodeEditorWidget.prototype._revealLines = function (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);
};
CodeEditorWidget.prototype.revealRange = function (range, scrollType, revealVerticalInCenter, revealHorizontal) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
if (revealVerticalInCenter === void 0) { revealVerticalInCenter = false; }
if (revealHorizontal === void 0) { revealHorizontal = true; }
this._revealRange(range, revealVerticalInCenter ? 1 /* Center */ : 0 /* Simple */, revealHorizontal, scrollType);
};
CodeEditorWidget.prototype.revealRangeInCenter = function (range, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealRange(range, 1 /* Center */, true, scrollType);
};
CodeEditorWidget.prototype.revealRangeInCenterIfOutsideViewport = function (range, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealRange(range, 2 /* CenterIfOutsideViewport */, true, scrollType);
};
CodeEditorWidget.prototype.revealRangeAtTop = function (range, scrollType) {
if (scrollType === void 0) { scrollType = 0 /* Smooth */; }
this._revealRange(range, 3 /* Top */, true, scrollType);
};
CodeEditorWidget.prototype._revealRange = function (range, verticalType, revealHorizontal, scrollType) {
if (!Range.isIRange(range)) {
throw new Error('Invalid arguments');
}
this._sendRevealRange(Range.lift(range), verticalType, revealHorizontal, scrollType);
};
CodeEditorWidget.prototype.setSelections = function (ranges, source) {
if (source === void 0) { source = 'api'; }
if (!this._modelData) {
return;
}
if (!ranges || ranges.length === 0) {
throw new Error('Invalid arguments');
}
for (var i = 0, len = ranges.length; i < len; i++) {
if (!Selection.isISelection(ranges[i])) {
throw new Error('Invalid arguments');
}
}
this._modelData.cursor.setSelections(source, ranges);
};
CodeEditorWidget.prototype.getScrollWidth = function () {
if (!this._modelData) {
return -1;
}
return this._modelData.viewModel.viewLayout.getScrollWidth();
};
CodeEditorWidget.prototype.getScrollLeft = function () {
if (!this._modelData) {
return -1;
}
return this._modelData.viewModel.viewLayout.getCurrentScrollLeft();
};
CodeEditorWidget.prototype.getScrollHeight = function () {
if (!this._modelData) {
return -1;
}
return this._modelData.viewModel.viewLayout.getScrollHeight();
};
CodeEditorWidget.prototype.getScrollTop = function () {
if (!this._modelData) {
return -1;
}
return this._modelData.viewModel.viewLayout.getCurrentScrollTop();
};
CodeEditorWidget.prototype.setScrollLeft = function (newScrollLeft) {
if (!this._modelData) {
return;
}
if (typeof newScrollLeft !== 'number') {
throw new Error('Invalid arguments');
}
this._modelData.viewModel.viewLayout.setScrollPositionNow({
scrollLeft: newScrollLeft
});
};
CodeEditorWidget.prototype.setScrollTop = function (newScrollTop) {
if (!this._modelData) {
return;
}
if (typeof newScrollTop !== 'number') {
throw new Error('Invalid arguments');
}
this._modelData.viewModel.viewLayout.setScrollPositionNow({
scrollTop: newScrollTop
});
};
CodeEditorWidget.prototype.setScrollPosition = function (position) {
if (!this._modelData) {
return;
}
this._modelData.viewModel.viewLayout.setScrollPositionNow(position);
};
CodeEditorWidget.prototype.saveViewState = function () {
if (!this._modelData) {
return null;
}
var contributionsState = {};
var keys = Object.keys(this._contributions);
for (var i = 0, len = keys.length; i < len; i++) {
var id = keys[i];
var contribution = this._contributions[id];
if (typeof contribution.saveViewState === 'function') {
contributionsState[id] = contribution.saveViewState();
}
}
var cursorState = this._modelData.cursor.saveState();
var viewState = this._modelData.viewModel.saveState();
return {
cursorState: cursorState,
viewState: viewState,
contributionsState: contributionsState
};
};
CodeEditorWidget.prototype.restoreViewState = function (s) {
if (!this._modelData || !this._modelData.hasRealView) {
return;
}
if (s && s.cursorState && s.viewState) {
var codeEditorState = s;
var cursorState = codeEditorState.cursorState;
if (Array.isArray(cursorState)) {
this._modelData.cursor.restoreState(cursorState);
}
else {
// Backwards compatibility
this._modelData.cursor.restoreState([cursorState]);
}
var contributionsState = s.contributionsState || {};
var keys = Object.keys(this._contributions);
for (var i = 0, len = keys.length; i < len; i++) {
var id = keys[i];
var contribution = this._contributions[id];
if (typeof contribution.restoreViewState === 'function') {
contribution.restoreViewState(contributionsState[id]);
}
}
var reducedState = this._modelData.viewModel.reduceRestoreState(s.viewState);
var linesViewportData = this._modelData.viewModel.viewLayout.getLinesViewportDataAtScrollTop(reducedState.scrollTop);
var startPosition = this._modelData.viewModel.coordinatesConverter.convertViewPositionToModelPosition(new Position(linesViewportData.startLineNumber, 1));
var endPosition = this._modelData.viewModel.coordinatesConverter.convertViewPositionToModelPosition(new Position(linesViewportData.endLineNumber, 1));
this._modelData.model.tokenizeViewport(startPosition.lineNumber, endPosition.lineNumber);
this._modelData.view.restoreState(reducedState);
}
};
CodeEditorWidget.prototype.getContribution = function (id) {
return (this._contributions[id] || null);
};
CodeEditorWidget.prototype.getActions = function () {
var result = [];
var keys = Object.keys(this._actions);
for (var i = 0, len = keys.length; i < len; i++) {
var id = keys[i];
result.push(this._actions[id]);
}
return result;
};
CodeEditorWidget.prototype.getSupportedActions = function () {
var result = this.getActions();
result = result.filter(function (action) { return action.isSupported(); });
return result;
};
CodeEditorWidget.prototype.getAction = function (id) {
return this._actions[id] || null;
};
CodeEditorWidget.prototype.trigger = function (source, handlerId, payload) {
payload = payload || {};
// Special case for typing
if (handlerId === editorCommon.Handler.Type) {
if (!this._modelData || typeof payload.text !== 'string' || payload.text.length === 0) {
// nothing to do
return;
}
if (source === 'keyboard') {
this._onWillType.fire(payload.text);
}
this._modelData.cursor.trigger(source, handlerId, payload);
if (source === 'keyboard') {
this._onDidType.fire(payload.text);
}
return;
}
// Special case for pasting
if (handlerId === editorCommon.Handler.Paste) {
if (!this._modelData || typeof payload.text !== 'string' || payload.text.length === 0) {
// nothing to do
return;
}
var startPosition = this._modelData.cursor.getSelection().getStartPosition();
this._modelData.cursor.trigger(source, handlerId, payload);
var endPosition = this._modelData.cursor.getSelection().getStartPosition();
if (source === 'keyboard') {
this._onDidPaste.fire(new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column));
}
return;
}
if (handlerId === editorCommon.Handler.CompositionStart) {
this._onCompositionStart.fire();
}
if (handlerId === editorCommon.Handler.CompositionEnd) {
this._onCompositionEnd.fire();
}
var action = this.getAction(handlerId);
if (action) {
Promise.resolve(action.run()).then(null, onUnexpectedError);
return;
}
if (!this._modelData) {
return;
}
if (this._triggerEditorCommand(source, handlerId, payload)) {
return;
}
this._modelData.cursor.trigger(source, handlerId, payload);
};
CodeEditorWidget.prototype._triggerEditorCommand = function (source, handlerId, payload) {
var _this = this;
var command = EditorExtensionsRegistry.getEditorCommand(handlerId);
if (command) {
payload = payload || {};
payload.source = source;
this._instantiationService.invokeFunction(function (accessor) {
Promise.resolve(command.runEditorCommand(accessor, _this, payload)).then(null, onUnexpectedError);
});
return true;
}
return false;
};
CodeEditorWidget.prototype._getCursors = function () {
if (!this._modelData) {
return null;
}
return this._modelData.cursor;
};
CodeEditorWidget.prototype.pushUndoStop = function () {
if (!this._modelData) {
return false;
}
if (this._configuration.editor.readOnly) {
// read only editor => sorry!
return false;
}
this._modelData.model.pushStackElement();
return true;
};
CodeEditorWidget.prototype.executeEdits = function (source, edits, endCursorState) {
if (!this._modelData) {
return false;
}
if (this._configuration.editor.readOnly) {
// read only editor => sorry!
return false;
}
this._modelData.model.pushEditOperations(this._modelData.cursor.getSelections(), edits, function () {
return endCursorState ? endCursorState : null;
});
if (endCursorState) {
this._modelData.cursor.setSelections(source, endCursorState);
}
return true;
};
CodeEditorWidget.prototype.executeCommand = function (source, command) {
if (!this._modelData) {
return;
}
this._modelData.cursor.trigger(source, editorCommon.Handler.ExecuteCommand, command);
};
CodeEditorWidget.prototype.executeCommands = function (source, commands) {
if (!this._modelData) {
return;
}
this._modelData.cursor.trigger(source, editorCommon.Handler.ExecuteCommands, commands);
};
CodeEditorWidget.prototype.changeDecorations = function (callback) {
if (!this._modelData) {
// callback will not be called
return null;
}
return this._modelData.model.changeDecorations(callback, this._id);
};
CodeEditorWidget.prototype.getLineDecorations = function (lineNumber) {
if (!this._modelData) {
return null;
}
return this._modelData.model.getLineDecorations(lineNumber, this._id, this._configuration.editor.readOnly);
};
CodeEditorWidget.prototype.deltaDecorations = function (oldDecorations, newDecorations) {
if (!this._modelData) {
return [];
}
if (oldDecorations.length === 0 && newDecorations.length === 0) {
return oldDecorations;
}
return this._modelData.model.deltaDecorations(oldDecorations, newDecorations, this._id);
};
CodeEditorWidget.prototype.removeDecorations = function (decorationTypeKey) {
// remove decorations for type and sub type
var oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey];
if (oldDecorationsIds) {
this.deltaDecorations(oldDecorationsIds, []);
}
if (this._decorationTypeKeysToIds.hasOwnProperty(decorationTypeKey)) {
delete this._decorationTypeKeysToIds[decorationTypeKey];
}
if (this._decorationTypeSubtypes.hasOwnProperty(decorationTypeKey)) {
delete this._decorationTypeSubtypes[decorationTypeKey];
}
};
CodeEditorWidget.prototype.getLayoutInfo = function () {
return this._configuration.editor.layoutInfo;
};
CodeEditorWidget.prototype.createOverviewRuler = function (cssClassName) {
if (!this._modelData || !this._modelData.hasRealView) {
return null;
}
return this._modelData.view.createOverviewRuler(cssClassName);
};
CodeEditorWidget.prototype.getDomNode = function () {
if (!this._modelData || !this._modelData.hasRealView) {
return null;
}
return this._modelData.view.domNode.domNode;
};
CodeEditorWidget.prototype.delegateVerticalScrollbarMouseDown = function (browserEvent) {
if (!this._modelData || !this._modelData.hasRealView) {
return;
}
this._modelData.view.delegateVerticalScrollbarMouseDown(browserEvent);
};
CodeEditorWidget.prototype.layout = function (dimension) {
this._configuration.observeReferenceElement(dimension);
this.render();
};
CodeEditorWidget.prototype.focus = function () {
if (!this._modelData || !this._modelData.hasRealView) {
return;
}
this._modelData.view.focus();
};
CodeEditorWidget.prototype.hasTextFocus = function () {
if (!this._modelData || !this._modelData.hasRealView) {
return false;
}
return this._modelData.view.isFocused();
};
CodeEditorWidget.prototype.hasWidgetFocus = function () {
return this._focusTracker && this._focusTracker.hasFocus();
};
CodeEditorWidget.prototype.addContentWidget = function (widget) {
var widgetData = {
widget: widget,
position: widget.getPosition()
};
if (this._contentWidgets.hasOwnProperty(widget.getId())) {
console.warn('Overwriting a content widget with the same id.');
}
this._contentWidgets[widget.getId()] = widgetData;
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.addContentWidget(widgetData);
}
};
CodeEditorWidget.prototype.layoutContentWidget = function (widget) {
var widgetId = widget.getId();
if (this._contentWidgets.hasOwnProperty(widgetId)) {
var widgetData = this._contentWidgets[widgetId];
widgetData.position = widget.getPosition();
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.layoutContentWidget(widgetData);
}
}
};
CodeEditorWidget.prototype.removeContentWidget = function (widget) {
var widgetId = widget.getId();
if (this._contentWidgets.hasOwnProperty(widgetId)) {
var widgetData = this._contentWidgets[widgetId];
delete this._contentWidgets[widgetId];
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.removeContentWidget(widgetData);
}
}
};
CodeEditorWidget.prototype.addOverlayWidget = function (widget) {
var 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);
}
};
CodeEditorWidget.prototype.layoutOverlayWidget = function (widget) {
var widgetId = widget.getId();
if (this._overlayWidgets.hasOwnProperty(widgetId)) {
var widgetData = this._overlayWidgets[widgetId];
widgetData.position = widget.getPosition();
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.layoutOverlayWidget(widgetData);
}
}
};
CodeEditorWidget.prototype.removeOverlayWidget = function (widget) {
var widgetId = widget.getId();
if (this._overlayWidgets.hasOwnProperty(widgetId)) {
var widgetData = this._overlayWidgets[widgetId];
delete this._overlayWidgets[widgetId];
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.removeOverlayWidget(widgetData);
}
}
};
CodeEditorWidget.prototype.changeViewZones = function (callback) {
if (!this._modelData || !this._modelData.hasRealView) {
return;
}
var hasChanges = this._modelData.view.change(callback);
if (hasChanges) {
this._onDidChangeViewZones.fire();
}
};
CodeEditorWidget.prototype.getTargetAtClientPoint = function (clientX, clientY) {
if (!this._modelData || !this._modelData.hasRealView) {
return null;
}
return this._modelData.view.getTargetAtClientPoint(clientX, clientY);
};
CodeEditorWidget.prototype.getScrolledVisiblePosition = function (rawPosition) {
if (!this._modelData || !this._modelData.hasRealView) {
return null;
}
var position = this._modelData.model.validatePosition(rawPosition);
var layoutInfo = this._configuration.editor.layoutInfo;
var top = CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, position.lineNumber, position.column) - this.getScrollTop();
var left = this._modelData.view.getOffsetForColumn(position.lineNumber, position.column) + layoutInfo.glyphMarginWidth + layoutInfo.lineNumbersWidth + layoutInfo.decorationsWidth - this.getScrollLeft();
return {
top: top,
left: left,
height: this._configuration.editor.lineHeight
};
};
CodeEditorWidget.prototype.getOffsetForColumn = function (lineNumber, column) {
if (!this._modelData || !this._modelData.hasRealView) {
return -1;
}
return this._modelData.view.getOffsetForColumn(lineNumber, column);
};
CodeEditorWidget.prototype.render = function () {
if (!this._modelData || !this._modelData.hasRealView) {
return;
}
this._modelData.view.render(true, false);
};
CodeEditorWidget.prototype.applyFontInfo = function (target) {
Configuration.applyFontInfoSlow(target, this._configuration.editor.fontInfo);
};
CodeEditorWidget.prototype._attachModel = function (model) {
var _this = this;
if (!model) {
this._modelData = null;
return;
}
var listenersToRemove = [];
this._domElement.setAttribute('data-mode-id', model.getLanguageIdentifier().language);
this._configuration.setIsDominatedByLongLines(model.isDominatedByLongLines());
this._configuration.setMaxLineNumber(model.getLineCount());
model.onBeforeAttached();
var viewModel = new ViewModel(this._id, this._configuration, model, function (callback) { return dom.scheduleAtNextAnimationFrame(callback); });
listenersToRemove.push(model.onDidChangeDecorations(function (e) { return _this._onDidChangeModelDecorations.fire(e); }));
listenersToRemove.push(model.onDidChangeLanguage(function (e) {
_this._domElement.setAttribute('data-mode-id', model.getLanguageIdentifier().language);
_this._onDidChangeModelLanguage.fire(e);
}));
listenersToRemove.push(model.onDidChangeLanguageConfiguration(function (e) { return _this._onDidChangeModelLanguageConfiguration.fire(e); }));
listenersToRemove.push(model.onDidChangeContent(function (e) { return _this._onDidChangeModelContent.fire(e); }));
listenersToRemove.push(model.onDidChangeOptions(function (e) { return _this._onDidChangeModelOptions.fire(e); }));
// Someone might destroy the model from under the editor, so prevent any exceptions by setting a null model
listenersToRemove.push(model.onWillDispose(function () { return _this.setModel(null); }));
var cursor = new Cursor(this._configuration, model, viewModel);
listenersToRemove.push(cursor.onDidReachMaxCursorCount(function () {
_this._notificationService.warn(nls.localize('cursors.maximum', "The number of cursors has been limited to {0}.", Cursor.MAX_CURSOR_COUNT));
}));
listenersToRemove.push(cursor.onDidAttemptReadOnlyEdit(function () {
_this._onDidAttemptReadOnlyEdit.fire(void 0);
}));
listenersToRemove.push(cursor.onDidChange(function (e) {
var positions = [];
for (var i = 0, len = e.selections.length; i < len; i++) {
positions[i] = e.selections[i].getPosition();
}
var e1 = {
position: positions[0],
secondaryPositions: positions.slice(1),
reason: e.reason,
source: e.source
};
_this._onDidChangeCursorPosition.fire(e1);
var e2 = {
selection: e.selections[0],
secondarySelections: e.selections.slice(1),
source: e.source,
reason: e.reason
};
_this._onDidChangeCursorSelection.fire(e2);
}));
var _a = this._createView(viewModel, cursor), view = _a[0], hasRealView = _a[1];
if (hasRealView) {
this._domElement.appendChild(view.domNode.domNode);
var keys = Object.keys(this._contentWidgets);
for (var i = 0, len = keys.length; i < len; i++) {
var widgetId = keys[i];
view.addContentWidget(this._contentWidgets[widgetId]);
}
keys = Object.keys(this._overlayWidgets);
for (var i = 0, len = keys.length; i < len; i++) {
var widgetId = keys[i];
view.addOverlayWidget(this._overlayWidgets[widgetId]);
}
view.render(false, true);
view.domNode.domNode.setAttribute('data-uri', model.uri.toString());
}
this._modelData = new ModelData(model, viewModel, cursor, view, hasRealView, listenersToRemove);
};
CodeEditorWidget.prototype._createView = function (viewModel, cursor) {
var _this = this;
var commandDelegate;
if (this.isSimpleWidget) {
commandDelegate = {
executeEditorCommand: function (editorCommand, args) {
editorCommand.runCoreEditorCommand(cursor, args);
},
paste: function (source, text, pasteOnNewLine, multicursorText) {
_this.trigger(source, editorCommon.Handler.Paste, { text: text, pasteOnNewLine: pasteOnNewLine, multicursorText: multicursorText });
},
type: function (source, text) {
_this.trigger(source, editorCommon.Handler.Type, { text: text });
},
replacePreviousChar: function (source, text, replaceCharCnt) {
_this.trigger(source, editorCommon.Handler.ReplacePreviousChar, { text: text, replaceCharCnt: replaceCharCnt });
},
compositionStart: function (source) {
_this.trigger(source, editorCommon.Handler.CompositionStart, undefined);
},
compositionEnd: function (source) {
_this.trigger(source, editorCommon.Handler.CompositionEnd, undefined);
},
cut: function (source) {