@xterm/xterm 5.4.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/css/xterm.css +209 -0
  4. package/lib/xterm.js +2 -0
  5. package/lib/xterm.js.map +1 -0
  6. package/package.json +101 -0
  7. package/src/browser/AccessibilityManager.ts +278 -0
  8. package/src/browser/Clipboard.ts +93 -0
  9. package/src/browser/ColorContrastCache.ts +34 -0
  10. package/src/browser/Lifecycle.ts +33 -0
  11. package/src/browser/Linkifier2.ts +416 -0
  12. package/src/browser/LocalizableStrings.ts +12 -0
  13. package/src/browser/OscLinkProvider.ts +128 -0
  14. package/src/browser/RenderDebouncer.ts +83 -0
  15. package/src/browser/Terminal.ts +1317 -0
  16. package/src/browser/TimeBasedDebouncer.ts +86 -0
  17. package/src/browser/Types.d.ts +181 -0
  18. package/src/browser/Viewport.ts +401 -0
  19. package/src/browser/decorations/BufferDecorationRenderer.ts +134 -0
  20. package/src/browser/decorations/ColorZoneStore.ts +117 -0
  21. package/src/browser/decorations/OverviewRulerRenderer.ts +218 -0
  22. package/src/browser/input/CompositionHelper.ts +246 -0
  23. package/src/browser/input/Mouse.ts +54 -0
  24. package/src/browser/input/MoveToCell.ts +249 -0
  25. package/src/browser/public/Terminal.ts +260 -0
  26. package/src/browser/renderer/dom/DomRenderer.ts +509 -0
  27. package/src/browser/renderer/dom/DomRendererRowFactory.ts +526 -0
  28. package/src/browser/renderer/dom/WidthCache.ts +160 -0
  29. package/src/browser/renderer/shared/CellColorResolver.ts +137 -0
  30. package/src/browser/renderer/shared/CharAtlasCache.ts +96 -0
  31. package/src/browser/renderer/shared/CharAtlasUtils.ts +75 -0
  32. package/src/browser/renderer/shared/Constants.ts +14 -0
  33. package/src/browser/renderer/shared/CursorBlinkStateManager.ts +146 -0
  34. package/src/browser/renderer/shared/CustomGlyphs.ts +687 -0
  35. package/src/browser/renderer/shared/DevicePixelObserver.ts +41 -0
  36. package/src/browser/renderer/shared/README.md +1 -0
  37. package/src/browser/renderer/shared/RendererUtils.ts +58 -0
  38. package/src/browser/renderer/shared/SelectionRenderModel.ts +91 -0
  39. package/src/browser/renderer/shared/TextureAtlas.ts +1082 -0
  40. package/src/browser/renderer/shared/Types.d.ts +173 -0
  41. package/src/browser/selection/SelectionModel.ts +144 -0
  42. package/src/browser/selection/Types.d.ts +15 -0
  43. package/src/browser/services/CharSizeService.ts +102 -0
  44. package/src/browser/services/CharacterJoinerService.ts +339 -0
  45. package/src/browser/services/CoreBrowserService.ts +137 -0
  46. package/src/browser/services/MouseService.ts +46 -0
  47. package/src/browser/services/RenderService.ts +279 -0
  48. package/src/browser/services/SelectionService.ts +1031 -0
  49. package/src/browser/services/Services.ts +147 -0
  50. package/src/browser/services/ThemeService.ts +237 -0
  51. package/src/common/CircularList.ts +241 -0
  52. package/src/common/Clone.ts +23 -0
  53. package/src/common/Color.ts +357 -0
  54. package/src/common/CoreTerminal.ts +284 -0
  55. package/src/common/EventEmitter.ts +78 -0
  56. package/src/common/InputHandler.ts +3461 -0
  57. package/src/common/Lifecycle.ts +108 -0
  58. package/src/common/MultiKeyMap.ts +42 -0
  59. package/src/common/Platform.ts +44 -0
  60. package/src/common/SortedList.ts +118 -0
  61. package/src/common/TaskQueue.ts +166 -0
  62. package/src/common/TypedArrayUtils.ts +17 -0
  63. package/src/common/Types.d.ts +553 -0
  64. package/src/common/WindowsMode.ts +27 -0
  65. package/src/common/buffer/AttributeData.ts +196 -0
  66. package/src/common/buffer/Buffer.ts +654 -0
  67. package/src/common/buffer/BufferLine.ts +524 -0
  68. package/src/common/buffer/BufferRange.ts +13 -0
  69. package/src/common/buffer/BufferReflow.ts +223 -0
  70. package/src/common/buffer/BufferSet.ts +134 -0
  71. package/src/common/buffer/CellData.ts +94 -0
  72. package/src/common/buffer/Constants.ts +149 -0
  73. package/src/common/buffer/Marker.ts +43 -0
  74. package/src/common/buffer/Types.d.ts +52 -0
  75. package/src/common/data/Charsets.ts +256 -0
  76. package/src/common/data/EscapeSequences.ts +153 -0
  77. package/src/common/input/Keyboard.ts +398 -0
  78. package/src/common/input/TextDecoder.ts +346 -0
  79. package/src/common/input/UnicodeV6.ts +145 -0
  80. package/src/common/input/WriteBuffer.ts +246 -0
  81. package/src/common/input/XParseColor.ts +80 -0
  82. package/src/common/parser/Constants.ts +58 -0
  83. package/src/common/parser/DcsParser.ts +192 -0
  84. package/src/common/parser/EscapeSequenceParser.ts +792 -0
  85. package/src/common/parser/OscParser.ts +238 -0
  86. package/src/common/parser/Params.ts +229 -0
  87. package/src/common/parser/Types.d.ts +275 -0
  88. package/src/common/public/AddonManager.ts +53 -0
  89. package/src/common/public/BufferApiView.ts +35 -0
  90. package/src/common/public/BufferLineApiView.ts +29 -0
  91. package/src/common/public/BufferNamespaceApi.ts +36 -0
  92. package/src/common/public/ParserApi.ts +37 -0
  93. package/src/common/public/UnicodeApi.ts +27 -0
  94. package/src/common/services/BufferService.ts +151 -0
  95. package/src/common/services/CharsetService.ts +34 -0
  96. package/src/common/services/CoreMouseService.ts +318 -0
  97. package/src/common/services/CoreService.ts +87 -0
  98. package/src/common/services/DecorationService.ts +140 -0
  99. package/src/common/services/InstantiationService.ts +85 -0
  100. package/src/common/services/LogService.ts +124 -0
  101. package/src/common/services/OptionsService.ts +202 -0
  102. package/src/common/services/OscLinkService.ts +115 -0
  103. package/src/common/services/ServiceRegistry.ts +49 -0
  104. package/src/common/services/Services.ts +373 -0
  105. package/src/common/services/UnicodeService.ts +111 -0
  106. package/src/headless/Terminal.ts +136 -0
  107. package/src/headless/public/Terminal.ts +195 -0
  108. package/typings/xterm.d.ts +1857 -0
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Copyright (c) 2019 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { BufferLine } from 'common/buffer/BufferLine';
7
+ import { CircularList } from 'common/CircularList';
8
+ import { IBufferLine, ICellData } from 'common/Types';
9
+
10
+ export interface INewLayoutResult {
11
+ layout: number[];
12
+ countRemoved: number;
13
+ }
14
+
15
+ /**
16
+ * Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed
17
+ * when a wrapped line unwraps.
18
+ * @param lines The buffer lines.
19
+ * @param oldCols The columns before resize
20
+ * @param newCols The columns after resize.
21
+ * @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).
22
+ * @param nullCell The cell data to use when filling in empty cells.
23
+ */
24
+ export function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData): number[] {
25
+ // Gather all BufferLines that need to be removed from the Buffer here so that they can be
26
+ // batched up and only committed once
27
+ const toRemove: number[] = [];
28
+
29
+ for (let y = 0; y < lines.length - 1; y++) {
30
+ // Check if this row is wrapped
31
+ let i = y;
32
+ let nextLine = lines.get(++i) as BufferLine;
33
+ if (!nextLine.isWrapped) {
34
+ continue;
35
+ }
36
+
37
+ // Check how many lines it's wrapped for
38
+ const wrappedLines: BufferLine[] = [lines.get(y) as BufferLine];
39
+ while (i < lines.length && nextLine.isWrapped) {
40
+ wrappedLines.push(nextLine);
41
+ nextLine = lines.get(++i) as BufferLine;
42
+ }
43
+
44
+ // If these lines contain the cursor don't touch them, the program will handle fixing up wrapped
45
+ // lines with the cursor
46
+ if (bufferAbsoluteY >= y && bufferAbsoluteY < i) {
47
+ y += wrappedLines.length - 1;
48
+ continue;
49
+ }
50
+
51
+ // Copy buffer data to new locations
52
+ let destLineIndex = 0;
53
+ let destCol = getWrappedLineTrimmedLength(wrappedLines, destLineIndex, oldCols);
54
+ let srcLineIndex = 1;
55
+ let srcCol = 0;
56
+ while (srcLineIndex < wrappedLines.length) {
57
+ const srcTrimmedTineLength = getWrappedLineTrimmedLength(wrappedLines, srcLineIndex, oldCols);
58
+ const srcRemainingCells = srcTrimmedTineLength - srcCol;
59
+ const destRemainingCells = newCols - destCol;
60
+ const cellsToCopy = Math.min(srcRemainingCells, destRemainingCells);
61
+
62
+ wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol, destCol, cellsToCopy, false);
63
+
64
+ destCol += cellsToCopy;
65
+ if (destCol === newCols) {
66
+ destLineIndex++;
67
+ destCol = 0;
68
+ }
69
+ srcCol += cellsToCopy;
70
+ if (srcCol === srcTrimmedTineLength) {
71
+ srcLineIndex++;
72
+ srcCol = 0;
73
+ }
74
+
75
+ // Make sure the last cell isn't wide, if it is copy it to the current dest
76
+ if (destCol === 0 && destLineIndex !== 0) {
77
+ if (wrappedLines[destLineIndex - 1].getWidth(newCols - 1) === 2) {
78
+ wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[destLineIndex - 1], newCols - 1, destCol++, 1, false);
79
+ // Null out the end of the last row
80
+ wrappedLines[destLineIndex - 1].setCell(newCols - 1, nullCell);
81
+ }
82
+ }
83
+ }
84
+
85
+ // Clear out remaining cells or fragments could remain;
86
+ wrappedLines[destLineIndex].replaceCells(destCol, newCols, nullCell);
87
+
88
+ // Work backwards and remove any rows at the end that only contain null cells
89
+ let countToRemove = 0;
90
+ for (let i = wrappedLines.length - 1; i > 0; i--) {
91
+ if (i > destLineIndex || wrappedLines[i].getTrimmedLength() === 0) {
92
+ countToRemove++;
93
+ } else {
94
+ break;
95
+ }
96
+ }
97
+
98
+ if (countToRemove > 0) {
99
+ toRemove.push(y + wrappedLines.length - countToRemove); // index
100
+ toRemove.push(countToRemove);
101
+ }
102
+
103
+ y += wrappedLines.length - 1;
104
+ }
105
+ return toRemove;
106
+ }
107
+
108
+ /**
109
+ * Creates and return the new layout for lines given an array of indexes to be removed.
110
+ * @param lines The buffer lines.
111
+ * @param toRemove The indexes to remove.
112
+ */
113
+ export function reflowLargerCreateNewLayout(lines: CircularList<IBufferLine>, toRemove: number[]): INewLayoutResult {
114
+ const layout: number[] = [];
115
+ // First iterate through the list and get the actual indexes to use for rows
116
+ let nextToRemoveIndex = 0;
117
+ let nextToRemoveStart = toRemove[nextToRemoveIndex];
118
+ let countRemovedSoFar = 0;
119
+ for (let i = 0; i < lines.length; i++) {
120
+ if (nextToRemoveStart === i) {
121
+ const countToRemove = toRemove[++nextToRemoveIndex];
122
+
123
+ // Tell markers that there was a deletion
124
+ lines.onDeleteEmitter.fire({
125
+ index: i - countRemovedSoFar,
126
+ amount: countToRemove
127
+ });
128
+
129
+ i += countToRemove - 1;
130
+ countRemovedSoFar += countToRemove;
131
+ nextToRemoveStart = toRemove[++nextToRemoveIndex];
132
+ } else {
133
+ layout.push(i);
134
+ }
135
+ }
136
+ return {
137
+ layout,
138
+ countRemoved: countRemovedSoFar
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Applies a new layout to the buffer. This essentially does the same as many splice calls but it's
144
+ * done all at once in a single iteration through the list since splice is very expensive.
145
+ * @param lines The buffer lines.
146
+ * @param newLayout The new layout to apply.
147
+ */
148
+ export function reflowLargerApplyNewLayout(lines: CircularList<IBufferLine>, newLayout: number[]): void {
149
+ // Record original lines so they don't get overridden when we rearrange the list
150
+ const newLayoutLines: BufferLine[] = [];
151
+ for (let i = 0; i < newLayout.length; i++) {
152
+ newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);
153
+ }
154
+
155
+ // Rearrange the list
156
+ for (let i = 0; i < newLayoutLines.length; i++) {
157
+ lines.set(i, newLayoutLines[i]);
158
+ }
159
+ lines.length = newLayout.length;
160
+ }
161
+
162
+ /**
163
+ * Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-
164
+ * compute the wrapping points since wide characters may need to be wrapped onto the following line.
165
+ * This function will return an array of numbers of where each line wraps to, the resulting array
166
+ * will only contain the values `newCols` (when the line does not end with a wide character) and
167
+ * `newCols - 1` (when the line does end with a wide character), except for the last value which
168
+ * will contain the remaining items to fill the line.
169
+ *
170
+ * Calling this with a `newCols` value of `1` will lock up.
171
+ *
172
+ * @param wrappedLines The wrapped lines to evaluate.
173
+ * @param oldCols The columns before resize.
174
+ * @param newCols The columns after resize.
175
+ */
176
+ export function reflowSmallerGetNewLineLengths(wrappedLines: BufferLine[], oldCols: number, newCols: number): number[] {
177
+ const newLineLengths: number[] = [];
178
+ const cellsNeeded = wrappedLines.map((l, i) => getWrappedLineTrimmedLength(wrappedLines, i, oldCols)).reduce((p, c) => p + c);
179
+
180
+ // Use srcCol and srcLine to find the new wrapping point, use that to get the cellsAvailable and
181
+ // linesNeeded
182
+ let srcCol = 0;
183
+ let srcLine = 0;
184
+ let cellsAvailable = 0;
185
+ while (cellsAvailable < cellsNeeded) {
186
+ if (cellsNeeded - cellsAvailable < newCols) {
187
+ // Add the final line and exit the loop
188
+ newLineLengths.push(cellsNeeded - cellsAvailable);
189
+ break;
190
+ }
191
+ srcCol += newCols;
192
+ const oldTrimmedLength = getWrappedLineTrimmedLength(wrappedLines, srcLine, oldCols);
193
+ if (srcCol > oldTrimmedLength) {
194
+ srcCol -= oldTrimmedLength;
195
+ srcLine++;
196
+ }
197
+ const endsWithWide = wrappedLines[srcLine].getWidth(srcCol - 1) === 2;
198
+ if (endsWithWide) {
199
+ srcCol--;
200
+ }
201
+ const lineLength = endsWithWide ? newCols - 1 : newCols;
202
+ newLineLengths.push(lineLength);
203
+ cellsAvailable += lineLength;
204
+ }
205
+
206
+ return newLineLengths;
207
+ }
208
+
209
+ export function getWrappedLineTrimmedLength(lines: BufferLine[], i: number, cols: number): number {
210
+ // If this is the last row in the wrapped line, get the actual trimmed length
211
+ if (i === lines.length - 1) {
212
+ return lines[i].getTrimmedLength();
213
+ }
214
+ // Detect whether the following line starts with a wide character and the end of the current line
215
+ // is null, if so then we can be pretty sure the null character should be excluded from the line
216
+ // length]
217
+ const endsInNull = !(lines[i].hasContent(cols - 1)) && lines[i].getWidth(cols - 1) === 1;
218
+ const followingLineStartsWithWide = lines[i + 1].getWidth(0) === 2;
219
+ if (endsInNull && followingLineStartsWithWide) {
220
+ return cols - 1;
221
+ }
222
+ return cols;
223
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Copyright (c) 2017 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { EventEmitter } from 'common/EventEmitter';
7
+ import { Disposable } from 'common/Lifecycle';
8
+ import { IAttributeData } from 'common/Types';
9
+ import { Buffer } from 'common/buffer/Buffer';
10
+ import { IBuffer, IBufferSet } from 'common/buffer/Types';
11
+ import { IBufferService, IOptionsService } from 'common/services/Services';
12
+
13
+ /**
14
+ * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and
15
+ * provides also utilities for working with them.
16
+ */
17
+ export class BufferSet extends Disposable implements IBufferSet {
18
+ private _normal!: Buffer;
19
+ private _alt!: Buffer;
20
+ private _activeBuffer!: Buffer;
21
+
22
+ private readonly _onBufferActivate = this.register(new EventEmitter<{activeBuffer: IBuffer, inactiveBuffer: IBuffer}>());
23
+ public readonly onBufferActivate = this._onBufferActivate.event;
24
+
25
+ /**
26
+ * Create a new BufferSet for the given terminal.
27
+ */
28
+ constructor(
29
+ private readonly _optionsService: IOptionsService,
30
+ private readonly _bufferService: IBufferService
31
+ ) {
32
+ super();
33
+ this.reset();
34
+ this.register(this._optionsService.onSpecificOptionChange('scrollback', () => this.resize(this._bufferService.cols, this._bufferService.rows)));
35
+ this.register(this._optionsService.onSpecificOptionChange('tabStopWidth', () => this.setupTabStops()));
36
+ }
37
+
38
+ public reset(): void {
39
+ this._normal = new Buffer(true, this._optionsService, this._bufferService);
40
+ this._normal.fillViewportRows();
41
+
42
+ // The alt buffer should never have scrollback.
43
+ // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer
44
+ this._alt = new Buffer(false, this._optionsService, this._bufferService);
45
+ this._activeBuffer = this._normal;
46
+ this._onBufferActivate.fire({
47
+ activeBuffer: this._normal,
48
+ inactiveBuffer: this._alt
49
+ });
50
+
51
+ this.setupTabStops();
52
+ }
53
+
54
+ /**
55
+ * Returns the alt Buffer of the BufferSet
56
+ */
57
+ public get alt(): Buffer {
58
+ return this._alt;
59
+ }
60
+
61
+ /**
62
+ * Returns the currently active Buffer of the BufferSet
63
+ */
64
+ public get active(): Buffer {
65
+ return this._activeBuffer;
66
+ }
67
+
68
+ /**
69
+ * Returns the normal Buffer of the BufferSet
70
+ */
71
+ public get normal(): Buffer {
72
+ return this._normal;
73
+ }
74
+
75
+ /**
76
+ * Sets the normal Buffer of the BufferSet as its currently active Buffer
77
+ */
78
+ public activateNormalBuffer(): void {
79
+ if (this._activeBuffer === this._normal) {
80
+ return;
81
+ }
82
+ this._normal.x = this._alt.x;
83
+ this._normal.y = this._alt.y;
84
+ // The alt buffer should always be cleared when we switch to the normal
85
+ // buffer. This frees up memory since the alt buffer should always be new
86
+ // when activated.
87
+ this._alt.clearAllMarkers();
88
+ this._alt.clear();
89
+ this._activeBuffer = this._normal;
90
+ this._onBufferActivate.fire({
91
+ activeBuffer: this._normal,
92
+ inactiveBuffer: this._alt
93
+ });
94
+ }
95
+
96
+ /**
97
+ * Sets the alt Buffer of the BufferSet as its currently active Buffer
98
+ */
99
+ public activateAltBuffer(fillAttr?: IAttributeData): void {
100
+ if (this._activeBuffer === this._alt) {
101
+ return;
102
+ }
103
+ // Since the alt buffer is always cleared when the normal buffer is
104
+ // activated, we want to fill it when switching to it.
105
+ this._alt.fillViewportRows(fillAttr);
106
+ this._alt.x = this._normal.x;
107
+ this._alt.y = this._normal.y;
108
+ this._activeBuffer = this._alt;
109
+ this._onBufferActivate.fire({
110
+ activeBuffer: this._alt,
111
+ inactiveBuffer: this._normal
112
+ });
113
+ }
114
+
115
+ /**
116
+ * Resizes both normal and alt buffers, adjusting their data accordingly.
117
+ * @param newCols The new number of columns.
118
+ * @param newRows The new number of rows.
119
+ */
120
+ public resize(newCols: number, newRows: number): void {
121
+ this._normal.resize(newCols, newRows);
122
+ this._alt.resize(newCols, newRows);
123
+ this.setupTabStops(newCols);
124
+ }
125
+
126
+ /**
127
+ * Setup the tab stops.
128
+ * @param i The index to start setting up tab stops from.
129
+ */
130
+ public setupTabStops(i?: number): void {
131
+ this._normal.setupTabStops(i);
132
+ this._alt.setupTabStops(i);
133
+ }
134
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { CharData, ICellData, IExtendedAttrs } from 'common/Types';
7
+ import { stringFromCodePoint } from 'common/input/TextDecoder';
8
+ import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, Content } from 'common/buffer/Constants';
9
+ import { AttributeData, ExtendedAttrs } from 'common/buffer/AttributeData';
10
+
11
+ /**
12
+ * CellData - represents a single Cell in the terminal buffer.
13
+ */
14
+ export class CellData extends AttributeData implements ICellData {
15
+ /** Helper to create CellData from CharData. */
16
+ public static fromCharData(value: CharData): CellData {
17
+ const obj = new CellData();
18
+ obj.setFromCharData(value);
19
+ return obj;
20
+ }
21
+ /** Primitives from terminal buffer. */
22
+ public content = 0;
23
+ public fg = 0;
24
+ public bg = 0;
25
+ public extended: IExtendedAttrs = new ExtendedAttrs();
26
+ public combinedData = '';
27
+ /** Whether cell contains a combined string. */
28
+ public isCombined(): number {
29
+ return this.content & Content.IS_COMBINED_MASK;
30
+ }
31
+ /** Width of the cell. */
32
+ public getWidth(): number {
33
+ return this.content >> Content.WIDTH_SHIFT;
34
+ }
35
+ /** JS string of the content. */
36
+ public getChars(): string {
37
+ if (this.content & Content.IS_COMBINED_MASK) {
38
+ return this.combinedData;
39
+ }
40
+ if (this.content & Content.CODEPOINT_MASK) {
41
+ return stringFromCodePoint(this.content & Content.CODEPOINT_MASK);
42
+ }
43
+ return '';
44
+ }
45
+ /**
46
+ * Codepoint of cell
47
+ * Note this returns the UTF32 codepoint of single chars,
48
+ * if content is a combined string it returns the codepoint
49
+ * of the last char in string to be in line with code in CharData.
50
+ */
51
+ public getCode(): number {
52
+ return (this.isCombined())
53
+ ? this.combinedData.charCodeAt(this.combinedData.length - 1)
54
+ : this.content & Content.CODEPOINT_MASK;
55
+ }
56
+ /** Set data from CharData */
57
+ public setFromCharData(value: CharData): void {
58
+ this.fg = value[CHAR_DATA_ATTR_INDEX];
59
+ this.bg = 0;
60
+ let combined = false;
61
+ // surrogates and combined strings need special treatment
62
+ if (value[CHAR_DATA_CHAR_INDEX].length > 2) {
63
+ combined = true;
64
+ }
65
+ else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {
66
+ const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);
67
+ // if the 2-char string is a surrogate create single codepoint
68
+ // everything else is combined
69
+ if (0xD800 <= code && code <= 0xDBFF) {
70
+ const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);
71
+ if (0xDC00 <= second && second <= 0xDFFF) {
72
+ this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
73
+ }
74
+ else {
75
+ combined = true;
76
+ }
77
+ }
78
+ else {
79
+ combined = true;
80
+ }
81
+ }
82
+ else {
83
+ this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
84
+ }
85
+ if (combined) {
86
+ this.combinedData = value[CHAR_DATA_CHAR_INDEX];
87
+ this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
88
+ }
89
+ }
90
+ /** Get data as CharData. */
91
+ public getAsCharData(): CharData {
92
+ return [this.fg, this.getChars(), this.getWidth(), this.getCode()];
93
+ }
94
+ }
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Copyright (c) 2019 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ export const DEFAULT_COLOR = 0;
7
+ export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);
8
+ export const DEFAULT_EXT = 0;
9
+
10
+ export const CHAR_DATA_ATTR_INDEX = 0;
11
+ export const CHAR_DATA_CHAR_INDEX = 1;
12
+ export const CHAR_DATA_WIDTH_INDEX = 2;
13
+ export const CHAR_DATA_CODE_INDEX = 3;
14
+
15
+ /**
16
+ * Null cell - a real empty cell (containing nothing).
17
+ * Note that code should always be 0 for a null cell as
18
+ * several test condition of the buffer line rely on this.
19
+ */
20
+ export const NULL_CELL_CHAR = '';
21
+ export const NULL_CELL_WIDTH = 1;
22
+ export const NULL_CELL_CODE = 0;
23
+
24
+ /**
25
+ * Whitespace cell.
26
+ * This is meant as a replacement for empty cells when needed
27
+ * during rendering lines to preserve correct aligment.
28
+ */
29
+ export const WHITESPACE_CELL_CHAR = ' ';
30
+ export const WHITESPACE_CELL_WIDTH = 1;
31
+ export const WHITESPACE_CELL_CODE = 32;
32
+
33
+ /**
34
+ * Bitmasks for accessing data in `content`.
35
+ */
36
+ export const enum Content {
37
+ /**
38
+ * bit 1..21 codepoint, max allowed in UTF32 is 0x10FFFF (21 bits taken)
39
+ * read: `codepoint = content & Content.codepointMask;`
40
+ * write: `content |= codepoint & Content.codepointMask;`
41
+ * shortcut if precondition `codepoint <= 0x10FFFF` is met:
42
+ * `content |= codepoint;`
43
+ */
44
+ CODEPOINT_MASK = 0x1FFFFF,
45
+
46
+ /**
47
+ * bit 22 flag indication whether a cell contains combined content
48
+ * read: `isCombined = content & Content.isCombined;`
49
+ * set: `content |= Content.isCombined;`
50
+ * clear: `content &= ~Content.isCombined;`
51
+ */
52
+ IS_COMBINED_MASK = 0x200000, // 1 << 21
53
+
54
+ /**
55
+ * bit 1..22 mask to check whether a cell contains any string data
56
+ * we need to check for codepoint and isCombined bits to see
57
+ * whether a cell contains anything
58
+ * read: `isEmpty = !(content & Content.hasContent)`
59
+ */
60
+ HAS_CONTENT_MASK = 0x3FFFFF,
61
+
62
+ /**
63
+ * bit 23..24 wcwidth value of cell, takes 2 bits (ranges from 0..2)
64
+ * read: `width = (content & Content.widthMask) >> Content.widthShift;`
65
+ * `hasWidth = content & Content.widthMask;`
66
+ * as long as wcwidth is highest value in `content`:
67
+ * `width = content >> Content.widthShift;`
68
+ * write: `content |= (width << Content.widthShift) & Content.widthMask;`
69
+ * shortcut if precondition `0 <= width <= 3` is met:
70
+ * `content |= width << Content.widthShift;`
71
+ */
72
+ WIDTH_MASK = 0xC00000, // 3 << 22
73
+ WIDTH_SHIFT = 22
74
+ }
75
+
76
+ export const enum Attributes {
77
+ /**
78
+ * bit 1..8 blue in RGB, color in P256 and P16
79
+ */
80
+ BLUE_MASK = 0xFF,
81
+ BLUE_SHIFT = 0,
82
+ PCOLOR_MASK = 0xFF,
83
+ PCOLOR_SHIFT = 0,
84
+
85
+ /**
86
+ * bit 9..16 green in RGB
87
+ */
88
+ GREEN_MASK = 0xFF00,
89
+ GREEN_SHIFT = 8,
90
+
91
+ /**
92
+ * bit 17..24 red in RGB
93
+ */
94
+ RED_MASK = 0xFF0000,
95
+ RED_SHIFT = 16,
96
+
97
+ /**
98
+ * bit 25..26 color mode: DEFAULT (0) | P16 (1) | P256 (2) | RGB (3)
99
+ */
100
+ CM_MASK = 0x3000000,
101
+ CM_DEFAULT = 0,
102
+ CM_P16 = 0x1000000,
103
+ CM_P256 = 0x2000000,
104
+ CM_RGB = 0x3000000,
105
+
106
+ /**
107
+ * bit 1..24 RGB room
108
+ */
109
+ RGB_MASK = 0xFFFFFF
110
+ }
111
+
112
+ export const enum FgFlags {
113
+ /**
114
+ * bit 27..32
115
+ */
116
+ INVERSE = 0x4000000,
117
+ BOLD = 0x8000000,
118
+ UNDERLINE = 0x10000000,
119
+ BLINK = 0x20000000,
120
+ INVISIBLE = 0x40000000,
121
+ STRIKETHROUGH = 0x80000000,
122
+ }
123
+
124
+ export const enum BgFlags {
125
+ /**
126
+ * bit 27..32 (upper 2 unused)
127
+ */
128
+ ITALIC = 0x4000000,
129
+ DIM = 0x8000000,
130
+ HAS_EXTENDED = 0x10000000,
131
+ PROTECTED = 0x20000000,
132
+ OVERLINE = 0x40000000
133
+ }
134
+
135
+ export const enum ExtFlags {
136
+ /**
137
+ * bit 27..32 (upper 3 unused)
138
+ */
139
+ UNDERLINE_STYLE = 0x1C000000
140
+ }
141
+
142
+ export const enum UnderlineStyle {
143
+ NONE = 0,
144
+ SINGLE = 1,
145
+ DOUBLE = 2,
146
+ CURLY = 3,
147
+ DOTTED = 4,
148
+ DASHED = 5
149
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { EventEmitter } from 'common/EventEmitter';
7
+ import { disposeArray } from 'common/Lifecycle';
8
+ import { IDisposable, IMarker } from 'common/Types';
9
+
10
+ export class Marker implements IMarker {
11
+ private static _nextId = 1;
12
+
13
+ public isDisposed: boolean = false;
14
+ private readonly _disposables: IDisposable[] = [];
15
+
16
+ private readonly _id: number = Marker._nextId++;
17
+ public get id(): number { return this._id; }
18
+
19
+ private readonly _onDispose = this.register(new EventEmitter<void>());
20
+ public readonly onDispose = this._onDispose.event;
21
+
22
+ constructor(
23
+ public line: number
24
+ ) {
25
+ }
26
+
27
+ public dispose(): void {
28
+ if (this.isDisposed) {
29
+ return;
30
+ }
31
+ this.isDisposed = true;
32
+ this.line = -1;
33
+ // Emit before super.dispose such that dispose listeners get a change to react
34
+ this._onDispose.fire();
35
+ disposeArray(this._disposables);
36
+ this._disposables.length = 0;
37
+ }
38
+
39
+ public register<T extends IDisposable>(disposable: T): T {
40
+ this._disposables.push(disposable);
41
+ return disposable;
42
+ }
43
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright (c) 2019 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { IAttributeData, ICircularList, IBufferLine, ICellData, IMarker, ICharset, IDisposable } from 'common/Types';
7
+ import { IEvent } from 'common/EventEmitter';
8
+
9
+ // BufferIndex denotes a position in the buffer: [rowIndex, colIndex]
10
+ export type BufferIndex = [number, number];
11
+
12
+ export interface IBuffer {
13
+ readonly lines: ICircularList<IBufferLine>;
14
+ ydisp: number;
15
+ ybase: number;
16
+ y: number;
17
+ x: number;
18
+ tabs: any;
19
+ scrollBottom: number;
20
+ scrollTop: number;
21
+ hasScrollback: boolean;
22
+ savedY: number;
23
+ savedX: number;
24
+ savedCharset: ICharset | undefined;
25
+ savedCurAttrData: IAttributeData;
26
+ isCursorInViewport: boolean;
27
+ markers: IMarker[];
28
+ translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string;
29
+ getWrappedRangeForLine(y: number): { first: number, last: number };
30
+ nextStop(x?: number): number;
31
+ prevStop(x?: number): number;
32
+ getBlankLine(attr: IAttributeData, isWrapped?: boolean): IBufferLine;
33
+ getNullCell(attr?: IAttributeData): ICellData;
34
+ getWhitespaceCell(attr?: IAttributeData): ICellData;
35
+ addMarker(y: number): IMarker;
36
+ clearMarkers(y: number): void;
37
+ clearAllMarkers(): void;
38
+ }
39
+
40
+ export interface IBufferSet extends IDisposable {
41
+ alt: IBuffer;
42
+ normal: IBuffer;
43
+ active: IBuffer;
44
+
45
+ onBufferActivate: IEvent<{ activeBuffer: IBuffer, inactiveBuffer: IBuffer }>;
46
+
47
+ activateNormalBuffer(): void;
48
+ activateAltBuffer(fillAttr?: IAttributeData): void;
49
+ reset(): void;
50
+ resize(newCols: number, newRows: number): void;
51
+ setupTabStops(i?: number): void;
52
+ }