Merge VS Code 1.21 source code (#1067)

* Initial VS Code 1.21 file copy with patches

* A few more merges

* Post npm install

* Fix batch of build breaks

* Fix more build breaks

* Fix more build errors

* Fix more build breaks

* Runtime fixes 1

* Get connection dialog working with some todos

* Fix a few packaging issues

* Copy several node_modules to package build to fix loader issues

* Fix breaks from master

* A few more fixes

* Make tests pass

* First pass of license header updates

* Second pass of license header updates

* Fix restore dialog issues

* Remove add additional themes menu items

* fix select box issues where the list doesn't show up

* formatting

* Fix editor dispose issue

* Copy over node modules to correct location on all platforms
This commit is contained in:
Karl Burtram
2018-04-04 15:27:51 -07:00
committed by GitHub
parent 5fba3e31b4
commit dafb780987
9412 changed files with 141255 additions and 98813 deletions

View File

@@ -5,16 +5,16 @@
'use strict';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { Range, IRange } from 'vs/editor/common/core/range';
import { LineTokens } from 'vs/editor/common/core/lineTokens';
import { PrefixSumComputerWithCache } from 'vs/editor/common/viewModel/prefixSumComputer';
import { ViewLineData, ICoordinatesConverter, IOverviewRulerDecorations } from 'vs/editor/common/viewModel/viewModel';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { WrappingIndent } from 'vs/editor/common/config/editorOptions';
import { ModelDecorationOptions, ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModelWithDecorations';
import { ModelDecorationOptions, ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModel';
import { ThemeColor, ITheme } from 'vs/platform/theme/common/themeService';
import { Color } from 'vs/base/common/color';
import { IModelDecoration, ITextModel, IModelDeltaDecoration, EndOfLinePreference } from 'vs/editor/common/model';
export class OutputPosition {
_outputPositionBrand: void;
@@ -38,11 +38,12 @@ export interface ILineMapperFactory {
createLineMapping(lineText: string, tabSize: number, wrappingColumn: number, columnsForFullWidthChar: number, wrappingIndent: WrappingIndent): ILineMapping;
}
export interface IModel {
export interface ISimpleModel {
getLineTokens(lineNumber: number): LineTokens;
getLineContent(lineNumber: number): string;
getLineMinColumn(lineNumber: number): number;
getLineMaxColumn(lineNumber: number): number;
getValueInRange(range: IRange, eol?: EndOfLinePreference): string;
}
export interface ISplitLine {
@@ -50,11 +51,11 @@ export interface ISplitLine {
setVisible(isVisible: boolean): ISplitLine;
getViewLineCount(): number;
getViewLineContent(model: IModel, modelLineNumber: number, outputLineIndex: number): string;
getViewLineMinColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number;
getViewLineMaxColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number;
getViewLineData(model: IModel, modelLineNumber: number, outputLineIndex: number): ViewLineData;
getViewLinesData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void;
getViewLineContent(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): string;
getViewLineMinColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number;
getViewLineMaxColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number;
getViewLineData(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): ViewLineData;
getViewLinesData(model: ISimpleModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void;
getModelColumnOfViewPosition(outputLineIndex: number, outputColumn: number): number;
getViewPositionOfModelPosition(deltaLineNumber: number, inputColumn: number): Position;
@@ -68,6 +69,7 @@ export interface IViewModelLinesCollection {
setWrappingSettings(wrappingIndent: WrappingIndent, wrappingColumn: number, columnsForFullWidthChar: number): boolean;
setTabSize(newTabSize: number): boolean;
getHiddenAreas(): Range[];
setHiddenAreas(_ranges: Range[]): boolean;
onModelFlushed(): void;
@@ -86,7 +88,7 @@ export interface IViewModelLinesCollection {
getViewLinesData(viewStartLineNumber: number, viewEndLineNumber: number, needed: boolean[]): ViewLineData[];
getAllOverviewRulerDecorations(ownerId: number, filterOutValidation: boolean, theme: ITheme): IOverviewRulerDecorations;
getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): editorCommon.IModelDecoration[];
getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[];
}
export class CoordinatesConverter implements ICoordinatesConverter {
@@ -114,8 +116,8 @@ export class CoordinatesConverter implements ICoordinatesConverter {
}
public validateViewRange(viewRange: Range, expectedModelRange: Range): Range {
var validViewStart = this._lines.validateViewPosition(viewRange.startLineNumber, viewRange.startColumn, expectedModelRange.getStartPosition());
var validViewEnd = this._lines.validateViewPosition(viewRange.endLineNumber, viewRange.endColumn, expectedModelRange.getEndPosition());
const validViewStart = this._lines.validateViewPosition(viewRange.startLineNumber, viewRange.startColumn, expectedModelRange.getStartPosition());
const validViewEnd = this._lines.validateViewPosition(viewRange.endLineNumber, viewRange.endColumn, expectedModelRange.getEndPosition());
return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column);
}
@@ -139,7 +141,7 @@ export class CoordinatesConverter implements ICoordinatesConverter {
export class SplitLinesCollection implements IViewModelLinesCollection {
private model: editorCommon.IModel;
private model: ITextModel;
private _validModelVersionId: number;
private wrappingColumn: number;
@@ -154,7 +156,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
private hiddenAreasIds: string[];
constructor(model: editorCommon.IModel, linePositionMapperFactory: ILineMapperFactory, tabSize: number, wrappingColumn: number, columnsForFullWidthChar: number, wrappingIndent: WrappingIndent) {
constructor(model: ITextModel, linePositionMapperFactory: ILineMapperFactory, tabSize: number, wrappingColumn: number, columnsForFullWidthChar: number, wrappingIndent: WrappingIndent) {
this.model = model;
this._validModelVersionId = -1;
this.tabSize = tabSize;
@@ -177,7 +179,8 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
private _ensureValidState(): void {
let modelVersion = this.model.getVersionId();
if (modelVersion !== this._validModelVersionId) {
throw new Error('SplitLinesCollection: attempt to access a \'newer\' model');
// This is pretty bad, it means we lost track of the model...
throw new Error(`ViewModel is out of sync with Model!`);
}
}
@@ -218,10 +221,10 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
this.prefixSumComputer = new PrefixSumComputerWithCache(values);
}
private getHiddenAreas(): Range[] {
public getHiddenAreas(): Range[] {
return this.hiddenAreasIds.map((decId) => {
return this.model.getDecorationRange(decId);
}).sort(Range.compareRangesUsingStarts);
});
}
private _reduceRanges(_ranges: Range[]): Range[] {
@@ -270,7 +273,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
}
// END TODO@Martin: Please stop calling this method on each model change!
let newDecorations: editorCommon.IModelDeltaDecoration[] = [];
let newDecorations: IModelDeltaDecoration[] = [];
for (let i = 0; i < newRanges.length; i++) {
newDecorations.push({
range: newRanges[i],
@@ -285,6 +288,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
let hiddenAreaIdx = -1;
let nextLineNumberToUpdateHiddenArea = (hiddenAreaIdx + 1 < hiddenAreas.length) ? hiddenAreaEnd + 1 : this.lines.length + 2;
let hasVisibleLine = false;
for (let i = 0; i < this.lines.length; i++) {
let lineNumber = i + 1;
@@ -303,6 +307,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
lineChanged = true;
}
} else {
hasVisibleLine = true;
// Line should be visible
if (!this.lines[i].isVisible()) {
this.lines[i] = this.lines[i].setVisible(true);
@@ -315,6 +320,11 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
}
}
if (!hasVisibleLine) {
// Cannot have everything be hidden => reveal everything!
this.setHiddenAreas([]);
}
return true;
}
@@ -403,6 +413,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
insertPrefixSumValues[i] = outputLineCount;
}
// TODO@Alex: use arrays.arrayInsert
this.lines = this.lines.slice(0, fromLineNumber - 1).concat(insertLines).concat(this.lines.slice(fromLineNumber - 1));
this.prefixSumComputer.insertValues(fromLineNumber - 1, insertPrefixSumValues);
@@ -461,6 +472,10 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
public acceptVersionId(versionId: number): void {
this._validModelVersionId = versionId;
if (this.lines.length === 1 && !this.lines[0].isVisible()) {
// At least one line must be visible => reset hidden areas
this.setHiddenAreas([]);
}
}
public getViewLineCount(): number {
@@ -735,7 +750,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
return result.result;
}
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): editorCommon.IModelDecoration[] {
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[] {
const modelStart = this.convertViewPositionToModelPosition(range.startLineNumber, range.startColumn);
const modelEnd = this.convertViewPositionToModelPosition(range.endLineNumber, range.endColumn);
@@ -744,7 +759,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
return this.model.getDecorationsInRange(new Range(modelStart.lineNumber, modelStart.column, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation);
}
let result: editorCommon.IModelDecoration[] = [];
let result: IModelDecoration[] = [];
const modelStartLineIndex = modelStart.lineNumber - 1;
const modelEndLineIndex = modelEnd.lineNumber - 1;
@@ -796,19 +811,19 @@ class VisibleIdentitySplitLine implements ISplitLine {
return 1;
}
public getViewLineContent(model: IModel, modelLineNumber: number, outputLineIndex: number): string {
public getViewLineContent(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): string {
return model.getLineContent(modelLineNumber);
}
public getViewLineMinColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number {
public getViewLineMinColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number {
return model.getLineMinColumn(modelLineNumber);
}
public getViewLineMaxColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number {
public getViewLineMaxColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number {
return model.getLineMaxColumn(modelLineNumber);
}
public getViewLineData(model: IModel, modelLineNumber: number, outputLineIndex: number): ViewLineData {
public getViewLineData(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): ViewLineData {
let lineTokens = model.getLineTokens(modelLineNumber);
let lineContent = lineTokens.getLineContent();
return new ViewLineData(
@@ -819,7 +834,7 @@ class VisibleIdentitySplitLine implements ISplitLine {
);
}
public getViewLinesData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void {
public getViewLinesData(model: ISimpleModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void {
if (!needed[globalStartIndex]) {
result[globalStartIndex] = null;
return;
@@ -861,23 +876,23 @@ class InvisibleIdentitySplitLine implements ISplitLine {
return 0;
}
public getViewLineContent(model: IModel, modelLineNumber: number, outputLineIndex: number): string {
public getViewLineContent(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): string {
throw new Error('Not supported');
}
public getViewLineMinColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number {
public getViewLineMinColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number {
throw new Error('Not supported');
}
public getViewLineMaxColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number {
public getViewLineMaxColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number {
throw new Error('Not supported');
}
public getViewLineData(model: IModel, modelLineNumber: number, outputLineIndex: number): ViewLineData {
public getViewLineData(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): ViewLineData {
throw new Error('Not supported');
}
public getViewLinesData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void {
public getViewLinesData(model: ISimpleModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void {
throw new Error('Not supported');
}
@@ -931,20 +946,25 @@ export class SplitLine implements ISplitLine {
return this.positionMapper.getInputOffsetOfOutputPosition(outputLineIndex, 0);
}
private getInputEndOffsetOfOutputLineIndex(model: IModel, modelLineNumber: number, outputLineIndex: number): number {
private getInputEndOffsetOfOutputLineIndex(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number {
if (outputLineIndex + 1 === this.outputLineCount) {
return model.getLineMaxColumn(modelLineNumber) - 1;
}
return this.positionMapper.getInputOffsetOfOutputPosition(outputLineIndex + 1, 0);
}
public getViewLineContent(model: IModel, modelLineNumber: number, outputLineIndex: number): string {
public getViewLineContent(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): string {
if (!this._isVisible) {
throw new Error('Not supported');
}
let startOffset = this.getInputStartOffsetOfOutputLineIndex(outputLineIndex);
let endOffset = this.getInputEndOffsetOfOutputLineIndex(model, modelLineNumber, outputLineIndex);
let r = model.getLineContent(modelLineNumber).substring(startOffset, endOffset);
let r = model.getValueInRange({
startLineNumber: modelLineNumber,
startColumn: startOffset + 1,
endLineNumber: modelLineNumber,
endColumn: endOffset + 1
});
if (outputLineIndex > 0) {
r = this.wrappedIndent + r;
@@ -953,7 +973,7 @@ export class SplitLine implements ISplitLine {
return r;
}
public getViewLineMinColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number {
public getViewLineMinColumn(model: ITextModel, modelLineNumber: number, outputLineIndex: number): number {
if (!this._isVisible) {
throw new Error('Not supported');
}
@@ -963,14 +983,14 @@ export class SplitLine implements ISplitLine {
return 1;
}
public getViewLineMaxColumn(model: IModel, modelLineNumber: number, outputLineIndex: number): number {
public getViewLineMaxColumn(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): number {
if (!this._isVisible) {
throw new Error('Not supported');
}
return this.getViewLineContent(model, modelLineNumber, outputLineIndex).length + 1;
}
public getViewLineData(model: IModel, modelLineNumber: number, outputLineIndex: number): ViewLineData {
public getViewLineData(model: ISimpleModel, modelLineNumber: number, outputLineIndex: number): ViewLineData {
if (!this._isVisible) {
throw new Error('Not supported');
}
@@ -978,7 +998,13 @@ export class SplitLine implements ISplitLine {
let startOffset = this.getInputStartOffsetOfOutputLineIndex(outputLineIndex);
let endOffset = this.getInputEndOffsetOfOutputLineIndex(model, modelLineNumber, outputLineIndex);
let lineContent = model.getLineContent(modelLineNumber).substring(startOffset, endOffset);
let lineContent = model.getValueInRange({
startLineNumber: modelLineNumber,
startColumn: startOffset + 1,
endLineNumber: modelLineNumber,
endColumn: endOffset + 1
});
if (outputLineIndex > 0) {
lineContent = this.wrappedIndent + lineContent;
}
@@ -1000,7 +1026,7 @@ export class SplitLine implements ISplitLine {
);
}
public getViewLinesData(model: IModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void {
public getViewLinesData(model: ITextModel, modelLineNumber: number, fromOuputLineIndex: number, toOutputLineIndex: number, globalStartIndex: number, needed: boolean[], result: ViewLineData[]): void {
if (!this._isVisible) {
throw new Error('Not supported');
}
@@ -1125,9 +1151,9 @@ export class IdentityCoordinatesConverter implements ICoordinatesConverter {
export class IdentityLinesCollection implements IViewModelLinesCollection {
public readonly model: editorCommon.IModel;
public readonly model: ITextModel;
constructor(model: editorCommon.IModel) {
constructor(model: ITextModel) {
this.model = model;
}
@@ -1138,6 +1164,10 @@ export class IdentityLinesCollection implements IViewModelLinesCollection {
return new IdentityCoordinatesConverter(this);
}
public getHiddenAreas(): Range[] {
return [];
}
public setHiddenAreas(_ranges: Range[]): boolean {
return false;
}
@@ -1243,7 +1273,7 @@ export class IdentityLinesCollection implements IViewModelLinesCollection {
return result.result;
}
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): editorCommon.IModelDecoration[] {
public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[] {
return this.model.getDecorationsInRange(range, ownerId, filterOutValidation);
}
}

View File

@@ -4,11 +4,12 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { INewScrollPosition, EndOfLinePreference, IViewState, IModelDecorationOptions } from 'vs/editor/common/editorCommon';
import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
import { INewScrollPosition, IViewState } from 'vs/editor/common/editorCommon';
import { EndOfLinePreference, IModelDecorationOptions } from 'vs/editor/common/model';
import { IViewLineTokens } from 'vs/editor/common/core/lineTokens';
import { Position, IPosition } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { ViewEvent, IViewEventListener } from 'vs/editor/common/view/viewEvents';
import { IViewEventListener } from 'vs/editor/common/view/viewEvents';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Scrollable, IScrollPosition } from 'vs/base/common/scrollable';
import { IPartialViewLinesViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
@@ -63,7 +64,7 @@ export interface IViewLayout {
getWhitespaces(): IEditorWhitespace[];
saveState(): IViewState;
restoreState(state: IViewState): void;
reduceRestoreState(state: IViewState): { scrollLeft: number; scrollTop: number; };
isAfterLines(verticalOffset: number): boolean;
getLineNumberAtVerticalOffset(verticalOffset: number): number;
@@ -144,7 +145,8 @@ export interface IViewModel {
validateModelPosition(modelPosition: IPosition): Position;
deduceModelPositionRelativeToViewPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position;
getPlainTextToCopy(ranges: Range[], emptySelectionClipboard: boolean): string;
getEOL(): string;
getPlainTextToCopy(ranges: Range[], emptySelectionClipboard: boolean): string | string[];
getHTMLToCopy(ranges: Range[], emptySelectionClipboard: boolean): string;
}
@@ -179,13 +181,13 @@ export class ViewLineData {
/**
* The tokens at this view line.
*/
public readonly tokens: ViewLineToken[];
public readonly tokens: IViewLineTokens;
constructor(
content: string,
minColumn: number,
maxColumn: number,
tokens: ViewLineToken[]
tokens: IViewLineTokens
) {
this.content = content;
this.minColumn = minColumn;
@@ -218,7 +220,7 @@ export class ViewLineRenderingData {
/**
* The tokens at this view line.
*/
public readonly tokens: ViewLineToken[];
public readonly tokens: IViewLineTokens;
/**
* Inline decorations at this view line.
*/
@@ -234,7 +236,7 @@ export class ViewLineRenderingData {
content: string,
mightContainRTL: boolean,
mightContainNonBasicASCII: boolean,
tokens: ViewLineToken[],
tokens: IViewLineTokens,
inlineDecorations: InlineDecoration[],
tabSize: number
) {
@@ -285,25 +287,3 @@ export class ViewModelDecoration {
export interface IOverviewRulerDecorations {
[color: string]: number[];
}
export class ViewEventsCollector {
private _events: ViewEvent[];
private _eventsLen = 0;
constructor() {
this._events = [];
this._eventsLen = 0;
}
public emit(event: ViewEvent) {
this._events[this._eventsLen++] = event;
}
public finalize(): ViewEvent[] {
let result = this._events;
this._events = null;
return result;
}
}

View File

@@ -10,6 +10,7 @@ import { Position } from 'vs/editor/common/core/position';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { InlineDecoration, ViewModelDecoration, ICoordinatesConverter, InlineDecorationType } from 'vs/editor/common/viewModel/viewModel';
import { IViewModelLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection';
import { ITextModel, IModelDecoration } from 'vs/editor/common/model';
export interface IDecorationsViewportData {
/**
@@ -25,7 +26,7 @@ export interface IDecorationsViewportData {
export class ViewModelDecorations implements IDisposable {
private readonly editorId: number;
private readonly model: editorCommon.IModel;
private readonly model: ITextModel;
private readonly configuration: editorCommon.IConfiguration;
private readonly _linesCollection: IViewModelLinesCollection;
private readonly _coordinatesConverter: ICoordinatesConverter;
@@ -35,7 +36,7 @@ export class ViewModelDecorations implements IDisposable {
private _cachedModelDecorationsResolver: IDecorationsViewportData;
private _cachedModelDecorationsResolverViewRange: Range;
constructor(editorId: number, model: editorCommon.IModel, configuration: editorCommon.IConfiguration, linesCollection: IViewModelLinesCollection, coordinatesConverter: ICoordinatesConverter) {
constructor(editorId: number, model: ITextModel, configuration: editorCommon.IConfiguration, linesCollection: IViewModelLinesCollection, coordinatesConverter: ICoordinatesConverter) {
this.editorId = editorId;
this.model = model;
this.configuration = configuration;
@@ -71,7 +72,7 @@ export class ViewModelDecorations implements IDisposable {
this._clearCachedModelDecorationsResolver();
}
private _getOrCreateViewModelDecoration(modelDecoration: editorCommon.IModelDecoration): ViewModelDecoration {
private _getOrCreateViewModelDecoration(modelDecoration: IModelDecoration): ViewModelDecoration {
const id = modelDecoration.id;
let r = this._decorationsCache[id];
if (!r) {
@@ -92,7 +93,7 @@ export class ViewModelDecorations implements IDisposable {
}
public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData {
var cacheIsValid = true;
let cacheIsValid = true;
cacheIsValid = cacheIsValid && (this._cachedModelDecorationsResolver !== null);
cacheIsValid = cacheIsValid && (viewRange.equalsRange(this._cachedModelDecorationsResolverViewRange));
if (!cacheIsValid) {

View File

@@ -11,7 +11,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import { TokenizationRegistry, ColorId, LanguageId } from 'vs/editor/common/modes';
import { tokenizeLineToHTML } from 'vs/editor/common/modes/textToHtmlTokenizer';
import { ViewModelDecorations } from 'vs/editor/common/viewModel/viewModelDecorations';
import { MinimapLinesRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter, ViewEventsCollector, IOverviewRulerDecorations } from 'vs/editor/common/viewModel/viewModel';
import { MinimapLinesRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter, IOverviewRulerDecorations } from 'vs/editor/common/viewModel/viewModel';
import { SplitLinesCollection, IViewModelLinesCollection, IdentityLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { MinimapTokensColorTracker } from 'vs/editor/common/view/minimapCharRenderer';
@@ -22,7 +22,8 @@ import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout';
import { Color } from 'vs/base/common/color';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ITheme } from 'vs/platform/theme/common/themeService';
import { ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModelWithDecorations';
import { ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModel';
import { ITextModel, EndOfLinePreference } from 'vs/editor/common/model';
const USE_IDENTITY_LINES_COLLECTION = true;
@@ -30,7 +31,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
private readonly editorId: number;
private readonly configuration: editorCommon.IConfiguration;
private readonly model: editorCommon.IModel;
private readonly model: ITextModel;
private readonly lines: IViewModelLinesCollection;
public readonly coordinatesConverter: ICoordinatesConverter;
public readonly viewLayout: ViewLayout;
@@ -39,7 +40,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
private _centeredViewLine: number;
constructor(editorId: number, configuration: editorCommon.IConfiguration, model: editorCommon.IModel, scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable) {
constructor(editorId: number, configuration: editorCommon.IConfiguration, model: ITextModel, scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable) {
super();
this.editorId = editorId;
@@ -74,7 +75,12 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.viewLayout = this._register(new ViewLayout(this.configuration, this.getLineCount(), scheduleAtNextAnimationFrame));
this._register(this.viewLayout.onDidScroll((e) => {
this._emit([new viewEvents.ViewScrollChangedEvent(e)]);
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewScrollChangedEvent(e));
} finally {
this._endEmit();
}
}));
this._centeredViewLine = -1;
@@ -84,13 +90,21 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this._registerModelEvents();
this._register(this.configuration.onDidChange((e) => {
const eventsCollector = new ViewEventsCollector();
this._onConfigurationChanged(eventsCollector, e);
this._emit(eventsCollector.finalize());
try {
const eventsCollector = this._beginEmit();
this._onConfigurationChanged(eventsCollector, e);
} finally {
this._endEmit();
}
}));
this._register(MinimapTokensColorTracker.getInstance().onDidChange(() => {
this._emit([new viewEvents.ViewTokensColorsChangedEvent()]);
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewTokensColorsChangedEvent());
} finally {
this._endEmit();
}
}));
}
@@ -102,7 +116,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.lines.dispose();
}
private _onConfigurationChanged(eventsCollector: ViewEventsCollector, e: IConfigurationChangedEvent): void {
private _onConfigurationChanged(eventsCollector: viewEvents.ViewEventsCollector, e: IConfigurationChangedEvent): void {
// We might need to restore the current centered view range, so save it (if available)
const previousCenteredModelRange = this.getCenteredRangeInViewport();
@@ -149,79 +163,81 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
private _registerModelEvents(): void {
this._register(this.model.onDidChangeRawContent((e) => {
const eventsCollector = new ViewEventsCollector();
try {
const eventsCollector = this._beginEmit();
let hadOtherModelChange = false;
let hadModelLineChangeThatChangedLineMapping = false;
const changes = e.changes;
const versionId = e.versionId;
for (let j = 0, lenJ = changes.length; j < lenJ; j++) {
const change = changes[j];
switch (change.changeType) {
case textModelEvents.RawContentChangedType.Flush: {
this.lines.onModelFlushed();
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
this.decorations.reset();
this.viewLayout.onFlushed(this.getLineCount());
hadOtherModelChange = true;
break;
}
case textModelEvents.RawContentChangedType.LinesDeleted: {
const linesDeletedEvent = this.lines.onModelLinesDeleted(versionId, change.fromLineNumber, change.toLineNumber);
if (linesDeletedEvent !== null) {
eventsCollector.emit(linesDeletedEvent);
this.viewLayout.onLinesDeleted(linesDeletedEvent.fromLineNumber, linesDeletedEvent.toLineNumber);
}
hadOtherModelChange = true;
break;
}
case textModelEvents.RawContentChangedType.LinesInserted: {
const linesInsertedEvent = this.lines.onModelLinesInserted(versionId, change.fromLineNumber, change.toLineNumber, change.detail);
if (linesInsertedEvent !== null) {
eventsCollector.emit(linesInsertedEvent);
this.viewLayout.onLinesInserted(linesInsertedEvent.fromLineNumber, linesInsertedEvent.toLineNumber);
}
hadOtherModelChange = true;
break;
}
case textModelEvents.RawContentChangedType.LineChanged: {
const [lineMappingChanged, linesChangedEvent, linesInsertedEvent, linesDeletedEvent] = this.lines.onModelLineChanged(versionId, change.lineNumber, change.detail);
hadModelLineChangeThatChangedLineMapping = lineMappingChanged;
if (linesChangedEvent) {
eventsCollector.emit(linesChangedEvent);
}
if (linesInsertedEvent) {
eventsCollector.emit(linesInsertedEvent);
this.viewLayout.onLinesInserted(linesInsertedEvent.fromLineNumber, linesInsertedEvent.toLineNumber);
}
if (linesDeletedEvent) {
eventsCollector.emit(linesDeletedEvent);
this.viewLayout.onLinesDeleted(linesDeletedEvent.fromLineNumber, linesDeletedEvent.toLineNumber);
}
break;
}
case textModelEvents.RawContentChangedType.EOLChanged: {
// Nothing to do. The new version will be accepted below
break;
}
}
}
this.lines.acceptVersionId(versionId);
if (!hadOtherModelChange && hadModelLineChangeThatChangedLineMapping) {
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
eventsCollector.emit(new viewEvents.ViewDecorationsChangedEvent());
this.decorations.onLineMappingChanged();
}
} finally {
this._endEmit();
}
// Update the configuration and reset the centered view line
this._centeredViewLine = -1;
this.configuration.setMaxLineNumber(this.model.getLineCount());
let hadOtherModelChange = false;
let hadModelLineChangeThatChangedLineMapping = false;
const changes = e.changes;
const versionId = e.versionId;
for (let j = 0, lenJ = changes.length; j < lenJ; j++) {
const change = changes[j];
switch (change.changeType) {
case textModelEvents.RawContentChangedType.Flush: {
this.lines.onModelFlushed();
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
this.decorations.reset();
this.viewLayout.onFlushed(this.getLineCount());
hadOtherModelChange = true;
break;
}
case textModelEvents.RawContentChangedType.LinesDeleted: {
const linesDeletedEvent = this.lines.onModelLinesDeleted(versionId, change.fromLineNumber, change.toLineNumber);
if (linesDeletedEvent !== null) {
eventsCollector.emit(linesDeletedEvent);
this.viewLayout.onLinesDeleted(linesDeletedEvent.fromLineNumber, linesDeletedEvent.toLineNumber);
}
hadOtherModelChange = true;
break;
}
case textModelEvents.RawContentChangedType.LinesInserted: {
const linesInsertedEvent = this.lines.onModelLinesInserted(versionId, change.fromLineNumber, change.toLineNumber, change.detail.split('\n'));
if (linesInsertedEvent !== null) {
eventsCollector.emit(linesInsertedEvent);
this.viewLayout.onLinesInserted(linesInsertedEvent.fromLineNumber, linesInsertedEvent.toLineNumber);
}
hadOtherModelChange = true;
break;
}
case textModelEvents.RawContentChangedType.LineChanged: {
const [lineMappingChanged, linesChangedEvent, linesInsertedEvent, linesDeletedEvent] = this.lines.onModelLineChanged(versionId, change.lineNumber, change.detail);
hadModelLineChangeThatChangedLineMapping = lineMappingChanged;
if (linesChangedEvent) {
eventsCollector.emit(linesChangedEvent);
}
if (linesInsertedEvent) {
eventsCollector.emit(linesInsertedEvent);
this.viewLayout.onLinesInserted(linesInsertedEvent.fromLineNumber, linesInsertedEvent.toLineNumber);
}
if (linesDeletedEvent) {
eventsCollector.emit(linesDeletedEvent);
this.viewLayout.onLinesDeleted(linesDeletedEvent.fromLineNumber, linesDeletedEvent.toLineNumber);
}
break;
}
case textModelEvents.RawContentChangedType.EOLChanged: {
// Nothing to do. The new version will be accepted below
break;
}
}
}
this.lines.acceptVersionId(versionId);
if (!hadOtherModelChange && hadModelLineChangeThatChangedLineMapping) {
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
eventsCollector.emit(new viewEvents.ViewDecorationsChangedEvent());
this.decorations.onLineMappingChanged();
}
this._emit(eventsCollector.finalize());
}));
this._register(this.model.onDidChangeTokens((e) => {
@@ -235,11 +251,21 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
toLineNumber: viewEndLineNumber
};
}
this._emit([new viewEvents.ViewTokensChangedEvent(viewRanges)]);
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewTokensChangedEvent(viewRanges));
} finally {
this._endEmit();
}
}));
this._register(this.model.onDidChangeLanguageConfiguration((e) => {
this._emit([new viewEvents.ViewLanguageConfigurationEvent()]);
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewLanguageConfigurationEvent());
} finally {
this._endEmit();
}
}));
this._register(this.model.onDidChangeOptions((e) => {
@@ -247,31 +273,42 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
if (this.lines.setTabSize(this.model.getOptions().tabSize)) {
this.decorations.onLineMappingChanged();
this.viewLayout.onFlushed(this.getLineCount());
this._emit([
new viewEvents.ViewFlushedEvent(),
new viewEvents.ViewLineMappingChangedEvent(),
new viewEvents.ViewDecorationsChangedEvent(),
]);
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
eventsCollector.emit(new viewEvents.ViewDecorationsChangedEvent());
} finally {
this._endEmit();
}
}
}));
this._register(this.model.onDidChangeDecorations((e) => {
this.decorations.onModelDecorationsChanged();
this._emit([new viewEvents.ViewDecorationsChangedEvent()]);
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewDecorationsChangedEvent());
} finally {
this._endEmit();
}
}));
}
public setHiddenAreas(ranges: Range[]): void {
let eventsCollector = new ViewEventsCollector();
let lineMappingChanged = this.lines.setHiddenAreas(ranges);
if (lineMappingChanged) {
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
eventsCollector.emit(new viewEvents.ViewDecorationsChangedEvent());
this.decorations.onLineMappingChanged();
this.viewLayout.onFlushed(this.getLineCount());
try {
const eventsCollector = this._beginEmit();
let lineMappingChanged = this.lines.setHiddenAreas(ranges);
if (lineMappingChanged) {
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
eventsCollector.emit(new viewEvents.ViewDecorationsChangedEvent());
this.decorations.onLineMappingChanged();
this.viewLayout.onFlushed(this.getLineCount());
}
} finally {
this._endEmit();
}
this._emit(eventsCollector.finalize());
}
public getCenteredRangeInViewport(): Range {
@@ -284,6 +321,51 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
return this.coordinatesConverter.convertViewRangeToModelRange(currentCenteredViewRange);
}
public getVisibleRanges(): Range[] {
const visibleViewRange = this.getCompletelyVisibleViewRange();
const visibleRange = this.coordinatesConverter.convertViewRangeToModelRange(visibleViewRange);
const hiddenAreas = this.lines.getHiddenAreas();
if (hiddenAreas.length === 0) {
return [visibleRange];
}
let result: Range[] = [], resultLen = 0;
let startLineNumber = visibleRange.startLineNumber;
let startColumn = visibleRange.startColumn;
let endLineNumber = visibleRange.endLineNumber;
let endColumn = visibleRange.endColumn;
for (let i = 0, len = hiddenAreas.length; i < len; i++) {
const hiddenStartLineNumber = hiddenAreas[i].startLineNumber;
const hiddenEndLineNumber = hiddenAreas[i].endLineNumber;
if (hiddenEndLineNumber < startLineNumber) {
continue;
}
if (hiddenStartLineNumber > endLineNumber) {
continue;
}
if (startLineNumber < hiddenStartLineNumber) {
result[resultLen++] = new Range(
startLineNumber, startColumn,
hiddenStartLineNumber - 1, this.model.getLineMaxColumn(hiddenStartLineNumber - 1)
);
}
startLineNumber = hiddenEndLineNumber + 1;
startColumn = 1;
}
if (startLineNumber < endLineNumber || (startLineNumber === endLineNumber && startColumn < endColumn)) {
result[resultLen++] = new Range(
startLineNumber, startColumn,
endLineNumber, endColumn
);
}
return result;
}
public getCompletelyVisibleViewRange(): Range {
const partialData = this.viewLayout.getLinesViewportData();
const startViewLineNumber = partialData.completelyVisibleStartLineNumber;
@@ -339,7 +421,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
}
public getLineFirstNonWhitespaceColumn(lineNumber: number): number {
var result = strings.firstNonWhitespaceIndex(this.getLineContent(lineNumber));
const result = strings.firstNonWhitespaceIndex(this.getLineContent(lineNumber));
if (result === -1) {
return 0;
}
@@ -347,7 +429,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
}
public getLineLastNonWhitespaceColumn(lineNumber: number): number {
var result = strings.lastNonWhitespaceIndex(this.getLineContent(lineNumber));
const result = strings.lastNonWhitespaceIndex(this.getLineContent(lineNumber));
if (result === -1) {
return 0;
}
@@ -399,8 +481,8 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
}
}
public getValueInRange(range: Range, eol: editorCommon.EndOfLinePreference): string {
var modelRange = this.coordinatesConverter.convertViewRangeToModelRange(range);
public getValueInRange(range: Range, eol: EndOfLinePreference): string {
const modelRange = this.coordinatesConverter.convertViewRangeToModelRange(range);
return this.model.getValueInRange(modelRange, eol);
}
@@ -428,7 +510,11 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
return this.model.getPositionAt(resultOffset);
}
public getPlainTextToCopy(ranges: Range[], emptySelectionClipboard: boolean): string {
public getEOL(): string {
return this.model.getEOL();
}
public getPlainTextToCopy(ranges: Range[], emptySelectionClipboard: boolean): string | string[] {
const newLineCharacter = this.model.getEOL();
ranges = ranges.slice(0);
@@ -457,9 +543,9 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
let result: string[] = [];
for (let i = 0; i < nonEmptyRanges.length; i++) {
result.push(this.getValueInRange(nonEmptyRanges[i], editorCommon.EndOfLinePreference.TextDefined));
result.push(this.getValueInRange(nonEmptyRanges[i], EndOfLinePreference.TextDefined));
}
return result.join(newLineCharacter);
return result.length === 1 ? result[0] : result;
}
public getHTMLToCopy(viewRanges: Range[], emptySelectionClipboard: boolean): string {