diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index f8b8b3e4..115ccce7 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -53,6 +53,7 @@ import { Linkifier2 } from 'browser/Linkifier2'; import { CoreBrowserService } from 'browser/services/CoreBrowserService'; import { CoreTerminal } from 'common/CoreTerminal'; import { ITerminalOptions as IInitializedTerminalOptions } from 'common/services/Services'; +import { css } from 'browser/Color'; // Let it work inside Node.js for automated testing purposes. const document: Document = (typeof window !== 'undefined') ? window.document : null as any; @@ -150,6 +151,7 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type))); this.register(forwardEvent(this._inputHandler.onCursorMove, this._onCursorMove)); this.register(forwardEvent(this._inputHandler.onTitleChange, this._onTitleChange)); + this.register(this._inputHandler.onAnsiColorChange((index, color) => this.changeAnsiColor(index, color))); this.register(forwardEvent(this._inputHandler.onA11yChar, this._onA11yCharEmitter)); this.register(forwardEvent(this._inputHandler.onA11yTab, this._onA11yTabEmitter)); @@ -157,6 +159,21 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows))); } + private changeAnsiColor(colorIndex: number, colorValue: string): void { + // colorValue = rgb:xx/yy/zz + const r = colorValue.substring(4, 6); + const g = colorValue.substring(7, 9); + const b = colorValue.substring(10, 12); + const color = `#${r}${g}${b}`; + + //TODO: remove debug + console.log(`Change ANSI color[${colorIndex}]=${colorValue} (${color})`); + + this._colorManager!.colors.ansi[colorIndex] = css.toColor(color); + this._renderService?.setColors(this._colorManager!.colors); + this.viewport?.onThemeChange(this._colorManager!.colors); + } + public dispose(): void { if (this._isDisposed) { return; diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index dbf695e6..3dd0c11b 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -250,6 +250,8 @@ export class InputHandler extends Disposable implements IInputHandler { public get onScroll(): IEvent { return this._onScroll.event; } private _onTitleChange = new EventEmitter(); public get onTitleChange(): IEvent { return this._onTitleChange.event; } + private _onAnsiColorChange = new EventEmitter(); + public get onAnsiColorChange(): IEvent { return this._onAnsiColorChange.event; } constructor( private readonly _bufferService: IBufferService, @@ -372,6 +374,12 @@ export class InputHandler extends Disposable implements IInputHandler { this._parser.setOscHandler(2, new OscHandler((data: string) => this.setTitle(data))); // 3 - set property X in the form "prop=value" // 4 - Change Color Number + this._parser.setOscHandler(4, new OscHandler((data: string) => { + const ansiColor = data.split(';'); + const colorIndex = parseInt(ansiColor[0]); + const colorValue = ansiColor[1]; + this.setAnsiColor(colorIndex, colorValue); + })); // 5 - Change Special Color Number // 6 - Enable/disable Special Color Number c // 7 - current directory? (not in xterm spec, see https://gitlab.com/gnachman/iterm2/issues/3939) @@ -2711,6 +2719,15 @@ export class InputHandler extends Disposable implements IInputHandler { this._iconName = data; } + /** + * OSC 4; ; ST (set ANSI color to ) + */ + public setAnsiColor(colorIndex: number, colorData: string): void { + //TODO: remove debug + console.log(`Setting ANSI color ${colorIndex} to value ${colorData}`); + this._onAnsiColorChange.fire(colorIndex, colorData); + } + /** * ESC E * C1.NEL diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index bd0d11c6..00497932 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -389,6 +389,7 @@ export interface IInputHandler { /** CSI ' ~ */ deleteColumns(params: IParams): void; /** OSC 0 OSC 2 */ setTitle(data: string): void; + /** OSC 4 */ setAnsiColor(colorIndex: number, colorData: string): void; /** ESC E */ nextLine(): void; /** ESC = */ keypadApplicationMode(): void; /** ESC > */ keypadNumericMode(): void;