mirror of
https://github.com/stablyai/orca.git
synced 2026-10-04 16:02:08 +00:00
214 lines
8.8 KiB
Diff
214 lines
8.8 KiB
Diff
diff --git a/src/browser/ColorContrastCache.ts b/src/browser/ColorContrastCache.ts
|
|
index fdcd9d133199a6cd6ba9bea9606a02c03ad03b3d..0558a8873f680e8fb2a27cc833c49c5ba658e1dd 100644
|
|
--- a/src/browser/ColorContrastCache.ts
|
|
+++ b/src/browser/ColorContrastCache.ts
|
|
@@ -7,11 +7,17 @@ import { IColorContrastCache } from './Types';
|
|
import { IColor } from '../common/Types';
|
|
import { TwoKeyMap } from '../common/MultiKeyMap';
|
|
|
|
+const CONTRAST_CACHE_MAX_ENTRIES = 4096;
|
|
+
|
|
export class ColorContrastCache implements IColorContrastCache {
|
|
private _color: TwoKeyMap</* bg */number, /* fg */number, IColor | null> = new TwoKeyMap();
|
|
private _css: TwoKeyMap</* bg */number, /* fg */number, string | null> = new TwoKeyMap();
|
|
+ private _entryCount = 0;
|
|
|
|
public setCss(bg: number, fg: number, value: string | null): void {
|
|
+ if (this._css.get(bg, fg) === undefined) {
|
|
+ this._admitNewEntry();
|
|
+ }
|
|
this._css.set(bg, fg, value);
|
|
}
|
|
|
|
@@ -20,6 +26,9 @@ export class ColorContrastCache implements IColorContrastCache {
|
|
}
|
|
|
|
public setColor(bg: number, fg: number, value: IColor | null): void {
|
|
+ if (this._color.get(bg, fg) === undefined) {
|
|
+ this._admitNewEntry();
|
|
+ }
|
|
this._color.set(bg, fg, value);
|
|
}
|
|
|
|
@@ -30,5 +39,14 @@ export class ColorContrastCache implements IColorContrastCache {
|
|
public clear(): void {
|
|
this._color.clear();
|
|
this._css.clear();
|
|
+ this._entryCount = 0;
|
|
+ }
|
|
+
|
|
+ private _admitNewEntry(): void {
|
|
+ // Color pairs outlive atlas pages, including cached misses and DOM-rendered colors.
|
|
+ if (this._entryCount >= CONTRAST_CACHE_MAX_ENTRIES) {
|
|
+ this.clear();
|
|
+ }
|
|
+ this._entryCount++;
|
|
}
|
|
}
|
|
diff --git a/src/common/buffer/Buffer.ts b/src/common/buffer/Buffer.ts
|
|
index e3a88bfeb4bbf79214d799adec30cba8e4dc1b49..f11e55306dde553d8f68b17340c9022cd749e914 100644
|
|
--- a/src/common/buffer/Buffer.ts
|
|
+++ b/src/common/buffer/Buffer.ts
|
|
@@ -504,7 +504,7 @@ export class Buffer extends Disposable implements IBuffer {
|
|
for (let i = Math.min(this.lines.maxLength - 1, originalLinesLength + countToInsert - 1); i >= 0; i--) {
|
|
if (nextToInsert && nextToInsert.start > originalLineIndex + countInsertedSoFar) {
|
|
// Insert extra lines here, adjusting i as needed
|
|
- for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0; nextI--) {
|
|
+ for (let nextI = nextToInsert.newLines.length - 1; nextI >= 0 && i >= 0; nextI--) {
|
|
this.lines.set(i--, nextToInsert.newLines[nextI]);
|
|
}
|
|
i++;
|
|
diff --git a/src/common/buffer/BufferLine.ts b/src/common/buffer/BufferLine.ts
|
|
index 4984f3a49abe8437475c206db1345f5f5fe3979c..43fd5c5b286f23f11d407c9098062e970b6a2ec6 100644
|
|
--- a/src/common/buffer/BufferLine.ts
|
|
+++ b/src/common/buffer/BufferLine.ts
|
|
@@ -116,12 +116,16 @@ export class BufferLine implements IBufferLine {
|
|
* @deprecated
|
|
*/
|
|
public set(index: number, value: CharData): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
this._data[index * Constants.CELL_INDICIES + Cell.FG] = value[CHAR_DATA_ATTR_INDEX];
|
|
if (value[CHAR_DATA_CHAR_INDEX].length > 1) {
|
|
this._combined[index] = value[1];
|
|
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = index | Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
|
|
} else {
|
|
+ if ((this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK)) {
|
|
+ delete this._combined[index];
|
|
+ }
|
|
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
|
|
}
|
|
}
|
|
@@ -226,12 +230,21 @@ export class BufferLine implements IBufferLine {
|
|
* Set data at `index` to `cell`.
|
|
*/
|
|
public setCell(index: number, cell: ICellData): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
if (cell.content & Content.IS_COMBINED_MASK) {
|
|
this._combined[index] = cell.combinedData;
|
|
+ } else {
|
|
+ if ((this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK)) {
|
|
+ delete this._combined[index];
|
|
+ }
|
|
}
|
|
if (cell.bg & BgFlags.HAS_EXTENDED) {
|
|
this._extendedAttrs[index] = cell.extended;
|
|
+ } else {
|
|
+ if ((this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.HAS_EXTENDED)) {
|
|
+ delete this._extendedAttrs[index];
|
|
+ }
|
|
}
|
|
this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] = cell.content;
|
|
this._data[index * Constants.CELL_INDICIES + Cell.FG] = cell.fg;
|
|
@@ -244,9 +257,17 @@ export class BufferLine implements IBufferLine {
|
|
* it gets an optimized access method.
|
|
*/
|
|
public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
+ if ((this._data[index * Constants.CELL_INDICIES + Cell.CONTENT] & Content.IS_COMBINED_MASK)) {
|
|
+ delete this._combined[index];
|
|
+ }
|
|
if (attrs.bg & BgFlags.HAS_EXTENDED) {
|
|
this._extendedAttrs[index] = attrs.extended;
|
|
+ } else {
|
|
+ if ((this._data[index * Constants.CELL_INDICIES + Cell.BG] & BgFlags.HAS_EXTENDED)) {
|
|
+ delete this._extendedAttrs[index];
|
|
+ }
|
|
}
|
|
const $idx = index * Constants.CELL_INDICIES;
|
|
this._data[$idx + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT);
|
|
@@ -261,6 +282,7 @@ export class BufferLine implements IBufferLine {
|
|
* by the previous `setDataFromCodePoint` call, we can omit it here.
|
|
*/
|
|
public addCodepointToCell(index: number, codePoint: number, width: number): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
let content = this._data[index * Constants.CELL_INDICIES + Cell.CONTENT];
|
|
if (content & Content.IS_COMBINED_MASK) {
|
|
@@ -288,6 +310,7 @@ export class BufferLine implements IBufferLine {
|
|
}
|
|
|
|
public insertCells(pos: number, n: number, fillCellData: ICellData): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
pos %= this.length;
|
|
|
|
@@ -309,6 +332,8 @@ export class BufferLine implements IBufferLine {
|
|
}
|
|
}
|
|
|
|
+ $workCell.combinedData = '';
|
|
+
|
|
// handle fullwidth at line end: reset last cell if it is first cell of a wide char
|
|
if (this.getWidth(this.length - 1) === 2) {
|
|
this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData);
|
|
@@ -316,6 +341,7 @@ export class BufferLine implements IBufferLine {
|
|
}
|
|
|
|
public deleteCells(pos: number, n: number, fillCellData: ICellData): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
pos %= this.length;
|
|
if (n < this.length - pos) {
|
|
@@ -331,6 +357,8 @@ export class BufferLine implements IBufferLine {
|
|
}
|
|
}
|
|
|
|
+ $workCell.combinedData = '';
|
|
+
|
|
// handle fullwidth at pos:
|
|
// - reset pos-1 if wide char
|
|
// - reset pos if width==0 (previous second cell of a wide char)
|
|
@@ -343,6 +371,7 @@ export class BufferLine implements IBufferLine {
|
|
}
|
|
|
|
public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
// full branching on respectProtect==true, hopefully getting fast JIT for standard case
|
|
if (respectProtect) {
|
|
@@ -383,6 +412,7 @@ export class BufferLine implements IBufferLine {
|
|
* excess memory (true after shrinking > Constants.CLEANUP_THRESHOLD).
|
|
*/
|
|
public resize(cols: number, fillCellData: ICellData): boolean {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
if (cols === this.length) {
|
|
return this._data.length * 4 * Constants.CLEANUP_THRESHOLD < this._data.buffer.byteLength;
|
|
@@ -443,6 +473,7 @@ export class BufferLine implements IBufferLine {
|
|
|
|
/** fill a line with fillCharData */
|
|
public fill(fillCellData: ICellData, respectProtect: boolean = false): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
// full branching on respectProtect==true, hopefully getting fast JIT for standard case
|
|
if (respectProtect) {
|
|
@@ -515,6 +546,7 @@ export class BufferLine implements IBufferLine {
|
|
}
|
|
|
|
public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {
|
|
+ this._cache = '';
|
|
this._cacheValid = false;
|
|
const srcData = src._data;
|
|
if (applyInReverse) {
|
|
@@ -596,9 +628,17 @@ export class BufferLine implements IBufferLine {
|
|
const srcStart = srcCol * Constants.CELL_INDICIES;
|
|
if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {
|
|
this._combined[destCol] = src._combined[srcCol];
|
|
+ } else {
|
|
+ if (this._combined[destCol] !== undefined) {
|
|
+ delete this._combined[destCol];
|
|
+ }
|
|
}
|
|
if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {
|
|
this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];
|
|
+ } else {
|
|
+ if (this._extendedAttrs[destCol] !== undefined) {
|
|
+ delete this._extendedAttrs[destCol];
|
|
+ }
|
|
}
|
|
}
|
|
|