From d7cebc312eb1301983dbe4b35ecb7968c39671b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 7 Jan 2025 19:21:51 +0100 Subject: [PATCH] use event from xterm.js instead of own impl --- addons/addon-progress/src/ProgressAddon.ts | 47 +++++-------------- addons/addon-progress/src/tsconfig.json | 9 +++- .../typings/addon-progress.d.ts | 8 +--- addons/addon-progress/webpack.config.js | 9 ++++ demo/client.ts | 11 +++-- 5 files changed, 38 insertions(+), 46 deletions(-) diff --git a/addons/addon-progress/src/ProgressAddon.ts b/addons/addon-progress/src/ProgressAddon.ts index 5bee83d61c..5f661a576f 100644 --- a/addons/addon-progress/src/ProgressAddon.ts +++ b/addons/addon-progress/src/ProgressAddon.ts @@ -4,7 +4,9 @@ */ import type { Terminal, ITerminalAddon, IDisposable } from '@xterm/xterm'; -import type { ProgressAddon as IProgressApi, IProgress, ProgressHandler } from '@xterm/addon-progress'; +import type { ProgressAddon as IProgressApi, IProgress } from '@xterm/addon-progress'; +import { Emitter } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; export const enum ProgressState { @@ -32,19 +34,14 @@ function toInt(s: string): number { } -export class ProgressAddon implements ITerminalAddon, IProgressApi { - private _seqHandler: IDisposable | undefined; +export class ProgressAddon extends Disposable implements ITerminalAddon, IProgressApi { private _st: ProgressState = ProgressState.REMOVE; private _pr = 0; - private _handlers: ProgressHandler[] = []; - - public dispose(): void { - this._seqHandler?.dispose(); - this._handlers.length = 0; - } + private readonly _onChange = this._register(new Emitter()); + public readonly onChange = this._onChange.event; public activate(terminal: Terminal): void { - this._seqHandler = terminal.parser.registerOscHandler(9, data => { + this._register(terminal.parser.registerOscHandler(9, data => { if (!data.startsWith('4;')) { return false; } @@ -77,20 +74,7 @@ export class ProgressAddon implements ITerminalAddon, IProgressApi { break; } return true; - }); - } - - public register(handler: ProgressHandler): IDisposable { - const handlers = this._handlers; - handlers.push(handler); - return { - dispose: () => { - const idx = handlers.indexOf(handler); - if (idx !== -1) { - handlers.splice(idx, 1); - } - } - }; + })); } public get progress(): IProgress { @@ -98,17 +82,12 @@ export class ProgressAddon implements ITerminalAddon, IProgressApi { } public set progress(progress: IProgress) { - if (0 <= progress.state && progress.state <= 4) - { - this._st = progress.state; - this._pr = Math.min(Math.max(progress.value, 0), 100); - - // call progress handlers - for (let i = 0; i < this._handlers.length; ++i) { - this._handlers[i](this._st, this._pr); - } - } else { + if (progress.state < 0 || progress.state > 4) { console.warn(`progress state out of bounds, not applied`); + return; } + this._st = progress.state; + this._pr = Math.min(Math.max(progress.value, 0), 100); + this._onChange.fire({ state: this._st, value: this._pr }); } } diff --git a/addons/addon-progress/src/tsconfig.json b/addons/addon-progress/src/tsconfig.json index 8a90d6e358..ffc7b01a58 100644 --- a/addons/addon-progress/src/tsconfig.json +++ b/addons/addon-progress/src/tsconfig.json @@ -12,12 +12,16 @@ "removeComments": true, "strict": true, "types": [ - "../../../node_modules/@types/mocha" + "../../../node_modules/@types/mocha", + "../../../src/vs/typings/thenable" ], "paths": { "browser/*": [ "../../../src/browser/*" ], + "vs/*": [ + "../../../src/vs/*" + ], "@xterm/addon-progress": [ "../typings/addon-progress.d.ts" ] @@ -30,6 +34,9 @@ "references": [ { "path": "../../../src/browser" + }, + { + "path": "../../../src/vs" } ] } diff --git a/addons/addon-progress/typings/addon-progress.d.ts b/addons/addon-progress/typings/addon-progress.d.ts index bd80eeee9f..ba3d0da27f 100644 --- a/addons/addon-progress/typings/addon-progress.d.ts +++ b/addons/addon-progress/typings/addon-progress.d.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { Terminal, ITerminalAddon, IDisposable } from '@xterm/xterm'; +import { Terminal, ITerminalAddon, IDisposable, IEvent } from '@xterm/xterm'; import type { ProgressState } from '../src/ProgressAddon'; declare module '@xterm/addon-progress' { @@ -13,8 +13,7 @@ declare module '@xterm/addon-progress' { public activate(terminal: Terminal): void; public dispose(): void; - /** register progress handler */ - public register(handler: ProgressHandler): IDisposable; + public readonly onChange: IEvent; /** getter / setter for current progress */ public progress: IProgress; @@ -25,7 +24,4 @@ declare module '@xterm/addon-progress' { state: ProgressState; value: number; } - - /** Progress handler type */ - export type ProgressHandler = (state: ProgressState, value: number) => void; } diff --git a/addons/addon-progress/webpack.config.js b/addons/addon-progress/webpack.config.js index a612e29a79..1bf29bfd2c 100644 --- a/addons/addon-progress/webpack.config.js +++ b/addons/addon-progress/webpack.config.js @@ -21,6 +21,15 @@ module.exports = { } ] }, + resolve: { + modules: ['./node_modules'], + extensions: [ '.js' ], + alias: { + common: path.resolve('../../out/common'), + browser: path.resolve('../../out/browser'), + vs: path.resolve('../../out/vs') + } + }, output: { filename: mainFile, path: path.resolve('./lib'), diff --git a/demo/client.ts b/demo/client.ts index 080270976e..0df2d57415 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -21,7 +21,7 @@ import { AttachAddon } from '@xterm/addon-attach'; import { ClipboardAddon } from '@xterm/addon-clipboard'; import { FitAddon } from '@xterm/addon-fit'; import { LigaturesAddon } from '@xterm/addon-ligatures'; -import { ProgressAddon } from '@xterm/addon-progress'; +import { ProgressAddon, IProgress } from '@xterm/addon-progress'; import { SearchAddon, ISearchOptions } from '@xterm/addon-search'; import { SerializeAddon } from '@xterm/addon-serialize'; import { WebLinksAddon } from '@xterm/addon-web-links'; @@ -1454,7 +1454,8 @@ function progressButtons(): void { const STATES = { 0: 'remove', 1: 'set', 2: 'error', 3: 'indeterminate', 4: 'pause' }; const COLORS = { 0: '', 1: 'green', 2: 'red', 3: '', 4: 'yellow' }; - function progressHandler(state: number, value: number) { + function progressHandler(progress: IProgress) { + let {state, value} = progress; // Simulate windows taskbar hack by windows terminal: // Since the taskbar has no means to indicate error/pause state other than by coloring // the current progress, we move 0 to 10% and distribute higher values in the remaining 90 % @@ -1470,11 +1471,11 @@ function progressButtons(): void { } const progressAddon = addons.progress.instance; - progressAddon.register(progressHandler); + progressAddon.onChange(progressHandler); // apply initial state once to make it visible on page load - const {state, value} = progressAddon.progress; - progressHandler(state, value); + const initialProgress = progressAddon.progress; + progressHandler(initialProgress); document.getElementById('progress-run').addEventListener('click', async () => { term.write('\x1b]9;4;0\x1b\\');