diff --git a/.eslintrc.json b/.eslintrc.json index a6f2d2ed..d1092b09 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -14,31 +14,31 @@ "test/api/tsconfig.json", "test/benchmark/tsconfig.json", "test/playwright/tsconfig.json", - "addons/xterm-addon-attach/src/tsconfig.json", - "addons/xterm-addon-attach/test/tsconfig.json", - "addons/xterm-addon-canvas/src/tsconfig.json", - "addons/xterm-addon-canvas/test/tsconfig.json", + "addons/addon-attach/src/tsconfig.json", + "addons/addon-attach/test/tsconfig.json", + "addons/addon-canvas/src/tsconfig.json", + "addons/addon-canvas/test/tsconfig.json", "addons/xterm-addon-clipboard/src/tsconfig.json", "addons/xterm-addon-clipboard/test/tsconfig.json", - "addons/xterm-addon-fit/src/tsconfig.json", - "addons/xterm-addon-fit/test/tsconfig.json", - "addons/xterm-addon-image/src/tsconfig.json", - "addons/xterm-addon-image/test/tsconfig.json", - "addons/xterm-addon-ligatures/src/tsconfig.json", - "addons/xterm-addon-search/src/tsconfig.json", - "addons/xterm-addon-search/test/tsconfig.json", - "addons/xterm-addon-serialize/src/tsconfig.json", - "addons/xterm-addon-serialize/test/tsconfig.json", - "addons/xterm-addon-serialize/benchmark/tsconfig.json", - "addons/xterm-addon-unicode11/src/tsconfig.json", - "addons/xterm-addon-unicode11/test/tsconfig.json", - "addons/xterm-addon-unicode-graphemes/src/tsconfig.json", - "addons/xterm-addon-unicode-graphemes/test/tsconfig.json", - "addons/xterm-addon-unicode-graphemes/benchmark/tsconfig.json", - "addons/xterm-addon-web-links/src/tsconfig.json", - "addons/xterm-addon-web-links/test/tsconfig.json", - "addons/xterm-addon-webgl/src/tsconfig.json", - "addons/xterm-addon-webgl/test/tsconfig.json" + "addons/addon-fit/src/tsconfig.json", + "addons/addon-fit/test/tsconfig.json", + "addons/addon-image/src/tsconfig.json", + "addons/addon-image/test/tsconfig.json", + "addons/addon-ligatures/src/tsconfig.json", + "addons/addon-search/src/tsconfig.json", + "addons/addon-search/test/tsconfig.json", + "addons/addon-serialize/src/tsconfig.json", + "addons/addon-serialize/test/tsconfig.json", + "addons/addon-serialize/benchmark/tsconfig.json", + "addons/addon-unicode11/src/tsconfig.json", + "addons/addon-unicode11/test/tsconfig.json", + "addons/addon-unicode-graphemes/src/tsconfig.json", + "addons/addon-unicode-graphemes/test/tsconfig.json", + "addons/addon-unicode-graphemes/benchmark/tsconfig.json", + "addons/addon-web-links/src/tsconfig.json", + "addons/addon-web-links/test/tsconfig.json", + "addons/addon-webgl/src/tsconfig.json", + "addons/addon-webgl/test/tsconfig.json" ], "sourceType": "module" }, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eea525d0..0a64b6a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,28 +26,28 @@ jobs: zip -r compressed-build \ ./out/* \ ./out-test/* \ - ./addons/xterm-addon-attach/out/* \ - ./addons/xterm-addon-attach/out-test/* \ - ./addons/xterm-addon-canvas/out/* \ - ./addons/xterm-addon-canvas/out-test/* \ - ./addons/xterm-addon-fit/out/* \ - ./addons/xterm-addon-fit/out-test/* \ - ./addons/xterm-addon-image/out/* \ - ./addons/xterm-addon-image/out-test/* \ - ./addons/xterm-addon-ligatures/out/* \ - ./addons/xterm-addon-ligatures/out-test/* \ - ./addons/xterm-addon-search/out/* \ - ./addons/xterm-addon-search/out-test/* \ - ./addons/xterm-addon-serialize/out/* \ - ./addons/xterm-addon-serialize/out-test/* \ - ./addons/xterm-addon-unicode11/out/* \ - ./addons/xterm-addon-unicode11/out-test/* \ - ./addons/xterm-addon-unicode-graphemes/out/* \ - ./addons/xterm-addon-unicode-graphemes/out-test/* \ - ./addons/xterm-addon-web-links/out/* \ - ./addons/xterm-addon-web-links/out-test/* \ - ./addons/xterm-addon-webgl/out/* \ - ./addons/xterm-addon-webgl/out-test/* + ./addons/addon-attach/out/* \ + ./addons/addon-attach/out-test/* \ + ./addons/addon-canvas/out/* \ + ./addons/addon-canvas/out-test/* \ + ./addons/addon-fit/out/* \ + ./addons/addon-fit/out-test/* \ + ./addons/addon-image/out/* \ + ./addons/addon-image/out-test/* \ + ./addons/addon-ligatures/out/* \ + ./addons/addon-ligatures/out-test/* \ + ./addons/addon-search/out/* \ + ./addons/addon-search/out-test/* \ + ./addons/addon-serialize/out/* \ + ./addons/addon-serialize/out-test/* \ + ./addons/addon-unicode11/out/* \ + ./addons/addon-unicode11/out-test/* \ + ./addons/addon-unicode-graphemes/out/* \ + ./addons/addon-unicode-graphemes/out-test/* \ + ./addons/addon-web-links/out/* \ + ./addons/addon-web-links/out-test/* \ + ./addons/addon-webgl/out/* \ + ./addons/addon-webgl/out-test/* - name: Upload artifacts uses: actions/upload-artifact@v3 with: @@ -265,10 +265,10 @@ jobs: run: yarn build-demo - name: Integration tests (core) # Tests use 50% workers to reduce flakiness run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=core - - name: Integration tests (xterm-addon-canvas) - run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=xterm-addon-canvas - - name: Integration tests (xterm-addon-webgl) - run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=xterm-addon-webgl + - name: Integration tests (addon-canvas) + run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-canvas + - name: Integration tests (addon-webgl) + run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-webgl test-api: needs: build @@ -306,3 +306,41 @@ jobs: ls -R - name: Integration tests (${{ matrix.browser }}) run: yarn test-api-${{ matrix.browser }} --headless --forbid-only + + release-dry-run: + needs: build + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18] + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }}.x + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }}.x + cache: 'yarn' + - name: Install dependencies + run: | + yarn --frozen-lockfile + yarn install-addons + - name: Install playwright + run: npx playwright install + - uses: actions/download-artifact@v3 + with: + name: build-artifacts + - name: Unzip artifacts + shell: bash + run: | + if [ "$RUNNER_OS" == "Windows" ]; then + pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}" + else + unzip -o compressed-build.zip + fi + ls -R + - name: Package headless + run: | + yarn package-headless + node ./bin/package_headless.js + - name: Publish to npm (dry run) + run: node ./bin/publish.js --dry diff --git a/README.md b/README.md index 39cca88a..9ac2c009 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to t The recommended way to load xterm.js is via the ES6 module syntax: ```javascript -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; ``` ### Addons @@ -59,14 +59,14 @@ import { Terminal } from 'xterm'; Addons are separate modules that extend the `Terminal` by building on the [xterm.js API](https://github.com/xtermjs/xterm.js/blob/master/typings/xterm.d.ts). To use an addon, you first need to install it in your project: ```bash -npm i -S xterm-addon-web-links +npm i -S @xterm/addon-web-links ``` Then import the addon, instantiate it and call `Terminal.loadAddon`: ```ts -import { Terminal } from 'xterm'; -import { WebLinksAddon } from 'xterm-addon-web-links'; +import { Terminal } from '@xterm/xterm'; +import { WebLinksAddon } from '@xterm/addon-web-links'; const terminal = new Terminal(); // Load WebLinksAddon on terminal, this is all that's needed to get web links @@ -76,11 +76,16 @@ terminal.loadAddon(new WebLinksAddon()); The xterm.js team maintains the following addons, but anyone can build them: -- [`xterm-addon-attach`](https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-attach): Attaches to a server running a process via a websocket +- [`@xterm/addon-attach`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-attach): Attaches to a server running a process via a websocket +- [`@xterm/addon-canvas`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-canvas): Renders xterm.js using a `canvas` element's 2d context - [`xterm-addon-clipboard`](https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-clipboard): Access the browser's clipboard -- [`xterm-addon-fit`](https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-fit): Fits the terminal to the containing element -- [`xterm-addon-search`](https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-search): Adds search functionality -- [`xterm-addon-web-links`](https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-web-links): Adds web link detection and interaction +- [`@xterm/addon-fit`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-fit): Fits the terminal to the containing element +- [`@xterm/addon-image`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-image): Adds image support +- [`@xterm/addon-search`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-search): Adds search functionality +- [`@xterm/addon-serialize`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-serialize): Serializes the terminal's buffer to a VT sequences or HTML +- [`@xterm/addon-unicode11`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-unicode11): Updates character widths to their unicode11 values +- [`@xterm/addon-web-links`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-web-links): Adds web link detection and interaction +- [`@xterm/addon-webgl`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-webgl): Renders xterm.js using a `canvas` element's webgl2 context ## Browser Support diff --git a/addons/xterm-addon-attach/.gitignore b/addons/addon-attach/.gitignore similarity index 100% rename from addons/xterm-addon-attach/.gitignore rename to addons/addon-attach/.gitignore diff --git a/addons/xterm-addon-attach/.npmignore b/addons/addon-attach/.npmignore similarity index 100% rename from addons/xterm-addon-attach/.npmignore rename to addons/addon-attach/.npmignore diff --git a/addons/xterm-addon-attach/LICENSE b/addons/addon-attach/LICENSE similarity index 100% rename from addons/xterm-addon-attach/LICENSE rename to addons/addon-attach/LICENSE diff --git a/addons/xterm-addon-attach/README.md b/addons/addon-attach/README.md similarity index 61% rename from addons/xterm-addon-attach/README.md rename to addons/addon-attach/README.md index 67ebf17b..fa123fe2 100644 --- a/addons/xterm-addon-attach/README.md +++ b/addons/addon-attach/README.md @@ -1,22 +1,22 @@ -## xterm-addon-attach +## @xterm/addon-attach An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables attaching to a web socket. This addon requires xterm.js v4+. ### Install ```bash -npm install --save xterm-addon-attach +npm install --save @xterm/addon-attach ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { AttachAddon } from 'xterm-addon-attach'; +import { Terminal } from '@xterm/xterm'; +import { AttachAddon } from '@xterm/addon-attach'; const terminal = new Terminal(); const attachAddon = new AttachAddon(webSocket); terminal.loadAddon(attachAddon); ``` -See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-attach/typings/xterm-addon-attach.d.ts) for more advanced usage. +See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/addon-attach/typings/addon-attach.d.ts) for more advanced usage. diff --git a/addons/xterm-addon-attach/package.json b/addons/addon-attach/package.json similarity index 74% rename from addons/xterm-addon-attach/package.json rename to addons/addon-attach/package.json index be92fc66..94b483dd 100644 --- a/addons/xterm-addon-attach/package.json +++ b/addons/addon-attach/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-attach", + "name": "@xterm/addon-attach", "version": "0.9.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-attach.js", - "types": "typings/xterm-addon-attach.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-attach", + "main": "lib/addon-attach.js", + "types": "typings/addon-attach.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-attach", "license": "MIT", "keywords": [ "terminal", @@ -21,6 +21,6 @@ "prepublishOnly": "npm run package" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-attach/src/AttachAddon.ts b/addons/addon-attach/src/AttachAddon.ts similarity index 92% rename from addons/xterm-addon-attach/src/AttachAddon.ts rename to addons/addon-attach/src/AttachAddon.ts index 7fd8df29..37a10d17 100644 --- a/addons/xterm-addon-attach/src/AttachAddon.ts +++ b/addons/addon-attach/src/AttachAddon.ts @@ -5,13 +5,14 @@ * Implements the attach method, that attaches the terminal to a WebSocket stream. */ -import { Terminal, IDisposable, ITerminalAddon } from 'xterm'; +import type { Terminal, IDisposable, ITerminalAddon } from '@xterm/xterm'; +import type { AttachAddon as IAttachApi } from '@xterm/addon-attach'; interface IAttachOptions { bidirectional?: boolean; } -export class AttachAddon implements ITerminalAddon { +export class AttachAddon implements ITerminalAddon , IAttachApi { private _socket: WebSocket; private _bidirectional: boolean; private _disposables: IDisposable[] = []; diff --git a/addons/xterm-addon-attach/src/tsconfig.json b/addons/addon-attach/src/tsconfig.json similarity index 77% rename from addons/xterm-addon-attach/src/tsconfig.json rename to addons/addon-attach/src/tsconfig.json index 7e68574d..9838a3c5 100644 --- a/addons/xterm-addon-attach/src/tsconfig.json +++ b/addons/addon-attach/src/tsconfig.json @@ -13,7 +13,12 @@ "strict": true, "types": [ "../../../node_modules/@types/mocha" - ] + ], + "paths": { + "@xterm/addon-attach": [ + "../typings/addon-attach.d.ts" + ] + } }, "include": [ "./**/*", diff --git a/addons/xterm-addon-attach/test/AttachAddon.api.ts b/addons/addon-attach/test/AttachAddon.api.ts similarity index 100% rename from addons/xterm-addon-attach/test/AttachAddon.api.ts rename to addons/addon-attach/test/AttachAddon.api.ts diff --git a/addons/xterm-addon-attach/test/tsconfig.json b/addons/addon-attach/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-attach/test/tsconfig.json rename to addons/addon-attach/test/tsconfig.json diff --git a/addons/xterm-addon-attach/tsconfig.json b/addons/addon-attach/tsconfig.json similarity index 100% rename from addons/xterm-addon-attach/tsconfig.json rename to addons/addon-attach/tsconfig.json diff --git a/addons/xterm-addon-attach/typings/xterm-addon-attach.d.ts b/addons/addon-attach/typings/addon-attach.d.ts similarity index 82% rename from addons/xterm-addon-attach/typings/xterm-addon-attach.d.ts rename to addons/addon-attach/typings/addon-attach.d.ts index 2956b9d9..4e1b2fc3 100644 --- a/addons/xterm-addon-attach/typings/xterm-addon-attach.d.ts +++ b/addons/addon-attach/typings/addon-attach.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon } from 'xterm'; +import { Terminal, ITerminalAddon } from '@xterm/xterm'; -declare module 'xterm-addon-attach' { +declare module '@xterm/addon-attach' { export interface IAttachOptions { /** * Whether input should be written to the backend. Defaults to `true`. diff --git a/addons/xterm-addon-attach/webpack.config.js b/addons/addon-attach/webpack.config.js similarity index 92% rename from addons/xterm-addon-attach/webpack.config.js rename to addons/addon-attach/webpack.config.js index 65996f19..599bb142 100644 --- a/addons/xterm-addon-attach/webpack.config.js +++ b/addons/addon-attach/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'AttachAddon'; -const mainFile = 'xterm-addon-attach.js'; +const mainFile = 'addon-attach.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-canvas/.gitignore b/addons/addon-canvas/.gitignore similarity index 100% rename from addons/xterm-addon-canvas/.gitignore rename to addons/addon-canvas/.gitignore diff --git a/addons/xterm-addon-canvas/.npmignore b/addons/addon-canvas/.npmignore similarity index 100% rename from addons/xterm-addon-canvas/.npmignore rename to addons/addon-canvas/.npmignore diff --git a/addons/xterm-addon-canvas/LICENSE b/addons/addon-canvas/LICENSE similarity index 100% rename from addons/xterm-addon-canvas/LICENSE rename to addons/addon-canvas/LICENSE diff --git a/addons/addon-canvas/README.md b/addons/addon-canvas/README.md new file mode 100644 index 00000000..502ade25 --- /dev/null +++ b/addons/addon-canvas/README.md @@ -0,0 +1,28 @@ +## @xterm/addon-canvas + +An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables a canvas-based renderer using a 2d context to draw. This addon requires xterm.js v5+. + +The purpose of this addon is to be used as a fallback for the [webgl addon](https://www.npmjs.com/package/@xterm/addon-webgl) when better performance is desired over the default DOM renderer, but WebGL2 isn't supported or performant for some reason. + +### Install + +```bash +npm install --save @xterm/addon-canvas +``` + +### Usage + +```ts +import { Terminal } from '@xterm/xterm'; +import { CanvasAddon } from '@xterm/addon-canvas'; + +const terminal = new Terminal(); +terminal.open(element); +terminal.loadAddon(new CanvasAddon()); +``` + +See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/addon-canvas/typings/addon-canvas.d.ts) for more advanced usage. + +### See also + +- [@xterm/addon-webgl](https://www.npmjs.com/package/@xterm/addon-webgl) A renderer for xterm.js that uses WebGL diff --git a/addons/xterm-addon-canvas/package.json b/addons/addon-canvas/package.json similarity index 76% rename from addons/xterm-addon-canvas/package.json rename to addons/addon-canvas/package.json index eefdf375..9aabb001 100644 --- a/addons/xterm-addon-canvas/package.json +++ b/addons/addon-canvas/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-canvas", + "name": "@xterm/addon-canvas", "version": "0.5.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-canvas.js", - "types": "typings/xterm-addon-canvas.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-canvas", + "main": "lib/addon-canvas.js", + "types": "typings/addon-canvas.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-canvas", "license": "MIT", "keywords": [ "terminal", @@ -23,6 +23,6 @@ "start-server-only": "node ../../demo/start-server-only" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts b/addons/addon-canvas/src/BaseRenderLayer.ts similarity index 98% rename from addons/xterm-addon-canvas/src/BaseRenderLayer.ts rename to addons/addon-canvas/src/BaseRenderLayer.ts index 62fe71a7..e7e23400 100644 --- a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts +++ b/addons/addon-canvas/src/BaseRenderLayer.ts @@ -19,7 +19,7 @@ import { ICellData } from 'common/Types'; import { CellData } from 'common/buffer/CellData'; import { WHITESPACE_CELL_CODE } from 'common/buffer/Constants'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { IRenderLayer } from './Types'; export abstract class BaseRenderLayer extends Disposable implements IRenderLayer { @@ -58,7 +58,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer protected readonly _coreBrowserService: ICoreBrowserService ) { super(); - this._cellColorResolver = new CellColorResolver(this._terminal, this._selectionModel, this._decorationService, this._coreBrowserService, this._themeService); + this._cellColorResolver = new CellColorResolver(this._terminal, this._optionsService, this._selectionModel, this._decorationService, this._coreBrowserService, this._themeService); this._canvas = this._coreBrowserService.mainDocument.createElement('canvas'); this._canvas.classList.add(`xterm-${id}-layer`); this._canvas.style.zIndex = zIndex.toString(); @@ -91,7 +91,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer public handleGridChanged(startRow: number, endRow: number): void {} public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void { - this._selectionModel.update(this._terminal, start, end, columnSelectMode); + this._selectionModel.update((this._terminal as any)._core, start, end, columnSelectMode); } protected _setTransparency(alpha: boolean): void { @@ -365,7 +365,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer */ protected _drawChars(cell: ICellData, x: number, y: number): void { const chars = cell.getChars(); - this._cellColorResolver.resolve(cell, x, this._bufferService.buffer.ydisp + y); + this._cellColorResolver.resolve(cell, x, this._bufferService.buffer.ydisp + y, this._deviceCellWidth); if (!this._charAtlas) { return; diff --git a/addons/xterm-addon-canvas/src/CanvasAddon.ts b/addons/addon-canvas/src/CanvasAddon.ts similarity index 93% rename from addons/xterm-addon-canvas/src/CanvasAddon.ts rename to addons/addon-canvas/src/CanvasAddon.ts index 91438a4c..7f7f679b 100644 --- a/addons/xterm-addon-canvas/src/CanvasAddon.ts +++ b/addons/addon-canvas/src/CanvasAddon.ts @@ -3,16 +3,17 @@ * @license MIT */ +import type { ITerminalAddon, Terminal } from '@xterm/xterm'; +import type { CanvasAddon as ICanvasApi } from '@xterm/addon-canvas'; import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services'; import { ITerminal } from 'browser/Types'; import { EventEmitter, forwardEvent } from 'common/EventEmitter'; import { Disposable, toDisposable } from 'common/Lifecycle'; import { setTraceLogger } from 'common/services/LogService'; import { IBufferService, IDecorationService, ILogService } from 'common/services/Services'; -import { ITerminalAddon, Terminal } from 'xterm'; import { CanvasRenderer } from './CanvasRenderer'; -export class CanvasAddon extends Disposable implements ITerminalAddon { +export class CanvasAddon extends Disposable implements ITerminalAddon , ICanvasApi { private _terminal?: Terminal; private _renderer?: CanvasRenderer; @@ -65,4 +66,8 @@ export class CanvasAddon extends Disposable implements ITerminalAddon { this._renderer = undefined; })); } + + public clearTextureAtlas(): void { + this._renderer?.clearTextureAtlas(); + } } diff --git a/addons/xterm-addon-canvas/src/CanvasRenderer.ts b/addons/addon-canvas/src/CanvasRenderer.ts similarity index 99% rename from addons/xterm-addon-canvas/src/CanvasRenderer.ts rename to addons/addon-canvas/src/CanvasRenderer.ts index cd05f921..40b89546 100644 --- a/addons/xterm-addon-canvas/src/CanvasRenderer.ts +++ b/addons/addon-canvas/src/CanvasRenderer.ts @@ -12,7 +12,7 @@ import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeS import { EventEmitter, forwardEvent } from 'common/EventEmitter'; import { Disposable, toDisposable } from 'common/Lifecycle'; import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { CursorRenderLayer } from './CursorRenderLayer'; import { LinkRenderLayer } from './LinkRenderLayer'; import { SelectionRenderLayer } from './SelectionRenderLayer'; diff --git a/addons/xterm-addon-canvas/src/CursorRenderLayer.ts b/addons/addon-canvas/src/CursorRenderLayer.ts similarity index 99% rename from addons/xterm-addon-canvas/src/CursorRenderLayer.ts rename to addons/addon-canvas/src/CursorRenderLayer.ts index c5174f86..adc1db18 100644 --- a/addons/xterm-addon-canvas/src/CursorRenderLayer.ts +++ b/addons/addon-canvas/src/CursorRenderLayer.ts @@ -12,7 +12,7 @@ import { isFirefox } from 'common/Platform'; import { ICellData } from 'common/Types'; import { CellData } from 'common/buffer/CellData'; import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { BaseRenderLayer } from './BaseRenderLayer'; interface ICursorState { diff --git a/addons/xterm-addon-canvas/src/GridCache.test.ts b/addons/addon-canvas/src/GridCache.test.ts similarity index 100% rename from addons/xterm-addon-canvas/src/GridCache.test.ts rename to addons/addon-canvas/src/GridCache.test.ts diff --git a/addons/xterm-addon-canvas/src/GridCache.ts b/addons/addon-canvas/src/GridCache.ts similarity index 100% rename from addons/xterm-addon-canvas/src/GridCache.ts rename to addons/addon-canvas/src/GridCache.ts diff --git a/addons/xterm-addon-canvas/src/LinkRenderLayer.ts b/addons/addon-canvas/src/LinkRenderLayer.ts similarity index 98% rename from addons/xterm-addon-canvas/src/LinkRenderLayer.ts rename to addons/addon-canvas/src/LinkRenderLayer.ts index 882f7d8c..1cdf71c2 100644 --- a/addons/xterm-addon-canvas/src/LinkRenderLayer.ts +++ b/addons/addon-canvas/src/LinkRenderLayer.ts @@ -9,7 +9,7 @@ import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants'; import { IRenderDimensions } from 'browser/renderer/shared/Types'; import { ICoreBrowserService, IThemeService } from 'browser/services/Services'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { BaseRenderLayer } from './BaseRenderLayer'; export class LinkRenderLayer extends BaseRenderLayer { diff --git a/addons/xterm-addon-canvas/src/SelectionRenderLayer.ts b/addons/addon-canvas/src/SelectionRenderLayer.ts similarity index 99% rename from addons/xterm-addon-canvas/src/SelectionRenderLayer.ts rename to addons/addon-canvas/src/SelectionRenderLayer.ts index 10950868..01612a1d 100644 --- a/addons/xterm-addon-canvas/src/SelectionRenderLayer.ts +++ b/addons/addon-canvas/src/SelectionRenderLayer.ts @@ -7,7 +7,7 @@ import { IRenderDimensions } from 'browser/renderer/shared/Types'; import { BaseRenderLayer } from './BaseRenderLayer'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; import { ICoreBrowserService, IThemeService } from 'browser/services/Services'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; interface ISelectionState { start?: [number, number]; diff --git a/addons/xterm-addon-canvas/src/TextRenderLayer.ts b/addons/addon-canvas/src/TextRenderLayer.ts similarity index 99% rename from addons/xterm-addon-canvas/src/TextRenderLayer.ts rename to addons/addon-canvas/src/TextRenderLayer.ts index 46d052f3..43c33d64 100644 --- a/addons/xterm-addon-canvas/src/TextRenderLayer.ts +++ b/addons/addon-canvas/src/TextRenderLayer.ts @@ -11,7 +11,7 @@ import { AttributeData } from 'common/buffer/AttributeData'; import { CellData } from 'common/buffer/CellData'; import { Content, NULL_CELL_CODE } from 'common/buffer/Constants'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { BaseRenderLayer } from './BaseRenderLayer'; import { GridCache } from './GridCache'; diff --git a/addons/xterm-addon-canvas/src/Types.d.ts b/addons/addon-canvas/src/Types.d.ts similarity index 100% rename from addons/xterm-addon-canvas/src/Types.d.ts rename to addons/addon-canvas/src/Types.d.ts diff --git a/addons/xterm-addon-canvas/src/tsconfig.json b/addons/addon-canvas/src/tsconfig.json similarity index 89% rename from addons/xterm-addon-canvas/src/tsconfig.json rename to addons/addon-canvas/src/tsconfig.json index f6fb08a7..1ed8c2ac 100644 --- a/addons/xterm-addon-canvas/src/tsconfig.json +++ b/addons/addon-canvas/src/tsconfig.json @@ -17,6 +17,9 @@ ], "browser/*": [ "../../../src/browser/*" + ], + "@xterm/addon-canvas": [ + "../typings/addon-canvas.d.ts" ] }, "strict": true, diff --git a/addons/xterm-addon-canvas/test/CanvasRenderer.test.ts b/addons/addon-canvas/test/CanvasRenderer.test.ts similarity index 100% rename from addons/xterm-addon-canvas/test/CanvasRenderer.test.ts rename to addons/addon-canvas/test/CanvasRenderer.test.ts diff --git a/addons/xterm-addon-canvas/test/playwright.config.ts b/addons/addon-canvas/test/playwright.config.ts similarity index 100% rename from addons/xterm-addon-canvas/test/playwright.config.ts rename to addons/addon-canvas/test/playwright.config.ts diff --git a/addons/xterm-addon-canvas/test/tsconfig.json b/addons/addon-canvas/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-canvas/test/tsconfig.json rename to addons/addon-canvas/test/tsconfig.json diff --git a/addons/xterm-addon-canvas/tsconfig.json b/addons/addon-canvas/tsconfig.json similarity index 100% rename from addons/xterm-addon-canvas/tsconfig.json rename to addons/addon-canvas/tsconfig.json diff --git a/addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts b/addons/addon-canvas/typings/addon-canvas.d.ts similarity index 90% rename from addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts rename to addons/addon-canvas/typings/addon-canvas.d.ts index c983825c..a679f0a5 100644 --- a/addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts +++ b/addons/addon-canvas/typings/addon-canvas.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon, IEvent } from 'xterm'; +import { Terminal, ITerminalAddon, IEvent } from '@xterm/xterm'; -declare module 'xterm-addon-canvas' { +declare module '@xterm/addon-canvas' { /** * An xterm.js addon that provides search functionality. */ diff --git a/addons/xterm-addon-canvas/webpack.config.js b/addons/addon-canvas/webpack.config.js similarity index 94% rename from addons/xterm-addon-canvas/webpack.config.js rename to addons/addon-canvas/webpack.config.js index 9c98760a..9daa08f9 100644 --- a/addons/xterm-addon-canvas/webpack.config.js +++ b/addons/addon-canvas/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'CanvasAddon'; -const mainFile = 'xterm-addon-canvas.js'; +const mainFile = 'addon-canvas.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-fit/.gitignore b/addons/addon-fit/.gitignore similarity index 100% rename from addons/xterm-addon-fit/.gitignore rename to addons/addon-fit/.gitignore diff --git a/addons/xterm-addon-fit/.npmignore b/addons/addon-fit/.npmignore similarity index 100% rename from addons/xterm-addon-fit/.npmignore rename to addons/addon-fit/.npmignore diff --git a/addons/xterm-addon-fit/LICENSE b/addons/addon-fit/LICENSE similarity index 100% rename from addons/xterm-addon-fit/LICENSE rename to addons/addon-fit/LICENSE diff --git a/addons/xterm-addon-fit/README.md b/addons/addon-fit/README.md similarity index 66% rename from addons/xterm-addon-fit/README.md rename to addons/addon-fit/README.md index 321b2cf7..076e5127 100644 --- a/addons/xterm-addon-fit/README.md +++ b/addons/addon-fit/README.md @@ -1,18 +1,18 @@ -## xterm-addon-fit +## @xterm/addon-fit An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables fitting the terminal's dimensions to a containing element. This addon requires xterm.js v4+. ### Install ```bash -npm install --save xterm-addon-fit +npm install --save @xterm/addon-fit ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { FitAddon } from 'xterm-addon-fit'; +import { Terminal } from '@xterm/xterm'; +import { FitAddon } from '@xterm/addon-fit'; const terminal = new Terminal(); const fitAddon = new FitAddon(); @@ -21,4 +21,4 @@ terminal.open(containerElement); fitAddon.fit(); ``` -See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-fit/typings/xterm-addon-fit.d.ts) for more advanced usage. +See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/addon-fit/typings/addon-fit.d.ts) for more advanced usage. diff --git a/addons/xterm-addon-fit/package.json b/addons/addon-fit/package.json similarity index 75% rename from addons/xterm-addon-fit/package.json rename to addons/addon-fit/package.json index b2652aae..585f3621 100644 --- a/addons/xterm-addon-fit/package.json +++ b/addons/addon-fit/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-fit", + "name": "@xterm/addon-fit", "version": "0.8.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-fit.js", - "types": "typings/xterm-addon-fit.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-fit", + "main": "lib/addon-fit.js", + "types": "typings/addon-fit.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-fit", "license": "MIT", "keywords": [ "terminal", @@ -21,6 +21,6 @@ "prepublishOnly": "npm run package" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-fit/src/FitAddon.ts b/addons/addon-fit/src/FitAddon.ts similarity index 93% rename from addons/xterm-addon-fit/src/FitAddon.ts rename to addons/addon-fit/src/FitAddon.ts index f7245462..2087e614 100644 --- a/addons/xterm-addon-fit/src/FitAddon.ts +++ b/addons/addon-fit/src/FitAddon.ts @@ -3,7 +3,8 @@ * @license MIT */ -import { Terminal, ITerminalAddon } from 'xterm'; +import type { Terminal, ITerminalAddon } from '@xterm/xterm'; +import type { FitAddon as IFitApi } from '@xterm/addon-fit'; import { IRenderDimensions } from 'browser/renderer/shared/Types'; interface ITerminalDimensions { @@ -21,7 +22,7 @@ interface ITerminalDimensions { const MINIMUM_COLS = 2; const MINIMUM_ROWS = 1; -export class FitAddon implements ITerminalAddon { +export class FitAddon implements ITerminalAddon , IFitApi { private _terminal: Terminal | undefined; public activate(terminal: Terminal): void { diff --git a/addons/xterm-addon-fit/src/tsconfig.json b/addons/addon-fit/src/tsconfig.json similarity index 87% rename from addons/xterm-addon-fit/src/tsconfig.json rename to addons/addon-fit/src/tsconfig.json index 668f910b..068b4337 100644 --- a/addons/xterm-addon-fit/src/tsconfig.json +++ b/addons/addon-fit/src/tsconfig.json @@ -17,6 +17,9 @@ "paths": { "browser/*": [ "../../../src/browser/*" + ], + "@xterm/addon-fit": [ + "../typings/addon-fit.d.ts" ] } }, diff --git a/addons/xterm-addon-fit/test/FitAddon.api.ts b/addons/addon-fit/test/FitAddon.api.ts similarity index 100% rename from addons/xterm-addon-fit/test/FitAddon.api.ts rename to addons/addon-fit/test/FitAddon.api.ts diff --git a/addons/xterm-addon-fit/test/tsconfig.json b/addons/addon-fit/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-fit/test/tsconfig.json rename to addons/addon-fit/test/tsconfig.json diff --git a/addons/xterm-addon-fit/tsconfig.json b/addons/addon-fit/tsconfig.json similarity index 100% rename from addons/xterm-addon-fit/tsconfig.json rename to addons/addon-fit/tsconfig.json diff --git a/addons/xterm-addon-fit/typings/xterm-addon-fit.d.ts b/addons/addon-fit/typings/addon-fit.d.ts similarity index 92% rename from addons/xterm-addon-fit/typings/xterm-addon-fit.d.ts rename to addons/addon-fit/typings/addon-fit.d.ts index 2d1b8f1d..e3d20e29 100644 --- a/addons/xterm-addon-fit/typings/xterm-addon-fit.d.ts +++ b/addons/addon-fit/typings/addon-fit.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon } from 'xterm'; +import { Terminal, ITerminalAddon } from '@xterm/xterm'; -declare module 'xterm-addon-fit' { +declare module '@xterm/addon-fit' { /** * An xterm.js addon that enables resizing the terminal to the dimensions of * its containing element. diff --git a/addons/xterm-addon-fit/webpack.config.js b/addons/addon-fit/webpack.config.js similarity index 93% rename from addons/xterm-addon-fit/webpack.config.js rename to addons/addon-fit/webpack.config.js index 4b542150..e220668c 100644 --- a/addons/xterm-addon-fit/webpack.config.js +++ b/addons/addon-fit/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'FitAddon'; -const mainFile = 'xterm-addon-fit.js'; +const mainFile = 'addon-fit.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-image/.gitignore b/addons/addon-image/.gitignore similarity index 100% rename from addons/xterm-addon-image/.gitignore rename to addons/addon-image/.gitignore diff --git a/addons/xterm-addon-image/.npmignore b/addons/addon-image/.npmignore similarity index 100% rename from addons/xterm-addon-image/.npmignore rename to addons/addon-image/.npmignore diff --git a/addons/xterm-addon-image/LICENSE b/addons/addon-image/LICENSE similarity index 100% rename from addons/xterm-addon-image/LICENSE rename to addons/addon-image/LICENSE diff --git a/addons/xterm-addon-image/README.md b/addons/addon-image/README.md similarity index 98% rename from addons/xterm-addon-image/README.md rename to addons/addon-image/README.md index 686df9b4..9fd327e3 100644 --- a/addons/xterm-addon-image/README.md +++ b/addons/addon-image/README.md @@ -1,4 +1,4 @@ -## xterm-addon-image +## @xterm/addon-image Inline image output in xterm.js. Supports SIXEL and iTerm's inline image protocol (IIP). @@ -9,15 +9,15 @@ Inline image output in xterm.js. Supports SIXEL and iTerm's inline image protoco ### Install from npm ```bash -npm install --save xterm-addon-image +npm install --save @xterm/addon-image ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { ImageAddon, IImageAddonOptions } from 'xterm-addon-image'; +import { Terminal } from '@xterm/xterm'; +import { ImageAddon, IImageAddonOptions } from '@xterm/addon-image'; // customize as needed (showing addon defaults) const customSettings: IImageAddonOptions = { @@ -227,5 +227,5 @@ _How can I adjust the memory usage?_ - 0.1.2 bugfix: reset clear flag - 0.1.1 bugfixes: - clear sticky image tiles on render - - create xterm-addon-image folder from bootstrap.sh + - create folder from bootstrap.sh - fix peer dependency in package.json diff --git a/addons/xterm-addon-image/fixture/endless.sh b/addons/addon-image/fixture/endless.sh old mode 100755 new mode 100644 similarity index 100% rename from addons/xterm-addon-image/fixture/endless.sh rename to addons/addon-image/fixture/endless.sh diff --git a/addons/xterm-addon-image/fixture/example.png b/addons/addon-image/fixture/example.png similarity index 100% rename from addons/xterm-addon-image/fixture/example.png rename to addons/addon-image/fixture/example.png diff --git a/addons/xterm-addon-image/fixture/gcrglf.sh b/addons/addon-image/fixture/gcrglf.sh old mode 100755 new mode 100644 similarity index 100% rename from addons/xterm-addon-image/fixture/gcrglf.sh rename to addons/addon-image/fixture/gcrglf.sh diff --git a/addons/xterm-addon-image/fixture/growing_rect.js b/addons/addon-image/fixture/growing_rect.js similarity index 100% rename from addons/xterm-addon-image/fixture/growing_rect.js rename to addons/addon-image/fixture/growing_rect.js diff --git a/addons/xterm-addon-image/fixture/iip/palette.iip b/addons/addon-image/fixture/iip/palette.iip similarity index 100% rename from addons/xterm-addon-image/fixture/iip/palette.iip rename to addons/addon-image/fixture/iip/palette.iip diff --git a/addons/xterm-addon-image/fixture/iip/spinfox.iip b/addons/addon-image/fixture/iip/spinfox.iip similarity index 100% rename from addons/xterm-addon-image/fixture/iip/spinfox.iip rename to addons/addon-image/fixture/iip/spinfox.iip diff --git a/addons/xterm-addon-image/fixture/iip/w3c_gif.iip b/addons/addon-image/fixture/iip/w3c_gif.iip similarity index 100% rename from addons/xterm-addon-image/fixture/iip/w3c_gif.iip rename to addons/addon-image/fixture/iip/w3c_gif.iip diff --git a/addons/xterm-addon-image/fixture/iip/w3c_jpg.iip b/addons/addon-image/fixture/iip/w3c_jpg.iip similarity index 100% rename from addons/xterm-addon-image/fixture/iip/w3c_jpg.iip rename to addons/addon-image/fixture/iip/w3c_jpg.iip diff --git a/addons/xterm-addon-image/fixture/iip/w3c_png.iip b/addons/addon-image/fixture/iip/w3c_png.iip similarity index 100% rename from addons/xterm-addon-image/fixture/iip/w3c_png.iip rename to addons/addon-image/fixture/iip/w3c_png.iip diff --git a/addons/xterm-addon-image/fixture/inspect_palette.sh b/addons/addon-image/fixture/inspect_palette.sh old mode 100755 new mode 100644 similarity index 100% rename from addons/xterm-addon-image/fixture/inspect_palette.sh rename to addons/addon-image/fixture/inspect_palette.sh diff --git a/addons/xterm-addon-image/fixture/overdraw.sh b/addons/addon-image/fixture/overdraw.sh old mode 100755 new mode 100644 similarity index 100% rename from addons/xterm-addon-image/fixture/overdraw.sh rename to addons/addon-image/fixture/overdraw.sh diff --git a/addons/xterm-addon-image/fixture/palette.blob b/addons/addon-image/fixture/palette.blob similarity index 100% rename from addons/xterm-addon-image/fixture/palette.blob rename to addons/addon-image/fixture/palette.blob diff --git a/addons/xterm-addon-image/fixture/palette.png b/addons/addon-image/fixture/palette.png similarity index 100% rename from addons/xterm-addon-image/fixture/palette.png rename to addons/addon-image/fixture/palette.png diff --git a/addons/xterm-addon-image/fixture/palette.sixel b/addons/addon-image/fixture/palette.sixel similarity index 100% rename from addons/xterm-addon-image/fixture/palette.sixel rename to addons/addon-image/fixture/palette.sixel diff --git a/addons/xterm-addon-image/fixture/testimages/agfa-makernotes.jpg b/addons/addon-image/fixture/testimages/agfa-makernotes.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/agfa-makernotes.jpg rename to addons/addon-image/fixture/testimages/agfa-makernotes.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/iphone_hdr_YES.jpg b/addons/addon-image/fixture/testimages/iphone_hdr_YES.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/iphone_hdr_YES.jpg rename to addons/addon-image/fixture/testimages/iphone_hdr_YES.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/nikon-e950.jpg b/addons/addon-image/fixture/testimages/nikon-e950.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/nikon-e950.jpg rename to addons/addon-image/fixture/testimages/nikon-e950.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/sony-alpha-6000.jpg b/addons/addon-image/fixture/testimages/sony-alpha-6000.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/sony-alpha-6000.jpg rename to addons/addon-image/fixture/testimages/sony-alpha-6000.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/spinfox.png b/addons/addon-image/fixture/testimages/spinfox.png similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/spinfox.png rename to addons/addon-image/fixture/testimages/spinfox.png diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home.gif b/addons/addon-image/fixture/testimages/w3c_home.gif similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home.gif rename to addons/addon-image/fixture/testimages/w3c_home.gif diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home.jpg b/addons/addon-image/fixture/testimages/w3c_home.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home.jpg rename to addons/addon-image/fixture/testimages/w3c_home.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home.png b/addons/addon-image/fixture/testimages/w3c_home.png similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home.png rename to addons/addon-image/fixture/testimages/w3c_home.png diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_2.gif b/addons/addon-image/fixture/testimages/w3c_home_2.gif similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_2.gif rename to addons/addon-image/fixture/testimages/w3c_home_2.gif diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_2.jpg b/addons/addon-image/fixture/testimages/w3c_home_2.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_2.jpg rename to addons/addon-image/fixture/testimages/w3c_home_2.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_2.png b/addons/addon-image/fixture/testimages/w3c_home_2.png similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_2.png rename to addons/addon-image/fixture/testimages/w3c_home_2.png diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_256.gif b/addons/addon-image/fixture/testimages/w3c_home_256.gif similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_256.gif rename to addons/addon-image/fixture/testimages/w3c_home_256.gif diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_256.jpg b/addons/addon-image/fixture/testimages/w3c_home_256.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_256.jpg rename to addons/addon-image/fixture/testimages/w3c_home_256.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_256.png b/addons/addon-image/fixture/testimages/w3c_home_256.png similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_256.png rename to addons/addon-image/fixture/testimages/w3c_home_256.png diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_animation.gif b/addons/addon-image/fixture/testimages/w3c_home_animation.gif similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_animation.gif rename to addons/addon-image/fixture/testimages/w3c_home_animation.gif diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_gray.gif b/addons/addon-image/fixture/testimages/w3c_home_gray.gif similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_gray.gif rename to addons/addon-image/fixture/testimages/w3c_home_gray.gif diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_gray.jpg b/addons/addon-image/fixture/testimages/w3c_home_gray.jpg similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_gray.jpg rename to addons/addon-image/fixture/testimages/w3c_home_gray.jpg diff --git a/addons/xterm-addon-image/fixture/testimages/w3c_home_gray.png b/addons/addon-image/fixture/testimages/w3c_home_gray.png similarity index 100% rename from addons/xterm-addon-image/fixture/testimages/w3c_home_gray.png rename to addons/addon-image/fixture/testimages/w3c_home_gray.png diff --git a/addons/xterm-addon-image/fixture/textcursor.sh b/addons/addon-image/fixture/textcursor.sh old mode 100755 new mode 100644 similarity index 100% rename from addons/xterm-addon-image/fixture/textcursor.sh rename to addons/addon-image/fixture/textcursor.sh diff --git a/addons/xterm-addon-image/package.json b/addons/addon-image/package.json similarity index 77% rename from addons/xterm-addon-image/package.json rename to addons/addon-image/package.json index b07b5b6b..8572e330 100644 --- a/addons/xterm-addon-image/package.json +++ b/addons/addon-image/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-image", + "name": "@xterm/addon-image", "version": "0.6.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-image.js", - "types": "typings/xterm-addon-image.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-image", + "main": "lib/addon-image.js", + "types": "typings/addon-image.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-image", "license": "MIT", "keywords": [ "terminal", @@ -22,7 +22,7 @@ "prepublishOnly": "npm run package" }, "peerDependencies": { - "xterm": "^5.2.0" + "@xterm/xterm": "^5.2.0" }, "devDependencies": { "sixel": "^0.16.0", diff --git a/addons/xterm-addon-image/src/IIPHandler.ts b/addons/addon-image/src/IIPHandler.ts similarity index 100% rename from addons/xterm-addon-image/src/IIPHandler.ts rename to addons/addon-image/src/IIPHandler.ts diff --git a/addons/xterm-addon-image/src/IIPHeaderParser.test.ts b/addons/addon-image/src/IIPHeaderParser.test.ts similarity index 100% rename from addons/xterm-addon-image/src/IIPHeaderParser.test.ts rename to addons/addon-image/src/IIPHeaderParser.test.ts diff --git a/addons/xterm-addon-image/src/IIPHeaderParser.ts b/addons/addon-image/src/IIPHeaderParser.ts similarity index 100% rename from addons/xterm-addon-image/src/IIPHeaderParser.ts rename to addons/addon-image/src/IIPHeaderParser.ts diff --git a/addons/xterm-addon-image/src/IIPMetrics.test.ts b/addons/addon-image/src/IIPMetrics.test.ts similarity index 94% rename from addons/xterm-addon-image/src/IIPMetrics.test.ts rename to addons/addon-image/src/IIPMetrics.test.ts index 688d8d39..8ad5f05c 100644 --- a/addons/xterm-addon-image/src/IIPMetrics.test.ts +++ b/addons/addon-image/src/IIPMetrics.test.ts @@ -36,7 +36,7 @@ const TEST_IMAGES: [string, IMetrics][] = [ describe('IIPMetrics', () => { it('bunch of testimages', () => { for (let i = 0; i < TEST_IMAGES.length; ++i) { - const imageData = fs.readFileSync('./addons/xterm-addon-image/fixture/testimages/' + TEST_IMAGES[i][0]); + const imageData = fs.readFileSync('./addons/addon-image/fixture/testimages/' + TEST_IMAGES[i][0]); assert.deepStrictEqual(imageType(imageData), TEST_IMAGES[i][1]); } }); diff --git a/addons/xterm-addon-image/src/IIPMetrics.ts b/addons/addon-image/src/IIPMetrics.ts similarity index 100% rename from addons/xterm-addon-image/src/IIPMetrics.ts rename to addons/addon-image/src/IIPMetrics.ts diff --git a/addons/xterm-addon-image/src/ImageAddon.ts b/addons/addon-image/src/ImageAddon.ts similarity index 98% rename from addons/xterm-addon-image/src/ImageAddon.ts rename to addons/addon-image/src/ImageAddon.ts index bb633e6b..167e93a7 100644 --- a/addons/xterm-addon-image/src/ImageAddon.ts +++ b/addons/addon-image/src/ImageAddon.ts @@ -3,14 +3,14 @@ * @license MIT */ +import type { ITerminalAddon, IDisposable } from '@xterm/xterm'; +import type { ImageAddon as IImageApi } from '@xterm/addon-image'; import { IIPHandler } from './IIPHandler'; -import { ITerminalAddon, IDisposable } from 'xterm'; import { ImageRenderer } from './ImageRenderer'; import { ImageStorage, CELL_SIZE_DEFAULT } from './ImageStorage'; import { SixelHandler } from './SixelHandler'; import { ITerminalExt, IImageAddonOptions, IResetHandler } from './Types'; - // default values of addon ctor options const DEFAULT_OPTIONS: IImageAddonOptions = { enableSizeReports: true, @@ -48,7 +48,7 @@ const enum GaStatus { } -export class ImageAddon implements ITerminalAddon { +export class ImageAddon implements ITerminalAddon , IImageApi { private _opts: IImageAddonOptions; private _defaultOpts: IImageAddonOptions; private _storage: ImageStorage | undefined; diff --git a/addons/xterm-addon-image/src/ImageRenderer.ts b/addons/addon-image/src/ImageRenderer.ts similarity index 99% rename from addons/xterm-addon-image/src/ImageRenderer.ts rename to addons/addon-image/src/ImageRenderer.ts index 9b528efe..214a2e6b 100644 --- a/addons/xterm-addon-image/src/ImageRenderer.ts +++ b/addons/addon-image/src/ImageRenderer.ts @@ -4,7 +4,7 @@ */ import { toRGBA8888 } from 'sixel/lib/Colors'; -import { IDisposable } from 'xterm'; +import { IDisposable } from '@xterm/xterm'; import { ICellSize, ITerminalExt, IImageSpec, IRenderDimensions, IRenderService } from './Types'; import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle'; diff --git a/addons/xterm-addon-image/src/ImageStorage.ts b/addons/addon-image/src/ImageStorage.ts similarity index 97% rename from addons/xterm-addon-image/src/ImageStorage.ts rename to addons/addon-image/src/ImageStorage.ts index 97eef852..f9b6eef6 100644 --- a/addons/xterm-addon-image/src/ImageStorage.ts +++ b/addons/addon-image/src/ImageStorage.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IDisposable } from 'xterm'; +import { IDisposable } from '@xterm/xterm'; import { ImageRenderer } from './ImageRenderer'; import { ITerminalExt, IExtendedAttrsImage, IImageAddonOptions, IImageSpec, IBufferLineExt, BgFlags, Cell, Content, ICellSize, ExtFlags, Attributes, UnderlineStyle } from './Types'; @@ -53,6 +53,18 @@ class ExtendedAttrsImage implements IExtendedAttrsImage { this._ext |= value & (Attributes.CM_MASK | Attributes.RGB_MASK); } + public get underlineVariantOffset(): number { + const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29; + if (val < 0) { + return val ^ 0xFFFFFFF8; + } + return val; + } + public set underlineVariantOffset(value: number) { + this._ext &= ~ExtFlags.VARIANT_OFFSET; + this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET; + } + private _urlId: number = 0; public get urlId(): number { return this._urlId; diff --git a/addons/xterm-addon-image/src/SixelHandler.ts b/addons/addon-image/src/SixelHandler.ts similarity index 100% rename from addons/xterm-addon-image/src/SixelHandler.ts rename to addons/addon-image/src/SixelHandler.ts diff --git a/addons/xterm-addon-image/src/Types.d.ts b/addons/addon-image/src/Types.d.ts similarity index 98% rename from addons/xterm-addon-image/src/Types.d.ts rename to addons/addon-image/src/Types.d.ts index 62f4481a..60de0f3d 100644 --- a/addons/xterm-addon-image/src/Types.d.ts +++ b/addons/addon-image/src/Types.d.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IDisposable, IMarker, Terminal } from 'xterm'; +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'; diff --git a/addons/xterm-addon-image/src/tsconfig.json b/addons/addon-image/src/tsconfig.json similarity index 83% rename from addons/xterm-addon-image/src/tsconfig.json rename to addons/addon-image/src/tsconfig.json index da519e17..a18b47c9 100644 --- a/addons/xterm-addon-image/src/tsconfig.json +++ b/addons/addon-image/src/tsconfig.json @@ -14,7 +14,8 @@ "baseUrl": ".", "paths": { "browser/*": [ "../../../src/browser/*" ], - "common/*": [ "../../../src/common/*" ] + "common/*": [ "../../../src/common/*" ], + "@xterm/addon-image": [ "../typings/addon-image.d.ts" ] } }, "include": [ diff --git a/addons/xterm-addon-image/test/ImageAddon.api.ts b/addons/addon-image/test/ImageAddon.api.ts similarity index 95% rename from addons/xterm-addon-image/test/ImageAddon.api.ts rename to addons/addon-image/test/ImageAddon.api.ts index 43334bbb..776e96bf 100644 --- a/addons/xterm-addon-image/test/ImageAddon.api.ts +++ b/addons/addon-image/test/ImageAddon.api.ts @@ -39,7 +39,7 @@ interface IDimensions { // image: 640 x 80, 512 color const TESTDATA: ITestData = (() => { - const data8 = readFileSync('./addons/xterm-addon-image/fixture/palette.blob'); + const data8 = readFileSync('./addons/addon-image/fixture/palette.blob'); const data32 = new Uint32Array(data8.buffer); const palette = new Set(); for (let i = 0; i < data32.length; ++i) palette.add(data32[i]); @@ -58,11 +58,11 @@ const SIXEL_SEQ_0 = introducer(0) + TESTDATA.sixel + FINALIZER; // NOTE: the data is loaded as string for easier transport through playwright const TESTDATA_IIP: [string, [number, number]][] = [ - [readFileSync('./addons/xterm-addon-image/fixture/iip/palette.iip', { encoding: 'utf-8' }), [640, 80]], - [readFileSync('./addons/xterm-addon-image/fixture/iip/spinfox.iip', { encoding: 'utf-8' }), [148, 148]], - [readFileSync('./addons/xterm-addon-image/fixture/iip/w3c_gif.iip', { encoding: 'utf-8' }), [72, 48]], - [readFileSync('./addons/xterm-addon-image/fixture/iip/w3c_jpg.iip', { encoding: 'utf-8' }), [72, 48]], - [readFileSync('./addons/xterm-addon-image/fixture/iip/w3c_png.iip', { encoding: 'utf-8' }), [72, 48]] + [readFileSync('./addons/addon-image/fixture/iip/palette.iip', { encoding: 'utf-8' }), [640, 80]], + [readFileSync('./addons/addon-image/fixture/iip/spinfox.iip', { encoding: 'utf-8' }), [148, 148]], + [readFileSync('./addons/addon-image/fixture/iip/w3c_gif.iip', { encoding: 'utf-8' }), [72, 48]], + [readFileSync('./addons/addon-image/fixture/iip/w3c_jpg.iip', { encoding: 'utf-8' }), [72, 48]], + [readFileSync('./addons/addon-image/fixture/iip/w3c_png.iip', { encoding: 'utf-8' }), [72, 48]] ]; describe('ImageAddon', () => { diff --git a/addons/xterm-addon-image/test/tsconfig.json b/addons/addon-image/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-image/test/tsconfig.json rename to addons/addon-image/test/tsconfig.json diff --git a/addons/xterm-addon-image/tsconfig.json b/addons/addon-image/tsconfig.json similarity index 100% rename from addons/xterm-addon-image/tsconfig.json rename to addons/addon-image/tsconfig.json diff --git a/addons/xterm-addon-image/typings/xterm-addon-image.d.ts b/addons/addon-image/typings/addon-image.d.ts similarity index 97% rename from addons/xterm-addon-image/typings/xterm-addon-image.d.ts rename to addons/addon-image/typings/addon-image.d.ts index 94dc6f65..48ba488c 100644 --- a/addons/xterm-addon-image/typings/xterm-addon-image.d.ts +++ b/addons/addon-image/typings/addon-image.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon } from 'xterm'; +import { Terminal, ITerminalAddon } from '@xterm/xterm'; -declare module 'xterm-addon-image' { +declare module '@xterm/addon-image' { export interface IImageAddonOptions { /** * Enable size reports in windowOptions: @@ -37,7 +37,7 @@ declare module 'xterm-addon-image' { * * Note: `storageLimit` bytes are calculated from images by multiplying the pixels with 4 * (4 channels with one byte, images are stored as RGBA8888). - * + * * Default is 2^16 (4096 x 4096 pixels). */ pixelLimit?: number; diff --git a/addons/xterm-addon-image/webpack.config.js b/addons/addon-image/webpack.config.js similarity index 71% rename from addons/xterm-addon-image/webpack.config.js rename to addons/addon-image/webpack.config.js index fff66bec..b4283b66 100644 --- a/addons/xterm-addon-image/webpack.config.js +++ b/addons/addon-image/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'ImageAddon'; -const mainFile = 'xterm-addon-image.js'; +const mainFile = 'addon-image.js'; const addon = { entry: `./out/${addonName}.js`, @@ -21,6 +21,14 @@ const addon = { } ] }, + resolve: { + modules: ['./node_modules'], + extensions: [ '.js' ], + alias: { + common: path.resolve('../../out/common'), + browser: path.resolve('../../out/browser') + } + }, output: { filename: mainFile, path: path.resolve('./lib'), diff --git a/addons/xterm-addon-ligatures/.gitignore b/addons/addon-ligatures/.gitignore similarity index 100% rename from addons/xterm-addon-ligatures/.gitignore rename to addons/addon-ligatures/.gitignore diff --git a/addons/xterm-addon-ligatures/.npmignore b/addons/addon-ligatures/.npmignore similarity index 100% rename from addons/xterm-addon-ligatures/.npmignore rename to addons/addon-ligatures/.npmignore diff --git a/addons/xterm-addon-ligatures/LICENSE b/addons/addon-ligatures/LICENSE similarity index 100% rename from addons/xterm-addon-ligatures/LICENSE rename to addons/addon-ligatures/LICENSE diff --git a/addons/xterm-addon-ligatures/README.md b/addons/addon-ligatures/README.md similarity index 93% rename from addons/xterm-addon-ligatures/README.md rename to addons/addon-ligatures/README.md index fad2a7ef..3b5521e0 100644 --- a/addons/xterm-addon-ligatures/README.md +++ b/addons/addon-ligatures/README.md @@ -1,4 +1,4 @@ -## xterm-addon-ligatures +## @xterm/addon-ligatures Add support for programming ligatures to [xterm.js] when running in environments with access to [Node.js] APIs (such as [Electron]). @@ -10,14 +10,14 @@ Add support for programming ligatures to [xterm.js] when running in environments ### Install ```bash -npm install --save xterm-addon-ligatures +npm install --save @xterm/addon-ligatures ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { LigaturesAddon } from 'xterm-addon-ligatures'; +import { Terminal } from '@xterm/xterm'; +import { LigaturesAddon } from '@xterm/addon-ligatures'; const terminal = new Terminal(); const ligaturesAddon = new LigaturesAddon(); diff --git a/addons/xterm-addon-ligatures/bin/download-fonts.js b/addons/addon-ligatures/bin/download-fonts.js similarity index 100% rename from addons/xterm-addon-ligatures/bin/download-fonts.js rename to addons/addon-ligatures/bin/download-fonts.js diff --git a/addons/xterm-addon-ligatures/package.json b/addons/addon-ligatures/package.json similarity index 84% rename from addons/xterm-addon-ligatures/package.json rename to addons/addon-ligatures/package.json index 57c0cd56..30251888 100644 --- a/addons/xterm-addon-ligatures/package.json +++ b/addons/addon-ligatures/package.json @@ -1,14 +1,14 @@ { - "name": "xterm-addon-ligatures", + "name": "@xterm/addon-ligatures", "version": "0.7.0", "description": "Add support for programming ligatures to xterm.js", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-ligatures.js", - "types": "typings/xterm-addon-ligatures.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-ligatures", + "main": "lib/addon-ligatures.js", + "types": "typings/addon-ligatures.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-ligatures", "engines": { "node": ">8.0.0" }, @@ -42,6 +42,6 @@ "yauzl": "^2.10.0" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-ligatures/src/LigaturesAddon.ts b/addons/addon-ligatures/src/LigaturesAddon.ts similarity index 87% rename from addons/xterm-addon-ligatures/src/LigaturesAddon.ts rename to addons/addon-ligatures/src/LigaturesAddon.ts index c4586b38..cb589303 100644 --- a/addons/xterm-addon-ligatures/src/LigaturesAddon.ts +++ b/addons/addon-ligatures/src/LigaturesAddon.ts @@ -3,7 +3,8 @@ * @license MIT */ -import { Terminal } from 'xterm'; +import type { Terminal } from '@xterm/xterm'; +import type { LigaturesAddon as ILigaturesApi } from '@xterm/addon-ligatures'; import { enableLigatures } from '.'; import { ILigatureOptions } from './Types'; @@ -12,7 +13,7 @@ export interface ITerminalAddon { dispose(): void; } -export class LigaturesAddon implements ITerminalAddon { +export class LigaturesAddon implements ITerminalAddon , ILigaturesApi { private readonly _fallbackLigatures: string[]; private _terminal: Terminal | undefined; diff --git a/addons/xterm-addon-ligatures/src/Types.d.ts b/addons/addon-ligatures/src/Types.d.ts similarity index 100% rename from addons/xterm-addon-ligatures/src/Types.d.ts rename to addons/addon-ligatures/src/Types.d.ts diff --git a/addons/xterm-addon-ligatures/src/font.ts b/addons/addon-ligatures/src/font.ts similarity index 100% rename from addons/xterm-addon-ligatures/src/font.ts rename to addons/addon-ligatures/src/font.ts diff --git a/addons/xterm-addon-ligatures/src/index.test.ts b/addons/addon-ligatures/src/index.test.ts similarity index 99% rename from addons/xterm-addon-ligatures/src/index.test.ts rename to addons/addon-ligatures/src/index.test.ts index c7bf09ce..c6aead98 100644 --- a/addons/xterm-addon-ligatures/src/index.test.ts +++ b/addons/addon-ligatures/src/index.test.ts @@ -11,7 +11,7 @@ import * as fontLigatures from 'font-ligatures'; import * as ligatureSupport from '.'; -describe('xterm-addon-ligatures', () => { +describe('LigaturesAddon', () => { let onRefresh: sinon.SinonStub; let term: MockTerminal; diff --git a/addons/xterm-addon-ligatures/src/index.ts b/addons/addon-ligatures/src/index.ts similarity index 98% rename from addons/xterm-addon-ligatures/src/index.ts rename to addons/addon-ligatures/src/index.ts index 82675626..bd8ff215 100644 --- a/addons/xterm-addon-ligatures/src/index.ts +++ b/addons/addon-ligatures/src/index.ts @@ -3,7 +3,7 @@ * @license MIT */ -import type { Terminal } from 'xterm'; +import type { Terminal } from '@xterm/xterm'; import { Font } from 'font-ligatures'; import load from './font'; diff --git a/addons/xterm-addon-ligatures/src/parse.test.ts b/addons/addon-ligatures/src/parse.test.ts similarity index 100% rename from addons/xterm-addon-ligatures/src/parse.test.ts rename to addons/addon-ligatures/src/parse.test.ts diff --git a/addons/xterm-addon-ligatures/src/parse.ts b/addons/addon-ligatures/src/parse.ts similarity index 100% rename from addons/xterm-addon-ligatures/src/parse.ts rename to addons/addon-ligatures/src/parse.ts diff --git a/addons/xterm-addon-ligatures/src/tsconfig.json b/addons/addon-ligatures/src/tsconfig.json similarity index 75% rename from addons/xterm-addon-ligatures/src/tsconfig.json rename to addons/addon-ligatures/src/tsconfig.json index 28969f97..cc9a9bef 100644 --- a/addons/xterm-addon-ligatures/src/tsconfig.json +++ b/addons/addon-ligatures/src/tsconfig.json @@ -10,7 +10,12 @@ "preserveWatchOutput": true, "types": [ "../../../node_modules/@types/mocha" - ] + ], + "paths": { + "@xterm/addon-ligatures" : [ + "../typings/addon-ligatures.d.ts" + ] + } }, "include": [ "./**/*", diff --git a/addons/xterm-addon-ligatures/tsconfig.json b/addons/addon-ligatures/tsconfig.json similarity index 100% rename from addons/xterm-addon-ligatures/tsconfig.json rename to addons/addon-ligatures/tsconfig.json diff --git a/addons/xterm-addon-ligatures/typings/xterm-addon-ligatures.d.ts b/addons/addon-ligatures/typings/addon-ligatures.d.ts similarity index 89% rename from addons/xterm-addon-ligatures/typings/xterm-addon-ligatures.d.ts rename to addons/addon-ligatures/typings/addon-ligatures.d.ts index 4d8fbdf0..2fd4f3e7 100644 --- a/addons/xterm-addon-ligatures/typings/xterm-addon-ligatures.d.ts +++ b/addons/addon-ligatures/typings/addon-ligatures.d.ts @@ -2,15 +2,15 @@ * Copyright (c) 2018 The xterm.js authors. All rights reserved. * @license MIT * - * This contains the type declarations for the xterm-addon-ligatures library. + * This contains the type declarations for the @xterm/addon-ligatures library. * Note that some interfaces may differ between this file and the actual * implementation in src/, that's because this file declares the *public* API * which is intended to be stable and consumed by external programs. */ -import { Terminal, ITerminalAddon } from 'xterm'; +import { Terminal, ITerminalAddon } from '@xterm/xterm'; -declare module 'xterm-addon-ligatures' { +declare module '@xterm/addon-ligatures' { /** * An xterm.js addon that enables web links. */ diff --git a/addons/xterm-addon-ligatures/webpack.config.js b/addons/addon-ligatures/webpack.config.js similarity index 95% rename from addons/xterm-addon-ligatures/webpack.config.js rename to addons/addon-ligatures/webpack.config.js index 5aeebe2e..6ec7f42d 100644 --- a/addons/xterm-addon-ligatures/webpack.config.js +++ b/addons/addon-ligatures/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'LigaturesAddon'; -const mainFile = 'xterm-addon-ligatures.js'; +const mainFile = 'addon-ligatures.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-ligatures/yarn.lock b/addons/addon-ligatures/yarn.lock similarity index 100% rename from addons/xterm-addon-ligatures/yarn.lock rename to addons/addon-ligatures/yarn.lock diff --git a/addons/xterm-addon-search/.gitignore b/addons/addon-search/.gitignore similarity index 100% rename from addons/xterm-addon-search/.gitignore rename to addons/addon-search/.gitignore diff --git a/addons/xterm-addon-search/.npmignore b/addons/addon-search/.npmignore similarity index 100% rename from addons/xterm-addon-search/.npmignore rename to addons/addon-search/.npmignore diff --git a/addons/xterm-addon-search/LICENSE b/addons/addon-search/LICENSE similarity index 100% rename from addons/xterm-addon-search/LICENSE rename to addons/addon-search/LICENSE diff --git a/addons/xterm-addon-search/README.md b/addons/addon-search/README.md similarity index 62% rename from addons/xterm-addon-search/README.md rename to addons/addon-search/README.md index 91bcc34b..fab0b03f 100644 --- a/addons/xterm-addon-search/README.md +++ b/addons/addon-search/README.md @@ -1,18 +1,18 @@ -## xterm-addon-search +## @xterm/addon-search An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables searching the buffer. This addon requires xterm.js v4+. ### Install ```bash -npm install --save xterm-addon-search +npm install --save @xterm/addon-search ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { SearchAddon } from 'xterm-addon-search'; +import { Terminal } from '@xterm/xterm'; +import { SearchAddon } from '@xterm/addon-search'; const terminal = new Terminal(); const searchAddon = new SearchAddon(); @@ -20,4 +20,4 @@ terminal.loadAddon(searchAddon); searchAddon.findNext('foo'); ``` -See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-search/typings/xterm-addon-search.d.ts) for more advanced usage. +See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/addon-search/typings/addon-search.d.ts) for more advanced usage. diff --git a/addons/xterm-addon-search/fixtures/issue-2444 b/addons/addon-search/fixtures/issue-2444 similarity index 100% rename from addons/xterm-addon-search/fixtures/issue-2444 rename to addons/addon-search/fixtures/issue-2444 diff --git a/addons/xterm-addon-search/package.json b/addons/addon-search/package.json similarity index 61% rename from addons/xterm-addon-search/package.json rename to addons/addon-search/package.json index f846874d..369d11c3 100644 --- a/addons/xterm-addon-search/package.json +++ b/addons/addon-search/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-search", + "name": "@xterm/addon-search", "version": "0.13.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-search.js", - "types": "typings/xterm-addon-search.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-search", + "main": "lib/addon-search.js", + "types": "typings/addon-search.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-search", "license": "MIT", "keywords": [ "terminal", @@ -15,12 +15,11 @@ "xterm.js" ], "scripts": { - "build": "../../node_modules/.bin/tsc -p .", - "prepackage": "npm run build", + "prepackage": "../../node_modules/.bin/tsc -p .", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-search/src/SearchAddon.ts b/addons/addon-search/src/SearchAddon.ts similarity index 96% rename from addons/xterm-addon-search/src/SearchAddon.ts rename to addons/addon-search/src/SearchAddon.ts index 959214c9..3fae7373 100644 --- a/addons/xterm-addon-search/src/SearchAddon.ts +++ b/addons/addon-search/src/SearchAddon.ts @@ -3,7 +3,8 @@ * @license MIT */ -import { Terminal, IDisposable, ITerminalAddon, IDecoration } from 'xterm'; +import type { Terminal, IDisposable, ITerminalAddon, IDecoration } from '@xterm/xterm'; +import type { SearchAddon as ISearchApi } from '@xterm/addon-search'; import { EventEmitter } from 'common/EventEmitter'; import { Disposable, toDisposable, disposeArray, MutableDisposable } from 'common/Lifecycle'; @@ -61,7 +62,7 @@ const NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\;:"\',./<>?'; const LINES_CACHE_TIME_TO_LIVE = 15 * 1000; // 15 secs const DEFAULT_HIGHLIGHT_LIMIT = 1000; -export class SearchAddon extends Disposable implements ITerminalAddon { +export class SearchAddon extends Disposable implements ITerminalAddon , ISearchApi { private _terminal: Terminal | undefined; private _cachedSearchTerm: string | undefined; private _highlightedLines: Set = new Set(); @@ -134,9 +135,10 @@ export class SearchAddon extends Disposable implements ITerminalAddon { if (!this._terminal) { throw new Error('Cannot use addon until it has been loaded'); } + const didOptionsChanged = this._lastSearchOptions ? this._didOptionsChange(this._lastSearchOptions, searchOptions) : true; this._lastSearchOptions = searchOptions; if (searchOptions?.decorations) { - if (this._cachedSearchTerm === undefined || term !== this._cachedSearchTerm) { + if (this._cachedSearchTerm === undefined || term !== this._cachedSearchTerm || didOptionsChanged) { this._highlightAllMatches(term, searchOptions); } } @@ -302,9 +304,10 @@ export class SearchAddon extends Disposable implements ITerminalAddon { if (!this._terminal) { throw new Error('Cannot use addon until it has been loaded'); } + const didOptionsChanged = this._lastSearchOptions ? this._didOptionsChange(this._lastSearchOptions, searchOptions) : true; this._lastSearchOptions = searchOptions; if (searchOptions?.decorations) { - if (this._cachedSearchTerm === undefined || term !== this._cachedSearchTerm) { + if (this._cachedSearchTerm === undefined || term !== this._cachedSearchTerm || didOptionsChanged) { this._highlightAllMatches(term, searchOptions); } } @@ -316,6 +319,22 @@ export class SearchAddon extends Disposable implements ITerminalAddon { return found; } + private _didOptionsChange(lastSearchOptions: ISearchOptions, searchOptions?: ISearchOptions): boolean { + if (!searchOptions) { + return false; + } + if (lastSearchOptions.caseSensitive !== searchOptions.caseSensitive) { + return true; + } + if (lastSearchOptions.regex !== searchOptions.regex) { + return true; + } + if (lastSearchOptions.wholeWord !== searchOptions.wholeWord) { + return true; + } + return false; + } + private _fireResults(searchOptions?: ISearchOptions): void { if (searchOptions?.decorations) { let resultIndex = -1; diff --git a/addons/xterm-addon-search/src/tsconfig.json b/addons/addon-search/src/tsconfig.json similarity index 86% rename from addons/xterm-addon-search/src/tsconfig.json rename to addons/addon-search/src/tsconfig.json index 1f08b12d..bd3e48ad 100644 --- a/addons/xterm-addon-search/src/tsconfig.json +++ b/addons/addon-search/src/tsconfig.json @@ -17,6 +17,9 @@ "paths": { "common/*": [ "../../../src/common/*" + ], + "@xterm/addon-search" : [ + "../typings/addon-search.d.ts" ] } }, diff --git a/addons/xterm-addon-search/test/SearchAddon.api.ts b/addons/addon-search/test/SearchAddon.api.ts similarity index 100% rename from addons/xterm-addon-search/test/SearchAddon.api.ts rename to addons/addon-search/test/SearchAddon.api.ts diff --git a/addons/xterm-addon-search/test/tsconfig.json b/addons/addon-search/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-search/test/tsconfig.json rename to addons/addon-search/test/tsconfig.json diff --git a/addons/xterm-addon-search/tsconfig.json b/addons/addon-search/tsconfig.json similarity index 100% rename from addons/xterm-addon-search/tsconfig.json rename to addons/addon-search/tsconfig.json diff --git a/addons/xterm-addon-search/typings/xterm-addon-search.d.ts b/addons/addon-search/typings/addon-search.d.ts similarity index 97% rename from addons/xterm-addon-search/typings/xterm-addon-search.d.ts rename to addons/addon-search/typings/addon-search.d.ts index 3a3b7c89..282004a2 100644 --- a/addons/xterm-addon-search/typings/xterm-addon-search.d.ts +++ b/addons/addon-search/typings/addon-search.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon, IEvent } from 'xterm'; +import { Terminal, ITerminalAddon, IEvent } from '@xterm/xterm'; -declare module 'xterm-addon-search' { +declare module '@xterm/addon-search' { /** * Options for a search. */ diff --git a/addons/xterm-addon-search/webpack.config.js b/addons/addon-search/webpack.config.js similarity index 94% rename from addons/xterm-addon-search/webpack.config.js rename to addons/addon-search/webpack.config.js index 30526812..a770f93f 100644 --- a/addons/xterm-addon-search/webpack.config.js +++ b/addons/addon-search/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'SearchAddon'; -const mainFile = 'xterm-addon-search.js'; +const mainFile = 'addon-search.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-serialize/.gitignore b/addons/addon-serialize/.gitignore similarity index 100% rename from addons/xterm-addon-serialize/.gitignore rename to addons/addon-serialize/.gitignore diff --git a/addons/xterm-addon-serialize/.npmignore b/addons/addon-serialize/.npmignore similarity index 100% rename from addons/xterm-addon-serialize/.npmignore rename to addons/addon-serialize/.npmignore diff --git a/addons/xterm-addon-serialize/README.md b/addons/addon-serialize/README.md similarity index 71% rename from addons/xterm-addon-serialize/README.md rename to addons/addon-serialize/README.md index 12e0ac87..862ebac3 100644 --- a/addons/xterm-addon-serialize/README.md +++ b/addons/addon-serialize/README.md @@ -1,4 +1,4 @@ -## xterm-addon-serialize +## @xterm/addon-serialize An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables xterm.js to serialize a terminal framebuffer into string or html. This addon requires xterm.js v4+. @@ -7,14 +7,14 @@ An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables xterm. ### Install ```bash -npm install --save xterm-addon-serialize +npm install --save @xterm/addon-serialize ``` ### Usage ```ts -import { Terminal } from "xterm"; -import { SerializeAddon } from "xterm-addon-serialize"; +import { Terminal } from "@xterm/xterm"; +import { SerializeAddon } from "@xterm/addon-serialize"; const terminal = new Terminal(); const serializeAddon = new SerializeAddon(); @@ -25,7 +25,7 @@ terminal.write("something...", () => { }); ``` -See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-serialize/typings/xterm-addon-serialize.d.ts) for more advanced usage. +See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/addon-serialize/typings/addon-serialize.d.ts) for more advanced usage. ### Benchmark @@ -35,8 +35,8 @@ See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm- $ git clone https://github.com/xtermjs/xterm.js.git $ cd xterm.js $ yarn -$ cd addons/xterm-addon-serialize +$ cd addons/addon-serialize $ yarn benchmark && yarn benchmark-baseline -$ # change some code in `xterm-addon-serialize` +$ # change some code in `@xterm/addon-serialize` $ yarn benchmark-eval ``` diff --git a/addons/xterm-addon-serialize/benchmark/SerializeAddon.benchmark.ts b/addons/addon-serialize/benchmark/SerializeAddon.benchmark.ts similarity index 100% rename from addons/xterm-addon-serialize/benchmark/SerializeAddon.benchmark.ts rename to addons/addon-serialize/benchmark/SerializeAddon.benchmark.ts diff --git a/addons/xterm-addon-serialize/benchmark/benchmark.json b/addons/addon-serialize/benchmark/benchmark.json similarity index 100% rename from addons/xterm-addon-serialize/benchmark/benchmark.json rename to addons/addon-serialize/benchmark/benchmark.json diff --git a/addons/xterm-addon-serialize/benchmark/tsconfig.json b/addons/addon-serialize/benchmark/tsconfig.json similarity index 82% rename from addons/xterm-addon-serialize/benchmark/tsconfig.json rename to addons/addon-serialize/benchmark/tsconfig.json index 6bbb2a4b..1f6429f6 100644 --- a/addons/xterm-addon-serialize/benchmark/tsconfig.json +++ b/addons/addon-serialize/benchmark/tsconfig.json @@ -14,7 +14,10 @@ "paths": { "common/*": ["../../../src/common/*"], "browser/*": ["../../../src/browser/*"], - "SerializeAddon": ["../src/SerializeAddon"] + "SerializeAddon": ["../src/SerializeAddon"], + "@xterm/addon-serialize": [ + "../typings/addon-serialize.d.ts" + ] } }, "include": ["../**/*", "../../../typings/xterm.d.ts"], diff --git a/addons/xterm-addon-serialize/package.json b/addons/addon-serialize/package.json similarity index 84% rename from addons/xterm-addon-serialize/package.json rename to addons/addon-serialize/package.json index 8f914865..763c52ca 100644 --- a/addons/xterm-addon-serialize/package.json +++ b/addons/addon-serialize/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-serialize", + "name": "@xterm/addon-serialize", "version": "0.11.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-serialize.js", - "types": "typings/xterm-addon-serialize.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-serialize", + "main": "lib/addon-serialize.js", + "types": "typings/addon-serialize.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-serialize", "license": "MIT", "keywords": [ "terminal", @@ -24,6 +24,6 @@ "benchmark-eval": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json --eval out-benchmark/benchmark/*benchmark.js" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-serialize/src/SerializeAddon.test.ts b/addons/addon-serialize/src/SerializeAddon.test.ts similarity index 99% rename from addons/xterm-addon-serialize/src/SerializeAddon.test.ts rename to addons/addon-serialize/src/SerializeAddon.test.ts index 75148ab9..d41cfa12 100644 --- a/addons/xterm-addon-serialize/src/SerializeAddon.test.ts +++ b/addons/addon-serialize/src/SerializeAddon.test.ts @@ -44,7 +44,7 @@ class TestSelectionService { } } -describe('xterm-addon-serialize', () => { +describe('SerializeAddon', () => { let dom: jsdom.JSDOM; let window: jsdom.DOMWindow; diff --git a/addons/xterm-addon-serialize/src/SerializeAddon.ts b/addons/addon-serialize/src/SerializeAddon.ts similarity index 98% rename from addons/xterm-addon-serialize/src/SerializeAddon.ts rename to addons/addon-serialize/src/SerializeAddon.ts index 7a2db089..961d8546 100644 --- a/addons/xterm-addon-serialize/src/SerializeAddon.ts +++ b/addons/addon-serialize/src/SerializeAddon.ts @@ -5,9 +5,10 @@ * (EXPERIMENTAL) This Addon is still under development */ +import type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm'; +import type { SerializeAddon as ISerializeApi } from '@xterm/addon-serialize'; import { DEFAULT_ANSI_COLORS } from 'browser/services/ThemeService'; import { IAttributeData, IColor } from 'common/Types'; -import { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from 'xterm'; function constrain(value: number, low: number, high: number): number { return Math.max(low, Math.min(value, high)); @@ -411,7 +412,7 @@ class StringSerializeHandler extends BaseSerializeHandler { } } -export class SerializeAddon implements ITerminalAddon { +export class SerializeAddon implements ITerminalAddon , ISerializeApi { private _terminal: Terminal | undefined; public activate(terminal: Terminal): void { @@ -604,7 +605,7 @@ export class HTMLSerializeHandler extends BaseSerializeHandler { (color >> 8) & 255, (color ) & 255 ]; - return rgb.map(x => this._padStart(x.toString(16), 2, '0')).join(''); + return '#' + rgb.map(x => this._padStart(x.toString(16), 2, '0')).join(''); } if (isFg ? cell.isFgPalette() : cell.isBgPalette()) { return this._ansiColors[color].css; diff --git a/addons/xterm-addon-serialize/src/tsconfig.json b/addons/addon-serialize/src/tsconfig.json similarity index 88% rename from addons/xterm-addon-serialize/src/tsconfig.json rename to addons/addon-serialize/src/tsconfig.json index 22ffe53e..6fb641ef 100644 --- a/addons/xterm-addon-serialize/src/tsconfig.json +++ b/addons/addon-serialize/src/tsconfig.json @@ -17,6 +17,9 @@ ], "browser/*": [ "../../../src/browser/*" + ], + "@xterm/addon-serialize": [ + "../typings/addon-serialize.d.ts" ] }, "strict": true, diff --git a/addons/xterm-addon-serialize/test/SerializeAddon.api.ts b/addons/addon-serialize/test/SerializeAddon.api.ts similarity index 100% rename from addons/xterm-addon-serialize/test/SerializeAddon.api.ts rename to addons/addon-serialize/test/SerializeAddon.api.ts diff --git a/addons/xterm-addon-serialize/test/tsconfig.json b/addons/addon-serialize/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-serialize/test/tsconfig.json rename to addons/addon-serialize/test/tsconfig.json diff --git a/addons/xterm-addon-serialize/tsconfig.json b/addons/addon-serialize/tsconfig.json similarity index 100% rename from addons/xterm-addon-serialize/tsconfig.json rename to addons/addon-serialize/tsconfig.json diff --git a/addons/xterm-addon-serialize/typings/xterm-addon-serialize.d.ts b/addons/addon-serialize/typings/addon-serialize.d.ts similarity index 96% rename from addons/xterm-addon-serialize/typings/xterm-addon-serialize.d.ts rename to addons/addon-serialize/typings/addon-serialize.d.ts index 4cb6283d..0b127b50 100644 --- a/addons/xterm-addon-serialize/typings/xterm-addon-serialize.d.ts +++ b/addons/addon-serialize/typings/addon-serialize.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon } from 'xterm'; +import { Terminal, ITerminalAddon } from '@xterm/xterm'; -declare module 'xterm-addon-serialize' { +declare module '@xterm/addon-serialize' { /** * An xterm.js addon that enables serialization of terminal contents. */ diff --git a/addons/xterm-addon-serialize/webpack.config.js b/addons/addon-serialize/webpack.config.js similarity index 94% rename from addons/xterm-addon-serialize/webpack.config.js rename to addons/addon-serialize/webpack.config.js index fee297d8..bd08ca37 100644 --- a/addons/xterm-addon-serialize/webpack.config.js +++ b/addons/addon-serialize/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'SerializeAddon'; -const mainFile = 'xterm-addon-serialize.js'; +const mainFile = 'addon-serialize.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-unicode-graphemes/.gitignore b/addons/addon-unicode-graphemes/.gitignore similarity index 100% rename from addons/xterm-addon-unicode-graphemes/.gitignore rename to addons/addon-unicode-graphemes/.gitignore diff --git a/addons/xterm-addon-unicode-graphemes/.npmignore b/addons/addon-unicode-graphemes/.npmignore similarity index 100% rename from addons/xterm-addon-unicode-graphemes/.npmignore rename to addons/addon-unicode-graphemes/.npmignore diff --git a/addons/xterm-addon-unicode-graphemes/LICENSE b/addons/addon-unicode-graphemes/LICENSE similarity index 100% rename from addons/xterm-addon-unicode-graphemes/LICENSE rename to addons/addon-unicode-graphemes/LICENSE diff --git a/addons/xterm-addon-unicode-graphemes/README.md b/addons/addon-unicode-graphemes/README.md similarity index 74% rename from addons/xterm-addon-unicode-graphemes/README.md rename to addons/addon-unicode-graphemes/README.md index 2f5639fc..6e717c26 100644 --- a/addons/xterm-addon-unicode-graphemes/README.md +++ b/addons/addon-unicode-graphemes/README.md @@ -1,4 +1,4 @@ -## xterm-addon-unicode-graphemes +## @xterm/addon-unicode-graphemes ⚠️ **This addon is currently experimental and may introduce unexpected and non-standard behavior** @@ -8,15 +8,13 @@ The file `src/UnicodeProperties.ts` is generated and depends on the Unicode vers ### Install -```bash -npm install --save xterm-addon-unicode-graphemes -``` +This addon is not yet published to npm ### Usage ```ts -import { Terminal } from 'xterm'; -import { UnicodeGraphemesAddon } from 'xterm-addon-unicode-graphemes'; +import { Terminal } from '@xterm/xterm'; +import { UnicodeGraphemesAddon } from '@xterm/addon-unicode-graphemes'; const terminal = new Terminal(); const unicodeGraphemesAddon = new UnicodeGraphemesAddon(); diff --git a/addons/xterm-addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts b/addons/addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts similarity index 100% rename from addons/xterm-addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts rename to addons/addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts diff --git a/addons/xterm-addon-unicode-graphemes/benchmark/benchmark.json b/addons/addon-unicode-graphemes/benchmark/benchmark.json similarity index 100% rename from addons/xterm-addon-unicode-graphemes/benchmark/benchmark.json rename to addons/addon-unicode-graphemes/benchmark/benchmark.json diff --git a/addons/xterm-addon-unicode-graphemes/benchmark/tsconfig.json b/addons/addon-unicode-graphemes/benchmark/tsconfig.json similarity index 86% rename from addons/xterm-addon-unicode-graphemes/benchmark/tsconfig.json rename to addons/addon-unicode-graphemes/benchmark/tsconfig.json index 9bc532d3..c6f37a6c 100644 --- a/addons/xterm-addon-unicode-graphemes/benchmark/tsconfig.json +++ b/addons/addon-unicode-graphemes/benchmark/tsconfig.json @@ -11,7 +11,10 @@ "paths": { "common/*": ["../../../src/common/*"], "browser/*": ["../../../src/browser/*"], - "UnicodeGraphemeProvider": ["../src/UnicodeGraphemeProvider"] + "UnicodeGraphemeProvider": ["../src/UnicodeGraphemeProvider"], + "@xterm/addon-unicode-graphemes": [ + "../typings/addon-unicode-graphemes.d.ts" + ] } }, "include": ["../**/*", "../../../typings/xterm.d.ts"], diff --git a/addons/xterm-addon-unicode-graphemes/package.json b/addons/addon-unicode-graphemes/package.json similarity index 83% rename from addons/xterm-addon-unicode-graphemes/package.json rename to addons/addon-unicode-graphemes/package.json index 38ea7271..d49eda87 100644 --- a/addons/xterm-addon-unicode-graphemes/package.json +++ b/addons/addon-unicode-graphemes/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-unicode-graphemes", + "name": "@xterm/addon-unicode-graphemes", "version": "0.1.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-unicode-graphemes.js", - "types": "typings/xterm-addon-unicode-graphemes.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-unicode-graphemes", + "main": "lib/addon-unicode-graphemes.js", + "types": "typings/addon-unicode-graphemes.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-unicode-graphemes", "license": "MIT", "keywords": [ "terminal", @@ -24,6 +24,6 @@ "benchmark-eval": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json --eval out-benchmark/benchmark/*benchmark.js" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-unicode-graphemes/src/UnicodeGraphemeProvider.ts b/addons/addon-unicode-graphemes/src/UnicodeGraphemeProvider.ts similarity index 97% rename from addons/xterm-addon-unicode-graphemes/src/UnicodeGraphemeProvider.ts rename to addons/addon-unicode-graphemes/src/UnicodeGraphemeProvider.ts index 39fbec84..3d5717a0 100644 --- a/addons/xterm-addon-unicode-graphemes/src/UnicodeGraphemeProvider.ts +++ b/addons/addon-unicode-graphemes/src/UnicodeGraphemeProvider.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IUnicodeVersionProvider } from 'xterm'; +import { IUnicodeVersionProvider } from '@xterm/xterm'; import { UnicodeCharProperties, UnicodeCharWidth } from 'common/services/Services'; import { UnicodeService } from 'common/services/UnicodeService'; import * as UC from './third-party/UnicodeProperties'; diff --git a/addons/xterm-addon-unicode-graphemes/src/UnicodeGraphemesAddon.ts b/addons/addon-unicode-graphemes/src/UnicodeGraphemesAddon.ts similarity index 79% rename from addons/xterm-addon-unicode-graphemes/src/UnicodeGraphemesAddon.ts rename to addons/addon-unicode-graphemes/src/UnicodeGraphemesAddon.ts index 80290edf..6e4d2266 100644 --- a/addons/xterm-addon-unicode-graphemes/src/UnicodeGraphemesAddon.ts +++ b/addons/addon-unicode-graphemes/src/UnicodeGraphemesAddon.ts @@ -5,11 +5,11 @@ * UnicodeVersionProvider for V15 with grapeme cluster handleing. */ -import { Terminal, ITerminalAddon, IUnicodeHandling } from 'xterm'; +import type { Terminal, ITerminalAddon, IUnicodeHandling } from '@xterm/xterm'; +import type { UnicodeGraphemesAddon as IUnicodeGraphemesApi } from '@xterm/addon-unicode-graphemes'; import { UnicodeGraphemeProvider } from './UnicodeGraphemeProvider'; - -export class UnicodeGraphemesAddon implements ITerminalAddon { +export class UnicodeGraphemesAddon implements ITerminalAddon , IUnicodeGraphemesApi { private _provider15Graphemes?: UnicodeGraphemeProvider; private _provider15?: UnicodeGraphemeProvider; private _unicode?: IUnicodeHandling; diff --git a/addons/xterm-addon-unicode-graphemes/src/third-party/UnicodeProperties.ts b/addons/addon-unicode-graphemes/src/third-party/UnicodeProperties.ts similarity index 100% rename from addons/xterm-addon-unicode-graphemes/src/third-party/UnicodeProperties.ts rename to addons/addon-unicode-graphemes/src/third-party/UnicodeProperties.ts diff --git a/addons/xterm-addon-unicode-graphemes/src/third-party/tiny-inflate.ts b/addons/addon-unicode-graphemes/src/third-party/tiny-inflate.ts similarity index 100% rename from addons/xterm-addon-unicode-graphemes/src/third-party/tiny-inflate.ts rename to addons/addon-unicode-graphemes/src/third-party/tiny-inflate.ts diff --git a/addons/xterm-addon-unicode-graphemes/src/third-party/unicode-trie.ts b/addons/addon-unicode-graphemes/src/third-party/unicode-trie.ts similarity index 100% rename from addons/xterm-addon-unicode-graphemes/src/third-party/unicode-trie.ts rename to addons/addon-unicode-graphemes/src/third-party/unicode-trie.ts diff --git a/addons/xterm-addon-unicode-graphemes/src/tsconfig.json b/addons/addon-unicode-graphemes/src/tsconfig.json similarity index 84% rename from addons/xterm-addon-unicode-graphemes/src/tsconfig.json rename to addons/addon-unicode-graphemes/src/tsconfig.json index 60824fee..e9967bbe 100644 --- a/addons/xterm-addon-unicode-graphemes/src/tsconfig.json +++ b/addons/addon-unicode-graphemes/src/tsconfig.json @@ -15,6 +15,9 @@ "paths": { "common/*": [ "../../../src/common/*" + ], + "@xterm/addon-unicode-graphemes": [ + "../typings/addon-unicode-graphemes.d.ts" ] }, "types": [ diff --git a/addons/xterm-addon-unicode-graphemes/test/UnicodeGraphemesAddon.api.ts b/addons/addon-unicode-graphemes/test/UnicodeGraphemesAddon.api.ts similarity index 100% rename from addons/xterm-addon-unicode-graphemes/test/UnicodeGraphemesAddon.api.ts rename to addons/addon-unicode-graphemes/test/UnicodeGraphemesAddon.api.ts diff --git a/addons/xterm-addon-unicode-graphemes/test/tsconfig.json b/addons/addon-unicode-graphemes/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-unicode-graphemes/test/tsconfig.json rename to addons/addon-unicode-graphemes/test/tsconfig.json diff --git a/addons/xterm-addon-unicode-graphemes/tsconfig.json b/addons/addon-unicode-graphemes/tsconfig.json similarity index 100% rename from addons/xterm-addon-unicode-graphemes/tsconfig.json rename to addons/addon-unicode-graphemes/tsconfig.json diff --git a/addons/xterm-addon-unicode-graphemes/typings/xterm-addon-unicode-graphemes.d.ts b/addons/addon-unicode-graphemes/typings/addon-unicode-graphemes.d.ts similarity index 70% rename from addons/xterm-addon-unicode-graphemes/typings/xterm-addon-unicode-graphemes.d.ts rename to addons/addon-unicode-graphemes/typings/addon-unicode-graphemes.d.ts index 3ab25aa0..9443f1c8 100644 --- a/addons/xterm-addon-unicode-graphemes/typings/xterm-addon-unicode-graphemes.d.ts +++ b/addons/addon-unicode-graphemes/typings/addon-unicode-graphemes.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon } from 'xterm'; +import { Terminal, ITerminalAddon } from '@xterm/xterm'; -declare module 'xterm-addon-unicode-graphemes' { +declare module '@xterm/addon-unicode-graphemes' { export class UnicodeGraphemesAddon implements ITerminalAddon { constructor(); public activate(terminal: Terminal): void; diff --git a/addons/xterm-addon-unicode-graphemes/webpack.config.js b/addons/addon-unicode-graphemes/webpack.config.js similarity index 92% rename from addons/xterm-addon-unicode-graphemes/webpack.config.js rename to addons/addon-unicode-graphemes/webpack.config.js index 89abf53a..6a80bdea 100644 --- a/addons/xterm-addon-unicode-graphemes/webpack.config.js +++ b/addons/addon-unicode-graphemes/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'UnicodeGraphemesAddon'; -const mainFile = 'xterm-addon-unicode-graphemes.js'; +const mainFile = 'addon-unicode-graphemes.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-unicode11/.gitignore b/addons/addon-unicode11/.gitignore similarity index 100% rename from addons/xterm-addon-unicode11/.gitignore rename to addons/addon-unicode11/.gitignore diff --git a/addons/xterm-addon-unicode11/.npmignore b/addons/addon-unicode11/.npmignore similarity index 100% rename from addons/xterm-addon-unicode11/.npmignore rename to addons/addon-unicode11/.npmignore diff --git a/addons/xterm-addon-unicode11/LICENSE b/addons/addon-unicode11/LICENSE similarity index 100% rename from addons/xterm-addon-unicode11/LICENSE rename to addons/addon-unicode11/LICENSE diff --git a/addons/xterm-addon-unicode11/README.md b/addons/addon-unicode11/README.md similarity index 63% rename from addons/xterm-addon-unicode11/README.md rename to addons/addon-unicode11/README.md index ec01203e..ccfe77cf 100644 --- a/addons/xterm-addon-unicode11/README.md +++ b/addons/addon-unicode11/README.md @@ -1,18 +1,18 @@ -## xterm-addon-unicode11 +## @xterm/addon-unicode11 An addon providing Unicode version 11 rules for xterm.js. ### Install ```bash -npm install --save xterm-addon-unicode11 +npm install --save @xterm/addon-unicode11 ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { Unicode11Addon } from 'xterm-addon-unicode11'; +import { Terminal } from '@xterm/xterm'; +import { Unicode11Addon } from '@xterm/addon-unicode11'; const terminal = new Terminal(); const unicode11Addon = new Unicode11Addon(); diff --git a/addons/xterm-addon-unicode11/package.json b/addons/addon-unicode11/package.json similarity index 72% rename from addons/xterm-addon-unicode11/package.json rename to addons/addon-unicode11/package.json index d187d8ed..ad6a4892 100644 --- a/addons/xterm-addon-unicode11/package.json +++ b/addons/addon-unicode11/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-unicode11", + "name": "@xterm/addon-unicode11", "version": "0.6.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-unicode11.js", - "types": "typings/xterm-addon-unicode11.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-unicode11", + "main": "lib/addon-unicode11.js", + "types": "typings/addon-unicode11.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-unicode11", "license": "MIT", "keywords": [ "terminal", @@ -21,6 +21,6 @@ "prepublishOnly": "npm run package" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-unicode11/src/Unicode11Addon.ts b/addons/addon-unicode11/src/Unicode11Addon.ts similarity index 58% rename from addons/xterm-addon-unicode11/src/Unicode11Addon.ts rename to addons/addon-unicode11/src/Unicode11Addon.ts index d4ddf77e..301145ee 100644 --- a/addons/xterm-addon-unicode11/src/Unicode11Addon.ts +++ b/addons/addon-unicode11/src/Unicode11Addon.ts @@ -5,11 +5,11 @@ * UnicodeVersionProvider for V11. */ -import { Terminal, ITerminalAddon } from 'xterm'; +import type { Terminal, ITerminalAddon } from '@xterm/xterm'; +import type { Unicode11Addon as IUnicode11Api } from '@xterm/addon-unicode11'; import { UnicodeV11 } from './UnicodeV11'; - -export class Unicode11Addon implements ITerminalAddon { +export class Unicode11Addon implements ITerminalAddon , IUnicode11Api { public activate(terminal: Terminal): void { terminal.unicode.register(new UnicodeV11()); } diff --git a/addons/xterm-addon-unicode11/src/UnicodeV11.ts b/addons/addon-unicode11/src/UnicodeV11.ts similarity index 99% rename from addons/xterm-addon-unicode11/src/UnicodeV11.ts rename to addons/addon-unicode11/src/UnicodeV11.ts index c1ef08c1..79568960 100644 --- a/addons/xterm-addon-unicode11/src/UnicodeV11.ts +++ b/addons/addon-unicode11/src/UnicodeV11.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IUnicodeVersionProvider } from 'xterm'; +import { IUnicodeVersionProvider } from '@xterm/xterm'; import { UnicodeCharProperties, UnicodeCharWidth } from 'common/services/Services'; import { UnicodeService } from 'common/services/UnicodeService'; diff --git a/addons/xterm-addon-unicode11/src/tsconfig.json b/addons/addon-unicode11/src/tsconfig.json similarity index 86% rename from addons/xterm-addon-unicode11/src/tsconfig.json rename to addons/addon-unicode11/src/tsconfig.json index e2c1464e..8eb7752b 100644 --- a/addons/xterm-addon-unicode11/src/tsconfig.json +++ b/addons/addon-unicode11/src/tsconfig.json @@ -15,6 +15,9 @@ "paths": { "common/*": [ "../../../src/common/*" + ], + "@xterm/addon-unicode11": [ + "../typings/addon-unicode11.d.ts" ] }, "types": [ diff --git a/addons/xterm-addon-unicode11/test/Unicode11Addon.api.ts b/addons/addon-unicode11/test/Unicode11Addon.api.ts similarity index 100% rename from addons/xterm-addon-unicode11/test/Unicode11Addon.api.ts rename to addons/addon-unicode11/test/Unicode11Addon.api.ts diff --git a/addons/xterm-addon-unicode11/test/tsconfig.json b/addons/addon-unicode11/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-unicode11/test/tsconfig.json rename to addons/addon-unicode11/test/tsconfig.json diff --git a/addons/xterm-addon-unicode11/tsconfig.json b/addons/addon-unicode11/tsconfig.json similarity index 100% rename from addons/xterm-addon-unicode11/tsconfig.json rename to addons/addon-unicode11/tsconfig.json diff --git a/addons/xterm-addon-unicode11/typings/xterm-addon-unicode11.d.ts b/addons/addon-unicode11/typings/addon-unicode11.d.ts similarity index 71% rename from addons/xterm-addon-unicode11/typings/xterm-addon-unicode11.d.ts rename to addons/addon-unicode11/typings/addon-unicode11.d.ts index 1d0dce1b..74bd288d 100644 --- a/addons/xterm-addon-unicode11/typings/xterm-addon-unicode11.d.ts +++ b/addons/addon-unicode11/typings/addon-unicode11.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon } from 'xterm'; +import { Terminal, ITerminalAddon } from '@xterm/xterm'; -declare module 'xterm-addon-unicode11' { +declare module '@xterm/addon-unicode11' { export class Unicode11Addon implements ITerminalAddon { constructor(); public activate(terminal: Terminal): void; diff --git a/addons/xterm-addon-unicode11/webpack.config.js b/addons/addon-unicode11/webpack.config.js similarity index 94% rename from addons/xterm-addon-unicode11/webpack.config.js rename to addons/addon-unicode11/webpack.config.js index 10c0adc3..1913481d 100644 --- a/addons/xterm-addon-unicode11/webpack.config.js +++ b/addons/addon-unicode11/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'Unicode11Addon'; -const mainFile = 'xterm-addon-unicode11.js'; +const mainFile = 'addon-unicode11.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-web-links/.gitignore b/addons/addon-web-links/.gitignore similarity index 100% rename from addons/xterm-addon-web-links/.gitignore rename to addons/addon-web-links/.gitignore diff --git a/addons/xterm-addon-web-links/.npmignore b/addons/addon-web-links/.npmignore similarity index 100% rename from addons/xterm-addon-web-links/.npmignore rename to addons/addon-web-links/.npmignore diff --git a/addons/xterm-addon-web-links/LICENSE b/addons/addon-web-links/LICENSE similarity index 100% rename from addons/xterm-addon-web-links/LICENSE rename to addons/addon-web-links/LICENSE diff --git a/addons/xterm-addon-web-links/README.md b/addons/addon-web-links/README.md similarity index 55% rename from addons/xterm-addon-web-links/README.md rename to addons/addon-web-links/README.md index e53f4edf..16dfa571 100644 --- a/addons/xterm-addon-web-links/README.md +++ b/addons/addon-web-links/README.md @@ -1,21 +1,21 @@ -## xterm-addon-web-links +## @xterm/addon-web-links An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables web links. This addon requires xterm.js v4+. ### Install ```bash -npm install --save xterm-addon-web-links +npm install --save @xterm/addon-web-links ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { WebLinksAddon } from 'xterm-addon-web-links'; +import { Terminal } from '@xterm/xterm'; +import { WebLinksAddon } from '@xterm/addon-web-links'; const terminal = new Terminal(); terminal.loadAddon(new WebLinksAddon()); ``` -See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-web-links/typings/xterm-addon-web-links.d.ts) for more advanced usage. +See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/addon-web-links/typings/addon-web-links.d.ts) for more advanced usage. diff --git a/addons/xterm-addon-web-links/package.json b/addons/addon-web-links/package.json similarity index 73% rename from addons/xterm-addon-web-links/package.json rename to addons/addon-web-links/package.json index 783ee7e0..6367907a 100644 --- a/addons/xterm-addon-web-links/package.json +++ b/addons/addon-web-links/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-web-links", + "name": "@xterm/addon-web-links", "version": "0.9.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-web-links.js", - "types": "typings/xterm-addon-web-links.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-web-links", + "main": "lib/addon-web-links.js", + "types": "typings/addon-web-links.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-web-links", "license": "MIT", "keywords": [ "terminal", @@ -21,7 +21,7 @@ "prepublishOnly": "npm run package" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } } diff --git a/addons/xterm-addon-web-links/src/WebLinkProvider.ts b/addons/addon-web-links/src/WebLinkProvider.ts similarity index 99% rename from addons/xterm-addon-web-links/src/WebLinkProvider.ts rename to addons/addon-web-links/src/WebLinkProvider.ts index 1c9486f5..25dd983c 100644 --- a/addons/xterm-addon-web-links/src/WebLinkProvider.ts +++ b/addons/addon-web-links/src/WebLinkProvider.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ILinkProvider, ILink, Terminal, IViewportRange, IBufferLine } from 'xterm'; +import { ILinkProvider, ILink, Terminal, IViewportRange, IBufferLine } from '@xterm/xterm'; export interface ILinkProviderOptions { hover?(event: MouseEvent, text: string, location: IViewportRange): void; diff --git a/addons/xterm-addon-web-links/src/WebLinksAddon.ts b/addons/addon-web-links/src/WebLinksAddon.ts similarity index 89% rename from addons/xterm-addon-web-links/src/WebLinksAddon.ts rename to addons/addon-web-links/src/WebLinksAddon.ts index 5c956cec..8902d8e0 100644 --- a/addons/xterm-addon-web-links/src/WebLinksAddon.ts +++ b/addons/addon-web-links/src/WebLinksAddon.ts @@ -3,7 +3,8 @@ * @license MIT */ -import { Terminal, ITerminalAddon, IDisposable } from 'xterm'; +import type { Terminal, ITerminalAddon, IDisposable } from '@xterm/xterm'; +import type { WebLinksAddon as IWebLinksApi } from '@xterm/addon-web-links'; import { ILinkProviderOptions, WebLinkProvider } from './WebLinkProvider'; // consider everthing starting with http:// or https:// @@ -34,7 +35,7 @@ function handleLink(event: MouseEvent, uri: string): void { } } -export class WebLinksAddon implements ITerminalAddon { +export class WebLinksAddon implements ITerminalAddon , IWebLinksApi { private _terminal: Terminal | undefined; private _linkProvider: IDisposable | undefined; diff --git a/addons/xterm-addon-web-links/src/tsconfig.json b/addons/addon-web-links/src/tsconfig.json similarity index 76% rename from addons/xterm-addon-web-links/src/tsconfig.json rename to addons/addon-web-links/src/tsconfig.json index 7e68574d..217402de 100644 --- a/addons/xterm-addon-web-links/src/tsconfig.json +++ b/addons/addon-web-links/src/tsconfig.json @@ -13,7 +13,12 @@ "strict": true, "types": [ "../../../node_modules/@types/mocha" - ] + ], + "paths": { + "@xterm/addon-web-links": [ + "../typings/addon-web-links.d.ts" + ] + } }, "include": [ "./**/*", diff --git a/addons/xterm-addon-web-links/test/WebLinksAddon.api.ts b/addons/addon-web-links/test/WebLinksAddon.api.ts similarity index 100% rename from addons/xterm-addon-web-links/test/WebLinksAddon.api.ts rename to addons/addon-web-links/test/WebLinksAddon.api.ts diff --git a/addons/xterm-addon-web-links/test/tsconfig.json b/addons/addon-web-links/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-web-links/test/tsconfig.json rename to addons/addon-web-links/test/tsconfig.json diff --git a/addons/xterm-addon-web-links/tsconfig.json b/addons/addon-web-links/tsconfig.json similarity index 100% rename from addons/xterm-addon-web-links/tsconfig.json rename to addons/addon-web-links/tsconfig.json diff --git a/addons/xterm-addon-web-links/typings/xterm-addon-web-links.d.ts b/addons/addon-web-links/typings/addon-web-links.d.ts similarity index 91% rename from addons/xterm-addon-web-links/typings/xterm-addon-web-links.d.ts rename to addons/addon-web-links/typings/addon-web-links.d.ts index dc69d732..4ae4934e 100644 --- a/addons/xterm-addon-web-links/typings/xterm-addon-web-links.d.ts +++ b/addons/addon-web-links/typings/addon-web-links.d.ts @@ -4,9 +4,9 @@ */ -import { Terminal, ITerminalAddon, IViewportRange } from 'xterm'; +import { Terminal, ITerminalAddon, IViewportRange } from '@xterm/xterm'; -declare module 'xterm-addon-web-links' { +declare module '@xterm/addon-web-links' { /** * An xterm.js addon that enables web links. */ diff --git a/addons/xterm-addon-web-links/webpack.config.js b/addons/addon-web-links/webpack.config.js similarity index 92% rename from addons/xterm-addon-web-links/webpack.config.js rename to addons/addon-web-links/webpack.config.js index fd87d07e..4484dbf6 100644 --- a/addons/xterm-addon-web-links/webpack.config.js +++ b/addons/addon-web-links/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'WebLinksAddon'; -const mainFile = 'xterm-addon-web-links.js'; +const mainFile = 'addon-web-links.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-webgl/.gitignore b/addons/addon-webgl/.gitignore similarity index 100% rename from addons/xterm-addon-webgl/.gitignore rename to addons/addon-webgl/.gitignore diff --git a/addons/xterm-addon-webgl/.npmignore b/addons/addon-webgl/.npmignore similarity index 100% rename from addons/xterm-addon-webgl/.npmignore rename to addons/addon-webgl/.npmignore diff --git a/addons/xterm-addon-webgl/LICENSE b/addons/addon-webgl/LICENSE similarity index 100% rename from addons/xterm-addon-webgl/LICENSE rename to addons/addon-webgl/LICENSE diff --git a/addons/xterm-addon-webgl/README.md b/addons/addon-webgl/README.md similarity index 71% rename from addons/xterm-addon-webgl/README.md rename to addons/addon-webgl/README.md index 5dee6b62..05d753e8 100644 --- a/addons/xterm-addon-webgl/README.md +++ b/addons/addon-webgl/README.md @@ -1,25 +1,25 @@ -## xterm-addon-webgl +## @xterm/addon-webgl An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables a WebGL2-based renderer. This addon requires xterm.js v4+. ### Install ```bash -npm install --save xterm-addon-webgl +npm install --save @xterm/addon-webgl ``` ### Usage ```ts -import { Terminal } from 'xterm'; -import { WebglAddon } from 'xterm-addon-webgl'; +import { Terminal } from '@xterm/xterm'; +import { WebglAddon } from '@xterm/addon-webgl'; const terminal = new Terminal(); terminal.open(element); terminal.loadAddon(new WebglAddon()); ``` -See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-webgl/typings/xterm-addon-webgl.d.ts) for more advanced usage. +See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/addon-webgl/typings/addon-webgl.d.ts) for more advanced usage. ### Handling Context Loss @@ -38,4 +38,4 @@ Read more about handling WebGL context losses on the [Khronos wiki](https://www. ### See also -- [xterm-addon-canvas](https://www.npmjs.com/package/xterm-addon-canvas) A renderer for xterm.js that uses a 2d canvas that can be used as a fallback when WebGL is not available +- [@xterm/addon-canvas](https://www.npmjs.com/package/@xterm/addon-canvas) A renderer for xterm.js that uses a 2d canvas that can be used as a fallback when WebGL is not available diff --git a/addons/xterm-addon-webgl/package.json b/addons/addon-webgl/package.json similarity index 77% rename from addons/xterm-addon-webgl/package.json rename to addons/addon-webgl/package.json index 1458effc..9a31c306 100644 --- a/addons/xterm-addon-webgl/package.json +++ b/addons/addon-webgl/package.json @@ -1,13 +1,13 @@ { - "name": "xterm-addon-webgl", + "name": "@xterm/addon-webgl", "version": "0.16.0", "author": { "name": "The xterm.js authors", "url": "https://xtermjs.org/" }, - "main": "lib/xterm-addon-webgl.js", - "types": "typings/xterm-addon-webgl.d.ts", - "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/xterm-addon-webgl", + "main": "lib/addon-webgl.js", + "types": "typings/addon-webgl.d.ts", + "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-webgl", "license": "MIT", "keywords": [ "terminal", @@ -23,7 +23,6 @@ "start-server-only": "node ../../demo/start-server-only" }, "peerDependencies": { - "xterm": "^5.0.0" + "@xterm/xterm": "^5.0.0" } - } diff --git a/addons/xterm-addon-webgl/src/GlyphRenderer.ts b/addons/addon-webgl/src/GlyphRenderer.ts similarity index 99% rename from addons/xterm-addon-webgl/src/GlyphRenderer.ts rename to addons/addon-webgl/src/GlyphRenderer.ts index e0669102..1fb0e18c 100644 --- a/addons/xterm-addon-webgl/src/GlyphRenderer.ts +++ b/addons/addon-webgl/src/GlyphRenderer.ts @@ -8,7 +8,7 @@ import { TextureAtlas } from 'browser/renderer/shared/TextureAtlas'; import { IRasterizedGlyph, IRenderDimensions, ITextureAtlas } from 'browser/renderer/shared/Types'; import { NULL_CELL_CODE } from 'common/buffer/Constants'; import { Disposable, toDisposable } from 'common/Lifecycle'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject } from './Types'; import { createProgram, GLTexture, PROJECTION_MATRIX } from './WebglUtils'; diff --git a/addons/xterm-addon-webgl/src/RectangleRenderer.ts b/addons/addon-webgl/src/RectangleRenderer.ts similarity index 99% rename from addons/xterm-addon-webgl/src/RectangleRenderer.ts rename to addons/addon-webgl/src/RectangleRenderer.ts index 5e9c364e..2a1f5392 100644 --- a/addons/xterm-addon-webgl/src/RectangleRenderer.ts +++ b/addons/addon-webgl/src/RectangleRenderer.ts @@ -10,7 +10,7 @@ import { ReadonlyColorSet } from 'browser/Types'; import { Attributes, FgFlags } from 'common/buffer/Constants'; import { Disposable, toDisposable } from 'common/Lifecycle'; import { IColor } from 'common/Types'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { RENDER_MODEL_BG_OFFSET, RENDER_MODEL_FG_OFFSET, RENDER_MODEL_INDICIES_PER_CELL } from './RenderModel'; import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject } from './Types'; import { createProgram, expandFloat32Array, PROJECTION_MATRIX } from './WebglUtils'; diff --git a/addons/xterm-addon-webgl/src/RenderModel.ts b/addons/addon-webgl/src/RenderModel.ts similarity index 100% rename from addons/xterm-addon-webgl/src/RenderModel.ts rename to addons/addon-webgl/src/RenderModel.ts diff --git a/addons/xterm-addon-webgl/src/TypedArray.test.ts b/addons/addon-webgl/src/TypedArray.test.ts similarity index 100% rename from addons/xterm-addon-webgl/src/TypedArray.test.ts rename to addons/addon-webgl/src/TypedArray.test.ts diff --git a/addons/xterm-addon-webgl/src/TypedArray.ts b/addons/addon-webgl/src/TypedArray.ts similarity index 100% rename from addons/xterm-addon-webgl/src/TypedArray.ts rename to addons/addon-webgl/src/TypedArray.ts diff --git a/addons/xterm-addon-webgl/src/Types.d.ts b/addons/addon-webgl/src/Types.d.ts similarity index 100% rename from addons/xterm-addon-webgl/src/Types.d.ts rename to addons/addon-webgl/src/Types.d.ts diff --git a/addons/xterm-addon-webgl/src/WebglAddon.ts b/addons/addon-webgl/src/WebglAddon.ts similarity index 86% rename from addons/xterm-addon-webgl/src/WebglAddon.ts rename to addons/addon-webgl/src/WebglAddon.ts index 3e091f0b..2b3a7f96 100644 --- a/addons/xterm-addon-webgl/src/WebglAddon.ts +++ b/addons/addon-webgl/src/WebglAddon.ts @@ -3,17 +3,19 @@ * @license MIT */ +import type { ITerminalAddon, Terminal } from '@xterm/xterm'; +import type { WebglAddon as IWebglApi } from '@xterm/addon-webgl'; import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services'; import { ITerminal } from 'browser/Types'; import { EventEmitter, forwardEvent } from 'common/EventEmitter'; import { Disposable, toDisposable } from 'common/Lifecycle'; import { getSafariVersion, isSafari } from 'common/Platform'; import { ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services'; -import { ITerminalAddon, Terminal } from 'xterm'; +import { IWebGL2RenderingContext } from './Types'; import { WebglRenderer } from './WebglRenderer'; import { setTraceLogger } from 'common/services/LogService'; -export class WebglAddon extends Disposable implements ITerminalAddon { +export class WebglAddon extends Disposable implements ITerminalAddon , IWebglApi { private _terminal?: Terminal; private _renderer?: WebglRenderer; @@ -30,7 +32,16 @@ export class WebglAddon extends Disposable implements ITerminalAddon { private _preserveDrawingBuffer?: boolean ) { if (isSafari && getSafariVersion() < 16) { - throw new Error('Webgl2 is only supported on Safari 16 and above'); + // Perform an extra check to determine if Webgl2 is manually enabled in developer settings + const contextAttributes = { + antialias: false, + depth: false, + preserveDrawingBuffer: true + }; + const gl = document.createElement('canvas').getContext('webgl2', contextAttributes) as IWebGL2RenderingContext; + if (!gl) { + throw new Error('Webgl2 is only supported on Safari 16 and above'); + } } super(); } diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/addon-webgl/src/WebglRenderer.ts similarity index 98% rename from addons/xterm-addon-webgl/src/WebglRenderer.ts rename to addons/addon-webgl/src/WebglRenderer.ts index 51749984..2bccc9b7 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/addon-webgl/src/WebglRenderer.ts @@ -19,7 +19,7 @@ import { AttributeData } from 'common/buffer/AttributeData'; import { CellData } from 'common/buffer/CellData'; import { Attributes, Content, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants'; import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { GlyphRenderer } from './GlyphRenderer'; import { RectangleRenderer } from './RectangleRenderer'; import { COMBINED_CHAR_BIT_MASK, RENDER_MODEL_BG_OFFSET, RENDER_MODEL_EXT_OFFSET, RENDER_MODEL_FG_OFFSET, RENDER_MODEL_INDICIES_PER_CELL, RenderModel } from './RenderModel'; @@ -75,7 +75,7 @@ export class WebglRenderer extends Disposable implements IRenderer { this.register(this._themeService.onChangeColors(() => this._handleColorChange())); - this._cellColorResolver = new CellColorResolver(this._terminal, this._model.selection, this._decorationService, this._coreBrowserService, this._themeService); + this._cellColorResolver = new CellColorResolver(this._terminal, this._optionsService, this._model.selection, this._decorationService, this._coreBrowserService, this._themeService); this._core = (this._terminal as any)._core; @@ -219,7 +219,7 @@ export class WebglRenderer extends Disposable implements IRenderer { for (const l of this._renderLayers) { l.handleSelectionChanged(this._terminal, start, end, columnSelectMode); } - this._model.selection.update(this._terminal, start, end, columnSelectMode); + this._model.selection.update(this._core, start, end, columnSelectMode); this._requestRedrawViewport(); } @@ -391,6 +391,7 @@ export class WebglRenderer extends Disposable implements IRenderer { end = clamp(end, terminal.rows - 1, 0); const cursorY = this._terminal.buffer.active.baseY + this._terminal.buffer.active.cursorY; + const viewportRelativeCursorY = cursorY - terminal.buffer.ydisp; // in case cursor.x == cols adjust visual cursor to cols - 1 const cursorX = Math.min(this._terminal.buffer.active.cursorX, terminal.cols - 1); let lastCursorX = -1; @@ -442,14 +443,14 @@ export class WebglRenderer extends Disposable implements IRenderer { i = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL; // Load colors/resolve overrides into work colors - this._cellColorResolver.resolve(cell, x, row); + this._cellColorResolver.resolve(cell, x, row, this.dimensions.device.cell.width); // Override colors for cursor cell if (isCursorVisible && row === cursorY) { if (x === cursorX) { this._model.cursor = { x: cursorX, - y: this._terminal.buffer.active.cursorY, + y: viewportRelativeCursorY, width: cell.getWidth(), style: this._coreBrowserService.isFocused ? (terminal.options.cursorStyle || 'block') : terminal.options.cursorInactiveStyle, diff --git a/addons/xterm-addon-webgl/src/WebglUtils.ts b/addons/addon-webgl/src/WebglUtils.ts similarity index 100% rename from addons/xterm-addon-webgl/src/WebglUtils.ts rename to addons/addon-webgl/src/WebglUtils.ts diff --git a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts b/addons/addon-webgl/src/renderLayer/BaseRenderLayer.ts similarity index 99% rename from addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts rename to addons/addon-webgl/src/renderLayer/BaseRenderLayer.ts index 11f96ed8..93e0fcb1 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts +++ b/addons/addon-webgl/src/renderLayer/BaseRenderLayer.ts @@ -12,7 +12,7 @@ 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 { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { IRenderLayer } from './Types'; export abstract class BaseRenderLayer extends Disposable implements IRenderLayer { diff --git a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts b/addons/addon-webgl/src/renderLayer/LinkRenderLayer.ts similarity index 98% rename from addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts rename to addons/addon-webgl/src/renderLayer/LinkRenderLayer.ts index aefc9f6e..0aaf5e70 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts +++ b/addons/addon-webgl/src/renderLayer/LinkRenderLayer.ts @@ -9,7 +9,7 @@ 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 { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; import { BaseRenderLayer } from './BaseRenderLayer'; export class LinkRenderLayer extends BaseRenderLayer { diff --git a/addons/xterm-addon-webgl/src/renderLayer/Types.ts b/addons/addon-webgl/src/renderLayer/Types.ts similarity index 96% rename from addons/xterm-addon-webgl/src/renderLayer/Types.ts rename to addons/addon-webgl/src/renderLayer/Types.ts index 3dbdfd9c..feeceb14 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/Types.ts +++ b/addons/addon-webgl/src/renderLayer/Types.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IDisposable, Terminal } from 'xterm'; +import { IDisposable, Terminal } from '@xterm/xterm'; import { IRenderDimensions } from 'browser/renderer/shared/Types'; export interface IRenderLayer extends IDisposable { diff --git a/addons/xterm-addon-webgl/src/tsconfig.json b/addons/addon-webgl/src/tsconfig.json similarity index 90% rename from addons/xterm-addon-webgl/src/tsconfig.json rename to addons/addon-webgl/src/tsconfig.json index 4d4194db..924d3762 100644 --- a/addons/xterm-addon-webgl/src/tsconfig.json +++ b/addons/addon-webgl/src/tsconfig.json @@ -17,6 +17,9 @@ ], "browser/*": [ "../../../src/browser/*" + ], + "@xterm/addon-webgl": [ + "../typings/addon-webgl.d.ts" ] }, "strict": true, diff --git a/addons/xterm-addon-webgl/test/WebglRenderer.test.ts b/addons/addon-webgl/test/WebglRenderer.test.ts similarity index 100% rename from addons/xterm-addon-webgl/test/WebglRenderer.test.ts rename to addons/addon-webgl/test/WebglRenderer.test.ts diff --git a/addons/xterm-addon-webgl/test/playwright.config.ts b/addons/addon-webgl/test/playwright.config.ts similarity index 100% rename from addons/xterm-addon-webgl/test/playwright.config.ts rename to addons/addon-webgl/test/playwright.config.ts diff --git a/addons/xterm-addon-webgl/test/tsconfig.json b/addons/addon-webgl/test/tsconfig.json similarity index 100% rename from addons/xterm-addon-webgl/test/tsconfig.json rename to addons/addon-webgl/test/tsconfig.json diff --git a/addons/xterm-addon-webgl/tsconfig.json b/addons/addon-webgl/tsconfig.json similarity index 100% rename from addons/xterm-addon-webgl/tsconfig.json rename to addons/addon-webgl/tsconfig.json diff --git a/addons/xterm-addon-webgl/typings/xterm-addon-webgl.d.ts b/addons/addon-webgl/typings/addon-webgl.d.ts similarity index 91% rename from addons/xterm-addon-webgl/typings/xterm-addon-webgl.d.ts rename to addons/addon-webgl/typings/addon-webgl.d.ts index 79108e0d..8c560421 100644 --- a/addons/xterm-addon-webgl/typings/xterm-addon-webgl.d.ts +++ b/addons/addon-webgl/typings/addon-webgl.d.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { Terminal, ITerminalAddon, IEvent } from 'xterm'; +import { Terminal, ITerminalAddon, IEvent } from '@xterm/xterm'; -declare module 'xterm-addon-webgl' { +declare module '@xterm/addon-webgl' { /** * An xterm.js addon that provides search functionality. */ diff --git a/addons/xterm-addon-webgl/webpack.config.js b/addons/addon-webgl/webpack.config.js similarity index 94% rename from addons/xterm-addon-webgl/webpack.config.js rename to addons/addon-webgl/webpack.config.js index 578b1102..f31ffd51 100644 --- a/addons/xterm-addon-webgl/webpack.config.js +++ b/addons/addon-webgl/webpack.config.js @@ -6,7 +6,7 @@ const path = require('path'); const addonName = 'WebglAddon'; -const mainFile = 'xterm-addon-webgl.js'; +const mainFile = 'addon-webgl.js'; module.exports = { entry: `./out/${addonName}.js`, diff --git a/addons/xterm-addon-canvas/README.md b/addons/xterm-addon-canvas/README.md deleted file mode 100644 index bffac96e..00000000 --- a/addons/xterm-addon-canvas/README.md +++ /dev/null @@ -1,28 +0,0 @@ -## xterm-addon-canvas - -An addon for [xterm.js](https://github.com/xtermjs/xterm.js) that enables a canvas-based renderer using a 2d context to draw. This addon requires xterm.js v5+. - -The purpose of this addon is to be used as a fallback for the [webgl addon](https://www.npmjs.com/package/xterm-addon-webgl) when better performance is desired over the default DOM renderer, but WebGL2 isn't supported or performant for some reason. - -### Install - -```bash -npm install --save xterm-addon-canvas -``` - -### Usage - -```ts -import { Terminal } from 'xterm'; -import { CanvasAddon } from 'xterm-addon-canvas'; - -const terminal = new Terminal(); -terminal.open(element); -terminal.loadAddon(new CanvasAddon()); -``` - -See the full [API](https://github.com/xtermjs/xterm.js/blob/master/addons/xterm-addon-canvas/typings/xterm-addon-canvas.d.ts) for more advanced usage. - -### See also - -- [xterm-addon-webgl](https://www.npmjs.com/package/xterm-addon-webgl) A renderer for xterm.js that uses WebGL diff --git a/bin/package_headless.js b/bin/package_headless.js index d002a95e..6f891f05 100644 --- a/bin/package_headless.js +++ b/bin/package_headless.js @@ -14,7 +14,7 @@ console.log('> headless/package.json'); const xtermPackageJson = require('../package.json'); const xtermHeadlessPackageJson = { ...xtermPackageJson, - name: 'xterm-headless', + name: '@xterm/headless', description: 'A headless terminal component that runs in Node.js', main: 'lib-headless/xterm-headless.js', types: 'typings/xterm-headless.d.ts', diff --git a/bin/publish.js b/bin/publish.js index 909877f5..989b849d 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -27,17 +27,18 @@ if (changedFiles.some(e => e.search(/^addons\//) === -1)) { // Publish addons if any files were changed inside of the addon const addonPackageDirs = [ - path.resolve(__dirname, '../addons/xterm-addon-attach'), - path.resolve(__dirname, '../addons/xterm-addon-canvas'), + path.resolve(__dirname, '../addons/addon-attach'), + path.resolve(__dirname, '../addons/addon-canvas'), path.resolve(__dirname, '../addons/xterm-addon-clipboard'), - path.resolve(__dirname, '../addons/xterm-addon-fit'), - // path.resolve(__dirname, '../addons/xterm-addon-image'), - path.resolve(__dirname, '../addons/xterm-addon-ligatures'), - path.resolve(__dirname, '../addons/xterm-addon-search'), - path.resolve(__dirname, '../addons/xterm-addon-serialize'), - path.resolve(__dirname, '../addons/xterm-addon-unicode11'), - path.resolve(__dirname, '../addons/xterm-addon-web-links'), - path.resolve(__dirname, '../addons/xterm-addon-webgl') + path.resolve(__dirname, '../addons/addon-fit'), + path.resolve(__dirname, '../addons/addon-image'), + path.resolve(__dirname, '../addons/addon-ligatures'), + path.resolve(__dirname, '../addons/addon-search'), + path.resolve(__dirname, '../addons/addon-serialize'), + path.resolve(__dirname, '../addons/addon-unicode11'), + // path.resolve(__dirname, '../addons/addon-unicode-graphemes'), + path.resolve(__dirname, '../addons/addon-web-links'), + path.resolve(__dirname, '../addons/addon-webgl') ]; console.log(`Checking if addons need to be published`); for (const p of addonPackageDirs) { @@ -57,8 +58,9 @@ function checkAndPublishPackage(packageDir) { const packageJson = require(path.join(packageDir, 'package.json')); // Determine if this is a stable or beta release - const publishedVersions = getPublishedVersions(packageJson); - const isStableRelease = !publishedVersions.includes(packageJson.version); + // TODO: Uncomment when publishing 5.4 + // const publishedVersions = getPublishedVersions(packageJson); + const isStableRelease = false; //!publishedVersions.includes(packageJson.version); // Get the next version let nextVersion = isStableRelease ? packageJson.version : getNextBetaVersion(packageJson); @@ -71,7 +73,7 @@ function checkAndPublishPackage(packageDir) { fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2)); // Publish - const args = ['publish']; + const args = ['publish', '--access', 'public']; if (!isStableRelease) { args.push('--tag', 'beta'); } @@ -95,8 +97,7 @@ function checkAndPublishPackage(packageDir) { function getNextBetaVersion(packageJson) { if (!/^\d+\.\d+\.\d+$/.exec(packageJson.version)) { - console.error('The package.json version must be of the form x.y.z'); - process.exit(1); + throw new Error('The package.json version must be of the form x.y.z'); } const tag = 'beta'; const stableVersion = packageJson.version.split('.'); @@ -114,9 +115,30 @@ function getNextBetaVersion(packageJson) { return `${nextStableVersion}-${tag}.${latestTagVersion + 1}`; } +function asArray(value) { + return Array.isArray(value) ? value : [value]; +} + function getPublishedVersions(packageJson, version, tag) { - const versionsProcess = cp.spawnSync('npm', ['view', packageJson.name, 'versions', '--json']); - const versionsJson = JSON.parse(versionsProcess.stdout); + const versionsProcess = cp.spawnSync(os.platform === 'win32' ? 'npm.cmd' : 'npm', ['view', packageJson.name, 'versions', '--json']); + if (versionsProcess.stdout.length === 0 && versionsProcess.stderr) { + const err = versionsProcess.stderr.toString(); + if (err.indexOf('404 Not Found - GET https://registry.npmjs.org/@xterm') > 0) { + return []; + } + throw new Error('Could not get published versions\n' + err); + } + const output = JSON.parse(versionsProcess.stdout); + if (typeof output === 'object' && !Array.isArray(output)) { + if (output.error?.code === 'E404') { + return []; + } + throw new Error('Could not get published versions\n' + output); + } + if (!output || Array.isArray(output) && output.length === 0) { + return []; + } + const versionsJson = asArray(output); if (tag) { return versionsJson.filter(v => !v.search(new RegExp(`${version}-${tag}.[0-9]+`))); } diff --git a/bin/test_playwright.js b/bin/test_playwright.js index 02c2a763..0cd6f85c 100644 --- a/bin/test_playwright.js +++ b/bin/test_playwright.js @@ -19,8 +19,8 @@ while (argv.some(e => e.startsWith('--suite='))) { let configs = [ { name: 'core', path: 'out-test/playwright/playwright.config.js' }, - { name: 'xterm-addon-canvas', path: 'addons/xterm-addon-canvas/out-test/playwright.config.js' }, - { name: 'xterm-addon-webgl', path: 'addons/xterm-addon-webgl/out-test/playwright.config.js' } + { name: 'addon-canvas', path: 'addons/addon-canvas/out-test/playwright.config.js' }, + { name: 'addon-webgl', path: 'addons/addon-webgl/out-test/playwright.config.js' } ]; if (suiteFilter) { diff --git a/css/xterm.css b/css/xterm.css index 74acc267..e97b6439 100644 --- a/css/xterm.css +++ b/css/xterm.css @@ -140,7 +140,7 @@ cursor: crosshair; } -.xterm .xterm-accessibility, +.xterm .xterm-accessibility:not(.debug), .xterm .xterm-message { position: absolute; left: 0; @@ -152,6 +152,15 @@ pointer-events: none; } +.xterm .xterm-accessibility-tree:not(.debug) *::selection { + color: transparent; +} + +.xterm .xterm-accessibility-tree { + user-select: text; + white-space: pre; +} + .xterm .live-region { position: absolute; left: -9999px; diff --git a/demo/client.ts b/demo/client.ts index 78685b87..f88dcff1 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -10,43 +10,43 @@ // Use tsc version (yarn watch) import { Terminal } from '../out/browser/public/Terminal'; -import { AttachAddon } from '../addons/xterm-addon-attach/out/AttachAddon'; -import { CanvasAddon } from '../addons/xterm-addon-canvas/out/CanvasAddon'; +import { AttachAddon } from '../addons/addon-attach/out/AttachAddon'; +import { CanvasAddon } from '../addons/addon-canvas/out/CanvasAddon'; import { ClipboardAddon } from '../addons/xterm-addon-clipboard/out/ClipboardAddon'; -import { FitAddon } from '../addons/xterm-addon-fit/out/FitAddon'; -import { SearchAddon, ISearchOptions } from '../addons/xterm-addon-search/out/SearchAddon'; -import { SerializeAddon } from '../addons/xterm-addon-serialize/out/SerializeAddon'; -import { WebLinksAddon } from '../addons/xterm-addon-web-links/out/WebLinksAddon'; -import { WebglAddon } from '../addons/xterm-addon-webgl/out/WebglAddon'; -import { Unicode11Addon } from '../addons/xterm-addon-unicode11/out/Unicode11Addon'; -import { UnicodeGraphemesAddon } from '../addons/xterm-addon-unicode-graphemes/out/UnicodeGraphemesAddon'; -import { LigaturesAddon } from '../addons/xterm-addon-ligatures/out/LigaturesAddon'; +import { FitAddon } from '../addons/addon-fit/out/FitAddon'; +import { SearchAddon, ISearchOptions } from '../addons/addon-search/out/SearchAddon'; +import { SerializeAddon } from '../addons/addon-serialize/out/SerializeAddon'; +import { WebLinksAddon } from '../addons/addon-web-links/out/WebLinksAddon'; +import { WebglAddon } from '../addons/addon-webgl/out/WebglAddon'; +import { Unicode11Addon } from '../addons/addon-unicode11/out/Unicode11Addon'; +import { UnicodeGraphemesAddon } from '../addons/addon-unicode-graphemes/out/UnicodeGraphemesAddon'; +import { LigaturesAddon } from '../addons/addon-ligatures/out/LigaturesAddon'; // Playwright/WebKit on Windows does not support WebAssembly https://stackoverflow.com/q/62311688/1156119 -import type { ImageAddonType, IImageAddonOptions } from '../addons/xterm-addon-image/out/ImageAddon'; +import type { ImageAddonType, IImageAddonOptions } from '../addons/addon-image/out/ImageAddon'; let ImageAddon: ImageAddonType | undefined; // eslint-disable-line @typescript-eslint/naming-convention if ('WebAssembly' in window) { - const imageAddon = require('../addons/xterm-addon-image/out/ImageAddon'); + const imageAddon = require('../addons/addon-image/out/ImageAddon'); ImageAddon = imageAddon.ImageAddon; } // Use webpacked version (yarn package) // import { Terminal } from '../lib/xterm'; -// import { AttachAddon } from 'xterm-addon-attach'; +// import { AttachAddon } from '@xterm/addon-attach'; // import { ClipboardAddon } from 'xterm-addon-clipboard'; -// import { FitAddon } from 'xterm-addon-fit'; -// import { ImageAddon } from 'xterm-addon-image'; -// import { SearchAddon, ISearchOptions } from 'xterm-addon-search'; -// import { SerializeAddon } from 'xterm-addon-serialize'; -// import { WebLinksAddon } from 'xterm-addon-web-links'; -// import { WebglAddon } from 'xterm-addon-webgl'; -// import { Unicode11Addon } from 'xterm-addon-unicode11'; -// import { UnicodeGraphemesAddon } from 'xterm-addon-unicode-graphemes'; -// import { LigaturesAddon } from 'xterm-addon-ligatures'; +// import { FitAddon } from '@xterm/addon-fit'; +// import { ImageAddon } from '@xterm/addon-image'; +// import { SearchAddon, ISearchOptions } from '@xterm/addon-search'; +// import { SerializeAddon } from '@xterm/addon-serialize'; +// import { WebLinksAddon } from '@xterm/addon-web-links'; +// import { WebglAddon } from '@@xterm/addon-webgl'; +// import { Unicode11Addon } from '@xterm/addon-unicode11'; +// import { UnicodeGraphemesAddon } from '@xterm/addon-unicode-graphemes'; +// import { LigaturesAddon } from '@xterm/addon-ligatures'; // Pulling in the module's types relies on the above, it's looks a // little weird here as we're importing "this" module -import { Terminal as TerminalType, ITerminalOptions } from 'xterm'; +import { Terminal as TerminalType, ITerminalOptions } from '@xterm/xterm'; export interface IWindowWithTerminal extends Window { term: TerminalType; diff --git a/demo/tsconfig.json b/demo/tsconfig.json index d4c2abd4..ac318daa 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -6,14 +6,14 @@ "sourceMap": true, "baseUrl": ".", "paths": { - "xterm-addon-attach": ["../addons/xterm-addon-attach"], + "addon-attach": ["../addons/addon-attach"], "xterm-addon-clipboard": ["../addons/xterm-addon-clipboard"], - "xterm-addon-fit": ["../addons/xterm-addon-fit"], - "xterm-addon-image": ["../addons/xterm-addon-image"], - "xterm-addon-search": ["../addons/xterm-addon-search"], - "xterm-addon-serialize": ["../addons/xterm-addon-serialize"], - "xterm-addon-web-links": ["../addons/xterm-addon-web-links"], - "xterm-addon-webgl": ["../addons/xterm-addon-webgl"] + "addon-fit": ["../addons/addon-fit"], + "addon-image": ["../addons/addon-image"], + "addon-search": ["../addons/addon-search"], + "addon-serialize": ["../addons/addon-serialize"], + "addon-web-links": ["../addons/addon-web-links"], + "addon-webgl": ["../addons/addon-webgl"] } }, "include": [ diff --git a/headless/README.md b/headless/README.md index 1d2d6156..205fd79c 100644 --- a/headless/README.md +++ b/headless/README.md @@ -15,7 +15,7 @@ npm install xterm-headless Then import as you would a regular node package. The recommended way to load `xterm-headless` is with TypeScript and the ES6 module syntax: ```javascript -import { Terminal } from 'xterm-headless'; +import { Terminal } from '@xterm/headless'; ``` ## API diff --git a/package.json b/package.json index 70e0f4a9..d0510e5d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "xterm", + "name": "@xterm/xterm", "description": "Full xterm terminal, in your browser", "version": "5.3.0", "main": "lib/xterm.js", diff --git a/src/browser/AccessibilityManager.ts b/src/browser/AccessibilityManager.ts index 5f529589..68c65ebd 100644 --- a/src/browser/AccessibilityManager.ts +++ b/src/browser/AccessibilityManager.ts @@ -10,6 +10,7 @@ import { Disposable, toDisposable } from 'common/Lifecycle'; import { ICoreBrowserService, IRenderService } from 'browser/services/Services'; import { IBuffer } from 'common/buffer/Types'; import { IInstantiationService } from 'common/services/Services'; +import { addDisposableDomListener } from 'browser/Lifecycle'; const MAX_ROWS_TO_READ = 20; @@ -18,11 +19,17 @@ const enum BoundaryPosition { BOTTOM } +// Turn this on to unhide the accessibility tree and display it under +// (instead of overlapping with) the terminal. +const DEBUG = false; + export class AccessibilityManager extends Disposable { + private _debugRootContainer: HTMLElement | undefined; private _accessibilityContainer: HTMLElement; private _rowContainer: HTMLElement; private _rowElements: HTMLElement[]; + private _rowColumns: WeakMap = new WeakMap(); private _liveRegion: HTMLElement; private _liveRegionLineCount: number = 0; @@ -80,7 +87,23 @@ export class AccessibilityManager extends Disposable { if (!this._terminal.element) { throw new Error('Cannot enable accessibility before Terminal.open'); } - this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer); + + if (DEBUG) { + this._accessibilityContainer.classList.add('debug'); + this._rowContainer.classList.add('debug'); + + // Use a `
` container so that the css will still apply. + this._debugRootContainer = document.createElement('div'); + this._debugRootContainer.classList.add('xterm'); + + this._debugRootContainer.appendChild(document.createTextNode('------start a11y------')); + this._debugRootContainer.appendChild(this._accessibilityContainer); + this._debugRootContainer.appendChild(document.createTextNode('------end a11y------')); + + this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer); + } else { + this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer); + } this.register(this._terminal.onResize(e => this._handleResize(e.rows))); this.register(this._terminal.onRender(e => this._refreshRows(e.start, e.end))); @@ -92,11 +115,16 @@ export class AccessibilityManager extends Disposable { this.register(this._terminal.onKey(e => this._handleKey(e.key))); this.register(this._terminal.onBlur(() => this._clearLiveRegion())); this.register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions())); + this.register(addDisposableDomListener(document, 'selectionchange', () => this._handleSelectionChange())); this.register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions())); this._refreshRows(); this.register(toDisposable(() => { - this._accessibilityContainer.remove(); + if (DEBUG) { + this._debugRootContainer!.remove(); + } else { + this._accessibilityContainer.remove(); + } this._rowElements.length = 0; })); } @@ -149,14 +177,18 @@ export class AccessibilityManager extends Disposable { const buffer: IBuffer = this._terminal.buffer; const setSize = buffer.lines.length.toString(); for (let i = start; i <= end; i++) { - const lineData = buffer.translateBufferLineToString(buffer.ydisp + i, true); + const line = buffer.lines.get(buffer.ydisp + i); + const columns: number[] = []; + const lineData = line?.translateToString(true, undefined, undefined, columns) || ''; const posInSet = (buffer.ydisp + i + 1).toString(); const element = this._rowElements[i]; if (element) { if (lineData.length === 0) { element.innerText = '\u00a0'; + this._rowColumns.set(element, [0, 1]); } else { element.textContent = lineData; + this._rowColumns.set(element, columns); } element.setAttribute('aria-posinset', posInSet); element.setAttribute('aria-setsize', setSize); @@ -233,6 +265,103 @@ export class AccessibilityManager extends Disposable { e.stopImmediatePropagation(); } + private _handleSelectionChange(): void { + if (this._rowElements.length === 0) { + return; + } + + const selection = document.getSelection(); + if (!selection) { + return; + } + + if (selection.isCollapsed) { + // Only do something when the anchorNode is inside the row container. This + // behavior mirrors what we do with mouse --- if the mouse clicks + // somewhere outside of the terminal, we don't clear the selection. + if (this._rowContainer.contains(selection.anchorNode)) { + this._terminal.clearSelection(); + } + return; + } + + if (!selection.anchorNode || !selection.focusNode) { + console.error('anchorNode and/or focusNode are null'); + return; + } + + // Sort the two selection points in document order. + let begin = { node: selection.anchorNode, offset: selection.anchorOffset }; + let end = { node: selection.focusNode, offset: selection.focusOffset }; + if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) { + [begin, end] = [end, begin]; + } + + // Clamp begin/end to the inside of the row container. + if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) { + begin = { node: this._rowElements[0].childNodes[0], offset: 0 }; + } + if (!this._rowContainer.contains(begin.node)) { + // This happens when `begin` is below the last row. + return; + } + const lastRowElement = this._rowElements.slice(-1)[0]; + if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) { + end = { + node: lastRowElement, + offset: lastRowElement.textContent?.length ?? 0 + }; + } + if (!this._rowContainer.contains(end.node)) { + // This happens when `end` is above the first row. + return; + } + + const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => { + // `node` is either the row element or the Text node inside it. + const rowElement: any = node instanceof Text ? node.parentNode : node; + let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1; + if (isNaN(row)) { + console.warn('row is invalid. Race condition?'); + return null; + } + + const columns = this._rowColumns.get(rowElement); + if (!columns) { + console.warn('columns is null. Race condition?'); + return null; + } + + let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1; + if (column >= this._terminal.cols) { + ++row; + column = 0; + } + return { + row, + column + }; + }; + + const beginRowColumn = toRowColumn(begin); + const endRowColumn = toRowColumn(end); + + if (!beginRowColumn || !endRowColumn) { + return; + } + + if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) { + // This should not happen unless we have some bugs. + throw new Error('invalid range'); + } + + this._terminal.select( + beginRowColumn.column, + beginRowColumn.row, + (endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column + ); + } + private _handleResize(rows: number): void { // Remove bottom boundary listener this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener); diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 281bebd5..06b58a30 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -54,7 +54,7 @@ import { evaluateKeyboardEvent } from 'common/input/Keyboard'; import { toRgbString } from 'common/input/XParseColor'; import { DecorationService } from 'common/services/DecorationService'; import { IDecorationService } from 'common/services/Services'; -import { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IClipboardProvider } from 'xterm'; +import { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker, IClipboardProvider } from '@xterm/xterm'; import { WindowsOptionsReportType } from '../common/InputHandler'; import { AccessibilityManager } from './AccessibilityManager'; @@ -577,7 +577,7 @@ export class Terminal extends CoreTerminal implements ITerminal { } private _createRenderer(): IRenderer { - return this._instantiationService.createInstance(DomRenderer, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier2); + return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier2); } /** diff --git a/src/browser/Terminal2.test.ts b/src/browser/Terminal2.test.ts index 4965e8f3..abbb42d3 100644 --- a/src/browser/Terminal2.test.ts +++ b/src/browser/Terminal2.test.ts @@ -9,7 +9,7 @@ import * as os from 'os'; import * as fs from 'fs'; import * as pty from 'node-pty'; import { Terminal } from 'browser/Terminal'; -import { IDisposable } from 'xterm'; +import { IDisposable } from '@xterm/xterm'; // all test files expect terminal in 80x25 const COLS = 80; diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index 3b3f39f6..5ffe1a43 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IDisposable, IMarker, ILinkProvider, IDecorationOptions, IDecoration, IClipboardProvider } from 'xterm'; +import { IDisposable, IMarker, ILinkProvider, IDecorationOptions, IDecoration, IClipboardProvider } from '@xterm/xterm'; import { IEvent, EventEmitter } from 'common/EventEmitter'; import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IMouseService, IRenderService, ISelectionService, IThemeService } from 'browser/services/Services'; import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types'; diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index f2b5e220..b1f31b20 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -6,7 +6,7 @@ import { IEvent } from 'common/EventEmitter'; import { CharData, IColor, ICoreTerminal, ITerminalOptions } from 'common/Types'; import { IBuffer } from 'common/buffer/Types'; -import { IDisposable, Terminal as ITerminalApi } from 'xterm'; +import { IDisposable, Terminal as ITerminalApi } from '@xterm/xterm'; import { IMouseService, IRenderService } from './services/Services'; /** diff --git a/src/browser/public/Terminal.ts b/src/browser/public/Terminal.ts index 808519a5..7af6e4ea 100644 --- a/src/browser/public/Terminal.ts +++ b/src/browser/public/Terminal.ts @@ -13,7 +13,7 @@ import { AddonManager } from 'common/public/AddonManager'; import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi'; import { ParserApi } from 'common/public/ParserApi'; import { UnicodeApi } from 'common/public/UnicodeApi'; -import { IBufferNamespace as IBufferNamespaceApi, IClipboardProvider, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from 'xterm'; +import { IBufferNamespace as IBufferNamespaceApi, IClipboardProvider, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm'; /** * The set of options that only have an effect when set in the Terminal constructor. diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 2e9f3701..1549b130 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -7,9 +7,10 @@ import { DomRendererRowFactory, RowCss } from 'browser/renderer/dom/DomRendererR import { WidthCache } from 'browser/renderer/dom/WidthCache'; import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants'; import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils'; -import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types'; +import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel'; +import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from 'browser/renderer/shared/Types'; import { ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services'; -import { ILinkifier2, ILinkifierEvent, ReadonlyColorSet } from 'browser/Types'; +import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from 'browser/Types'; import { color } from 'common/Color'; import { EventEmitter } from 'common/EventEmitter'; import { Disposable, toDisposable } from 'common/Lifecycle'; @@ -25,7 +26,6 @@ const SELECTION_CLASS = 'xterm-selection'; let nextTerminalId = 1; - /** * A fallback renderer for when canvas is slow. This is not meant to be * particularly fast or feature complete, more just stable and usable for when @@ -41,12 +41,14 @@ export class DomRenderer extends Disposable implements IRenderer { private _rowElements: HTMLElement[] = []; private _selectionContainer: HTMLElement; private _widthCache: WidthCache; + private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel(); public dimensions: IRenderDimensions; public readonly onRequestRedraw = this.register(new EventEmitter()).event; constructor( + private readonly _terminal: ITerminal, private readonly _document: Document, private readonly _element: HTMLElement, private readonly _screenElement: HTMLElement, @@ -291,6 +293,7 @@ export class DomRenderer extends Disposable implements IRenderer { public handleResize(cols: number, rows: number): void { this._refreshRowElements(cols, rows); this._updateDimensions(); + this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode); } public handleCharSizeChanged(): void { @@ -320,11 +323,13 @@ export class DomRenderer extends Disposable implements IRenderer { return; } + this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode); + // Translate from buffer position to viewport position - const viewportStartRow = start[1] - this._bufferService.buffer.ydisp; - const viewportEndRow = end[1] - this._bufferService.buffer.ydisp; - const viewportCappedStartRow = Math.max(viewportStartRow, 0); - const viewportCappedEndRow = Math.min(viewportEndRow, this._bufferService.rows - 1); + const viewportStartRow = this._selectionRenderModel.viewportStartRow; + const viewportEndRow = this._selectionRenderModel.viewportEndRow; + const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow; + const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow; // No need to draw the selection if (viewportCappedStartRow >= this._bufferService.rows || viewportCappedEndRow < 0) { @@ -365,10 +370,16 @@ export class DomRenderer extends Disposable implements IRenderer { */ private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement { const element = this._document.createElement('div'); + const left = colStart * this.dimensions.css.cell.width; + let width = this.dimensions.css.cell.width * (colEnd - colStart); + if (left + width > this.dimensions.css.canvas.width) { + width = this.dimensions.css.canvas.width - left; + } + element.style.height = `${rowCount * this.dimensions.css.cell.height}px`; element.style.top = `${row * this.dimensions.css.cell.height}px`; - element.style.left = `${colStart * this.dimensions.css.cell.width}px`; - element.style.width = `${this.dimensions.css.cell.width * (colEnd - colStart)}px`; + element.style.left = `${left}px`; + element.style.width = `${width}px`; return element; } diff --git a/src/browser/renderer/shared/CellColorResolver.ts b/src/browser/renderer/shared/CellColorResolver.ts index 66e6a344..5837a675 100644 --- a/src/browser/renderer/shared/CellColorResolver.ts +++ b/src/browser/renderer/shared/CellColorResolver.ts @@ -1,10 +1,10 @@ import { ISelectionRenderModel } from 'browser/renderer/shared/Types'; import { ICoreBrowserService, IThemeService } from 'browser/services/Services'; import { ReadonlyColorSet } from 'browser/Types'; -import { Attributes, BgFlags, FgFlags } from 'common/buffer/Constants'; -import { IDecorationService } from 'common/services/Services'; +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 { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; // Work variables to avoid garbage collection let $fg = 0; @@ -13,6 +13,7 @@ let $hasFg = false; let $hasBg = false; let $isSelected = false; let $colors: ReadonlyColorSet | undefined; +let $variantOffset = 0; export class CellColorResolver { /** @@ -27,6 +28,7 @@ export class CellColorResolver { constructor( private readonly _terminal: Terminal, + private readonly _optionService: IOptionsService, private readonly _selectionRenderModel: ISelectionRenderModel, private readonly _decorationService: IDecorationService, private readonly _coreBrowserService: ICoreBrowserService, @@ -38,7 +40,7 @@ export class CellColorResolver { * Resolves colors for the cell, putting the result into the shared {@link result}. This resolves * overrides, inverse and selection for the cell which can then be used to feed into the renderer. */ - public resolve(cell: ICellData, x: number, y: number): void { + public resolve(cell: ICellData, x: number, y: number, deviceCellWidth: number): void { this.result.bg = cell.bg; this.result.fg = cell.fg; this.result.ext = cell.bg & BgFlags.HAS_EXTENDED ? cell.extended.ext : 0; @@ -52,6 +54,13 @@ export class CellColorResolver { $hasFg = false; $isSelected = false; $colors = this._themeService.colors; + $variantOffset = 0; + + const code = cell.getCode(); + if (code !== NULL_CELL_CODE && cell.extended.underlineStyle === UnderlineStyle.DOTTED) { + const lineWidth = Math.max(1, Math.floor(this._optionService.rawOptions.fontSize * this._coreBrowserService.dpr / 15)); + $variantOffset = x * deviceCellWidth % (Math.round(lineWidth) * 2); + } // Apply decorations on the bottom layer this._decorationService.forEachDecorationAtCell(x, y, 'bottom', d => { @@ -133,5 +142,9 @@ export class CellColorResolver { // Use the override if it exists this.result.bg = $hasBg ? $bg : this.result.bg; this.result.fg = $hasFg ? $fg : this.result.fg; + + // Reset overrides variantOffset + this.result.ext &= ~ExtFlags.VARIANT_OFFSET; + this.result.ext |= ($variantOffset << 29) & ExtFlags.VARIANT_OFFSET; } } diff --git a/src/browser/renderer/shared/CharAtlasCache.ts b/src/browser/renderer/shared/CharAtlasCache.ts index 67343912..0a871483 100644 --- a/src/browser/renderer/shared/CharAtlasCache.ts +++ b/src/browser/renderer/shared/CharAtlasCache.ts @@ -4,7 +4,7 @@ */ import { TextureAtlas } from 'browser/renderer/shared/TextureAtlas'; -import { ITerminalOptions, Terminal } from 'xterm'; +import { ITerminalOptions, Terminal } from '@xterm/xterm'; import { ITerminal, ReadonlyColorSet } from 'browser/Types'; import { ICharAtlasConfig, ITextureAtlas } from 'browser/renderer/shared/Types'; import { generateConfig, configEquals } from 'browser/renderer/shared/CharAtlasUtils'; diff --git a/src/browser/renderer/shared/CharAtlasUtils.ts b/src/browser/renderer/shared/CharAtlasUtils.ts index 955bd4e6..f8fe9104 100644 --- a/src/browser/renderer/shared/CharAtlasUtils.ts +++ b/src/browser/renderer/shared/CharAtlasUtils.ts @@ -5,7 +5,7 @@ import { ICharAtlasConfig } from './Types'; import { Attributes } from 'common/buffer/Constants'; -import { ITerminalOptions } from 'xterm'; +import { ITerminalOptions } from '@xterm/xterm'; import { IColorSet, ReadonlyColorSet } from 'browser/Types'; import { NULL_COLOR } from 'common/Color'; diff --git a/src/browser/renderer/shared/RendererUtils.test.ts b/src/browser/renderer/shared/RendererUtils.test.ts new file mode 100644 index 00000000..a050e8a9 --- /dev/null +++ b/src/browser/renderer/shared/RendererUtils.test.ts @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2023 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { computeNextVariantOffset } from 'browser/renderer/shared/RendererUtils'; +import { assert } from 'chai'; + +describe('RendererUtils', () => { + it('computeNextVariantOffset', () => { + const cellWidth = 11; + const doubleCellWidth = 22; + let line = 1; + let variantOffset = 0; + + // should line 1 + // =,_,=_,=_, + let cells = [cellWidth, cellWidth, doubleCellWidth, doubleCellWidth]; + let result = [1, 0, 0, 0]; + for (let index = 0; index < cells.length; index++) { + const cell = cells[index]; + variantOffset = computeNextVariantOffset(cell, line, variantOffset); + assert.equal(variantOffset, result[index]); + } + + // should line 2 + // ==__==__==_,_==__==__==,__==__==__==__==__==__,==__==__==__==__==__==, + line = 2; + variantOffset = 0; + cells = [cellWidth, cellWidth, doubleCellWidth, doubleCellWidth]; + result = [3, 2, 0 ,2]; + for (let index = 0; index < cells.length; index++) { + const cell = cells[index]; + variantOffset = computeNextVariantOffset(cell, line, variantOffset); + assert.equal(variantOffset, result[index]); + } + + // should line 3 + // ===___===__,_===___===_,__===___===___===___==,=___===___===___===___, + line = 3; + variantOffset = 0; + cells = [cellWidth, cellWidth, doubleCellWidth, doubleCellWidth]; + result = [5, 4, 2, 0]; + for (let index = 0; index < cells.length; index++) { + const cell = cells[index]; + variantOffset = computeNextVariantOffset(cell, line, variantOffset); + assert.equal(variantOffset, result[index]); + } + }); +}); diff --git a/src/browser/renderer/shared/RendererUtils.ts b/src/browser/renderer/shared/RendererUtils.ts index 70c9ad86..59b87b0e 100644 --- a/src/browser/renderer/shared/RendererUtils.ts +++ b/src/browser/renderer/shared/RendererUtils.ts @@ -56,3 +56,7 @@ function createDimension(): IDimensions { height: 0 }; } + +export function computeNextVariantOffset(cellWidth: number, lineWidth: number, currentOffset: number = 0): number { + return (cellWidth - (Math.round(lineWidth) * 2 - currentOffset)) % (Math.round(lineWidth) * 2); +} diff --git a/src/browser/renderer/shared/SelectionRenderModel.ts b/src/browser/renderer/shared/SelectionRenderModel.ts index db375778..d3b7a99c 100644 --- a/src/browser/renderer/shared/SelectionRenderModel.ts +++ b/src/browser/renderer/shared/SelectionRenderModel.ts @@ -3,8 +3,9 @@ * @license MIT */ +import { ITerminal } from 'browser/Types'; import { ISelectionRenderModel } from 'browser/renderer/shared/Types'; -import { Terminal } from 'xterm'; +import { Terminal } from '@xterm/xterm'; class SelectionRenderModel implements ISelectionRenderModel { public hasSelection!: boolean; @@ -35,7 +36,7 @@ class SelectionRenderModel implements ISelectionRenderModel { this.selectionEnd = undefined; } - public update(terminal: Terminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void { + public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void { this.selectionStart = start; this.selectionEnd = end; // Selection does not exist @@ -45,8 +46,9 @@ class SelectionRenderModel implements ISelectionRenderModel { } // Translate from buffer position to viewport position - const viewportStartRow = start[1] - terminal.buffer.active.viewportY; - const viewportEndRow = end[1] - terminal.buffer.active.viewportY; + const viewportY = terminal.buffers.active.ydisp; + const viewportStartRow = start[1] - viewportY; + const viewportEndRow = end[1] - viewportY; const viewportCappedStartRow = Math.max(viewportStartRow, 0); const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1); diff --git a/src/browser/renderer/shared/TextureAtlas.ts b/src/browser/renderer/shared/TextureAtlas.ts index 56c77b68..d7f65d00 100644 --- a/src/browser/renderer/shared/TextureAtlas.ts +++ b/src/browser/renderer/shared/TextureAtlas.ts @@ -6,7 +6,7 @@ import { IColorContrastCache } from 'browser/Types'; import { DIM_OPACITY, TEXT_BASELINE } from 'browser/renderer/shared/Constants'; import { tryDrawCustomChar } from 'browser/renderer/shared/CustomGlyphs'; -import { excludeFromContrastRatioDemands, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; +import { computeNextVariantOffset, excludeFromContrastRatioDemands, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; import { IBoundingBox, ICharAtlasConfig, IRasterizedGlyph, ITextureAtlas } from 'browser/renderer/shared/Types'; import { NULL_COLOR, color, rgba } from 'common/Color'; import { EventEmitter } from 'common/EventEmitter'; @@ -545,6 +545,7 @@ export class TextureAtlas implements ITextureAtlas { const yTop = Math.ceil(padding + this._config.deviceCharHeight) - yOffset - (restrictToCellHeight ? lineWidth * 2 : 0); const yMid = yTop + lineWidth; const yBot = yTop + lineWidth * 2; + let nextOffset = this._workAttributeData.getUnderlineVariantOffset(); for (let i = 0; i < chWidth; i++) { this._tmpCtx.save(); @@ -594,9 +595,22 @@ export class TextureAtlas implements ITextureAtlas { ); break; case UnderlineStyle.DOTTED: - this._tmpCtx.setLineDash([Math.round(lineWidth), Math.round(lineWidth)]); - this._tmpCtx.moveTo(xChLeft, yTop); - this._tmpCtx.lineTo(xChRight, yTop); + const offsetWidth = nextOffset === 0 ? 0 : + (nextOffset >= lineWidth ? lineWidth * 2 - nextOffset : lineWidth - nextOffset); + // a line and a gap. + const isLineStart = nextOffset >= lineWidth ? false : true; + if (isLineStart === false || offsetWidth === 0) { + this._tmpCtx.setLineDash([Math.round(lineWidth), Math.round(lineWidth)]); + this._tmpCtx.moveTo(xChLeft + offsetWidth, yTop); + this._tmpCtx.lineTo(xChRight, yTop); + } else { + this._tmpCtx.setLineDash([Math.round(lineWidth), Math.round(lineWidth)]); + this._tmpCtx.moveTo(xChLeft, yTop); + this._tmpCtx.lineTo(xChLeft + offsetWidth, yTop); + this._tmpCtx.moveTo(xChLeft + offsetWidth + lineWidth, yTop); + this._tmpCtx.lineTo(xChRight, yTop); + } + nextOffset = computeNextVariantOffset(xChRight - xChLeft, lineWidth, nextOffset); break; case UnderlineStyle.DASHED: this._tmpCtx.setLineDash([this._config.devicePixelRatio * 4, this._config.devicePixelRatio * 3]); diff --git a/src/browser/renderer/shared/Types.d.ts b/src/browser/renderer/shared/Types.d.ts index a7e55e72..c0d5e9d6 100644 --- a/src/browser/renderer/shared/Types.d.ts +++ b/src/browser/renderer/shared/Types.d.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { FontWeight, Terminal } from 'xterm'; -import { IColorSet } from 'browser/Types'; +import { FontWeight, Terminal } from '@xterm/xterm'; +import { IColorSet, ITerminal } from 'browser/Types'; import { IDisposable } from 'common/Types'; import { IEvent } from 'common/EventEmitter'; @@ -168,6 +168,6 @@ export interface ISelectionRenderModel { readonly selectionStart: [number, number] | undefined; readonly selectionEnd: [number, number] | undefined; clear(): void; - update(terminal: Terminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode?: boolean): void; + update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode?: boolean): void; isCellSelected(terminal: Terminal, x: number, y: number): boolean; } diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 7fd5ad24..b38bffa1 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -50,7 +50,7 @@ const GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': /** * Document xterm VT features here that are currently unsupported */ -// @vt: #E[Supported via xterm-addon-image.] DCS SIXEL "SIXEL Graphics" "DCS Ps ; Ps ; Ps ; q Pt ST" "Draw SIXEL image." +// @vt: #E[Supported via @xterm/addon-image.] DCS SIXEL "SIXEL Graphics" "DCS Ps ; Ps ; Ps ; q Pt ST" "Draw SIXEL image." // @vt: #N DCS DECUDK "User Defined Keys" "DCS Ps ; Ps \| Pt ST" "Definitions for user-defined keys." // @vt: #N DCS XTGETTCAP "Request Terminfo String" "DCS + q Pt ST" "Request Terminfo String." // @vt: #N DCS XTSETTCAP "Set Terminfo Data" "DCS + p Pt ST" "Set Terminfo Data." @@ -523,7 +523,7 @@ export class InputHandler extends Disposable implements IInputHandler { // handle wide chars: reset start_cell-1 if we would overwrite the second cell of a wide char if (this._activeBuffer.x && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x - 1) === 2) { - bufferRow.setCellFromCodePoint(this._activeBuffer.x - 1, 0, 1, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x - 1, 0, 1, curAttr); } let precedingJoinState = this._parser.precedingJoinState; @@ -585,7 +585,7 @@ export class InputHandler extends Disposable implements IInputHandler { } // clear left over cells to the right while (oldCol < cols) { - oldRow.setCellFromCodePoint(oldCol++, 0, 1, curAttr.fg, curAttr.bg, curAttr.extended); + oldRow.setCellFromCodepoint(oldCol++, 0, 1, curAttr); } } else { this._activeBuffer.x = cols - 1; @@ -609,7 +609,7 @@ export class InputHandler extends Disposable implements IInputHandler { bufferRow.addCodepointToCell(this._activeBuffer.x - offset, code, chWidth); for (let delta = chWidth - oldWidth; --delta >= 0; ) { - bufferRow.setCellFromCodePoint(this._activeBuffer.x++, 0, 0, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr); } continue; } @@ -617,17 +617,17 @@ export class InputHandler extends Disposable implements IInputHandler { // insert mode: move characters to right if (insertMode) { // right shift cells according to the width - bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr), curAttr); + bufferRow.insertCells(this._activeBuffer.x, chWidth - oldWidth, this._activeBuffer.getNullCell(curAttr)); // test last cell - since the last cell has only room for // a halfwidth char any fullwidth shifted there is lost // and will be set to empty cell if (bufferRow.getWidth(cols - 1) === 2) { - bufferRow.setCellFromCodePoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr); } } // write current char to buffer and advance cursor - bufferRow.setCellFromCodePoint(this._activeBuffer.x++, code, chWidth, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x++, code, chWidth, curAttr); // fullwidth char - also set next cell to placeholder stub and advance cursor // for graphemes bigger than fullwidth we can simply loop to zero @@ -635,7 +635,7 @@ export class InputHandler extends Disposable implements IInputHandler { if (chWidth > 0) { while (--chWidth) { // other than a regular empty cell a cell following a wide char has no width - bufferRow.setCellFromCodePoint(this._activeBuffer.x++, 0, 0, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x++, 0, 0, curAttr); } } } @@ -644,7 +644,7 @@ export class InputHandler extends Disposable implements IInputHandler { // handle wide chars: reset cell to the right if it is second cell of a wide char if (this._activeBuffer.x < cols && end - start > 0 && bufferRow.getWidth(this._activeBuffer.x) === 0 && !bufferRow.hasContent(this._activeBuffer.x)) { - bufferRow.setCellFromCodePoint(this._activeBuffer.x, 0, 1, curAttr.fg, curAttr.bg, curAttr.extended); + bufferRow.setCellFromCodepoint(this._activeBuffer.x, 0, 1, curAttr); } this._dirtyRowTracker.markDirty(this._activeBuffer.y); @@ -1149,7 +1149,6 @@ export class InputHandler extends Disposable implements IInputHandler { start, end, this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData(), respectProtect ); if (clearWrap) { @@ -1370,8 +1369,7 @@ export class InputHandler extends Disposable implements IInputHandler { line.insertCells( this._activeBuffer.x, params.params[0] || 1, - this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData() + this._activeBuffer.getNullCell(this._eraseAttrData()) ); this._dirtyRowTracker.markDirty(this._activeBuffer.y); } @@ -1397,8 +1395,7 @@ export class InputHandler extends Disposable implements IInputHandler { line.deleteCells( this._activeBuffer.x, params.params[0] || 1, - this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData() + this._activeBuffer.getNullCell(this._eraseAttrData()) ); this._dirtyRowTracker.markDirty(this._activeBuffer.y); } @@ -1465,7 +1462,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.deleteCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1498,7 +1495,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.insertCells(0, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1521,7 +1518,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.insertCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1544,7 +1541,7 @@ export class InputHandler extends Disposable implements IInputHandler { const param = params.params[0] || 1; for (let y = this._activeBuffer.scrollTop; y <= this._activeBuffer.scrollBottom; ++y) { const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!; - line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData()), this._eraseAttrData()); + line.deleteCells(this._activeBuffer.x, param, this._activeBuffer.getNullCell(this._eraseAttrData())); line.isWrapped = false; } this._dirtyRowTracker.markRangeDirty(this._activeBuffer.scrollTop, this._activeBuffer.scrollBottom); @@ -1566,8 +1563,7 @@ export class InputHandler extends Disposable implements IInputHandler { line.replaceCells( this._activeBuffer.x, this._activeBuffer.x + (params.params[0] || 1), - this._activeBuffer.getNullCell(this._eraseAttrData()), - this._eraseAttrData() + this._activeBuffer.getNullCell(this._eraseAttrData()) ); this._dirtyRowTracker.markDirty(this._activeBuffer.y); } diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 8e57664e..39e13fba 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -12,7 +12,7 @@ import { IBufferSet, IBuffer } from 'common/buffer/Types'; import { BufferSet } from 'common/buffer/BufferSet'; import { IDecPrivateModes, ICoreMouseEvent, CoreMouseEventType, ICharset, IModes, IAttributeData, IOscLinkData, IDisposable } from 'common/Types'; import { UnicodeV6 } from 'common/input/UnicodeV6'; -import { IDecorationOptions, IDecoration } from 'xterm'; +import { IDecorationOptions, IDecoration } from '@xterm/xterm'; export class MockBufferService implements IBufferService { public serviceBrand: any; diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index accd6243..440284a8 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -9,7 +9,7 @@ import { Attributes, UnderlineStyle } from 'common/buffer/Constants'; // eslint- import { IBufferSet } from 'common/buffer/Types'; import { IParams } from 'common/parser/Types'; import { ICoreMouseService, ICoreService, IOptionsService, IUnicodeService } from 'common/services/Services'; -import { ClipboardSelectionType as ClipboardSelectionType, IFunctionIdentifier, ITerminalOptions as IPublicTerminalOptions } from 'xterm'; +import { ClipboardSelectionType as ClipboardSelectionType, IFunctionIdentifier, ITerminalOptions as IPublicTerminalOptions } from '@xterm/xterm'; export interface ICoreTerminal { coreMouseService: ICoreMouseService; @@ -119,6 +119,7 @@ export interface IExtendedAttrs { ext: number; underlineStyle: UnderlineStyle; underlineColor: number; + underlineVariantOffset: number; urlId: number; clone(): IExtendedAttrs; isEmpty(): boolean; @@ -209,6 +210,7 @@ export interface IAttributeData { isUnderlineColorPalette(): boolean; isUnderlineColorDefault(): boolean; getUnderlineStyle(): number; + getUnderlineVariantOffset(): number; } /** Cell data */ @@ -233,11 +235,11 @@ export interface IBufferLine { set(index: number, value: CharData): void; loadCell(index: number, cell: ICellData): ICellData; setCell(index: number, cell: ICellData): void; - setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number, eAttrs: IExtendedAttrs): void; + setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void; addCodepointToCell(index: number, codePoint: number, width: number): void; - insertCells(pos: number, n: number, ch: ICellData, eraseAttr?: IAttributeData): void; - deleteCells(pos: number, n: number, fill: ICellData, eraseAttr?: IAttributeData): void; - replaceCells(start: number, end: number, fill: ICellData, eraseAttr?: IAttributeData, respectProtect?: boolean): void; + insertCells(pos: number, n: number, ch: ICellData): void; + deleteCells(pos: number, n: number, fill: ICellData): void; + replaceCells(start: number, end: number, fill: ICellData, respectProtect?: boolean): void; resize(cols: number, fill: ICellData): boolean; cleanupMemory(): number; fill(fillCellData: ICellData, respectProtect?: boolean): void; @@ -245,7 +247,7 @@ export interface IBufferLine { clone(): IBufferLine; getTrimmedLength(): number; getNoBgTrimmedLength(): number; - translateToString(trimRight?: boolean, startCol?: number, endCol?: number): string; + translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string; /* direct access to cell attrs */ getWidth(index: number): number; diff --git a/src/common/buffer/AttributeData.ts b/src/common/buffer/AttributeData.ts index f4d12c2b..6221fb81 100644 --- a/src/common/buffer/AttributeData.ts +++ b/src/common/buffer/AttributeData.ts @@ -126,6 +126,9 @@ export class AttributeData implements IAttributeData { ? (this.bg & BgFlags.HAS_EXTENDED ? this.extended.underlineStyle : UnderlineStyle.SINGLE) : UnderlineStyle.NONE; } + public getUnderlineVariantOffset(): number { + return this.extended.underlineVariantOffset; + } } @@ -174,6 +177,18 @@ export class ExtendedAttrs implements IExtendedAttrs { this._urlId = value; } + public get underlineVariantOffset(): number { + const val = (this._ext & ExtFlags.VARIANT_OFFSET) >> 29; + if (val < 0) { + return val ^ 0xFFFFFFF8; + } + return val; + } + public set underlineVariantOffset(value: number) { + this._ext &= ~ExtFlags.VARIANT_OFFSET; + this._ext |= (value << 29) & ExtFlags.VARIANT_OFFSET; + } + constructor( ext: number = 0, urlId: number = 0 diff --git a/src/common/buffer/BufferLine.test.ts b/src/common/buffer/BufferLine.test.ts index f2819aa8..9d08c2be 100644 --- a/src/common/buffer/BufferLine.test.ts +++ b/src/common/buffer/BufferLine.test.ts @@ -119,6 +119,18 @@ describe('AttributeData', () => { attrs.fg &= ~FgFlags.UNDERLINE; assert.equal(attrs.getUnderlineStyle(), UnderlineStyle.NONE); }); + it('getUnderlineVariantOffset', () => { + const attrs = new AttributeData(); + + // defaults to no offset + assert.equal(attrs.getUnderlineVariantOffset(), 0); + + // should return 0 - 7 + for (let i = 0; i < 8; ++i) { + attrs.extended.underlineVariantOffset = i; + assert.equal(attrs.getUnderlineVariantOffset(), i); + } + }); }); }); @@ -331,56 +343,75 @@ describe('BufferLine', function(): void { describe('translateToString with and w\'o trimming', function(): void { it('empty line', function(): void { const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); - assert.equal(line.translateToString(false), ' '); - assert.equal(line.translateToString(true), ''); + const columns: number[] = []; + assert.equal(line.translateToString(false, undefined, undefined, columns), ' '); + assert.deepEqual(columns, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + assert.equal(line.translateToString(true, undefined, undefined, columns), ''); + assert.deepEqual(columns, [0]); }); it('ASCII', function(): void { + const columns: number[] = []; const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(4, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(5, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); - assert.equal(line.translateToString(false), 'a a aa '); - assert.equal(line.translateToString(true), 'a a aa'); - assert.equal(line.translateToString(false, 0, 5), 'a a a'); - assert.equal(line.translateToString(false, 0, 4), 'a a '); - assert.equal(line.translateToString(false, 0, 3), 'a a'); - assert.equal(line.translateToString(true, 0, 5), 'a a a'); - assert.equal(line.translateToString(true, 0, 4), 'a a '); - assert.equal(line.translateToString(true, 0, 3), 'a a'); + assert.equal(line.translateToString(false, undefined, undefined, columns), 'a a aa '); + assert.deepEqual(columns, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + assert.equal(line.translateToString(true, undefined, undefined, columns), 'a a aa'); + assert.deepEqual(columns, [0, 1, 2, 3, 4, 5, 6]); + for (const trimRight of [true, false]) { + assert.equal(line.translateToString(trimRight, 0, 5, columns), 'a a a'); + assert.deepEqual(columns, [0, 1, 2, 3, 4, 5]); + assert.equal(line.translateToString(trimRight, 0, 4, columns), 'a a '); + assert.deepEqual(columns, [0, 1, 2, 3, 4]); + assert.equal(line.translateToString(trimRight, 0, 3, columns), 'a a'); + assert.deepEqual(columns, [0, 1, 2, 3]); + } }); it('surrogate', function(): void { + const columns: number[] = []; const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([1, '𝄞', 1, '𝄞'.charCodeAt(0)])); line.setCell(4, CellData.fromCharData([1, '𝄞', 1, '𝄞'.charCodeAt(0)])); line.setCell(5, CellData.fromCharData([1, '𝄞', 1, '𝄞'.charCodeAt(0)])); - assert.equal(line.translateToString(false), 'a 𝄞 𝄞𝄞 '); - assert.equal(line.translateToString(true), 'a 𝄞 𝄞𝄞'); - assert.equal(line.translateToString(false, 0, 5), 'a 𝄞 𝄞'); - assert.equal(line.translateToString(false, 0, 4), 'a 𝄞 '); - assert.equal(line.translateToString(false, 0, 3), 'a 𝄞'); - assert.equal(line.translateToString(true, 0, 5), 'a 𝄞 𝄞'); - assert.equal(line.translateToString(true, 0, 4), 'a 𝄞 '); - assert.equal(line.translateToString(true, 0, 3), 'a 𝄞'); + assert.equal(line.translateToString(false, undefined, undefined, columns), 'a 𝄞 𝄞𝄞 '); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10]); + assert.equal(line.translateToString(true, undefined, undefined, columns), 'a 𝄞 𝄞𝄞'); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4, 4, 5, 5, 6]); + for (const trimRight of [true, false]) { + assert.equal(line.translateToString(trimRight, 0, 5, columns), 'a 𝄞 𝄞'); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4, 4, 5]); + assert.equal(line.translateToString(trimRight, 0, 4, columns), 'a 𝄞 '); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4]); + assert.equal(line.translateToString(trimRight, 0, 3, columns), 'a 𝄞'); + assert.deepEqual(columns, [0, 1, 2, 2, 3]); + } }); it('combining', function(): void { + const columns: number[] = []; const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([1, 'e\u0301', 1, '\u0301'.charCodeAt(0)])); line.setCell(4, CellData.fromCharData([1, 'e\u0301', 1, '\u0301'.charCodeAt(0)])); line.setCell(5, CellData.fromCharData([1, 'e\u0301', 1, '\u0301'.charCodeAt(0)])); - assert.equal(line.translateToString(false), 'a e\u0301 e\u0301e\u0301 '); - assert.equal(line.translateToString(true), 'a e\u0301 e\u0301e\u0301'); - assert.equal(line.translateToString(false, 0, 5), 'a e\u0301 e\u0301'); - assert.equal(line.translateToString(false, 0, 4), 'a e\u0301 '); - assert.equal(line.translateToString(false, 0, 3), 'a e\u0301'); - assert.equal(line.translateToString(true, 0, 5), 'a e\u0301 e\u0301'); - assert.equal(line.translateToString(true, 0, 4), 'a e\u0301 '); - assert.equal(line.translateToString(true, 0, 3), 'a e\u0301'); + assert.equal(line.translateToString(false, undefined, undefined, columns), 'a e\u0301 e\u0301e\u0301 '); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10]); + assert.equal(line.translateToString(true, undefined, undefined, columns), 'a e\u0301 e\u0301e\u0301'); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4, 4, 5, 5, 6]); + for (const trimRight of [true, false]) { + assert.equal(line.translateToString(trimRight, 0, 5, columns), 'a e\u0301 e\u0301'); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4, 4, 5]); + assert.equal(line.translateToString(trimRight, 0, 4, columns), 'a e\u0301 '); + assert.deepEqual(columns, [0, 1, 2, 2, 3, 4]); + assert.equal(line.translateToString(trimRight, 0, 3, columns), 'a e\u0301'); + assert.deepEqual(columns, [0, 1, 2, 2, 3]); + } }); it('fullwidth', function(): void { + const columns: number[] = []; const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([1, '1', 2, '1'.charCodeAt(0)])); @@ -389,43 +420,55 @@ describe('BufferLine', function(): void { line.setCell(6, CellData.fromCharData([0, '', 0, 0])); line.setCell(7, CellData.fromCharData([1, '1', 2, '1'.charCodeAt(0)])); line.setCell(8, CellData.fromCharData([0, '', 0, 0])); - assert.equal(line.translateToString(false), 'a 1 11 '); - assert.equal(line.translateToString(true), 'a 1 11'); - assert.equal(line.translateToString(false, 0, 7), 'a 1 1'); - assert.equal(line.translateToString(false, 0, 6), 'a 1 1'); - assert.equal(line.translateToString(false, 0, 5), 'a 1 '); - assert.equal(line.translateToString(false, 0, 4), 'a 1'); - assert.equal(line.translateToString(false, 0, 3), 'a 1'); - assert.equal(line.translateToString(false, 0, 2), 'a '); - assert.equal(line.translateToString(true, 0, 7), 'a 1 1'); - assert.equal(line.translateToString(true, 0, 6), 'a 1 1'); - assert.equal(line.translateToString(true, 0, 5), 'a 1 '); - assert.equal(line.translateToString(true, 0, 4), 'a 1'); - assert.equal(line.translateToString(true, 0, 3), 'a 1'); - assert.equal(line.translateToString(true, 0, 2), 'a '); + assert.equal(line.translateToString(false, undefined, undefined, columns), 'a 1 11 '); + assert.deepEqual(columns, [0, 1, 2, 4, 5, 7, 9, 10]); + assert.equal(line.translateToString(true, undefined, undefined, columns), 'a 1 11'); + assert.deepEqual(columns, [0, 1, 2, 4, 5, 7, 9]); + for (const trimRight of [true, false]) { + assert.equal(line.translateToString(trimRight, 0, 7, columns), 'a 1 1'); + assert.deepEqual(columns, [0, 1, 2, 4, 5, 7]); + assert.equal(line.translateToString(trimRight, 0, 6, columns), 'a 1 1'); + assert.deepEqual(columns, [0, 1, 2, 4, 5, 7]); + assert.equal(line.translateToString(trimRight, 0, 5, columns), 'a 1 '); + assert.deepEqual(columns, [0, 1, 2, 4, 5]); + assert.equal(line.translateToString(trimRight, 0, 4, columns), 'a 1'); + assert.deepEqual(columns, [0, 1, 2, 4]); + assert.equal(line.translateToString(trimRight, 0, 3, columns), 'a 1'); + assert.deepEqual(columns, [0, 1, 2, 4]); + assert.equal(line.translateToString(trimRight, 0, 2, columns), 'a '); + assert.deepEqual(columns, [0, 1, 2]); + } }); it('space at end', function(): void { + const columns: number[] = []; const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(4, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(5, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(6, CellData.fromCharData([1, ' ', 1, ' '.charCodeAt(0)])); - assert.equal(line.translateToString(false), 'a a aa '); - assert.equal(line.translateToString(true), 'a a aa '); + assert.equal(line.translateToString(false, undefined, undefined, columns), 'a a aa '); + assert.deepEqual(columns, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + assert.equal(line.translateToString(true, undefined, undefined, columns), 'a a aa '); + assert.deepEqual(columns, [0, 1, 2, 3, 4, 5, 6, 7]); }); it('should always return some sane value', function(): void { + const columns: number[] = []; // sanity check - broken line with invalid out of bound null width cells // this can atm happen with deleting/inserting chars in inputhandler by "breaking" // fullwidth pairs --> needs to be fixed after settling BufferLine impl const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, 0, NULL_CELL_CODE]), false); - assert.equal(line.translateToString(false), ' '); - assert.equal(line.translateToString(true), ''); + assert.equal(line.translateToString(false, undefined, undefined, columns), ' '); + assert.deepEqual(columns, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + assert.equal(line.translateToString(true, undefined, undefined, columns), ''); + assert.deepEqual(columns, [0]); }); it('should work with endCol=0', () => { + const columns: number[] = []; const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, 0, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); - assert.equal(line.translateToString(true, 0, 0), ''); + assert.equal(line.translateToString(true, 0, 0, columns), ''); + assert.deepEqual(columns, [0]); }); }); describe('addCharToCell', () => { diff --git a/src/common/buffer/BufferLine.ts b/src/common/buffer/BufferLine.ts index a268f2bc..ee3481a2 100644 --- a/src/common/buffer/BufferLine.ts +++ b/src/common/buffer/BufferLine.ts @@ -4,7 +4,7 @@ */ import { CharData, IAttributeData, IBufferLine, ICellData, IExtendedAttrs } from 'common/Types'; -import { AttributeData, ExtendedAttrs } from 'common/buffer/AttributeData'; +import { AttributeData } from 'common/buffer/AttributeData'; import { CellData } from 'common/buffer/CellData'; import { Attributes, BgFlags, CHAR_DATA_ATTR_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, Content, NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR } from 'common/buffer/Constants'; import { stringFromCodePoint } from 'common/input/TextDecoder'; @@ -212,13 +212,13 @@ export class BufferLine implements IBufferLine { * Since the input handler see the incoming chars as UTF32 codepoints, * it gets an optimized access method. */ - public setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number, eAttrs: IExtendedAttrs): void { - if (bg & BgFlags.HAS_EXTENDED) { - this._extendedAttrs[index] = eAttrs; + public setCellFromCodepoint(index: number, codePoint: number, width: number, attrs: IAttributeData): void { + if (attrs.bg & BgFlags.HAS_EXTENDED) { + this._extendedAttrs[index] = attrs.extended; } this._data[index * CELL_SIZE + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT); - this._data[index * CELL_SIZE + Cell.FG] = fg; - this._data[index * CELL_SIZE + Cell.BG] = bg; + this._data[index * CELL_SIZE + Cell.FG] = attrs.fg; + this._data[index * CELL_SIZE + Cell.BG] = attrs.bg; } /** @@ -253,12 +253,12 @@ export class BufferLine implements IBufferLine { this._data[index * CELL_SIZE + Cell.CONTENT] = content; } - public insertCells(pos: number, n: number, fillCellData: ICellData, eraseAttr?: IAttributeData): void { + public insertCells(pos: number, n: number, fillCellData: ICellData): void { pos %= this.length; // handle fullwidth at pos: reset cell one to the left if pos is second cell of a wide char if (pos && this.getWidth(pos - 1) === 2) { - this.setCellFromCodePoint(pos - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData); } if (n < this.length - pos) { @@ -277,11 +277,11 @@ export class BufferLine implements IBufferLine { // handle fullwidth at line end: reset last cell if it is first cell of a wide char if (this.getWidth(this.length - 1) === 2) { - this.setCellFromCodePoint(this.length - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(this.length - 1, 0, 1, fillCellData); } } - public deleteCells(pos: number, n: number, fillCellData: ICellData, eraseAttr?: IAttributeData): void { + public deleteCells(pos: number, n: number, fillCellData: ICellData): void { pos %= this.length; if (n < this.length - pos) { const cell = new CellData(); @@ -301,21 +301,21 @@ export class BufferLine implements IBufferLine { // - reset pos-1 if wide char // - reset pos if width==0 (previous second cell of a wide char) if (pos && this.getWidth(pos - 1) === 2) { - this.setCellFromCodePoint(pos - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(pos - 1, 0, 1, fillCellData); } if (this.getWidth(pos) === 0 && !this.hasContent(pos)) { - this.setCellFromCodePoint(pos, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(pos, 0, 1, fillCellData); } } - public replaceCells(start: number, end: number, fillCellData: ICellData, eraseAttr?: IAttributeData, respectProtect: boolean = false): void { + public replaceCells(start: number, end: number, fillCellData: ICellData, respectProtect: boolean = false): void { // full branching on respectProtect==true, hopefully getting fast JIT for standard case if (respectProtect) { if (start && this.getWidth(start - 1) === 2 && !this.isProtected(start - 1)) { - this.setCellFromCodePoint(start - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(start - 1, 0, 1, fillCellData); } if (end < this.length && this.getWidth(end - 1) === 2 && !this.isProtected(end)) { - this.setCellFromCodePoint(end, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(end, 0, 1, fillCellData); } while (start < end && start < this.length) { if (!this.isProtected(start)) { @@ -328,11 +328,11 @@ export class BufferLine implements IBufferLine { // handle fullwidth at start: reset cell one to the left if start is second cell of a wide char if (start && this.getWidth(start - 1) === 2) { - this.setCellFromCodePoint(start - 1, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(start - 1, 0, 1, fillCellData); } // handle fullwidth at last cell + 1: reset to empty cell if it is second part of a wide char if (end < this.length && this.getWidth(end - 1) === 2) { - this.setCellFromCodePoint(end, 0, 1, eraseAttr?.fg || 0, eraseAttr?.bg || 0, eraseAttr?.extended || new ExtendedAttrs()); + this.setCellFromCodepoint(end, 0, 1, fillCellData); } while (start < end && start < this.length) { @@ -508,16 +508,43 @@ export class BufferLine implements IBufferLine { } } - public translateToString(trimRight: boolean = false, startCol: number = 0, endCol: number = this.length): string { + /** + * Translates the buffer line to a string. + * + * @param trimRight Whether to trim any empty cells on the right. + * @param startCol The column to start the string (0-based inclusive). + * @param endCol The column to end the string (0-based exclusive). + * @param outColumns if specified, this array will be filled with column numbers such that + * `returnedString[i]` is displayed at `outColumns[i]` column. `outColumns[returnedString.length]` + * is where the character following `returnedString` will be displayed. + * + * When a single cell is translated to multiple UTF-16 code units (e.g. surrogate pair) in the + * returned string, the corresponding entries in `outColumns` will have the same column number. + */ + public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string { + startCol = startCol ?? 0; + endCol = endCol ?? this.length; if (trimRight) { endCol = Math.min(endCol, this.getTrimmedLength()); } + if (outColumns) { + outColumns.length = 0; + } let result = ''; while (startCol < endCol) { const content = this._data[startCol * CELL_SIZE + Cell.CONTENT]; const cp = content & Content.CODEPOINT_MASK; - result += (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR; - startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by 1 + const chars = (content & Content.IS_COMBINED_MASK) ? this._combined[startCol] : (cp) ? stringFromCodePoint(cp) : WHITESPACE_CELL_CHAR; + result += chars; + if (outColumns) { + for (let i = 0; i < chars.length; ++i) { + outColumns.push(startCol); + } + } + startCol += (content >> Content.WIDTH_SHIFT) || 1; // always advance by at least 1 + } + if (outColumns) { + outColumns.push(startCol); } return result; } diff --git a/src/common/buffer/BufferRange.test.ts b/src/common/buffer/BufferRange.test.ts index 69aacd99..15d1b831 100644 --- a/src/common/buffer/BufferRange.test.ts +++ b/src/common/buffer/BufferRange.test.ts @@ -5,7 +5,7 @@ import { assert } from 'chai'; import { getRangeLength } from 'common/buffer/BufferRange'; -import { IBufferRange } from 'xterm'; +import { IBufferRange } from '@xterm/xterm'; describe('BufferRange', () => { describe('getRangeLength', () => { diff --git a/src/common/buffer/BufferRange.ts b/src/common/buffer/BufferRange.ts index a49cf481..aa7ee405 100644 --- a/src/common/buffer/BufferRange.ts +++ b/src/common/buffer/BufferRange.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IBufferRange } from 'xterm'; +import { IBufferRange } from '@xterm/xterm'; export function getRangeLength(range: IBufferRange, bufferCols: number): number { if (range.start.y > range.end.y) { diff --git a/src/common/buffer/Constants.ts b/src/common/buffer/Constants.ts index f6a31be7..5ce075cf 100644 --- a/src/common/buffer/Constants.ts +++ b/src/common/buffer/Constants.ts @@ -134,9 +134,17 @@ export const enum BgFlags { export const enum ExtFlags { /** - * bit 27..32 (upper 3 unused) + * bit 27..29 */ - UNDERLINE_STYLE = 0x1C000000 + UNDERLINE_STYLE = 0x1C000000, + + /** + * bit 30..32 + * + * An optional variant for the glyph, this can be used for example to offset underlines by a + * number of pixels to create a perfect pattern. + */ + VARIANT_OFFSET = 0xE0000000 } export const enum UnderlineStyle { diff --git a/src/common/input/Keyboard.test.ts b/src/common/input/Keyboard.test.ts index f2d0936b..c598fc58 100644 --- a/src/common/input/Keyboard.test.ts +++ b/src/common/input/Keyboard.test.ts @@ -106,6 +106,21 @@ describe('Keyboard', () => { it('should return \\x1b[5B for ctrl+down', () => { assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B }); + it('should return \\x08 for ctrl+backspace', () => { + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 8 }).key, '\x08'); + }); + it('should return \\x1b\\x7f for alt+backspace', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 8 }).key, '\x1b\x7f'); + }); + it('should return \\x1b\\x08 for ctrl+alt+backspace', () => { + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, altKey: true, keyCode: 8 }).key, '\x1b\x08'); + }); + it('should return \\x1b[3;2~ for shift+delete', () => { + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~'); + }); + it('should return \\x1b[3;3~ for alt+delete', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~'); + }); describe('On non-macOS platforms', () => { // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100 diff --git a/src/common/input/Keyboard.ts b/src/common/input/Keyboard.ts index 9420a974..b86eeac4 100644 --- a/src/common/input/Keyboard.ts +++ b/src/common/input/Keyboard.ts @@ -83,11 +83,10 @@ export function evaluateKeyboardEvent( break; case 8: // backspace + result.key = ev.ctrlKey ? '\b' : C0.DEL; // ^H or ^? if (ev.altKey) { - result.key = C0.ESC + C0.DEL; // \e ^? - break; + result.key = C0.ESC + result.key; } - result.key = C0.DEL; // ^? break; case 9: // tab diff --git a/src/common/public/AddonManager.test.ts b/src/common/public/AddonManager.test.ts index e947976a..239952ee 100644 --- a/src/common/public/AddonManager.test.ts +++ b/src/common/public/AddonManager.test.ts @@ -5,7 +5,7 @@ import { assert } from 'chai'; import { AddonManager, ILoadedAddon } from './AddonManager'; -import { ITerminalAddon } from 'xterm'; +import { ITerminalAddon } from '@xterm/xterm'; class TestAddonManager extends AddonManager { public get addons(): ILoadedAddon[] { diff --git a/src/common/public/AddonManager.ts b/src/common/public/AddonManager.ts index af04a269..9a36e2a0 100644 --- a/src/common/public/AddonManager.ts +++ b/src/common/public/AddonManager.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ITerminalAddon, IDisposable, Terminal } from 'xterm'; +import { ITerminalAddon, IDisposable, Terminal } from '@xterm/xterm'; export interface ILoadedAddon { instance: ITerminalAddon; diff --git a/src/common/public/BufferApiView.ts b/src/common/public/BufferApiView.ts index ca9ef2d8..834cedbe 100644 --- a/src/common/public/BufferApiView.ts +++ b/src/common/public/BufferApiView.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from 'xterm'; +import { IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from '@xterm/xterm'; import { IBuffer } from 'common/buffer/Types'; import { BufferLineApiView } from 'common/public/BufferLineApiView'; import { CellData } from 'common/buffer/CellData'; diff --git a/src/common/public/BufferLineApiView.ts b/src/common/public/BufferLineApiView.ts index 60375015..560dd0bf 100644 --- a/src/common/public/BufferLineApiView.ts +++ b/src/common/public/BufferLineApiView.ts @@ -5,7 +5,7 @@ import { CellData } from 'common/buffer/CellData'; import { IBufferLine, ICellData } from 'common/Types'; -import { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from 'xterm'; +import { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@xterm/xterm'; export class BufferLineApiView implements IBufferLineApi { constructor(private _line: IBufferLine) { } diff --git a/src/common/public/BufferNamespaceApi.ts b/src/common/public/BufferNamespaceApi.ts index aeaa4ac8..cef0ed16 100644 --- a/src/common/public/BufferNamespaceApi.ts +++ b/src/common/public/BufferNamespaceApi.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from 'xterm'; +import { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from '@xterm/xterm'; import { BufferApiView } from 'common/public/BufferApiView'; import { EventEmitter } from 'common/EventEmitter'; import { ICoreTerminal } from 'common/Types'; diff --git a/src/common/public/ParserApi.ts b/src/common/public/ParserApi.ts index 67df4be5..afcc01be 100644 --- a/src/common/public/ParserApi.ts +++ b/src/common/public/ParserApi.ts @@ -4,7 +4,7 @@ */ import { IParams } from 'common/parser/Types'; -import { IDisposable, IFunctionIdentifier, IParser } from 'xterm'; +import { IDisposable, IFunctionIdentifier, IParser } from '@xterm/xterm'; import { ICoreTerminal } from 'common/Types'; export class ParserApi implements IParser { diff --git a/src/common/public/UnicodeApi.ts b/src/common/public/UnicodeApi.ts index 8a669a05..ec9bd1f7 100644 --- a/src/common/public/UnicodeApi.ts +++ b/src/common/public/UnicodeApi.ts @@ -4,7 +4,7 @@ */ import { ICoreTerminal } from 'common/Types'; -import { IUnicodeHandling, IUnicodeVersionProvider } from 'xterm'; +import { IUnicodeHandling, IUnicodeVersionProvider } from '@xterm/xterm'; export class UnicodeApi implements IUnicodeHandling { constructor(private _core: ICoreTerminal) { } diff --git a/src/common/services/DecorationService.ts b/src/common/services/DecorationService.ts index 36faa509..da759152 100644 --- a/src/common/services/DecorationService.ts +++ b/src/common/services/DecorationService.ts @@ -9,7 +9,7 @@ import { Disposable, toDisposable } from 'common/Lifecycle'; import { IDecorationService, IInternalDecoration } from 'common/services/Services'; import { SortedList } from 'common/SortedList'; import { IColor } from 'common/Types'; -import { IDecoration, IDecorationOptions, IMarker } from 'xterm'; +import { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm'; // Work variables to avoid garbage collection let $xmin = 0; diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index e7108855..dd8da94b 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -7,7 +7,7 @@ import { IEvent, IEventEmitter } from 'common/EventEmitter'; import { IBuffer, IBufferSet } from 'common/buffer/Types'; import { IDecPrivateModes, ICoreMouseEvent, CoreMouseEncoding, ICoreMouseProtocol, CoreMouseEventType, ICharset, IWindowOptions, IModes, IAttributeData, ScrollSource, IDisposable, IColor, CursorStyle, CursorInactiveStyle, IOscLinkData } from 'common/Types'; import { createDecorator } from 'common/services/ServiceRegistry'; -import { IDecorationOptions, IDecoration, ILinkHandler, IWindowsPty, ILogger } from 'xterm'; +import { IDecorationOptions, IDecoration, ILinkHandler, IWindowsPty, ILogger } from '@xterm/xterm'; export const IBufferService = createDecorator('BufferService'); export interface IBufferService { diff --git a/src/headless/public/Terminal.test.ts b/src/headless/public/Terminal.test.ts index f869a991..2175c668 100644 --- a/src/headless/public/Terminal.test.ts +++ b/src/headless/public/Terminal.test.ts @@ -5,7 +5,7 @@ import { deepStrictEqual, strictEqual, throws } from 'assert'; import { Terminal } from 'headless/public/Terminal'; -import { ITerminalOptions } from 'xterm-headless'; +import { ITerminalOptions } from '@xterm/headless'; let term: Terminal; diff --git a/src/headless/public/Terminal.ts b/src/headless/public/Terminal.ts index b018d37c..df202660 100644 --- a/src/headless/public/Terminal.ts +++ b/src/headless/public/Terminal.ts @@ -7,7 +7,7 @@ import { IEvent } from 'common/EventEmitter'; import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi'; import { ParserApi } from 'common/public/ParserApi'; import { UnicodeApi } from 'common/public/UnicodeApi'; -import { IBufferNamespace as IBufferNamespaceApi, IMarker, IModes, IParser, ITerminalAddon, ITerminalInitOnlyOptions, IUnicodeHandling, Terminal as ITerminalApi } from 'xterm-headless'; +import { IBufferNamespace as IBufferNamespaceApi, IMarker, IModes, IParser, ITerminalAddon, ITerminalInitOnlyOptions, IUnicodeHandling, Terminal as ITerminalApi } from '@xterm/headless'; import { Terminal as TerminalCore } from 'headless/Terminal'; import { AddonManager } from 'common/public/AddonManager'; import { ITerminalOptions } from 'common/Types'; diff --git a/src/headless/tsconfig.json b/src/headless/tsconfig.json index b579af97..e48c4fd5 100644 --- a/src/headless/tsconfig.json +++ b/src/headless/tsconfig.json @@ -17,7 +17,7 @@ }, "include": [ "./**/*", - "../../typings/xterm.d.ts", // common/Types.d.ts imports from 'xterm' + "../../typings/xterm.d.ts", // common/Types.d.ts imports from '@xterm/xterm' "../../typings/xterm-headless.d.ts" ], "references": [ diff --git a/test/api/TestUtils.ts b/test/api/TestUtils.ts index a6bf51fc..cee59cce 100644 --- a/test/api/TestUtils.ts +++ b/test/api/TestUtils.ts @@ -5,7 +5,7 @@ import * as playwright from '@playwright/test'; import deepEqual = require('deep-equal'); -import { ITerminalInitOnlyOptions, ITerminalOptions } from 'xterm'; +import { ITerminalInitOnlyOptions, ITerminalOptions } from '@xterm/xterm'; import { deepStrictEqual } from 'assert'; export async function pollFor(page: playwright.Page, evalOrFn: string | (() => Promise), val: T, preFn?: () => Promise, maxDuration?: number): Promise { diff --git a/test/playwright/MouseTracking.test.ts b/test/playwright/MouseTracking.test.ts index dbce55cd..1cefd7cd 100644 --- a/test/playwright/MouseTracking.test.ts +++ b/test/playwright/MouseTracking.test.ts @@ -4,7 +4,7 @@ */ import { test } from '@playwright/test'; import { deepStrictEqual, ok, strictEqual } from 'assert'; -import type { IDisposable } from 'xterm'; +import type { IDisposable } from '@xterm/xterm'; import { createTestContext, ITestContext, openTerminal, pollFor } from './TestUtils'; let ctx: ITestContext; diff --git a/test/playwright/Parser.test.ts b/test/playwright/Parser.test.ts index 42406270..b793b00e 100644 --- a/test/playwright/Parser.test.ts +++ b/test/playwright/Parser.test.ts @@ -4,7 +4,7 @@ */ import { test } from '@playwright/test'; import { deepStrictEqual, ok, strictEqual } from 'assert'; -import type { IDisposable } from 'xterm'; +import type { IDisposable } from '@xterm/xterm'; import { createTestContext, ITestContext, openTerminal, pollFor } from './TestUtils'; let ctx: ITestContext; diff --git a/test/playwright/SharedRendererTests.ts b/test/playwright/SharedRendererTests.ts index eaa54d12..aa747277 100644 --- a/test/playwright/SharedRendererTests.ts +++ b/test/playwright/SharedRendererTests.ts @@ -5,7 +5,7 @@ import { IImage32, decodePng } from '@lunapaint/png-codec'; import { LocatorScreenshotOptions, test } from '@playwright/test'; -import { ITheme } from 'xterm'; +import { ITheme } from '@xterm/xterm'; import { ITestContext, MaybeAsync, openTerminal, pollFor, pollForApproximate } from './TestUtils'; export interface ISharedRendererTestContext { @@ -1171,9 +1171,35 @@ export function injectSharedRendererTests(ctx: ISharedRendererTestContext): void await ctx.value.proxy.selectAll(); await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, 1), [0, 0, 255, 255]); }); + test('#4799: cursor should be in the correct position', async () => { + const theme: ITheme = { + cursor: '#0000FF' + }; + await ctx.value.page.evaluate(`window.term.options.theme = ${JSON.stringify(theme)};`); + for (let index = 0; index < 160; index++) { + await ctx.value.proxy.writeln(``); + } + await ctx.value.proxy.focus(); + await ctx.value.proxy.write('\x1b[A'); + await ctx.value.proxy.write('\x1b[A'); + await ctx.value.proxy.scrollLines(-2); + const rows = await ctx.value.proxy.rows; + // block cursor style + await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, rows), [0, 0, 255, 255]); + await ctx.value.proxy.blur(); + frameDetails = undefined; + // outlink cursor style + await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, rows), [0, 0, 0, 255]); + await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, rows, CellColorPosition.FIRST), [0, 0, 255, 255]); + }); }); } +enum CellColorPosition { + CENTER = 0, + FIRST = 1 +} + /** * Injects shared renderer tests where it's required to re-initialize the terminal for each test. * This is much slower than just calling `Terminal.reset` but testing some features needs this @@ -1214,11 +1240,16 @@ export function injectSharedRendererTestsStandalone(ctx: ISharedRendererTestCont * @param col The 1-based column index to get the color for. * @param row The 1-based row index to get the color for. */ -function getCellColor(ctx: ITestContext, col: number, row: number): MaybeAsync<[red: number, green: number, blue: number, alpha: number]> { +function getCellColor(ctx: ITestContext, col: number, row: number, position: CellColorPosition = CellColorPosition.CENTER): MaybeAsync<[red: number, green: number, blue: number, alpha: number]> { if (!frameDetails) { return getFrameDetails(ctx).then(frameDetails => getCellColorInner(frameDetails, col, row)); } - return getCellColorInner(frameDetails, col, row); + switch (position) { + case CellColorPosition.CENTER: + return getCellColorInner(frameDetails, col, row); + case CellColorPosition.FIRST: + return getCellColorFirstPoint(frameDetails, col, row); + } } let frameDetails: { cols: number, rows: number, decoded: IImage32 } | undefined = undefined; @@ -1244,6 +1275,17 @@ function getCellColorInner(frameDetails: { cols: number, rows: number, decoded: return Array.from(frameDetails.decoded.data.slice(i, i + 4)) as [number, number, number, number]; } +function getCellColorFirstPoint(frameDetails: { cols: number, rows: number, decoded: IImage32 }, col: number, row: number): [red: number, green: number, blue: number, alpha: number] { + const cellSize = { + width: frameDetails.decoded.width / frameDetails.cols, + height: frameDetails.decoded.height / frameDetails.rows + }; + const x = Math.floor((col - 1/* 1- to 0-based index */) * cellSize.width); + const y = Math.floor((row - 1/* 1- to 0-based index */) * cellSize.height); + const i = (y * frameDetails.decoded.width + x) * 4/* 4 channels per pixel */; + return Array.from(frameDetails.decoded.data.slice(i, i + 4)) as [number, number, number, number]; +} + const COLORS_16_TO_255 = [ '#000000', '#00005f', '#000087', '#0000af', '#0000d7', '#0000ff', '#005f00', '#005f5f', '#005f87', '#005faf', '#005fd7', '#005fff', '#008700', '#00875f', '#008787', '#0087af', '#0087d7', '#0087ff', '#00af00', '#00af5f', '#00af87', '#00afaf', '#00afd7', '#00afff', '#00d700', '#00d75f', '#00d787', '#00d7af', '#00d7d7', '#00d7ff', '#00ff00', '#00ff5f', diff --git a/test/playwright/TestUtils.ts b/test/playwright/TestUtils.ts index d58aa88e..e21d2d96 100644 --- a/test/playwright/TestUtils.ts +++ b/test/playwright/TestUtils.ts @@ -10,7 +10,7 @@ import type { IRenderService } from 'browser/services/Services'; import type { ICoreTerminal, IMarker } from 'common/Types'; import * as playwright from '@playwright/test'; import { PageFunction } from 'playwright-core/types/structs'; -import { IBuffer, IBufferCell, IBufferLine, IBufferNamespace, IBufferRange, IDecoration, IDecorationOptions, IModes, ITerminalInitOnlyOptions, ITerminalOptions, Terminal } from 'xterm'; +import { IBuffer, IBufferCell, IBufferLine, IBufferNamespace, IBufferRange, IDecoration, IDecorationOptions, IModes, ITerminalInitOnlyOptions, ITerminalOptions, Terminal } from '@xterm/xterm'; import { EventEmitter } from '../../out/common/EventEmitter'; export interface ITestContext { diff --git a/tsconfig.all.json b/tsconfig.all.json index d09638e4..2092992c 100644 --- a/tsconfig.all.json +++ b/tsconfig.all.json @@ -7,17 +7,17 @@ { "path": "./test/api" }, { "path": "./test/benchmark" }, { "path": "./test/playwright" }, - { "path": "./addons/xterm-addon-attach" }, - { "path": "./addons/xterm-addon-canvas" }, + { "path": "./addons/addon-attach" }, + { "path": "./addons/addon-canvas" }, { "path": "./addons/xterm-addon-clipboard" }, - { "path": "./addons/xterm-addon-fit" }, - { "path": "./addons/xterm-addon-image" }, - { "path": "./addons/xterm-addon-ligatures" }, - { "path": "./addons/xterm-addon-search" }, - { "path": "./addons/xterm-addon-serialize" }, - { "path": "./addons/xterm-addon-unicode11" }, - { "path": "./addons/xterm-addon-unicode-graphemes" }, - { "path": "./addons/xterm-addon-web-links" }, - { "path": "./addons/xterm-addon-webgl" } + { "path": "./addons/addon-fit" }, + { "path": "./addons/addon-image" }, + { "path": "./addons/addon-ligatures" }, + { "path": "./addons/addon-search" }, + { "path": "./addons/addon-serialize" }, + { "path": "./addons/addon-unicode11" }, + { "path": "./addons/addon-unicode-graphemes" }, + { "path": "./addons/addon-web-links" }, + { "path": "./addons/addon-webgl" } ] } diff --git a/typings/xterm-headless.d.ts b/typings/xterm-headless.d.ts index 99aa8237..f8cef382 100644 --- a/typings/xterm-headless.d.ts +++ b/typings/xterm-headless.d.ts @@ -7,7 +7,7 @@ * to be stable and consumed by external programs. */ -declare module 'xterm-headless' { +declare module '@xterm/headless' { /** * A string representing log level. */ diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index d93e1d4c..41478a03 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -9,7 +9,7 @@ /// -declare module 'xterm' { +declare module '@xterm/xterm' { /** * A string or number representing text font weight. */ diff --git a/webpack.config.js b/webpack.config.js index ca7c059a..3769bfb0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -39,8 +39,10 @@ const config = { output: { filename: 'xterm.js', path: path.resolve('./lib'), - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, - mode: 'production' + mode: 'production', }; module.exports = config;