Compare commits
102
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18100d32fb | ||
|
|
07bdaf8767 | ||
|
|
584954b4fb | ||
|
|
9a96b27566 | ||
|
|
a04941a936 | ||
|
|
91fcb46a1a | ||
|
|
1d569f873d | ||
|
|
db244ea5a8 | ||
|
|
fdcd1c2720 | ||
|
|
57b48f6048 | ||
|
|
ec0c93fd5a | ||
|
|
be339bf796 | ||
|
|
7294124736 | ||
|
|
2c3fad39af | ||
|
|
edb4f89dd8 | ||
|
|
224c113b64 | ||
|
|
3e0c7d18e5 | ||
|
|
95d9224b8c | ||
|
|
7499a2181d | ||
|
|
7dc820f5fa | ||
|
|
e59a6c1f7b | ||
|
|
f3e2c08a5d | ||
|
|
b138bf38d0 | ||
|
|
c6e4627b45 | ||
|
|
d91045dc5f | ||
|
|
41dfdba2cf | ||
|
|
ba33decb68 | ||
|
|
17e3b84bcc | ||
|
|
182ff2f635 | ||
|
|
bcb4e5298b | ||
|
|
42facac2d9 | ||
|
|
2ab0f10a26 | ||
|
|
280dc0a36a | ||
|
|
ebe8cb749a | ||
|
|
c28f3c8d73 | ||
|
|
3bd7ac083a | ||
|
|
30b42838fd | ||
|
|
80e832e417 | ||
|
|
470947abd8 | ||
|
|
bb49a80ace | ||
|
|
65b87e0f40 | ||
|
|
39fc0f259e | ||
|
|
b787ac8b1b | ||
|
|
457efbf55d | ||
|
|
42270a0b68 | ||
|
|
090b77f354 | ||
|
|
534ce1365b | ||
|
|
f757c965ee | ||
|
|
4aa02f3fd9 | ||
|
|
f43273b3f0 | ||
|
|
c06c3025f2 | ||
|
|
1064e4f783 | ||
|
|
fad4821fd9 | ||
|
|
306c3d73ec | ||
|
|
8f2bb32c9c | ||
|
|
7b6c814566 | ||
|
|
adc9dea083 | ||
|
|
d565a2750e | ||
|
|
c5ab83d697 | ||
|
|
c62e6dd765 | ||
|
|
29a07f1d8f | ||
|
|
88cef97049 | ||
|
|
0e823004e6 | ||
|
|
df3422fb0b | ||
|
|
4ec85e67ba | ||
|
|
1a67b6f4b3 | ||
|
|
afaed108e4 | ||
|
|
c27d6bb462 | ||
|
|
9c4f0f96ca | ||
|
|
18c370a154 | ||
|
|
850f4ad738 | ||
|
|
b665f6259a | ||
|
|
d195dc9a3b | ||
|
|
4e5994d8a2 | ||
|
|
4a0cb5ae6b | ||
|
|
9e72a4b6d3 | ||
|
|
f484584b70 | ||
|
|
e749cb6125 | ||
|
|
8df996f9e7 | ||
|
|
51f6186352 | ||
|
|
ae5c41c518 | ||
|
|
17e7dafa17 | ||
|
|
df9fb7e473 | ||
|
|
41d9c4080f | ||
|
|
f100e93ba5 | ||
|
|
1d3825d341 | ||
|
|
57315e6cc9 | ||
|
|
2be4fc68e5 | ||
|
|
66fabfc232 | ||
|
|
3e2a42eb29 | ||
|
|
6a47d09b4c | ||
|
|
b36001ee7b | ||
|
|
e64f25a0dd | ||
|
|
3bcb57545e | ||
|
|
dc726a2ae6 | ||
|
|
06e5ac7ab4 | ||
|
|
c6e3492a4a | ||
|
|
86291b6e96 | ||
|
|
685434ca84 | ||
|
|
ff72c00219 | ||
|
|
69ee4ad23b | ||
|
|
253d1e9beb |
@@ -22,6 +22,10 @@ build/
|
||||
yarn.lock
|
||||
test-results/
|
||||
|
||||
# Tracing/debug files
|
||||
.cursor/nal-trace/
|
||||
.cursor/*.log
|
||||
|
||||
# Keep bundled code out of Git
|
||||
dist/
|
||||
demo/dist/
|
||||
|
||||
@@ -253,6 +253,7 @@ Xterm.js is used in many world-class applications to provide great terminal expe
|
||||
- [**SSH Connection Manager**](https://github.com/Amtrend/ssh-manager): Modern web-based SSH terminal and SFTP manager with AES-256 encryption, PWA support, and session management.
|
||||
- [**WooTTY**](https://github.com/icoretech/wootty): Flawless browser terminal for real operators.
|
||||
- [**Orca**](https://github.com/stablyai/orca): Agentic development environment for 100x builders.
|
||||
- [**4bit**](https://ciembor.github.io/4bit): Terminal Color Scheme Designer.
|
||||
- [And much more...](https://github.com/xtermjs/xterm.js/network/dependents?package_id=UGFja2FnZS0xNjYzMjc4OQ%3D%3D)
|
||||
|
||||
Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it on our list. Please add any new contributions to the end of the list.
|
||||
|
||||
@@ -13,15 +13,11 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-attach": [
|
||||
"../typings/addon-attach.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-attach.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,19 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-clipboard": [
|
||||
"../typings/addon-clipboard.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-clipboard.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { Terminal, ITerminalAddon, IRenderDimensions } from '@xterm/xterm';
|
||||
import type { FitAddon as IFitApi } from '@xterm/addon-fit';
|
||||
import { ViewportConstants } from 'browser/shared/Constants';
|
||||
import { ViewportConstants } from '../../../src/browser/shared/Constants';
|
||||
|
||||
interface ITerminalDimensions {
|
||||
/**
|
||||
|
||||
@@ -13,19 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-fit": [
|
||||
"../typings/addon-fit.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-fit.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { ITerminalAddon, IDisposable } from '@xterm/xterm';
|
||||
import type { ImageAddon as IImageApi } from '@xterm/addon-image';
|
||||
import { Emitter, type IEvent } from 'common/Event';
|
||||
import { Emitter, type IEvent } from '../../../src/common/Event';
|
||||
import { IIPHandler } from './IIPHandler';
|
||||
import { ImageRenderer } from './ImageRenderer';
|
||||
import { ImageStorage, CELL_SIZE_DEFAULT } from './ImageStorage';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { toRGBA8888 } from 'sixel/lib/Colors';
|
||||
import { IDisposable } from '@xterm/xterm';
|
||||
import { ICellSize, ImageLayer, ITerminalExt, IImageSpec, IRenderDimensions, IRenderService } from './Types';
|
||||
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
|
||||
const enum Constants {
|
||||
PLACEHOLDER_LENGTH = 4096,
|
||||
|
||||
@@ -91,7 +91,7 @@ export class SixelHandler implements IDcsHandler, IResetHandler {
|
||||
const height = this._dec.height;
|
||||
|
||||
// partial fix for https://github.com/jerch/xterm-addon-image/issues/37
|
||||
if (!width || ! height) {
|
||||
if (!width || !height) {
|
||||
if (height) {
|
||||
this._storage.advanceCursor(height);
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
import { IDisposable, IMarker, Terminal } from '@xterm/xterm';
|
||||
|
||||
// private imports from base repo we build against
|
||||
import { Attributes, BgFlags, Content, ExtFlags, UnderlineStyle } from 'common/buffer/Constants';
|
||||
import type { AttributeData } from 'common/buffer/AttributeData';
|
||||
import type { IParams, IDcsHandler, IOscHandler, IApcHandler, IEscapeSequenceParser } from 'common/parser/Types';
|
||||
import type { IBufferLine, IExtendedAttrs, IInputHandler } from 'common/Types';
|
||||
import type { ITerminal, ReadonlyColorSet } from 'browser/Types';
|
||||
import type { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import type { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
|
||||
import { Attributes, BgFlags, Content, ExtFlags, UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
import type { AttributeData } from '../../../src/common/buffer/AttributeData';
|
||||
import type { IParams, IDcsHandler, IOscHandler, IApcHandler, IEscapeSequenceParser } from '../../../src/common/parser/Types';
|
||||
import type { IBufferLine, IExtendedAttrs, IInputHandler } from '../../../src/common/Types';
|
||||
import type { ITerminal, ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import type { IRenderDimensions } from '../../../src/browser/renderer/shared/Types';
|
||||
import type { ICoreBrowserService, IRenderService, IThemeService } from '../../../src/browser/services/Services';
|
||||
|
||||
export const enum Cell {
|
||||
CONTENT = 0, // codepoint and wcwidth information (enum Content)
|
||||
|
||||
@@ -533,8 +533,8 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler, IDispos
|
||||
|
||||
private _sendResponse(id: number, message: string, quiet: number, placementId?: number): void {
|
||||
const isOk = message === 'OK';
|
||||
if (isOk && quiet === 1) return;
|
||||
if (!isOk && quiet === 2) return;
|
||||
if (isOk && quiet >= 1) return;
|
||||
if (!isOk && quiet >= 2) return;
|
||||
|
||||
const pPart = placementId ? `,p=${placementId}` : '';
|
||||
const response = `\x1b_Gi=${id}${pPart};${message}\x1b\\`;
|
||||
|
||||
@@ -10,20 +10,19 @@
|
||||
"preserveWatchOutput": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"browser/*": [ "../../../src/browser/*" ],
|
||||
"common/*": [ "../../../src/common/*" ],
|
||||
"@xterm/addon-image": [ "../typings/addon-image.d.ts" ],
|
||||
"*": [ "./*" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-image.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../../src/browser" },
|
||||
{ "path": "../../../src/common" }
|
||||
{
|
||||
"path": "../../../src/browser"
|
||||
},
|
||||
{
|
||||
"path": "../../../src/common"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -617,6 +617,18 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
strictEqual(await ctx.page.evaluate('window.kittyGotResponse'), false);
|
||||
});
|
||||
|
||||
test('suppresses OK response when q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=81,a=q,q=2,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
await timeout(100);
|
||||
|
||||
strictEqual(await ctx.page.evaluate('window.kittyGotResponse'), false);
|
||||
});
|
||||
|
||||
test('suppresses error response when q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
@@ -797,6 +809,30 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
|
||||
strictEqual(await ctx.page.evaluate('window.kittyGotResponse'), false);
|
||||
});
|
||||
|
||||
test('a=t OK suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=181,a=t,q=2,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
await timeout(100);
|
||||
|
||||
strictEqual(await ctx.page.evaluate('window.kittyGotResponse'), false);
|
||||
});
|
||||
|
||||
test('a=T OK suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=191,a=T,q=2,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
await timeout(100);
|
||||
|
||||
strictEqual(await ctx.page.evaluate('window.kittyGotResponse'), false);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Transmission medium rejection', () => {
|
||||
@@ -1146,6 +1182,22 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
strictEqual(await getImageStorageLength(), 1);
|
||||
});
|
||||
|
||||
test('OK response suppressed by q=2', async () => {
|
||||
await ctx.proxy.write(`\x1b_Ga=t,f=100,i=221;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
await timeout(100);
|
||||
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=221,q=2\x1b\\`);
|
||||
await timeout(100);
|
||||
|
||||
strictEqual(await ctx.page.evaluate('window.kittyGotResponse'), false);
|
||||
strictEqual(await getImageStorageLength(), 1);
|
||||
});
|
||||
|
||||
test('ENOENT error suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"package": "webpack",
|
||||
"pretest": "npm run build",
|
||||
"test": "nyc mocha out/**/*.test.js",
|
||||
"prepublish": "npm run package"
|
||||
"prepublishOnly": "npm run package"
|
||||
},
|
||||
"keywords": [
|
||||
"font",
|
||||
@@ -37,7 +37,7 @@
|
||||
"devDependencies": {
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/opentype.js": "^0.7.0",
|
||||
"axios": "^1.15.0",
|
||||
"axios": "^1.15.2",
|
||||
"font-finder": "^1.1.0",
|
||||
"mkdirp": "0.5.5",
|
||||
"yauzl": "^3.2.1"
|
||||
|
||||
@@ -10,17 +10,12 @@
|
||||
"preserveWatchOutput": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha",
|
||||
// HACK: src shouldn't use node types but it's needed for index.test.ts
|
||||
"../../../node_modules/@types/node"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-ligatures" : [
|
||||
"../typings/addon-ligatures.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-ligatures.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,11 +10,6 @@
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha",
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { Terminal, ITerminalAddon, IDisposable } from '@xterm/xterm';
|
||||
import type { ProgressAddon as IProgressApi, IProgressState } from '@xterm/addon-progress';
|
||||
import type { Emitter, IEvent } from 'common/Event';
|
||||
import type { Emitter, IEvent } from '../../../src/common/Event';
|
||||
|
||||
|
||||
const enum ProgressType {
|
||||
|
||||
@@ -13,22 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-progress": [
|
||||
"../typings/addon-progress.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-progress.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { Terminal, IDisposable, IDecoration } from '@xterm/xterm';
|
||||
import type { ISearchDecorationOptions } from '@xterm/addon-search';
|
||||
import { dispose, Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { dispose, Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import type { ISearchResult } from './SearchEngine';
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
import type { Terminal, IDisposable, ITerminalAddon } from '@xterm/xterm';
|
||||
import type { SearchAddon as ISearchApi, ISearchOptions, ISearchAddonOptions, ISearchResultChangeEvent, ISearchDecorationOptions } from '@xterm/addon-search';
|
||||
import { Emitter, type IEvent } from 'common/Event';
|
||||
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { disposableTimeout } from 'common/Async';
|
||||
import { Emitter, type IEvent } from '../../../src/common/Event';
|
||||
import { Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { disposableTimeout } from '../../../src/common/Async';
|
||||
import { SearchLineCache } from './SearchLineCache';
|
||||
import { SearchState } from './SearchState';
|
||||
import { SearchEngine, type ISearchResult } from './SearchEngine';
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import { assert } from 'chai';
|
||||
import { SearchEngine } from './SearchEngine';
|
||||
import { SearchLineCache } from './SearchLineCache';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import type { ISearchOptions } from '@xterm/addon-search';
|
||||
import { DisposableStore } from 'common/Lifecycle';
|
||||
import { DisposableStore } from '../../../src/common/Lifecycle';
|
||||
|
||||
function writeP(terminal: Terminal, data: string): Promise<void> {
|
||||
return new Promise(r => terminal.write(data, r));
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
import { assert } from 'chai';
|
||||
import { SearchLineCache, LineCacheEntry } from './SearchLineCache';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { timeout } from 'common/Async';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import { timeout } from '../../../src/common/Async';
|
||||
|
||||
function writeP(terminal: Terminal, data: string): Promise<void> {
|
||||
return new Promise(r => terminal.write(data, r));
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import type { Terminal } from '@xterm/xterm';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { disposableTimeout } from 'common/Async';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { disposableTimeout } from '../../../src/common/Async';
|
||||
|
||||
export type LineCacheEntry = [
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
import type { ISearchResultChangeEvent } from '@xterm/addon-search';
|
||||
import type { IDisposable } from '@xterm/xterm';
|
||||
import { Emitter, type IEvent } from 'common/Event';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { Emitter, type IEvent } from '../../../src/common/Event';
|
||||
import { Disposable } from '../../../src/common/Lifecycle';
|
||||
import type { ISearchResult } from './SearchEngine';
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"target": "es2021",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out",
|
||||
@@ -13,22 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-search" : [
|
||||
"../typings/addon-search.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-search.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';
|
||||
|
||||
import { spawn } from 'node-pty';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { SerializeAddon } from 'SerializeAddon';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from '../../../src/common/input/TextDecoder';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import { SerializeAddon } from '../src/SerializeAddon';
|
||||
|
||||
class TestTerminal extends Terminal {
|
||||
public writeSync(data: string): void {
|
||||
|
||||
@@ -6,24 +6,28 @@
|
||||
],
|
||||
"rootDir": "..",
|
||||
"outDir": "../out-benchmark",
|
||||
"types": ["../../../node_modules/@types/node"],
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
],
|
||||
"moduleResolution": "node",
|
||||
"strict": false,
|
||||
"target": "es2021",
|
||||
"module": "commonjs",
|
||||
"paths": {
|
||||
"common/*": ["../../../src/common/*"],
|
||||
"browser/*": ["../../../src/browser/*"],
|
||||
"SerializeAddon": ["../src/SerializeAddon"],
|
||||
"@xterm/addon-serialize": [
|
||||
"../typings/addon-serialize.d.ts"
|
||||
]
|
||||
}
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["../**/*", "../../../typings/xterm.d.ts"],
|
||||
"exclude": ["../../../**/*test.ts", "../../**/*api.ts"],
|
||||
"include": [
|
||||
"../**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"../../../**/*test.ts",
|
||||
"../../**/*api.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../../src/common" },
|
||||
{ "path": "../../../src/browser" }
|
||||
{
|
||||
"path": "../../../src/common"
|
||||
},
|
||||
{
|
||||
"path": "../../../src/browser"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
import jsdom = require('jsdom');
|
||||
import { assert } from 'chai';
|
||||
import { SerializeAddon } from './SerializeAddon';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { SelectionModel } from 'browser/selection/SelectionModel';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
import { ThemeService } from 'browser/services/ThemeService';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import { SelectionModel } from '../../../src/browser/selection/SelectionModel';
|
||||
import { IBufferService } from '../../../src/common/services/Services';
|
||||
import { ThemeService } from '../../../src/browser/services/ThemeService';
|
||||
|
||||
function sgr(...seq: string[]): string {
|
||||
return `\x1b[${seq.join(';')}m`;
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
import type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';
|
||||
import type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';
|
||||
import { IAttributeData, IColor } from 'common/Types';
|
||||
import { DEFAULT_ANSI_COLORS } from 'browser/Types';
|
||||
import { UnderlineStyle } from 'common/buffer/Constants';
|
||||
import { IAttributeData, IColor } from '../../../src/common/Types';
|
||||
import { DEFAULT_ANSI_COLORS } from '../../../src/browser/Types';
|
||||
import { UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
|
||||
function constrain(value: number, low: number, high: number): number {
|
||||
return Math.max(low, Math.min(value, high));
|
||||
|
||||
@@ -10,17 +10,6 @@
|
||||
"outDir": "../out",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-serialize": [
|
||||
"../typings/addon-serialize.d.ts"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
@@ -29,7 +18,8 @@
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-serialize.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,20 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" },
|
||||
{ "path": "./benchmark" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
},
|
||||
{
|
||||
"path": "./benchmark"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';
|
||||
|
||||
import { spawn } from 'node-pty';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder';
|
||||
import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal';
|
||||
import { UnicodeGraphemeProvider } from 'UnicodeGraphemeProvider';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from '../../../src/common/input/TextDecoder';
|
||||
import { CoreBrowserTerminal } from '../../../src/browser/CoreBrowserTerminal';
|
||||
import { UnicodeGraphemeProvider } from '../src/UnicodeGraphemeProvider';
|
||||
|
||||
|
||||
function fakedAddonLoad(terminal: any): void {
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "es6"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es6"
|
||||
],
|
||||
"rootDir": "..",
|
||||
"outDir": "../out-benchmark",
|
||||
"types": ["../../../node_modules/@types/node"],
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
],
|
||||
"moduleResolution": "node",
|
||||
"strict": false,
|
||||
"target": "es2015",
|
||||
"module": "commonjs",
|
||||
"paths": {
|
||||
"common/*": ["../../../src/common/*"],
|
||||
"browser/*": ["../../../src/browser/*"],
|
||||
"UnicodeGraphemeProvider": ["../src/UnicodeGraphemeProvider"],
|
||||
"@xterm/addon-unicode-graphemes": [
|
||||
"../typings/addon-unicode-graphemes.d.ts"
|
||||
]
|
||||
}
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["../**/*", "../../../typings/xterm.d.ts"],
|
||||
"exclude": ["../../../**/*test.ts", "../../**/*api.ts"],
|
||||
"include": [
|
||||
"../**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"../../../**/*test.ts",
|
||||
"../../**/*api.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../../src/common" },
|
||||
{ "path": "../../../src/browser" }
|
||||
{
|
||||
"path": "../../../src/common"
|
||||
},
|
||||
{
|
||||
"path": "../../../src/browser"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { IUnicodeVersionProvider } from '@xterm/xterm';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from 'common/services/Services';
|
||||
import { UnicodeService } from 'common/services/UnicodeService';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from '../../../src/common/services/Services';
|
||||
import { UnicodeService } from '../../../src/common/services/UnicodeService';
|
||||
import * as UC from './third-party/UnicodeProperties';
|
||||
|
||||
export class UnicodeGraphemeProvider implements IUnicodeVersionProvider {
|
||||
|
||||
@@ -11,21 +11,14 @@
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"@xterm/addon-unicode-graphemes": [
|
||||
"../typings/addon-unicode-graphemes.d.ts"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-unicode-graphemes.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,20 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" },
|
||||
{ "path": "./benchmark" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
},
|
||||
{
|
||||
"path": "./benchmark"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { IUnicodeVersionProvider } from '@xterm/xterm';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from 'common/services/Services';
|
||||
import { UnicodeService } from 'common/services/UnicodeService';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from '../../../src/common/services/Services';
|
||||
import { UnicodeService } from '../../../src/common/services/UnicodeService';
|
||||
|
||||
const BMP_COMBINING = [
|
||||
[0x0300, 0x036F], [0x0483, 0x0489], [0x0591, 0x05BD],
|
||||
|
||||
@@ -11,24 +11,14 @@
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"@xterm/addon-unicode11": [
|
||||
"../typings/addon-unicode11.d.ts"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-unicode11.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -14,15 +14,11 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-web-fonts": [
|
||||
"../typings/addon-web-fonts.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-web-fonts.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,24 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "es2021",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
// "downlevelIteration": true,
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,15 +13,11 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-web-links": [
|
||||
"../typings/addon-web-links.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-web-links.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,24 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "es2021",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
// "downlevelIteration": true,
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
||||
import { ReadonlyColorSet } from 'browser/Types';
|
||||
import { Attributes, BgFlags, ExtFlags, FgFlags, NULL_CELL_CODE, UnderlineStyle } from 'common/buffer/Constants';
|
||||
import { IDecorationService, IOptionsService } from 'common/services/Services';
|
||||
import { ICellData } from 'common/Types';
|
||||
import { ISelectionRenderModel } from '../../../src/browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from '../../../src/browser/services/Services';
|
||||
import { ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { Attributes, BgFlags, ExtFlags, FgFlags, NULL_CELL_CODE, UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
import { IDecorationService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { ICellData } from '../../../src/common/Types';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { rgba } from 'common/Color';
|
||||
import { treatGlyphAsBackgroundColor } from 'browser/renderer/shared/RendererUtils';
|
||||
import { rgba } from '../../../src/common/Color';
|
||||
import { treatGlyphAsBackgroundColor } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import { blockPatternCodepoints } from './customGlyphs/CustomGlyphDefinitions';
|
||||
|
||||
// Work variables to avoid garbage collection
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import { TextureAtlas } from './TextureAtlas';
|
||||
import { ITerminalOptions, Terminal } from '@xterm/xterm';
|
||||
import { ITerminal, ReadonlyColorSet } from 'browser/Types';
|
||||
import { ITerminal, ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { ICharAtlasConfig, ITextureAtlas } from './Types';
|
||||
import { generateConfig, configEquals } from './CharAtlasUtils';
|
||||
import type { ILogService } from 'common/services/Services';
|
||||
import type { ILogService } from '../../../src/common/services/Services';
|
||||
|
||||
interface ITextureAtlasCacheEntry {
|
||||
atlas: ITextureAtlas;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { configEquals } from './CharAtlasUtils';
|
||||
import { ICharAtlasConfig } from './Types';
|
||||
import { NULL_COLOR } from '../../../src/common/Color';
|
||||
import { IColor } from '../../../src/common/Types';
|
||||
|
||||
function createTestConfig(overrides: Partial<ICharAtlasConfig> = {}): ICharAtlasConfig {
|
||||
const color: IColor = { css: '#ffffff', rgba: 0xffffffff };
|
||||
const contrastCache = {
|
||||
clear: () => {},
|
||||
setCss: () => {},
|
||||
getCss: () => undefined,
|
||||
setColor: () => {},
|
||||
getColor: () => undefined
|
||||
};
|
||||
const colors = {
|
||||
foreground: color,
|
||||
background: color,
|
||||
cursor: NULL_COLOR,
|
||||
cursorAccent: NULL_COLOR,
|
||||
selectionForeground: undefined,
|
||||
selectionBackgroundTransparent: NULL_COLOR,
|
||||
selectionBackgroundOpaque: NULL_COLOR,
|
||||
selectionInactiveBackgroundTransparent: NULL_COLOR,
|
||||
selectionInactiveBackgroundOpaque: NULL_COLOR,
|
||||
overviewRulerBorder: NULL_COLOR,
|
||||
scrollbarSliderBackground: NULL_COLOR,
|
||||
scrollbarSliderHoverBackground: NULL_COLOR,
|
||||
scrollbarSliderActiveBackground: NULL_COLOR,
|
||||
ansi: new Array(256).fill(color),
|
||||
contrastCache,
|
||||
halfContrastCache: contrastCache
|
||||
};
|
||||
return {
|
||||
customGlyphs: true,
|
||||
devicePixelRatio: 1,
|
||||
deviceMaxTextureSize: 4096,
|
||||
letterSpacing: 0,
|
||||
lineHeight: 1,
|
||||
fontSize: 15,
|
||||
fontFamily: 'monospace',
|
||||
fontWeight: 'normal',
|
||||
fontWeightBold: 'bold',
|
||||
deviceCellWidth: 10,
|
||||
deviceCellHeight: 20,
|
||||
deviceCharWidth: 8,
|
||||
deviceCharHeight: 16,
|
||||
allowTransparency: false,
|
||||
drawBoldTextInBrightColors: true,
|
||||
minimumContrastRatio: 1,
|
||||
colors,
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
describe('CharAtlasUtils', () => {
|
||||
describe('configEquals', () => {
|
||||
it('should return true for identical configs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig();
|
||||
assert.ok(configEquals(a, b));
|
||||
});
|
||||
|
||||
it('should return false when deviceMaxTextureSize differs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig({ deviceMaxTextureSize: 8192 });
|
||||
assert.ok(!configEquals(a, b));
|
||||
});
|
||||
|
||||
it('should return false when deviceCellWidth differs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig({ deviceCellWidth: 11 });
|
||||
assert.ok(!configEquals(a, b));
|
||||
});
|
||||
|
||||
it('should return false when deviceCellHeight differs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig({ deviceCellHeight: 21 });
|
||||
assert.ok(!configEquals(a, b));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
|
||||
import { ICharAtlasConfig } from './Types';
|
||||
import { Attributes } from 'common/buffer/Constants';
|
||||
import { Attributes } from '../../../src/common/buffer/Constants';
|
||||
import { ITerminalOptions } from '@xterm/xterm';
|
||||
import { IColorSet, ReadonlyColorSet } from 'browser/Types';
|
||||
import { NULL_COLOR } from 'common/Color';
|
||||
import { IColorSet, ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { NULL_COLOR } from '../../../src/common/Color';
|
||||
|
||||
export function generateConfig(deviceCellWidth: number, deviceCellHeight: number, deviceCharWidth: number, deviceCharHeight: number, options: Required<ITerminalOptions>, colors: ReadonlyColorSet, devicePixelRatio: number, deviceMaxTextureSize: number, customGlyphs: boolean = true): ICharAtlasConfig {
|
||||
// null out some fields that don't matter
|
||||
@@ -59,6 +59,7 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean
|
||||
}
|
||||
}
|
||||
return a.devicePixelRatio === b.devicePixelRatio &&
|
||||
a.deviceMaxTextureSize === b.deviceMaxTextureSize &&
|
||||
a.customGlyphs === b.customGlyphs &&
|
||||
a.lineHeight === b.lineHeight &&
|
||||
a.letterSpacing === b.letterSpacing &&
|
||||
@@ -67,6 +68,8 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean
|
||||
a.fontWeight === b.fontWeight &&
|
||||
a.fontWeightBold === b.fontWeightBold &&
|
||||
a.allowTransparency === b.allowTransparency &&
|
||||
a.deviceCellWidth === b.deviceCellWidth &&
|
||||
a.deviceCellHeight === b.deviceCellHeight &&
|
||||
a.deviceCharWidth === b.deviceCharWidth &&
|
||||
a.deviceCharHeight === b.deviceCharHeight &&
|
||||
a.drawBoldTextInBrightColors === b.drawBoldTextInBrightColors &&
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { isFirefox, isLegacyEdge } from 'common/Platform';
|
||||
import { isFirefox, isLegacyEdge } from '../../../src/common/Platform';
|
||||
|
||||
export const DIM_OPACITY = 0.5;
|
||||
// The text baseline is set conditionally by browser. Using 'ideographic' for Firefox or Legacy Edge
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { RendererConstants } from 'browser/renderer/shared/Constants';
|
||||
import { ICoreBrowserService } from 'browser/services/Services';
|
||||
import { RendererConstants } from '../../../src/browser/renderer/shared/Constants';
|
||||
import { ICoreBrowserService } from '../../../src/browser/services/Services';
|
||||
|
||||
const enum Constants {
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { toDisposable, IDisposable } from 'common/Lifecycle';
|
||||
import { toDisposable, IDisposable } from '../../../src/common/Lifecycle';
|
||||
|
||||
export function observeDevicePixelDimensions(element: HTMLElement, parentWindow: Window & typeof globalThis, callback: (deviceWidth: number, deviceHeight: number) => void): IDisposable {
|
||||
// Observe any resizes to the element and extract the actual pixel size of the element if the
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
* @license MIT
|
||||
*/
|
||||
import { TextureAtlas } from './TextureAtlas';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { NULL_CELL_CODE } from 'common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { IRenderDimensions } from '../../../src/browser/renderer/shared/Types';
|
||||
import { NULL_CELL_CODE } from '../../../src/common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject, type IRasterizedGlyph, type ITextureAtlas } from './Types';
|
||||
import { createProgram, GLTexture, PROJECTION_MATRIX } from './WebglUtils';
|
||||
import type { IOptionsService } from 'common/services/Services';
|
||||
import { allowRescaling, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { allowRescaling, throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
|
||||
interface IVertices {
|
||||
attributes: Float32Array;
|
||||
@@ -114,7 +114,8 @@ export class GlyphRenderer extends Disposable {
|
||||
private readonly _terminal: Terminal,
|
||||
private readonly _gl: IWebGL2RenderingContext,
|
||||
private _dimensions: IRenderDimensions,
|
||||
private readonly _optionsService: IOptionsService
|
||||
private readonly _optionsService: IOptionsService,
|
||||
private readonly _logService: ILogService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -127,7 +128,7 @@ export class GlyphRenderer extends Disposable {
|
||||
TextureAtlas.maxTextureSize = throwIfFalsy(gl.getParameter(gl.MAX_TEXTURE_SIZE) as number | null);
|
||||
}
|
||||
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(TextureAtlas.maxAtlasPages)));
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(TextureAtlas.maxAtlasPages), this._logService));
|
||||
this._register(toDisposable(() => gl.deleteProgram(this._program)));
|
||||
|
||||
// Uniform locations
|
||||
@@ -136,8 +137,9 @@ export class GlyphRenderer extends Disposable {
|
||||
this._textureLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_texture'));
|
||||
|
||||
// Create and set the vertex array object
|
||||
this._vertexArrayObject = gl.createVertexArray();
|
||||
gl.bindVertexArray(this._vertexArrayObject);
|
||||
const vertexArrayObject = this._vertexArrayObject = gl.createVertexArray();
|
||||
this._register(toDisposable(() => gl.deleteVertexArray(vertexArrayObject)));
|
||||
gl.bindVertexArray(vertexArrayObject);
|
||||
|
||||
// Setup a_unitquad, this defines the 4 vertices of a rectangle
|
||||
const unitQuadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
|
||||
@@ -358,7 +360,9 @@ export class GlyphRenderer extends Disposable {
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this._attributesBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, activeBuffer.subarray(0, bufferLength), gl.STREAM_DRAW);
|
||||
|
||||
// Bind the atlas page texture if they have changed
|
||||
// Bind the atlas page texture if they have changed. AtlasPage.version is globally
|
||||
// monotonic, so a page object swap at the same index (which happens after a page merge)
|
||||
// is detected by the same comparison.
|
||||
for (let i = 0; i < this._atlas.pages.length; i++) {
|
||||
if (this._atlas.pages[i].version !== this._atlasTextures[i].version) {
|
||||
this._bindAtlasPageTexture(gl, this._atlas, i);
|
||||
@@ -371,6 +375,10 @@ export class GlyphRenderer extends Disposable {
|
||||
|
||||
public setAtlas(atlas: ITextureAtlas): void {
|
||||
this._atlas = atlas;
|
||||
this.invalidateAtlasTextures();
|
||||
}
|
||||
|
||||
public invalidateAtlasTextures(): void {
|
||||
for (const glTexture of this._atlasTextures) {
|
||||
glTexture.version = -1;
|
||||
}
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { IThemeService } from 'browser/services/Services';
|
||||
import { ReadonlyColorSet } from 'browser/Types';
|
||||
import { Attributes, FgFlags } from 'common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { IColor } from 'common/Types';
|
||||
import { IRenderDimensions } from '../../../src/browser/renderer/shared/Types';
|
||||
import { IThemeService } from '../../../src/browser/services/Services';
|
||||
import { ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { Attributes, FgFlags } from '../../../src/common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { IColor } from '../../../src/common/Types';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { RenderModelConstants } from './RenderModel';
|
||||
import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject } from './Types';
|
||||
import { createProgram, expandFloat32Array, PROJECTION_MATRIX } from './WebglUtils';
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService } from '../../../src/common/services/Services';
|
||||
|
||||
const enum VertexAttribLocations {
|
||||
POSITION = 0,
|
||||
@@ -89,21 +90,23 @@ export class RectangleRenderer extends Disposable {
|
||||
private _terminal: Terminal,
|
||||
private _gl: IWebGL2RenderingContext,
|
||||
private _dimensions: IRenderDimensions,
|
||||
private readonly _themeService: IThemeService
|
||||
private readonly _themeService: IThemeService,
|
||||
private readonly _logService: ILogService
|
||||
) {
|
||||
super();
|
||||
|
||||
const gl = this._gl;
|
||||
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource));
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource, this._logService));
|
||||
this._register(toDisposable(() => gl.deleteProgram(this._program)));
|
||||
|
||||
// Uniform locations
|
||||
this._projectionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_projection'));
|
||||
|
||||
// Create and set the vertex array object
|
||||
this._vertexArrayObject = gl.createVertexArray();
|
||||
gl.bindVertexArray(this._vertexArrayObject);
|
||||
const vertexArrayObject = this._vertexArrayObject = gl.createVertexArray();
|
||||
this._register(toDisposable(() => gl.deleteVertexArray(vertexArrayObject)));
|
||||
gl.bindVertexArray(vertexArrayObject);
|
||||
|
||||
// Setup a_unitquad, this defines the 4 vertices of a rectangle
|
||||
const unitQuadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
|
||||
@@ -336,8 +339,9 @@ export class RectangleRenderer extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices.attributes.length < offset + 4) {
|
||||
vertices.attributes = expandFloat32Array(vertices.attributes, this._terminal.rows * this._terminal.cols * INDICES_PER_RECTANGLE);
|
||||
if (vertices.attributes.length < offset + INDICES_PER_RECTANGLE) {
|
||||
// +1 for the viewport-clear rectangle at offset 0.
|
||||
vertices.attributes = expandFloat32Array(vertices.attributes, (this._terminal.rows * this._terminal.cols + 1) * INDICES_PER_RECTANGLE);
|
||||
}
|
||||
$x1 = startX * this._dimensions.device.cell.width;
|
||||
$y1 = y * this._dimensions.device.cell.height;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { ICursorRenderModel, IRenderModel } from './Types';
|
||||
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
|
||||
import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel';
|
||||
import { ISelectionRenderModel } from '../../../src/browser/renderer/shared/Types';
|
||||
import { createSelectionRenderModel } from '../../../src/browser/renderer/shared/SelectionRenderModel';
|
||||
|
||||
export const enum RenderModelConstants {
|
||||
INDICIES_PER_CELL = 4,
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IColorContrastCache } from 'browser/Types';
|
||||
import { IColorContrastCache } from '../../../src/browser/Types';
|
||||
import { DIM_OPACITY, TEXT_BASELINE } from './Constants';
|
||||
import { tryDrawCustomGlyph } from './customGlyphs/CustomGlyphRasterizer';
|
||||
import { computeNextVariantOffset, treatGlyphAsBackgroundColor, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { computeNextVariantOffset, treatGlyphAsBackgroundColor, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import { IBoundingBox, ICharAtlasConfig, IRasterizedGlyph, ITextureAtlas } from './Types';
|
||||
import { NULL_COLOR, channels, color, rgba } from 'common/Color';
|
||||
import { FourKeyMap } from 'common/MultiKeyMap';
|
||||
import { IdleTaskQueue } from 'common/TaskQueue';
|
||||
import { IColor } from 'common/Types';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { Attributes, DEFAULT_COLOR, DEFAULT_EXT, UnderlineStyle } from 'common/buffer/Constants';
|
||||
import { ILogService, IUnicodeService } from 'common/services/Services';
|
||||
import { Emitter } from 'common/Event';
|
||||
import { NULL_COLOR, channels, color, rgba } from '../../../src/common/Color';
|
||||
import { FourKeyMap } from '../../../src/common/MultiKeyMap';
|
||||
import { IdleTaskQueue } from '../../../src/common/TaskQueue';
|
||||
import { IColor } from '../../../src/common/Types';
|
||||
import { AttributeData } from '../../../src/common/buffer/AttributeData';
|
||||
import { Attributes, DEFAULT_COLOR, DEFAULT_EXT, UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
import { ILogService, IUnicodeService } from '../../../src/common/services/Services';
|
||||
import { Emitter } from '../../../src/common/Event';
|
||||
|
||||
/**
|
||||
* A shared object which is used to draw nothing for a particular cell.
|
||||
@@ -109,6 +109,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
page.canvas.remove();
|
||||
}
|
||||
this._onAddTextureAtlasCanvas.dispose();
|
||||
this._onRemoveTextureAtlasCanvas.dispose();
|
||||
}
|
||||
|
||||
public warmUp(): void {
|
||||
@@ -133,7 +134,9 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
|
||||
private _requestClearModel = false;
|
||||
public beginFrame(): boolean {
|
||||
return this._requestClearModel;
|
||||
const result = this._requestClearModel;
|
||||
this._requestClearModel = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public clearTexture(): void {
|
||||
@@ -193,7 +196,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
|
||||
// Merge into the new page
|
||||
const mergedPage = this._mergePages(mergingPages, mergedPageIndex);
|
||||
mergedPage.version++;
|
||||
mergedPage.version = ++AtlasPage.nextVersion;
|
||||
|
||||
// Delete the pages, shifting glyph texture pages as needed
|
||||
for (let i = sortedMergingPagesIndexes.length - 1; i >= 0; i--) {
|
||||
@@ -251,7 +254,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
for (const g of adjustingPage.glyphs) {
|
||||
g.texturePage--;
|
||||
}
|
||||
adjustingPage.version++;
|
||||
adjustingPage.version = ++AtlasPage.nextVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,7 +530,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
let customGlyph = false;
|
||||
if (this._config.customGlyphs !== false) {
|
||||
const variantOffset = this._workAttributeData.getUnderlineVariantOffset();
|
||||
customGlyph = tryDrawCustomGlyph(this._tmpCtx, chars, padding, padding, this._config.deviceCellWidth, this._config.deviceCellHeight, this._config.deviceCharWidth, this._config.deviceCharHeight, this._config.fontSize, this._config.devicePixelRatio, backgroundColor.css, variantOffset);
|
||||
customGlyph = tryDrawCustomGlyph(this._tmpCtx, chars, padding, padding, this._config.deviceCellWidth, this._config.deviceCellHeight, this._config.deviceCharWidth, this._config.deviceCharHeight, this._config.fontSize, this._config.devicePixelRatio, this._logService, backgroundColor.css, variantOffset);
|
||||
}
|
||||
|
||||
// Whether to clear pixels based on a threshold difference between the glyph color and the
|
||||
@@ -937,7 +940,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
rasterizedGlyph.size.y
|
||||
);
|
||||
activePage.addGlyph(rasterizedGlyph);
|
||||
activePage.version++;
|
||||
activePage.version = ++AtlasPage.nextVersion;
|
||||
|
||||
return rasterizedGlyph;
|
||||
}
|
||||
@@ -1047,9 +1050,13 @@ class AtlasPage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to check whether the canvas of the atlas page has changed.
|
||||
* Monotonically increasing across all atlas pages globally. Used to detect when the texture
|
||||
* unit at a given index needs to be re-uploaded — both for content changes within the same
|
||||
* page and for a page object swap at the same index (which happens after a page merge,
|
||||
* where a per-page counter could coincide with the previously-bound page's value).
|
||||
*/
|
||||
public version = 0;
|
||||
public static nextVersion: number = 0;
|
||||
public version = ++AtlasPage.nextVersion;
|
||||
|
||||
// Texture atlas current positioning data. The texture packing strategy used is to fill from
|
||||
// left-to-right and top-to-bottom. When the glyph being written is less than half of the current
|
||||
@@ -1092,7 +1099,7 @@ class AtlasPage {
|
||||
this.currentRow.y = 0;
|
||||
this.currentRow.height = 0;
|
||||
this.fixedRows.length = 0;
|
||||
this.version++;
|
||||
this.version = ++AtlasPage.nextVersion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
|
||||
import { FontWeight } from '@xterm/xterm';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
|
||||
import { CursorInactiveStyle, CursorStyle, type IDisposable } from 'common/Types';
|
||||
import type { IEvent } from 'common/Event';
|
||||
import { IColorSet } from '../../../src/browser/Types';
|
||||
import { ISelectionRenderModel } from '../../../src/browser/renderer/shared/Types';
|
||||
import { CursorInactiveStyle, CursorStyle, type IDisposable } from '../../../src/common/Types';
|
||||
import type { IEvent } from '../../../src/common/Event';
|
||||
|
||||
export interface IRenderModel {
|
||||
cells: Uint32Array;
|
||||
@@ -28,6 +28,7 @@ export interface ICursorRenderModel {
|
||||
export interface IWebGL2RenderingContext extends WebGLRenderingContext {
|
||||
vertexAttribDivisor(index: number, divisor: number): void;
|
||||
createVertexArray(): IWebGLVertexArrayObject;
|
||||
deleteVertexArray(vao: IWebGLVertexArrayObject): void;
|
||||
bindVertexArray(vao: IWebGLVertexArrayObject): void;
|
||||
drawElementsInstanced(mode: number, count: number, type: number, offset: number, instanceCount: number): void;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
import type { ITerminalAddon, Terminal } from '@xterm/xterm';
|
||||
import type { IWebglAddonOptions, WebglAddon as IWebglApi } from '@xterm/addon-webgl';
|
||||
import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
|
||||
import { ITerminal } from 'browser/Types';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { getSafariVersion, isSafari } from 'common/Platform';
|
||||
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
|
||||
import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from '../../../src/browser/services/Services';
|
||||
import { ITerminal } from '../../../src/browser/Types';
|
||||
import { Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { getSafariVersion, isSafari } from '../../../src/common/Platform';
|
||||
import { ICoreService, IDecorationService, ILogService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { IWebGL2RenderingContext } from './Types';
|
||||
import { WebglRenderer } from './WebglRenderer';
|
||||
import { Emitter, EventUtils } from 'common/Event';
|
||||
import { Emitter, EventUtils } from '../../../src/common/Event';
|
||||
|
||||
export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi {
|
||||
private _terminal?: Terminal;
|
||||
@@ -65,6 +65,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi
|
||||
const charSizeService: ICharSizeService = unsafeCore._charSizeService;
|
||||
const coreBrowserService: ICoreBrowserService = unsafeCore._coreBrowserService;
|
||||
const decorationService: IDecorationService = unsafeCore._decorationService;
|
||||
const logService: ILogService = unsafeCore._logService;
|
||||
const themeService: IThemeService = unsafeCore._themeService;
|
||||
|
||||
this._renderer = this._register(new WebglRenderer(
|
||||
@@ -74,6 +75,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi
|
||||
coreBrowserService,
|
||||
coreService,
|
||||
decorationService,
|
||||
logService,
|
||||
optionsService,
|
||||
themeService,
|
||||
this._customGlyphs,
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminal } from 'browser/Types';
|
||||
import { ITerminal } from '../../../src/browser/Types';
|
||||
import { CellColorResolver } from './CellColorResolver';
|
||||
import { acquireTextureAtlas, removeTerminalFromCache } from './CharAtlasCache';
|
||||
import { CursorBlinkStateManager } from './CursorBlinkStateManager';
|
||||
import { observeDevicePixelDimensions } from './DevicePixelObserver';
|
||||
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types';
|
||||
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
||||
import { CharData, IBufferLine, ICellData } from 'common/Types';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants';
|
||||
import { TextBlinkStateManager } from 'browser/renderer/shared/TextBlinkStateManager';
|
||||
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
|
||||
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from '../../../src/browser/renderer/shared/Types';
|
||||
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../../src/browser/services/Services';
|
||||
import { CharData, IBufferLine, ICellData } from '../../../src/common/Types';
|
||||
import { AttributeData } from '../../../src/common/buffer/AttributeData';
|
||||
import { CellData } from '../../../src/common/buffer/CellData';
|
||||
import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from '../../../src/common/buffer/Constants';
|
||||
import { TextBlinkStateManager } from '../../../src/browser/renderer/shared/TextBlinkStateManager';
|
||||
import { ICoreService, IDecorationService, ILogService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { GlyphRenderer } from './GlyphRenderer';
|
||||
import { RectangleRenderer } from './RectangleRenderer';
|
||||
@@ -23,10 +23,14 @@ import { COMBINED_CHAR_BIT_MASK, RenderModel, RenderModelConstants } from './Ren
|
||||
import { IWebGL2RenderingContext, type ITextureAtlas } from './Types';
|
||||
import { LinkRenderLayer } from './renderLayer/LinkRenderLayer';
|
||||
import { IRenderLayer } from './renderLayer/Types';
|
||||
import { Emitter, EventUtils } from 'common/Event';
|
||||
import { addDisposableListener } from 'browser/Dom';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
|
||||
import { Emitter, EventUtils } from '../../../src/common/Event';
|
||||
import { addDisposableListener } from '../../../src/browser/Dom';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { createRenderDimensions } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
|
||||
const enum Constants {
|
||||
MERGE_RETRY_LIMIT = 32
|
||||
}
|
||||
|
||||
export class WebglRenderer extends Disposable implements IRenderer {
|
||||
private _renderLayers: IRenderLayer[];
|
||||
@@ -73,6 +77,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
private readonly _coreBrowserService: ICoreBrowserService,
|
||||
private readonly _coreService: ICoreService,
|
||||
private readonly _decorationService: IDecorationService,
|
||||
private readonly _logService: ILogService,
|
||||
private readonly _optionsService: IOptionsService,
|
||||
private readonly _themeService: IThemeService,
|
||||
private readonly _customGlyphs: boolean = true,
|
||||
@@ -118,19 +123,19 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
this._deviceMaxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
|
||||
|
||||
this._register(addDisposableListener(this._canvas, 'webglcontextlost', (e) => {
|
||||
console.log('webglcontextlost event received');
|
||||
this._logService.debug('webglcontextlost event received');
|
||||
// Prevent the default behavior in order to enable WebGL context restoration.
|
||||
e.preventDefault();
|
||||
// Wait a few seconds to see if the 'webglcontextrestored' event is fired.
|
||||
// If not, dispatch the onContextLoss notification to observers.
|
||||
this._contextRestorationTimeout = setTimeout(() => {
|
||||
this._contextRestorationTimeout = undefined;
|
||||
console.warn('webgl context not restored; firing onContextLoss');
|
||||
this._logService.warn('webgl context not restored; firing onContextLoss');
|
||||
this._onContextLoss.fire(e);
|
||||
}, 3000 /* ms */);
|
||||
}));
|
||||
this._register(addDisposableListener(this._canvas, 'webglcontextrestored', (e) => {
|
||||
console.warn('webglcontextrestored event received');
|
||||
this._logService.warn('webglcontextrestored event received');
|
||||
clearTimeout(this._contextRestorationTimeout);
|
||||
this._contextRestorationTimeout = undefined;
|
||||
// The texture atlas and glyph renderer must be fully reinitialized
|
||||
@@ -154,6 +159,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
this._isAttached = this._core.screenElement!.isConnected;
|
||||
|
||||
this._register(toDisposable(() => {
|
||||
clearTimeout(this._contextRestorationTimeout);
|
||||
this._contextRestorationTimeout = undefined;
|
||||
for (const l of this._renderLayers) {
|
||||
l.dispose();
|
||||
}
|
||||
@@ -270,8 +277,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
* Initializes members dependent on WebGL context state.
|
||||
*/
|
||||
private _initializeWebGLState(): [RectangleRenderer, GlyphRenderer] {
|
||||
this._rectangleRenderer.value = new RectangleRenderer(this._terminal, this._gl, this.dimensions, this._themeService);
|
||||
this._glyphRenderer.value = new GlyphRenderer(this._terminal, this._gl, this.dimensions, this._optionsService);
|
||||
this._rectangleRenderer.value = new RectangleRenderer(this._terminal, this._gl, this.dimensions, this._themeService, this._logService);
|
||||
this._glyphRenderer.value = new GlyphRenderer(this._terminal, this._gl, this.dimensions, this._optionsService, this._logService);
|
||||
|
||||
// Update dimensions and acquire char atlas
|
||||
this.handleCharSizeChanged();
|
||||
@@ -375,6 +382,19 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
this._updateModel(start, end);
|
||||
}
|
||||
|
||||
// A mid-update atlas page merge invalidates vertex data and may not bump the host
|
||||
// page's version, so re-run the update and force a full texture rebind.
|
||||
let merged = false;
|
||||
let mergeRetries = 0;
|
||||
while (this._charAtlas && this._glyphRenderer.value.beginFrame() && mergeRetries++ < Constants.MERGE_RETRY_LIMIT) {
|
||||
merged = true;
|
||||
this._clearModel(true);
|
||||
this._updateModel(0, this._terminal.rows - 1);
|
||||
}
|
||||
if (merged) {
|
||||
this._glyphRenderer.value.invalidateAtlasTextures();
|
||||
}
|
||||
|
||||
// Render
|
||||
this._rectangleRenderer.value.renderBackgrounds();
|
||||
this._glyphRenderer.value.render(this._model);
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService } from '../../../src/common/services/Services';
|
||||
|
||||
/**
|
||||
* A matrix that when multiplies will translate 0-1 coordinates (left to right,
|
||||
@@ -16,21 +17,21 @@ export const PROJECTION_MATRIX = new Float32Array([
|
||||
-1, 1, 0, 1
|
||||
]);
|
||||
|
||||
export function createProgram(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string): WebGLProgram | undefined {
|
||||
export function createProgram(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string, logService: ILogService): WebGLProgram | undefined {
|
||||
const program = throwIfFalsy(gl.createProgram());
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.VERTEX_SHADER, vertexSource)));
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)));
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.VERTEX_SHADER, vertexSource, logService)));
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.FRAGMENT_SHADER, fragmentSource, logService)));
|
||||
gl.linkProgram(program);
|
||||
const success = gl.getProgramParameter(program, gl.LINK_STATUS);
|
||||
if (success) {
|
||||
return program;
|
||||
}
|
||||
|
||||
console.error(gl.getProgramInfoLog(program));
|
||||
logService.error(gl.getProgramInfoLog(program));
|
||||
gl.deleteProgram(program);
|
||||
}
|
||||
|
||||
export function createShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader | undefined {
|
||||
export function createShader(gl: WebGLRenderingContext, type: number, source: string, logService: ILogService): WebGLShader | undefined {
|
||||
const shader = throwIfFalsy(gl.createShader(type));
|
||||
gl.shaderSource(shader, source);
|
||||
gl.compileShader(shader);
|
||||
@@ -39,7 +40,7 @@ export function createShader(gl: WebGLRenderingContext, type: number, source: st
|
||||
return shader;
|
||||
}
|
||||
|
||||
console.error(gl.getShaderInfoLog(shader));
|
||||
logService.error(gl.getShaderInfoLog(shader));
|
||||
gl.deleteShader(shader);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../../src/browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService } from '../../../../src/common/services/Services';
|
||||
import { customGlyphDefinitions } from './CustomGlyphDefinitions';
|
||||
import { CustomGlyphDefinitionType, CustomGlyphScaleType, CustomGlyphVectorType, type CustomGlyphDefinitionPart, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from './Types';
|
||||
|
||||
@@ -22,6 +23,7 @@ export function tryDrawCustomGlyph(
|
||||
deviceCharHeight: number,
|
||||
fontSize: number,
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService,
|
||||
backgroundColor?: string,
|
||||
variantOffset: number = 0
|
||||
): boolean {
|
||||
@@ -30,7 +32,7 @@ export function tryDrawCustomGlyph(
|
||||
// Normalize to array for uniform handling
|
||||
const parts = Array.isArray(unifiedCharDefinition) ? unifiedCharDefinition : [unifiedCharDefinition];
|
||||
for (const part of parts) {
|
||||
drawDefinitionPart(ctx, part, xOffset, yOffset, deviceCellWidth, deviceCellHeight, deviceCharWidth, deviceCharHeight, fontSize, devicePixelRatio, backgroundColor, variantOffset);
|
||||
drawDefinitionPart(ctx, part, xOffset, yOffset, deviceCellWidth, deviceCellHeight, deviceCharWidth, deviceCharHeight, fontSize, devicePixelRatio, logService, backgroundColor, variantOffset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -49,6 +51,7 @@ function drawDefinitionPart(
|
||||
deviceCharHeight: number,
|
||||
fontSize: number,
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService,
|
||||
backgroundColor?: string,
|
||||
variantOffset: number = 0
|
||||
): void {
|
||||
@@ -79,7 +82,7 @@ function drawDefinitionPart(
|
||||
drawPatternChar(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, variantOffset);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.PATH_FUNCTION:
|
||||
drawPathFunctionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, part.strokeWidth);
|
||||
drawPathFunctionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, logService, part.strokeWidth);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.PATH:
|
||||
drawPathDefinitionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, part.strokeWidth);
|
||||
@@ -88,7 +91,7 @@ function drawDefinitionPart(
|
||||
drawPathNegativeDefinitionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, backgroundColor);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.VECTOR_SHAPE:
|
||||
drawVectorShape(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, fontSize, devicePixelRatio);
|
||||
drawVectorShape(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, fontSize, devicePixelRatio, logService);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.BRAILLE:
|
||||
drawBrailleCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight);
|
||||
@@ -510,6 +513,7 @@ function drawPathFunctionCharacter(
|
||||
deviceCellWidth: number,
|
||||
deviceCellHeight: number,
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService,
|
||||
strokeWidth?: number
|
||||
): void {
|
||||
ctx.save();
|
||||
@@ -536,7 +540,7 @@ function drawPathFunctionCharacter(
|
||||
}
|
||||
const f = svgToCanvasInstructionMap[type];
|
||||
if (!f) {
|
||||
console.error(`Could not find drawing instructions for "${type}"`);
|
||||
logService.error(`Could not find drawing instructions for "${type}"`);
|
||||
continue;
|
||||
}
|
||||
const args: string[] = instruction.substring(1).split(',');
|
||||
@@ -598,7 +602,8 @@ function drawVectorShape(
|
||||
deviceCellWidth: number,
|
||||
deviceCellHeight: number,
|
||||
fontSize: number,
|
||||
devicePixelRatio: number
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService
|
||||
): void {
|
||||
// Clip the cell to make sure drawing doesn't occur beyond bounds
|
||||
const clipRegion = new Path2D();
|
||||
@@ -619,7 +624,7 @@ function drawVectorShape(
|
||||
}
|
||||
const f = svgToCanvasInstructionMap[type];
|
||||
if (!f) {
|
||||
console.error(`Could not find drawing instructions for "${type}"`);
|
||||
logService.error(`Could not find drawing instructions for "${type}"`);
|
||||
continue;
|
||||
}
|
||||
const args: string[] = instruction.substring(1).split(',');
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ReadonlyColorSet } from 'browser/Types';
|
||||
import { ReadonlyColorSet } from '../../../../src/browser/Types';
|
||||
import { acquireTextureAtlas } from '../CharAtlasCache';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
import { IRenderDimensions } from '../../../../src/browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from '../../../../src/browser/services/Services';
|
||||
import { Disposable, toDisposable } from '../../../../src/common/Lifecycle';
|
||||
import { CellData } from '../../../../src/common/buffer/CellData';
|
||||
import { IOptionsService } from '../../../../src/common/services/Services';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { IRenderLayer } from './Types';
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../../src/browser/renderer/shared/RendererUtils';
|
||||
import { TEXT_BASELINE } from '../Constants';
|
||||
import type { ITextureAtlas } from '../Types';
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
*/
|
||||
|
||||
import { is256Color } from '../CharAtlasUtils';
|
||||
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
||||
import { ILinkifier2, ILinkifierEvent } from 'browser/Types';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
import { INVERTED_DEFAULT_COLOR } from '../../../../src/browser/renderer/shared/Constants';
|
||||
import { IRenderDimensions } from '../../../../src/browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from '../../../../src/browser/services/Services';
|
||||
import { ILinkifier2, ILinkifierEvent } from '../../../../src/browser/Types';
|
||||
import { IOptionsService } from '../../../../src/common/services/Services';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { IDisposable, Terminal } from '@xterm/xterm';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { IRenderDimensions } from '../../../../src/browser/renderer/shared/Types';
|
||||
|
||||
export interface IRenderLayer extends IDisposable {
|
||||
/**
|
||||
|
||||
@@ -10,20 +10,6 @@
|
||||
"outDir": "../out",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-webgl": [
|
||||
"../typings/addon-webgl.d.ts"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
@@ -33,7 +19,8 @@
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-webgl.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node",
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+10
-3
@@ -107,13 +107,20 @@ if (config.addon) {
|
||||
};
|
||||
outConfig = {
|
||||
...outConfig,
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
packages: 'external',
|
||||
entryPoints: [`addons/addon-${config.addon}/src/**/*.ts`],
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild/`
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild/`,
|
||||
// Public API stays external; src/common|browser are bundled from source.
|
||||
external: ['@xterm/xterm', '@xterm/headless', '@xterm/addon-*'],
|
||||
};
|
||||
// Playwright suites only (not run by unit tests); keep unbundled.
|
||||
outTestConfig = {
|
||||
...outConfig,
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
entryPoints: [`addons/addon-${config.addon}/test/**/*.ts`],
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild-test/`
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild-test/`,
|
||||
};
|
||||
|
||||
if (config.addon === 'ligatures') {
|
||||
|
||||
+15
-4
@@ -7,19 +7,30 @@ import { argv } from "process";
|
||||
/** @type {{cp: import("child_process").ChildProcessByStdio<any, any, any>, name: string}[]} */
|
||||
const jobs = [];
|
||||
|
||||
// Core job
|
||||
jobs.push(createJob('xterm', []));
|
||||
// Core job must finish before addons (addon tests resolve src/* via out-esbuild).
|
||||
const xtermJob = createJob('xterm', []);
|
||||
const xtermCode = await new Promise(r => {
|
||||
xtermJob.cp.on('exit', code => {
|
||||
log(`Finished \x1b[32m${xtermJob.name}\x1b[0m${code ? ' \x1b[31mwith errors\x1b[0m' : ''}`);
|
||||
r(code ?? 1);
|
||||
});
|
||||
});
|
||||
if (xtermCode !== 0) {
|
||||
process.exit(xtermCode);
|
||||
}
|
||||
|
||||
// Addon jobs
|
||||
const addons = (await readdir('addons')).filter(e => e.startsWith('addon-')).map(e => e.replace('addon-', ''));
|
||||
/** @type {{cp: import("child_process").ChildProcessByStdio<any, any, any>, name: string}[]} */
|
||||
const addonJobs = [];
|
||||
for (const addon of addons) {
|
||||
jobs.push(createJob(`xterm-addon-${addon}`, [`--addon=${addon}`]));
|
||||
addonJobs.push(createJob(`xterm-addon-${addon}`, [`--addon=${addon}`]));
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
await Promise.all(addonJobs.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' : ''}`);
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
from termios import tcgetattr, tcsetattr, TCSADRAIN, TIOCGWINSZ, TCSAFLUSH
|
||||
from tty import setcbreak, setraw
|
||||
import os
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from select import select
|
||||
from time import sleep
|
||||
from json import dumps, loads
|
||||
from typing import Optional, Tuple, Union
|
||||
|
||||
|
||||
class TerminalContext:
|
||||
def __init__(self, fd: int, close_fd=False) -> None:
|
||||
if not os.isatty(fd):
|
||||
raise TypeError('fd is not a terminal')
|
||||
self.close_fd = close_fd
|
||||
self.fd = fd
|
||||
self.is_cbreak = False
|
||||
self.is_raw = False
|
||||
self._initial_attr = self.termios_attributes
|
||||
|
||||
@classmethod
|
||||
def from_cterm(cls):
|
||||
fd = os.open(os.ctermid(), os.O_RDWR)
|
||||
return TerminalContext(fd, True)
|
||||
|
||||
def close(self) -> None:
|
||||
tcsetattr(self.fd, TCSADRAIN, self._initial_attr)
|
||||
if self.close_fd:
|
||||
os.close(self.fd)
|
||||
|
||||
@property
|
||||
def termios_attributes(self) -> list:
|
||||
return tcgetattr(self.fd)
|
||||
|
||||
@property
|
||||
def ttyname(self) -> str:
|
||||
return os.ttyname(self.fd)
|
||||
|
||||
@contextmanager
|
||||
def cbreak_mode(self):
|
||||
"""
|
||||
Enter cbreak mode context.
|
||||
"""
|
||||
if self.is_cbreak:
|
||||
yield
|
||||
return
|
||||
tattr = self.termios_attributes
|
||||
try:
|
||||
setcbreak(self.fd, TCSADRAIN)
|
||||
self.is_cbreak = True
|
||||
yield
|
||||
finally:
|
||||
tcsetattr(self.fd, TCSADRAIN, tattr)
|
||||
self.is_cbreak = False
|
||||
|
||||
@contextmanager
|
||||
def raw_mode(self):
|
||||
"""
|
||||
Enter cbreak mode context.
|
||||
"""
|
||||
if self.is_raw:
|
||||
yield
|
||||
return
|
||||
tattr = self.termios_attributes
|
||||
try:
|
||||
setraw(self.fd, TCSADRAIN)
|
||||
self.is_raw = True
|
||||
yield
|
||||
finally:
|
||||
tcsetattr(self.fd, TCSADRAIN, tattr)
|
||||
self.is_raw = False
|
||||
|
||||
@contextmanager
|
||||
def custom_state(self, undo=None):
|
||||
"""
|
||||
Enter custom terminal state, that needs to to be undone by ``undo``.
|
||||
Useful, if you want to apply a custom terminal state and
|
||||
have to make sure, that it gets properly reset to previous state.
|
||||
"""
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if undo:
|
||||
undo()
|
||||
|
||||
def write(self, data: Union[str, bytes]) -> None:
|
||||
"""
|
||||
Write string or bytes directly to the terminal.
|
||||
"""
|
||||
if isinstance(data, str):
|
||||
data = data.encode('utf-8')
|
||||
sent = os.write(self.fd, data)
|
||||
while sent:
|
||||
data = data[sent:]
|
||||
sent = os.write(self.fd, data)
|
||||
|
||||
def read(self, amount: int = 1024, timeout: Optional[float] = None) -> bytes:
|
||||
"""
|
||||
Blocking read from the terminal.
|
||||
If nothing was sent from the terminal within ``timeout``,
|
||||
empty bytes are returned.
|
||||
"""
|
||||
can_read, _, _ = select([self.fd], [], [], timeout)
|
||||
if can_read:
|
||||
return os.read(self.fd, amount)
|
||||
return b''
|
||||
|
||||
|
||||
@contextmanager
|
||||
def cterminal_context():
|
||||
t = TerminalContext.from_cterm()
|
||||
try:
|
||||
yield t
|
||||
finally:
|
||||
t.close()
|
||||
|
||||
|
||||
def extract_events(data: list[str]):
|
||||
if len(data) < 5:
|
||||
raise Exception('not enough reports')
|
||||
types = set(data)
|
||||
if len(types) == 1:
|
||||
return {'PRESS': data[0], 'REPEAT': data[0], 'RELEASE': None}
|
||||
if len(types) == 2:
|
||||
last = data.pop()
|
||||
if last != data[0] and len(set(data)) == 1:
|
||||
return {'PRESS': data[0], 'REPEAT': data[0], 'RELEASE': last}
|
||||
raise Exception('weird reports, 2 types')
|
||||
if len(types) == 3:
|
||||
first = data.pop(0)
|
||||
last = data.pop()
|
||||
if first != last and first != data[0] and last != data[0]:
|
||||
return {'PRESS': first, 'REPEAT': data[0], 'RELEASE': last}
|
||||
raise Exception('weird reports, 3 types')
|
||||
raise Exception('more than 3 types')
|
||||
|
||||
|
||||
def query(term: TerminalContext, mode: int):
|
||||
with term.custom_state(undo=lambda:term.write('\x1b[<u')):
|
||||
term.write(f'\x1b[>{mode}u')
|
||||
term.read(timeout=.1)
|
||||
print('PRESS (within 5s) and HOLD (for 5s)\r')
|
||||
data: list[bytes] = []
|
||||
cur = term.read(timeout=5)
|
||||
while cur:
|
||||
data.append(cur)
|
||||
cur = term.read(timeout=.5)
|
||||
if len(data) > 5:
|
||||
print('RELEASE\r', end='')
|
||||
try:
|
||||
return extract_events([b.decode('utf-8') for b in data])
|
||||
except Exception as e:
|
||||
print('Error:', e, '\r')
|
||||
print(data, '\r')
|
||||
term.read(timeout=.1)
|
||||
|
||||
|
||||
def save(filedata: dict[str, dict[str, str]], filename, entry, mode, events):
|
||||
try:
|
||||
filedata[entry][mode] = events
|
||||
except KeyError:
|
||||
filedata[entry] = {mode: events}
|
||||
with open(filename, 'w') as f:
|
||||
f.write(dumps(filedata, indent=2))
|
||||
|
||||
|
||||
def main():
|
||||
mode = 1
|
||||
filedata = {}
|
||||
print(sys.argv)
|
||||
if len(sys.argv) != 3:
|
||||
print('ERROR: not enough arguments')
|
||||
print('Usage: python kitty_keytester.py <mode> <json-file>')
|
||||
return
|
||||
mode = int(sys.argv[1])
|
||||
filename = sys.argv[2]
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as f:
|
||||
filedata = loads(f.read())
|
||||
with cterminal_context() as term:
|
||||
while True:
|
||||
with term.raw_mode():
|
||||
events = query(term, mode)
|
||||
if events:
|
||||
print(events)
|
||||
entry = input('Entry: ')
|
||||
if entry:
|
||||
save(filedata, filename, entry, str(mode), events)
|
||||
cont = input('Continue? (y)')
|
||||
if cont not in ['y', '']:
|
||||
break
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+1
-1
@@ -8,7 +8,7 @@ const path = require('path');
|
||||
|
||||
const COVERAGE_LINES_THRESHOLD = 40;
|
||||
|
||||
// Add `out` to the NODE_PATH so absolute paths can be resolved.
|
||||
// Add `out-esbuild` to NODE_PATH for any remaining non-relative requires in test bundles.
|
||||
const env = { ...process.env };
|
||||
env.NODE_PATH = path.resolve(__dirname, '../out-esbuild');
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { BaseWindow } from './baseWindow';
|
||||
import type { Terminal, ITheme } from '@xterm/xterm';
|
||||
import type { IControlWindow } from '../controlBar';
|
||||
import type { AddonCollection } from 'types';
|
||||
import type { AddonCollection } from '../../types';
|
||||
|
||||
const xtermjsTheme: ITheme = Object.freeze({
|
||||
foreground: '#F8F8F8',
|
||||
@@ -252,6 +252,11 @@ export class OptionsWindow extends BaseWindow implements IControlWindow {
|
||||
input.value = 'auto';
|
||||
this._handlers.updateTerminalSize();
|
||||
}
|
||||
const screenElement = document.querySelector('.xterm-screen');
|
||||
if (screenElement instanceof HTMLElement) {
|
||||
screenElement.style.outline = this._autoResize ? ''
|
||||
: 'solid thin red';
|
||||
}
|
||||
} else if (o === 'theme') {
|
||||
value = this._getTheme();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { writeUnicodeTable } from '../../unicodeTable';
|
||||
import type { IControlWindow } from '../controlBar';
|
||||
import { BaseWindow } from './baseWindow';
|
||||
import type { IDisposable, Terminal } from '@xterm/xterm';
|
||||
import type { AddonCollection } from 'types';
|
||||
import type { AddonCollection } from '../../types';
|
||||
|
||||
export class TestWindow extends BaseWindow implements IControlWindow {
|
||||
public readonly id = 'test';
|
||||
|
||||
@@ -6,23 +6,7 @@
|
||||
"rootDir": ".",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"@xterm/addon-attach": ["../../addons/addon-attach"],
|
||||
"@xterm/addon-clipboard": ["../../addons/addon-clipboard"],
|
||||
"@xterm/addon-fit": ["../../addons/addon-fit"],
|
||||
"@xterm/addon-image": ["../../addons/addon-image"],
|
||||
"@xterm/addon-progress": ["../../addons/addon-progress"],
|
||||
"@xterm/addon-search": ["../../addons/addon-search"],
|
||||
"@xterm/addon-serialize": ["../../addons/addon-serialize"],
|
||||
"@xterm/addon-web-fonts": ["../../addons/addon-web-fonts"],
|
||||
"@xterm/addon-web-links": ["../../addons/addon-web-links"],
|
||||
"@xterm/addon-webgl": ["../../addons/addon-webgl"],
|
||||
"@xterm/addon-unicode11": ["../../addons/addon-unicode11"],
|
||||
"@xterm/addon-unicode-graphemes": ["../../addons/addon-unicode-graphemes"],
|
||||
"@xterm/addon-ligatures": ["../../addons/addon-ligatures"],
|
||||
"*": ["./*"]
|
||||
}
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"./**/*"
|
||||
]
|
||||
}
|
||||
|
||||
+6
-2
@@ -1,7 +1,11 @@
|
||||
{
|
||||
"references": [
|
||||
{ "path": "./client" },
|
||||
{ "path": "./server" }
|
||||
{
|
||||
"path": "./client"
|
||||
},
|
||||
{
|
||||
"path": "./server"
|
||||
}
|
||||
],
|
||||
"files": []
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ export default tseslint.config(
|
||||
singleline: { delimiter: 'comma', requireLast: false }
|
||||
}],
|
||||
'@stylistic/type-annotation-spacing': 'warn',
|
||||
'@stylistic/space-unary-ops': 'warn',
|
||||
|
||||
'@typescript-eslint/array-type': ['warn', { default: 'array', readonly: 'generic' }],
|
||||
'@typescript-eslint/consistent-type-assertions': 'warn',
|
||||
@@ -85,6 +86,7 @@ export default tseslint.config(
|
||||
'eqeqeq': ['warn', 'always'],
|
||||
'jsdoc/check-alignment': 'warn',
|
||||
'jsdoc/check-param-names': 'warn',
|
||||
'jsdoc/multiline-blocks': 'warn',
|
||||
'jsdoc/no-multi-asterisks': 'warn',
|
||||
'keyword-spacing': 'warn',
|
||||
'max-len': ['warn', {
|
||||
|
||||
@@ -1,373 +0,0 @@
|
||||
{
|
||||
"Escape +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[27;65u",
|
||||
"REPEAT": "\u001b[27;65u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F1 +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;65P",
|
||||
"REPEAT": "\u001b[1;65P",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Insert +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[2;65~",
|
||||
"REPEAT": "\u001b[2;65~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Delete +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[3;65~",
|
||||
"REPEAT": "\u001b[3;65~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageUp +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[5;65~",
|
||||
"REPEAT": "\u001b[5;65~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Dead (Backquote) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "^",
|
||||
"REPEAT": "^",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"1 (Digit1) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "1",
|
||||
"REPEAT": "1",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00df (Minus) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u1e9e",
|
||||
"REPEAT": "\u1e9e",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Dead (Equal) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u00b4",
|
||||
"REPEAT": "\u00b4",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Backspace +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u007f",
|
||||
"REPEAT": "\u007f",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Tab +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\t",
|
||||
"REPEAT": "\t",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Q (KeyQ) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "Q",
|
||||
"REPEAT": "Q",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00dc (BracketLeft) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u00dc",
|
||||
"REPEAT": "\u00dc",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"+ (BracketRight) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "+",
|
||||
"REPEAT": "+",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Enter +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\r",
|
||||
"REPEAT": "\r",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00d6 (Semicolon) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u00d6",
|
||||
"REPEAT": "\u00d6",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00c4 (Quote) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u00c4",
|
||||
"REPEAT": "\u00c4",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"# (Bashslash) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "#",
|
||||
"REPEAT": "#",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"< (IntlBackslash) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "<",
|
||||
"REPEAT": "<",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
", (Comma) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": ",",
|
||||
"REPEAT": ",",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
". (Period) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": ".",
|
||||
"REPEAT": ".",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"- (Slash) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "-",
|
||||
"REPEAT": "-",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowUp +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;65A",
|
||||
"REPEAT": "\u001b[1;65A",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageDown +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[6;65~",
|
||||
"REPEAT": "\u001b[6;65~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Home +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;65H",
|
||||
"REPEAT": "\u001b[1;65H",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"End +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;65F",
|
||||
"REPEAT": "\u001b[1;65F",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"+ (NumpadAdd) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "+",
|
||||
"REPEAT": "+",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Enter (NumpadEnter) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57414;65u",
|
||||
"REPEAT": "\u001b[57414;65u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Insert (Numpad0) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57425;65u",
|
||||
"REPEAT": "\u001b[57425;65u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u0000 (NumpadDecimal) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57426;65u",
|
||||
"REPEAT": "\u001b[57426;65u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Numlock +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"CapsLock +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Shift (ShiftLeft) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Shift (ShiftRight) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Control (ControlLeft) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Meta (MetaLeft) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Alt (AltLeft) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"AltGraph (AltRight) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Control (ControlRight) +CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"/ (NumpadDivide) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "/",
|
||||
"REPEAT": "/",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"* (NumpadMultiply) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "*",
|
||||
"REPEAT": "*",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"- (NumpadSubtract) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "-",
|
||||
"REPEAT": "-",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"0 (Numpad0) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "0",
|
||||
"REPEAT": "0",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"1 (Numpad1) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "1",
|
||||
"REPEAT": "1",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"2 (Numpad2) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "2",
|
||||
"REPEAT": "2",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"3 (Numpad3) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "3",
|
||||
"REPEAT": "3",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"4 (Numpad4) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "4",
|
||||
"REPEAT": "4",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"5 (Numpad5) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "5",
|
||||
"REPEAT": "5",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"6 (Numpad6) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "6",
|
||||
"REPEAT": "6",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"7 (Numpad7) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "7",
|
||||
"REPEAT": "7",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"8 (Numpad8) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "8",
|
||||
"REPEAT": "8",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"9 (Numpad9) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": "9",
|
||||
"REPEAT": "9",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
", (NumpadDecimal) +NumLock": {
|
||||
"1": {
|
||||
"PRESS": ",",
|
||||
"REPEAT": ",",
|
||||
"RELEASE": null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,702 +0,0 @@
|
||||
{
|
||||
"Escape": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[27u",
|
||||
"REPEAT": "\u001b[27u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F1": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[P",
|
||||
"REPEAT": "\u001b[P",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F2": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[Q",
|
||||
"REPEAT": "\u001b[Q",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F3": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[13~",
|
||||
"REPEAT": "\u001b[13~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F4": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[S",
|
||||
"REPEAT": "\u001b[S",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F5": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[15~",
|
||||
"REPEAT": "\u001b[15~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F6": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[17~",
|
||||
"REPEAT": "\u001b[17~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F7": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[18~",
|
||||
"REPEAT": "\u001b[18~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F8": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[19~",
|
||||
"REPEAT": "\u001b[19~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F9": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[20~",
|
||||
"REPEAT": "\u001b[20~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F10": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[21~",
|
||||
"REPEAT": "\u001b[21~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F11": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[23~",
|
||||
"REPEAT": "\u001b[23~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F12": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[24~",
|
||||
"REPEAT": "\u001b[24~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Insert": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[2~",
|
||||
"REPEAT": "\u001b[2~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Delete": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[3~",
|
||||
"REPEAT": "\u001b[3~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageUp": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[5~",
|
||||
"REPEAT": "\u001b[5~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageDown": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[6~",
|
||||
"REPEAT": "\u001b[6~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Home": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[H",
|
||||
"REPEAT": "\u001b[H",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"End": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[F",
|
||||
"REPEAT": "\u001b[F",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Dead (Backquote)": {
|
||||
"1": {
|
||||
"PRESS": "^",
|
||||
"REPEAT": "^",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"1 (Digit1)": {
|
||||
"1": {
|
||||
"PRESS": "1",
|
||||
"REPEAT": "1",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"2 (Digit2)": {
|
||||
"1": {
|
||||
"PRESS": "2",
|
||||
"REPEAT": "2",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"3 (Digit3)": {
|
||||
"1": {
|
||||
"PRESS": "3",
|
||||
"REPEAT": "3",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"4 (Digit4)": {
|
||||
"1": {
|
||||
"PRESS": "4",
|
||||
"REPEAT": "4",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"5 (Digit5)": {
|
||||
"1": {
|
||||
"PRESS": "5",
|
||||
"REPEAT": "5",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"6 (Digit6)": {
|
||||
"1": {
|
||||
"PRESS": "6",
|
||||
"REPEAT": "6",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"7 (Digit7)": {
|
||||
"1": {
|
||||
"PRESS": "7",
|
||||
"REPEAT": "7",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"8 (Digit8)": {
|
||||
"1": {
|
||||
"PRESS": "8",
|
||||
"REPEAT": "8",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"9 (Digit9)": {
|
||||
"1": {
|
||||
"PRESS": "9",
|
||||
"REPEAT": "9",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"0 (Digit0)": {
|
||||
"1": {
|
||||
"PRESS": "0",
|
||||
"REPEAT": "0",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00df (Minus)": {
|
||||
"1": {
|
||||
"PRESS": "\u00df",
|
||||
"REPEAT": "\u00df",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Dead (Equal)": {
|
||||
"1": {
|
||||
"PRESS": "\u00b4",
|
||||
"REPEAT": "\u00b4",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Backspace": {
|
||||
"1": {
|
||||
"PRESS": "\u007f",
|
||||
"REPEAT": "\u007f",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Tab": {
|
||||
"1": {
|
||||
"PRESS": "\t",
|
||||
"REPEAT": "\t",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"q (KeyQ)": {
|
||||
"1": {
|
||||
"PRESS": "q",
|
||||
"REPEAT": "q",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"w (KeyW)": {
|
||||
"1": {
|
||||
"PRESS": "w",
|
||||
"REPEAT": "w",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"e (KeyE)": {
|
||||
"1": {
|
||||
"PRESS": "e",
|
||||
"REPEAT": "e",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"r (KeyR)": {
|
||||
"1": {
|
||||
"PRESS": "r",
|
||||
"REPEAT": "r",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"t (KeyT)": {
|
||||
"1": {
|
||||
"PRESS": "t",
|
||||
"REPEAT": "t",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"z (KeyY)": {
|
||||
"1": {
|
||||
"PRESS": "z",
|
||||
"REPEAT": "z",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"u (KeyU)": {
|
||||
"1": {
|
||||
"PRESS": "u",
|
||||
"REPEAT": "u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"i (KeyI)": {
|
||||
"1": {
|
||||
"PRESS": "i",
|
||||
"REPEAT": "i",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"o (KeyO)": {
|
||||
"1": {
|
||||
"PRESS": "o",
|
||||
"REPEAT": "o",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"p (KeyP)": {
|
||||
"1": {
|
||||
"PRESS": "p",
|
||||
"REPEAT": "p",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00fc (BracketLeft)": {
|
||||
"1": {
|
||||
"PRESS": "\u00fc",
|
||||
"REPEAT": "\u00fc",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"+ (BracketRight)": {
|
||||
"1": {
|
||||
"PRESS": "+",
|
||||
"REPEAT": "+",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Enter": {
|
||||
"1": {
|
||||
"PRESS": "\r",
|
||||
"REPEAT": "\r",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"a (KeyA)": {
|
||||
"1": {
|
||||
"PRESS": "a",
|
||||
"REPEAT": "a",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"s (KeyS)": {
|
||||
"1": {
|
||||
"PRESS": "s",
|
||||
"REPEAT": "s",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"d (KeyD)": {
|
||||
"1": {
|
||||
"PRESS": "d",
|
||||
"REPEAT": "d",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"f (KeyF)": {
|
||||
"1": {
|
||||
"PRESS": "f",
|
||||
"REPEAT": "f",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"g (KeyG)": {
|
||||
"1": {
|
||||
"PRESS": "g",
|
||||
"REPEAT": "g",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"h (KeyH)": {
|
||||
"1": {
|
||||
"PRESS": "h",
|
||||
"REPEAT": "h",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"j (KeyJ)": {
|
||||
"1": {
|
||||
"PRESS": "j",
|
||||
"REPEAT": "j",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"k (KeyK)": {
|
||||
"1": {
|
||||
"PRESS": "k",
|
||||
"REPEAT": "k",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"l (KeyL)": {
|
||||
"1": {
|
||||
"PRESS": "l",
|
||||
"REPEAT": "l",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00f6 (Semicolon)": {
|
||||
"1": {
|
||||
"PRESS": "\u00f6",
|
||||
"REPEAT": "\u00f6",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00e4 (Quote)": {
|
||||
"1": {
|
||||
"PRESS": "\u00e4",
|
||||
"REPEAT": "\u00e4",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"# (Backslash)": {
|
||||
"1": {
|
||||
"PRESS": "#",
|
||||
"REPEAT": "#",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"< (IntlBackslash)": {
|
||||
"1": {
|
||||
"PRESS": "<",
|
||||
"REPEAT": "<",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"y (KeyZ)": {
|
||||
"1": {
|
||||
"PRESS": "y",
|
||||
"REPEAT": "y",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"x (KeyX)": {
|
||||
"1": {
|
||||
"PRESS": "x",
|
||||
"REPEAT": "x",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"c (KeyC)": {
|
||||
"1": {
|
||||
"PRESS": "c",
|
||||
"REPEAT": "c",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"v (KeyV)": {
|
||||
"1": {
|
||||
"PRESS": "v",
|
||||
"REPEAT": "v",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"b (KeyB)": {
|
||||
"1": {
|
||||
"PRESS": "b",
|
||||
"REPEAT": "b",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"n (KeyN)": {
|
||||
"1": {
|
||||
"PRESS": "n",
|
||||
"REPEAT": "n",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"m (KeyM)": {
|
||||
"1": {
|
||||
"PRESS": "m",
|
||||
"REPEAT": "m",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
", (Comma)": {
|
||||
"1": {
|
||||
"PRESS": ",",
|
||||
"REPEAT": ",",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
". (Period)": {
|
||||
"1": {
|
||||
"PRESS": ".",
|
||||
"REPEAT": ".",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"- (Slash)": {
|
||||
"1": {
|
||||
"PRESS": "-",
|
||||
"REPEAT": "-",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowLeft": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[D",
|
||||
"REPEAT": "\u001b[D",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowUp": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[A",
|
||||
"REPEAT": "\u001b[A",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowRight": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[C",
|
||||
"REPEAT": "\u001b[C",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowDown": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[B",
|
||||
"REPEAT": "\u001b[B",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"/ (NumpadDivide)": {
|
||||
"1": {
|
||||
"PRESS": "/",
|
||||
"REPEAT": "/",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"* (NumpadMultiply)": {
|
||||
"1": {
|
||||
"PRESS": "*",
|
||||
"REPEAT": "*",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"- (NumpadSubtract)": {
|
||||
"1": {
|
||||
"PRESS": "-",
|
||||
"REPEAT": "-",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Home (Numpad7)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57423u",
|
||||
"REPEAT": "\u001b[57423u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowUp (Numpad8)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57419u",
|
||||
"REPEAT": "\u001b[57419u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageUp (Numpad9)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57421u",
|
||||
"REPEAT": "\u001b[57421u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"+ (NumpadAdd)": {
|
||||
"1": {
|
||||
"PRESS": "+",
|
||||
"REPEAT": "+",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowLeft (Numpad4)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57417u",
|
||||
"REPEAT": "\u001b[57417u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Clear (Numpad5)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[E",
|
||||
"REPEAT": "\u001b[E",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowRight (Numpad6)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57418u",
|
||||
"REPEAT": "\u001b[57418u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"End (Numpad1)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57424u",
|
||||
"REPEAT": "\u001b[57424u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowDown (Numpad2)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57420u",
|
||||
"REPEAT": "\u001b[57420u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageDown (Numpad3)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57422u",
|
||||
"REPEAT": "\u001b[57422u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Enter (NumpadEnter)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57414u",
|
||||
"REPEAT": "\u001b[57414u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Insert (Numpad0)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57425u",
|
||||
"REPEAT": "\u001b[57425u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u0000 (NumpadDecimal)": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57426u",
|
||||
"REPEAT": "\u001b[57426u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Numlock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"CapsLock": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Shift (ShiftLeft)": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Shift (ShiftRight)": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Control (ControlLeft)": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Meta (MetaLeft)": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Alt (AltLeft)": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
" (Space)": {
|
||||
"1": {
|
||||
"PRESS": " ",
|
||||
"REPEAT": " ",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"AltGraph (AltRight)": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Control (ControlRight)": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,331 +0,0 @@
|
||||
{
|
||||
"Escape +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[27;2u",
|
||||
"REPEAT": "\u001b[27;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"F1 +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;2P",
|
||||
"REPEAT": "\u001b[1;2P",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Delete +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[3;2~",
|
||||
"REPEAT": "\u001b[3;2~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageUp +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[5;2~",
|
||||
"REPEAT": "\u001b[5;2~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Dead (Backquote) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u00b0",
|
||||
"REPEAT": "\u00b0",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"! (Digit1) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "!",
|
||||
"REPEAT": "!",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\" (Digit2) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\"",
|
||||
"REPEAT": "\"",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00a7 (Digit3) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u00a7",
|
||||
"REPEAT": "\u00a7",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"$ (Digit4) +Shifft": {
|
||||
"1": {
|
||||
"PRESS": "$",
|
||||
"REPEAT": "$",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"% (Digit5) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "%",
|
||||
"REPEAT": "%",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"& (Digit6) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "&",
|
||||
"REPEAT": "&",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"/ (Digit7) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "/",
|
||||
"REPEAT": "/",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"( (Digit8) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "(",
|
||||
"REPEAT": "(",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
") (Digit9) +Shift": {
|
||||
"1": {
|
||||
"PRESS": ")",
|
||||
"REPEAT": ")",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"= (Digit0) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "=",
|
||||
"REPEAT": "=",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"? (Minus) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "?",
|
||||
"REPEAT": "?",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Backspace +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[127;2u",
|
||||
"REPEAT": "\u001b[127;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Tab +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[9;2u",
|
||||
"REPEAT": "\u001b[9;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Q (KeyQ) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "Q",
|
||||
"REPEAT": "Q",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00dc (BracketLeft) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u00dc",
|
||||
"REPEAT": "\u00dc",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"* (BracketRight) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "*",
|
||||
"REPEAT": "*",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Enter +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[13;2u",
|
||||
"REPEAT": "\u001b[13;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00d6 (Semicolon) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u00d6",
|
||||
"REPEAT": "\u00d6",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u00c4 (Quote) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u00c4",
|
||||
"REPEAT": "\u00c4",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"' (Backslash) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "'",
|
||||
"REPEAT": "'",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"> (IntlBackslash) +Shift": {
|
||||
"1": {
|
||||
"PRESS": ">",
|
||||
"REPEAT": ">",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"; (Comma) +Shift": {
|
||||
"1": {
|
||||
"PRESS": ";",
|
||||
"REPEAT": ";",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
": (Period) +Shift": {
|
||||
"1": {
|
||||
"PRESS": ":",
|
||||
"REPEAT": ":",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"_ (Slash) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "_",
|
||||
"REPEAT": "_",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowUp +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;2A",
|
||||
"REPEAT": "\u001b[1;2A",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"PageDown +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[6;2~",
|
||||
"REPEAT": "\u001b[6;2~",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Home +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;2H",
|
||||
"REPEAT": "\u001b[1;2H",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Home (Numpad7) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57423;2u",
|
||||
"REPEAT": "\u001b[57423;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"ArrowUp (Numapd8) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57419;2u",
|
||||
"REPEAT": "\u001b[57419;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Clear (Numpad5) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[1;2E",
|
||||
"REPEAT": "\u001b[1;2E",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Enter (NumpadEnter) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57414;2u",
|
||||
"REPEAT": "\u001b[57414;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Insert (Numpad0) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57425;2u",
|
||||
"REPEAT": "\u001b[57425;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"\u0000 (NumpadDecimal) +Shift": {
|
||||
"1": {
|
||||
"PRESS": "\u001b[57426;2u",
|
||||
"REPEAT": "\u001b[57426;2u",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Numlock +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"CapsLock +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Shift (ShiftRight) +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Control (ControlLeft) +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Meta (MetaLeft) +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Alt (AltLeft) +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
" (Space) +Shift": {
|
||||
"1": {
|
||||
"PRESS": " ",
|
||||
"REPEAT": " ",
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"AltGraph (AltRight) +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
},
|
||||
"Control (ControlRight) +Shift": {
|
||||
"1": {
|
||||
"PRESS": null,
|
||||
"REPEAT": null,
|
||||
"RELEASE": null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,13 @@
|
||||
"description": "A headless terminal component that runs in Node.js",
|
||||
"version": "6.0.0",
|
||||
"main": "lib-headless/xterm-headless.js",
|
||||
"module": "lib-headless/xterm-headless.mjs",
|
||||
"module": "lib/xterm.mjs",
|
||||
"types": "typings/xterm-headless.d.ts",
|
||||
"exports": {
|
||||
"types": "./typings/xterm-headless.d.ts",
|
||||
"import": "./lib-headless/xterm-headless.mjs",
|
||||
"require": "./lib-headless/xterm-headless.js"
|
||||
},
|
||||
"repository": "https://github.com/xtermjs/xterm.js",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"addons/*"
|
||||
],
|
||||
"keywords": [
|
||||
"cli",
|
||||
"command-line",
|
||||
@@ -27,4 +25,4 @@
|
||||
"webgl",
|
||||
"xterm"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Smoke test: @xterm/headless loads and runs in Node.js (require).
|
||||
*/
|
||||
const { strictEqual } = require('node:assert');
|
||||
const { Terminal } = require('./lib-headless/xterm-headless.js');
|
||||
|
||||
function writeSync(term, data) {
|
||||
return new Promise(resolve => term.write(data, resolve));
|
||||
}
|
||||
|
||||
function lineEquals(term, index, text) {
|
||||
strictEqual(term.buffer.active.getLine(index).translateToString(true), text);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const term = new Terminal({ cols: 80, rows: 24, allowProposedApi: true });
|
||||
strictEqual(term.cols, 80);
|
||||
strictEqual(term.rows, 24);
|
||||
|
||||
await writeSync(term, 'hello from node');
|
||||
lineEquals(term, 0, 'hello from node');
|
||||
|
||||
await writeSync(term, 'foo');
|
||||
await writeSync(term, 'bar');
|
||||
await writeSync(term, '文');
|
||||
lineEquals(term, 0, 'hello from nodefoobar文');
|
||||
|
||||
term.resize(60, 15);
|
||||
strictEqual(term.cols, 60);
|
||||
strictEqual(term.rows, 15);
|
||||
|
||||
term.dispose();
|
||||
strictEqual(term._core._store.isDisposed, true);
|
||||
|
||||
console.log('headless package (CJS): load, write, buffer, resize, dispose OK');
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Smoke test: @xterm/headless loads and runs in Node.js (ESM + CJS).
|
||||
*/
|
||||
import { createRequire } from 'node:module';
|
||||
import { strictEqual } from 'node:assert';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
function writeSync(term, data) {
|
||||
return new Promise(resolve => term.write(data, resolve));
|
||||
}
|
||||
|
||||
function lineEquals(term, index, text) {
|
||||
strictEqual(term.buffer.active.getLine(index).translateToString(true), text);
|
||||
}
|
||||
|
||||
const { Terminal: TerminalEsm } = await import('./lib-headless/xterm-headless.mjs');
|
||||
const termEsm = new TerminalEsm({ cols: 80, rows: 24 });
|
||||
await writeSync(termEsm, 'esm ok');
|
||||
lineEquals(termEsm, 0, 'esm ok');
|
||||
termEsm.dispose();
|
||||
|
||||
const { Terminal: TerminalCjs } = require('./lib-headless/xterm-headless.js');
|
||||
const termCjs = new TerminalCjs({ cols: 40, rows: 10 });
|
||||
await writeSync(termCjs, 'cjs ok');
|
||||
lineEquals(termCjs, 0, 'cjs ok');
|
||||
termCjs.dispose();
|
||||
|
||||
console.log('headless package: ESM and CJS load, write, and buffer read OK');
|
||||
Generated
+9
-706
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user