Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/addon-search/src/SearchEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class SearchEngine {
this._terminal.clearSelection();
return undefined;
}
if (startCol > this._terminal.cols) {
if (startCol >= this._terminal.cols) {
throw new Error(`Invalid col: ${startCol} to search in terminal of ${this._terminal.cols} cols`);
}

Expand Down
3 changes: 2 additions & 1 deletion addons/addon-web-links/src/WebLinkProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ function isUrl(urlString: string): boolean {

export class LinkComputer {
public static computeLink(y: number, regex: RegExp, terminal: Terminal, activate: (event: MouseEvent, uri: string) => void): ILink[] {
const rex = new RegExp(regex.source, (regex.flags || '') + 'g');
const flags = regex.flags.includes('g') ? regex.flags : `${regex.flags}g`;
const rex = new RegExp(regex.source, flags);

const [lines, startLineIndex] = LinkComputer._getWindowedLineStrings(y - 1, terminal);
const line = lines.join('');
Expand Down
2 changes: 1 addition & 1 deletion addons/addon-webgl/src/TextureAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export class TextureAtlas implements ITextureAtlas {
return newPage;
}

const sortedMergingPagesIndexes = mergingPages.map(e => e.glyphs[0].texturePage).sort((a, b) => a > b ? 1 : -1);
const sortedMergingPagesIndexes = mergingPages.map(e => e.glyphs[0].texturePage).sort((a, b) => a - b);
const mergedPageIndex = this.pages.length - mergingPages.length;

// Merge into the new page
Expand Down
7 changes: 5 additions & 2 deletions bin/esbuild_all.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ for (const addon of addons) {
// Demo job - This requires the others to be built so it's not included when building all
// jobs.push(createJob('demo-client', [`--demo-client`]));

await Promise.all(jobs.map((job, i) => {
const codes = await Promise.all(jobs.map(job => {
return new Promise(r => {
job.cp.on('exit', code => {
log(`Finished \x1b[32m${job.name}\x1b[0m${code ? ' \x1b[31mwith errors\x1b[0m' : ''}`);
r(code);
r(code ?? 1);
});
});
}));
if (codes.some(code => code !== 0)) {
process.exit(1);
}

/**
* @param {string} message
Expand Down
4 changes: 2 additions & 2 deletions bin/setup-full.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { spawnSync } from 'node:child_process';
import { basename, dirname, resolve, sep } from 'node:path';
import { fileURLToPath } from 'node:url';

const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const nodeModulesPath = resolve(repoRoot, 'node_modules');
const npmExecutable = process.platform === 'win32' ? 'npm.cmd' : 'npm';

/** @typedef {{ folder: string; reason: string }} Candidate */

/** @param {string} message */
function log(message) {
console.info(`[setup-fast] ${message}`);
console.info(`[setup-full] ${message}`);
}

/** @param {string[]} args */
Expand Down
15 changes: 12 additions & 3 deletions bin/test_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ let argv = process.argv.slice(2);
let suiteFilter = undefined;
while (argv.some(e => e.startsWith('--suite='))) {
const i = argv.findIndex(e => e.startsWith('--suite='));
const match = argv[i].match(/--suite=(?<suitename>.+)/)
const match = argv[i].match(/--suite=(?<suitename>.+)/);
suiteFilter = match?.groups?.suitename ?? undefined;
argv.splice(i, 1);
}
Expand Down Expand Up @@ -42,12 +42,18 @@ if (suiteFilter) {
configs = configs.filter(e => e.name === suiteFilter);
}

if (suiteFilter && configs.length === 0) {
console.error(`Unknown suite: ${suiteFilter}`);
process.exit(1);
}

function npmBinScript(script) {
return path.resolve(__dirname, `../node_modules/.bin/` + (process.platform === 'win32' ?
`${script}.cmd` : script));
}

async function run() {
let exitCode = 0;
for (const config of configs) {
const command = npmBinScript('playwright');
const args = ['test', '-c', config.path, ...argv];
Expand All @@ -62,10 +68,13 @@ async function run() {

if (run.error) {
console.error(run.error);
process.exit(run.status ?? -1);
process.exit(run.status ?? 1);
}

process.exit(run.status);
if (run.status) {
exitCode = run.status;
}
}
process.exit(exitCode);
}
run();
2 changes: 1 addition & 1 deletion bin/test_mousemodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ const ENC = {
}

function printMenu() {
console.log('\x1b[2J\x1b\[HTest mouse reports [Ctrl-C to exit]');
console.log('\x1b[2J\x1b[HTest mouse reports [Ctrl-C to exit]');
console.log();
console.log(' Selected protocol [Ctrl-A to switch]');
const protocols = Object.keys(PROTOCOLS);
Expand Down
6 changes: 2 additions & 4 deletions bin/test_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if (process.argv.length > 2) {
flagArgs = args.filter(e => e.startsWith('--'));
// ability to inject particular test files via
// npm run test [testFileA testFileB ...]
files = args.filter(e => !e.startsWith('--'));
const files = args.filter(e => !e.startsWith('--'));
if (files.length) {
testFiles = files;
}
Expand All @@ -39,8 +39,6 @@ if (checkCoverage) {
...testFiles,
...flagArgs
];
console.info('executable', executable);
console.info('args', args);
const run = cp.spawnSync(
executable,
args,
Expand All @@ -51,7 +49,7 @@ if (checkCoverage) {
stdio: 'inherit'
}
);
process.exit(run.status);
process.exit(run.status ?? -1);
}

const run = cp.spawnSync(
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@
"test-integration-firefox": "node ./bin/test_integration.js --workers=75% \"--project=FirefoxStable\"",
"test-integration-webkit": "node ./bin/test_integration.js --workers=75% \"--project=WebKit\"",
"test-integration-debug": "node ./bin/test_integration.js --workers=1 --headed --timeout=30000",
"benchmark": "xterm-benchmark -r 5 -c test/benchmark/benchmark.json",
"benchmark-baseline": "xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/*benchmark.js",
"benchmark-eval": "xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/*benchmark.js",
"benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json",
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/*benchmark.js",
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/*benchmark.js",
"clean": "rm -rf lib out addons/*/lib addons/*/out",
"vtfeatures": "node bin/extract_vtfeatures.js src/*/*.ts src/*/*/*.ts src/*.ts addons/**/src/*.ts",
"prepackage": "npm run build",
Expand Down
61 changes: 32 additions & 29 deletions src/common/buffer/BufferLine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ export interface IBufferLineStringCache {
*/
export class BufferLine implements IBufferLine {
protected _data: Uint32Array;
/** Sparse cache; only read when `IS_COMBINED_MASK` is set in `_data`. */
protected _combined: {[index: number]: string} = {};
/** Sparse cache; only read when `HAS_EXTENDED` is set in `_data`. */
protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};
protected _stringCacheEntryRef: WeakRef<IBufferLineStringCacheEntry> | undefined;
public length: number;
Expand Down Expand Up @@ -205,9 +207,15 @@ export class BufferLine implements IBufferLine {
cell.bg = this._data[$startIndex + Cell.BG];
if (cell.content & Content.IS_COMBINED_MASK) {
cell.combinedData = this._combined[index];
} else {
cell.combinedData = '';
}
if (cell.bg & BgFlags.HAS_EXTENDED) {
cell.extended = this._extendedAttrs[index]!;
} else {
// Do not mutate cell.extended in place: it may still reference this line's map entry from a
// prior loadCell into a reused CellData (e.g. $workCell during insert/delete).
cell.extended = DEFAULT_ATTR_DATA.extended.clone();
}
return cell;
}
Expand Down Expand Up @@ -459,14 +467,7 @@ export class BufferLine implements IBufferLine {
this._data.set(line._data);
}
this.length = line.length;
this._combined = {};
for (const el in line._combined) {
this._combined[el] = line._combined[el];
}
this._extendedAttrs = {};
for (const el in line._extendedAttrs) {
this._extendedAttrs[el] = line._extendedAttrs[el];
}
this._copySparseMapsFrom(line);
this.isWrapped = line.isWrapped;
}

Expand All @@ -475,12 +476,7 @@ export class BufferLine implements IBufferLine {
const newLine = new BufferLine(this._stringCache, 0, undefined, false);
newLine._data = new Uint32Array(this._data);
newLine.length = this.length;
for (const el in this._combined) {
newLine._combined[el] = this._combined[el];
}
for (const el in this._extendedAttrs) {
newLine._extendedAttrs[el] = this._extendedAttrs[el];
}
newLine._copySparseMapsFrom(this);
newLine.isWrapped = this.isWrapped;
return newLine;
}
Expand Down Expand Up @@ -511,27 +507,14 @@ export class BufferLine implements IBufferLine {
for (let i = 0; i < Constants.CELL_INDICIES; i++) {
this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];
}
if (srcData[(srcCol + cell) * Constants.CELL_INDICIES + Cell.BG] & BgFlags.HAS_EXTENDED) {
this._extendedAttrs[destCol + cell] = src._extendedAttrs[srcCol + cell];
}
this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);
}
} else {
for (let cell = 0; cell < length; cell++) {
for (let i = 0; i < Constants.CELL_INDICIES; i++) {
this._data[(destCol + cell) * Constants.CELL_INDICIES + i] = srcData[(srcCol + cell) * Constants.CELL_INDICIES + i];
}
if (srcData[(srcCol + cell) * Constants.CELL_INDICIES + Cell.BG] & BgFlags.HAS_EXTENDED) {
this._extendedAttrs[destCol + cell] = src._extendedAttrs[srcCol + cell];
}
}
}

// Move any combined data over as needed, FIXME: repeat for extended attrs
const srcCombinedKeys = Object.keys(src._combined);
for (let i = 0; i < srcCombinedKeys.length; i++) {
const key = parseInt(srcCombinedKeys[i], 10);
if (key >= srcCol) {
this._combined[key - srcCol + destCol] = src._combined[key];
this._copyCellMapsFrom(src, srcCol + cell, destCol + cell);
}
}
}
Expand Down Expand Up @@ -620,4 +603,24 @@ export class BufferLine implements IBufferLine {
cacheEntry.isTrimmed = false;
}
}

/** Copy sparse map entries for a single cell when `_data` flags require them. */
private _copyCellMapsFrom(src: BufferLine, srcCol: number, destCol: number): void {
const srcStart = srcCol * Constants.CELL_INDICIES;
if (src._data[srcStart + Cell.CONTENT] & Content.IS_COMBINED_MASK) {
this._combined[destCol] = src._combined[srcCol];
}
if (src._data[srcStart + Cell.BG] & BgFlags.HAS_EXTENDED) {
this._extendedAttrs[destCol] = src._extendedAttrs[srcCol];
}
}

/** Rebuild sparse maps from another line, keyed only by `_data` flags. */
private _copySparseMapsFrom(line: BufferLine): void {
this._combined = {};
this._extendedAttrs = {};
for (let i = 0; i < line.length; i++) {
this._copyCellMapsFrom(line, i, i);
}
}
}
4 changes: 2 additions & 2 deletions test/benchmark/DecorationService.benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
*/

import { perfContext, before, RuntimeCase } from 'xterm-benchmark';
import { DecorationService } from '../../src/common/services/DecorationService';
import { MockLogService, MockBufferService, MockOptionsService } from '../../src/common/TestUtils.test';
import { DecorationService } from 'common/services/DecorationService';
import { MockLogService, MockBufferService, MockOptionsService } from 'common/TestUtils.test';
const enum Constants {
COLS = 80,
ROWS = 30,
Expand Down
12 changes: 6 additions & 6 deletions test/benchmark/EscapeSequenceParser.benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
*/
import { perfContext, before, beforeEach, ThroughputRuntimeCase } from 'xterm-benchmark';

import { EscapeSequenceParser } from '../../src/common/parser/EscapeSequenceParser';
import { C0, C1 } from '../../src/common/data/EscapeSequences';
import { IDcsHandler, IOscHandler, IApcHandler, IParams } from '../../src/common/parser/Types';
import { OscHandler } from '../../src/common/parser/OscParser';
import { DcsHandler } from '../../src/common/parser/DcsParser';
import { ApcHandler } from '../../src/common/parser/ApcParser';
import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser';
import { C0, C1 } from 'common/data/EscapeSequences';
import { IDcsHandler, IOscHandler, IApcHandler, IParams } from 'common/parser/Types';
import { OscHandler } from 'common/parser/OscParser';
import { DcsHandler } from 'common/parser/DcsParser';
import { ApcHandler } from 'common/parser/ApcParser';

const SIZE = 5000000;

Expand Down
2 changes: 1 addition & 1 deletion test/benchmark/Event.benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { perfContext, before, RuntimeCase } from 'xterm-benchmark';
import { Emitter } from '../../src/common/Event';
import { Emitter } from 'common/Event';

const ITERATIONS = 1_000_000;

Expand Down
4 changes: 2 additions & 2 deletions test/benchmark/Terminal.benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';

import { spawn } from 'node-pty';
import { Utf8ToUtf32, stringFromCodePoint } from '../../src/common/input/TextDecoder';
import { CoreBrowserTerminal } from '../../src/browser/CoreBrowserTerminal';
import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder';
import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal';

perfContext('Terminal: ls -lR /usr/lib', () => {
let content = '';
Expand Down
6 changes: 5 additions & 1 deletion test/benchmark/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
"moduleResolution": "nodenext",
"strict": false,
"target": "es2021",
"module": "nodenext"
"module": "nodenext",
"paths": {
"common/*": ["../../src/common/*"],
"browser/*": ["../../src/browser/*"]
}
},
"include": [
"./**/*",
Expand Down
Loading