Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/common/viewModel.ts
5220 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as arrays from '../../base/common/arrays.js';
7
import { IScrollPosition, Scrollable } from '../../base/common/scrollable.js';
8
import * as strings from '../../base/common/strings.js';
9
import { ISimpleModel } from './viewModel/screenReaderSimpleModel.js';
10
import { ICoordinatesConverter } from './coordinatesConverter.js';
11
import { IPosition, Position } from './core/position.js';
12
import { Range } from './core/range.js';
13
import { CursorConfiguration, CursorState, EditOperationType, IColumnSelectData, ICursorSimpleModel, PartialCursorState } from './cursorCommon.js';
14
import { CursorChangeReason } from './cursorEvents.js';
15
import { INewScrollPosition, ScrollType } from './editorCommon.js';
16
import { EditorTheme } from './editorTheme.js';
17
import { EndOfLinePreference, IGlyphMarginLanesModel, IModelDecorationOptions, ITextModel, TextDirection } from './model.js';
18
import { ILineBreaksComputer, InjectedText } from './modelLineProjectionData.js';
19
import { InternalModelContentChangeEvent, ModelInjectedTextChangedEvent } from './textModelEvents.js';
20
import { BracketGuideOptions, IActiveIndentGuideInfo, IndentGuide } from './textModelGuides.js';
21
import { IViewLineTokens } from './tokens/lineTokens.js';
22
import { ViewEventHandler } from './viewEventHandler.js';
23
import { VerticalRevealType } from './viewEvents.js';
24
import { InlineDecoration, SingleLineInlineDecoration } from './viewModel/inlineDecorations.js';
25
import { EditorOption, FindComputedEditorOptionValueById } from './config/editorOptions.js';
26
27
export interface IViewModel extends ICursorSimpleModel, ISimpleModel {
28
29
readonly model: ITextModel;
30
31
readonly coordinatesConverter: ICoordinatesConverter;
32
33
readonly viewLayout: IViewLayout;
34
35
readonly cursorConfig: CursorConfiguration;
36
37
readonly glyphLanes: IGlyphMarginLanesModel;
38
39
addViewEventHandler(eventHandler: ViewEventHandler): void;
40
removeViewEventHandler(eventHandler: ViewEventHandler): void;
41
42
getEditorOption<T extends EditorOption>(id: T): FindComputedEditorOptionValueById<T>;
43
44
/**
45
* Gives a hint that a lot of requests are about to come in for these line numbers.
46
*/
47
setViewport(startLineNumber: number, endLineNumber: number, centeredLineNumber: number): void;
48
visibleLinesStabilized(): void;
49
setHasFocus(hasFocus: boolean): void;
50
setHasWidgetFocus(hasWidgetFocus: boolean): void;
51
onCompositionStart(): void;
52
onCompositionEnd(): void;
53
54
getFontSizeAtPosition(position: IPosition): string | null;
55
getMinimapDecorationsInRange(range: Range): ViewModelDecoration[];
56
getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[];
57
getTextDirection(lineNumber: number): TextDirection;
58
getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData;
59
getViewLineRenderingData(lineNumber: number): ViewLineRenderingData;
60
getViewLineData(lineNumber: number): ViewLineData;
61
getMinimapLinesRenderingData(startLineNumber: number, endLineNumber: number, needed: boolean[]): MinimapLinesRenderingData;
62
getCompletelyVisibleViewRange(): Range;
63
getCompletelyVisibleViewRangeAtScrollTop(scrollTop: number): Range;
64
getViewRangeWithCursorPadding(viewRange: Range): Range;
65
66
getHiddenAreas(): Range[];
67
68
getLineCount(): number;
69
getLineContent(lineNumber: number): string;
70
getLineLength(lineNumber: number): number;
71
getActiveIndentGuide(lineNumber: number, minLineNumber: number, maxLineNumber: number): IActiveIndentGuideInfo;
72
getLinesIndentGuides(startLineNumber: number, endLineNumber: number): number[];
73
getBracketGuidesInRangeByLine(startLineNumber: number, endLineNumber: number, activePosition: IPosition | null, options: BracketGuideOptions): IndentGuide[][];
74
getLineMinColumn(lineNumber: number): number;
75
getLineMaxColumn(lineNumber: number): number;
76
getLineFirstNonWhitespaceColumn(lineNumber: number): number;
77
getLineLastNonWhitespaceColumn(lineNumber: number): number;
78
getAllOverviewRulerDecorations(theme: EditorTheme): OverviewRulerDecorationsGroup[];
79
getValueInRange(range: Range, eol: EndOfLinePreference): string;
80
getValueLengthInRange(range: Range, eol: EndOfLinePreference): number;
81
modifyPosition(position: Position, offset: number): Position;
82
83
getInjectedTextAt(viewPosition: Position): InjectedText | null;
84
85
deduceModelPositionRelativeToViewPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position;
86
getPlainTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean, forceCRLF: boolean): { sourceRanges: Range[]; sourceText: string | string[] };
87
getRichTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean): { html: string; mode: string } | null;
88
89
onDidChangeContentOrInjectedText(e: InternalModelContentChangeEvent | ModelInjectedTextChangedEvent): void;
90
emitContentChangeEvent(e: InternalModelContentChangeEvent | ModelInjectedTextChangedEvent): void;
91
92
createLineBreaksComputer(): ILineBreaksComputer;
93
94
//#region cursor
95
getPrimaryCursorState(): CursorState;
96
getLastAddedCursorIndex(): number;
97
getCursorStates(): CursorState[];
98
setCursorStates(source: string | null | undefined, reason: CursorChangeReason, states: PartialCursorState[] | null): boolean;
99
getCursorColumnSelectData(): IColumnSelectData;
100
getCursorAutoClosedCharacters(): Range[];
101
setCursorColumnSelectData(columnSelectData: IColumnSelectData): void;
102
getPrevEditOperationType(): EditOperationType;
103
setPrevEditOperationType(type: EditOperationType): void;
104
revealAllCursors(source: string | null | undefined, revealHorizontal: boolean, minimalReveal?: boolean): void;
105
revealPrimaryCursor(source: string | null | undefined, revealHorizontal: boolean, minimalReveal?: boolean): void;
106
revealTopMostCursor(source: string | null | undefined): void;
107
revealBottomMostCursor(source: string | null | undefined): void;
108
revealRange(source: string | null | undefined, revealHorizontal: boolean, viewRange: Range, verticalType: VerticalRevealType, scrollType: ScrollType): void;
109
//#endregion
110
111
//#region viewLayout
112
changeWhitespace(callback: (accessor: IWhitespaceChangeAccessor) => void): void;
113
//#endregion
114
115
batchEvents(callback: () => void): void;
116
}
117
118
export interface IViewLayout {
119
120
getScrollable(): Scrollable;
121
122
getScrollWidth(): number;
123
getScrollHeight(): number;
124
125
getCurrentScrollLeft(): number;
126
getCurrentScrollTop(): number;
127
getCurrentViewport(): Viewport;
128
129
getFutureViewport(): Viewport;
130
131
setScrollPosition(position: INewScrollPosition, type: ScrollType): void;
132
deltaScrollNow(deltaScrollLeft: number, deltaScrollTop: number): void;
133
134
validateScrollPosition(scrollPosition: INewScrollPosition): IScrollPosition;
135
136
setMaxLineWidth(maxLineWidth: number): void;
137
setOverlayWidgetsMinWidth(overlayWidgetsMinWidth: number): void;
138
139
getLinesViewportData(): IPartialViewLinesViewportData;
140
getLinesViewportDataAtScrollTop(scrollTop: number): IPartialViewLinesViewportData;
141
getWhitespaces(): IEditorWhitespace[];
142
143
isAfterLines(verticalOffset: number): boolean;
144
isInTopPadding(verticalOffset: number): boolean;
145
isInBottomPadding(verticalOffset: number): boolean;
146
getLineNumberAtVerticalOffset(verticalOffset: number): number;
147
getVerticalOffsetForLineNumber(lineNumber: number, includeViewZones?: boolean): number;
148
getVerticalOffsetAfterLineNumber(lineNumber: number, includeViewZones?: boolean): number;
149
getLineHeightForLineNumber(lineNumber: number): number;
150
getWhitespaceAtVerticalOffset(verticalOffset: number): IViewWhitespaceViewportData | null;
151
152
/**
153
* Get the layout information for whitespaces currently in the viewport
154
*/
155
getWhitespaceViewportData(): IViewWhitespaceViewportData[];
156
}
157
158
export interface IEditorWhitespace {
159
readonly id: string;
160
readonly afterLineNumber: number;
161
readonly height: number;
162
}
163
164
/**
165
* An accessor that allows for whitespace to be added, removed or changed in bulk.
166
*/
167
export interface IWhitespaceChangeAccessor {
168
insertWhitespace(afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): string;
169
changeOneWhitespace(id: string, newAfterLineNumber: number, newHeight: number): void;
170
removeWhitespace(id: string): void;
171
}
172
173
export interface ILineHeightChangeAccessor {
174
insertOrChangeCustomLineHeight(decorationId: string, startLineNumber: number, endLineNumber: number, lineHeight: number): void;
175
removeCustomLineHeight(decorationId: string): void;
176
}
177
178
export interface IPartialViewLinesViewportData {
179
/**
180
* Value to be substracted from `scrollTop` (in order to vertical offset numbers < 1MM)
181
*/
182
readonly bigNumbersDelta: number;
183
/**
184
* The first (partially) visible line number.
185
*/
186
readonly startLineNumber: number;
187
/**
188
* The last (partially) visible line number.
189
*/
190
readonly endLineNumber: number;
191
/**
192
* relativeVerticalOffset[i] is the `top` position for line at `i` + `startLineNumber`.
193
*/
194
readonly relativeVerticalOffset: number[];
195
/**
196
* The centered line in the viewport.
197
*/
198
readonly centeredLineNumber: number;
199
/**
200
* The first completely visible line number.
201
*/
202
readonly completelyVisibleStartLineNumber: number;
203
/**
204
* The last completely visible line number.
205
*/
206
readonly completelyVisibleEndLineNumber: number;
207
208
/**
209
* The height of a line.
210
*/
211
readonly lineHeight: number;
212
}
213
214
export interface IViewWhitespaceViewportData {
215
readonly id: string;
216
readonly afterLineNumber: number;
217
readonly verticalOffset: number;
218
readonly height: number;
219
}
220
221
export class Viewport {
222
readonly _viewportBrand: void = undefined;
223
224
readonly top: number;
225
readonly left: number;
226
readonly width: number;
227
readonly height: number;
228
229
constructor(top: number, left: number, width: number, height: number) {
230
this.top = top | 0;
231
this.left = left | 0;
232
this.width = width | 0;
233
this.height = height | 0;
234
}
235
}
236
237
export class MinimapLinesRenderingData {
238
public readonly tabSize: number;
239
public readonly data: Array<ViewLineData | null>;
240
241
constructor(
242
tabSize: number,
243
data: Array<ViewLineData | null>
244
) {
245
this.tabSize = tabSize;
246
this.data = data;
247
}
248
}
249
250
export class ViewLineData {
251
_viewLineDataBrand: void = undefined;
252
253
/**
254
* The content at this view line.
255
*/
256
public readonly content: string;
257
/**
258
* Does this line continue with a wrapped line?
259
*/
260
public readonly continuesWithWrappedLine: boolean;
261
/**
262
* The minimum allowed column at this view line.
263
*/
264
public readonly minColumn: number;
265
/**
266
* The maximum allowed column at this view line.
267
*/
268
public readonly maxColumn: number;
269
/**
270
* The visible column at the start of the line (after the fauxIndent).
271
*/
272
public readonly startVisibleColumn: number;
273
/**
274
* The tokens at this view line.
275
*/
276
public readonly tokens: IViewLineTokens;
277
278
/**
279
* Additional inline decorations for this line.
280
*/
281
public readonly inlineDecorations: readonly SingleLineInlineDecoration[] | null;
282
283
constructor(
284
content: string,
285
continuesWithWrappedLine: boolean,
286
minColumn: number,
287
maxColumn: number,
288
startVisibleColumn: number,
289
tokens: IViewLineTokens,
290
inlineDecorations: readonly SingleLineInlineDecoration[] | null
291
) {
292
this.content = content;
293
this.continuesWithWrappedLine = continuesWithWrappedLine;
294
this.minColumn = minColumn;
295
this.maxColumn = maxColumn;
296
this.startVisibleColumn = startVisibleColumn;
297
this.tokens = tokens;
298
this.inlineDecorations = inlineDecorations;
299
}
300
}
301
302
export class ViewLineRenderingData {
303
/**
304
* The minimum allowed column at this view line.
305
*/
306
public readonly minColumn: number;
307
/**
308
* The maximum allowed column at this view line.
309
*/
310
public readonly maxColumn: number;
311
/**
312
* The content at this view line.
313
*/
314
public readonly content: string;
315
/**
316
* Does this line continue with a wrapped line?
317
*/
318
public readonly continuesWithWrappedLine: boolean;
319
/**
320
* Describes if `content` contains RTL characters.
321
*/
322
public readonly containsRTL: boolean;
323
/**
324
* Describes if `content` contains non basic ASCII chars.
325
*/
326
public readonly isBasicASCII: boolean;
327
/**
328
* The tokens at this view line.
329
*/
330
public readonly tokens: IViewLineTokens;
331
/**
332
* Inline decorations at this view line.
333
*/
334
public readonly inlineDecorations: InlineDecoration[];
335
/**
336
* The tab size for this view model.
337
*/
338
public readonly tabSize: number;
339
/**
340
* The visible column at the start of the line (after the fauxIndent)
341
*/
342
public readonly startVisibleColumn: number;
343
/**
344
* The direction to use for rendering the line.
345
*/
346
public readonly textDirection: TextDirection;
347
/**
348
* Whether the line has variable fonts
349
*/
350
public readonly hasVariableFonts: boolean;
351
352
constructor(
353
minColumn: number,
354
maxColumn: number,
355
content: string,
356
continuesWithWrappedLine: boolean,
357
mightContainRTL: boolean,
358
mightContainNonBasicASCII: boolean,
359
tokens: IViewLineTokens,
360
inlineDecorations: InlineDecoration[],
361
tabSize: number,
362
startVisibleColumn: number,
363
textDirection: TextDirection,
364
hasVariableFonts: boolean
365
) {
366
this.minColumn = minColumn;
367
this.maxColumn = maxColumn;
368
this.content = content;
369
this.continuesWithWrappedLine = continuesWithWrappedLine;
370
371
this.isBasicASCII = ViewLineRenderingData.isBasicASCII(content, mightContainNonBasicASCII);
372
this.containsRTL = ViewLineRenderingData.containsRTL(content, this.isBasicASCII, mightContainRTL);
373
374
this.tokens = tokens;
375
this.inlineDecorations = inlineDecorations;
376
this.tabSize = tabSize;
377
this.startVisibleColumn = startVisibleColumn;
378
this.textDirection = textDirection;
379
this.hasVariableFonts = hasVariableFonts;
380
}
381
382
public static isBasicASCII(lineContent: string, mightContainNonBasicASCII: boolean): boolean {
383
if (mightContainNonBasicASCII) {
384
return strings.isBasicASCII(lineContent);
385
}
386
return true;
387
}
388
389
public static containsRTL(lineContent: string, isBasicASCII: boolean, mightContainRTL: boolean): boolean {
390
if (!isBasicASCII && mightContainRTL) {
391
return strings.containsRTL(lineContent);
392
}
393
return false;
394
}
395
}
396
397
export class ViewModelDecoration {
398
_viewModelDecorationBrand: void = undefined;
399
400
public readonly range: Range;
401
public readonly options: IModelDecorationOptions;
402
403
constructor(range: Range, options: IModelDecorationOptions) {
404
this.range = range;
405
this.options = options;
406
}
407
}
408
409
export class OverviewRulerDecorationsGroup {
410
411
constructor(
412
public readonly color: string,
413
public readonly zIndex: number,
414
/**
415
* Decorations are encoded in a number array using the following scheme:
416
* - 3*i = lane
417
* - 3*i+1 = startLineNumber
418
* - 3*i+2 = endLineNumber
419
*/
420
public readonly data: number[]
421
) { }
422
423
public static compareByRenderingProps(a: OverviewRulerDecorationsGroup, b: OverviewRulerDecorationsGroup): number {
424
if (a.zIndex === b.zIndex) {
425
if (a.color < b.color) {
426
return -1;
427
}
428
if (a.color > b.color) {
429
return 1;
430
}
431
return 0;
432
}
433
return a.zIndex - b.zIndex;
434
}
435
436
public static equals(a: OverviewRulerDecorationsGroup, b: OverviewRulerDecorationsGroup): boolean {
437
return (
438
a.color === b.color
439
&& a.zIndex === b.zIndex
440
&& arrays.equals(a.data, b.data)
441
);
442
}
443
444
public static equalsArr(a: OverviewRulerDecorationsGroup[], b: OverviewRulerDecorationsGroup[]): boolean {
445
return arrays.equals(a, b, OverviewRulerDecorationsGroup.equals);
446
}
447
}
448
449