From 5660c404f0811deb45b7683cd5c46cb8bca22103 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 28 Jul 2023 16:32:05 -0700 Subject: [PATCH] Differentiate special color indexes and others --- src/browser/Terminal.ts | 8 +++--- src/browser/services/Services.ts | 5 ++-- src/browser/services/ThemeService.ts | 12 ++++---- src/common/InputHandler.test.ts | 42 ++++++++++++++-------------- src/common/InputHandler.ts | 10 +++---- src/common/Types.d.ts | 12 ++++---- 6 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index f5957076..7b407957 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -35,7 +35,7 @@ import * as Strings from 'browser/LocalizableStrings'; import { AccessibilityManager } from './AccessibilityManager'; import { ITheme, IMarker, IDisposable, ILinkProvider, IDecorationOptions, IDecoration } from 'xterm'; import { DomRenderer } from 'browser/renderer/dom/DomRenderer'; -import { KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, ColorRequestType, ColorIndexValue } from 'common/Types'; +import { KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, ColorRequestType, SpecialColorIndex } from 'common/Types'; import { evaluateKeyboardEvent } from 'common/input/Keyboard'; import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; @@ -203,15 +203,15 @@ export class Terminal extends CoreTerminal implements ITerminal { let acc: 'foreground' | 'background' | 'cursor' | 'ansi'; let ident = ''; switch (req.index) { - case ColorIndexValue.FOREGROUND: // OSC 10 | 110 + case SpecialColorIndex.FOREGROUND: // OSC 10 | 110 acc = 'foreground'; ident = '10'; break; - case ColorIndexValue.BACKGROUND: // OSC 11 | 111 + case SpecialColorIndex.BACKGROUND: // OSC 11 | 111 acc = 'background'; ident = '11'; break; - case ColorIndexValue.CURSOR: // OSC 12 | 112 + case SpecialColorIndex.CURSOR: // OSC 12 | 112 acc = 'cursor'; ident = '12'; break; diff --git a/src/browser/services/Services.ts b/src/browser/services/Services.ts index 76a0f7df..d96285f7 100644 --- a/src/browser/services/Services.ts +++ b/src/browser/services/Services.ts @@ -8,8 +8,7 @@ import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types'; import { IColorSet, ReadonlyColorSet } from 'browser/Types'; import { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types'; import { createDecorator } from 'common/services/ServiceRegistry'; -import { ColorIndex, IDisposable } from 'common/Types'; -import { ITheme } from 'common/services/Services'; +import { AllColorIndex, IDisposable } from 'common/Types'; export const ICharSizeService = createDecorator('CharSizeService'); export interface ICharSizeService { @@ -130,7 +129,7 @@ export interface IThemeService { readonly onChangeColors: IEvent; - restoreColor(slot?: ColorIndex): void; + restoreColor(slot?: AllColorIndex): void; /** * Allows external modifying of colors in the theme, this is used instead of {@link colors} to * prevent accidental writes. diff --git a/src/browser/services/ThemeService.ts b/src/browser/services/ThemeService.ts index d810d44b..2411ce85 100644 --- a/src/browser/services/ThemeService.ts +++ b/src/browser/services/ThemeService.ts @@ -10,7 +10,7 @@ import { channels, color, css, NULL_COLOR } from 'common/Color'; import { EventEmitter } from 'common/EventEmitter'; import { Disposable } from 'common/Lifecycle'; import { IOptionsService, ITheme } from 'common/services/Services'; -import { ColorIndex, ColorIndexValue, IColor } from 'common/Types'; +import { ColorIndex, SpecialColorIndex, IColor, AllColorIndex } from 'common/Types'; interface IRestoreColorSet { foreground: IColor; @@ -176,12 +176,12 @@ export class ThemeService extends Disposable implements IThemeService { this._onChangeColors.fire(this.colors); } - public restoreColor(slot?: ColorIndex): void { + public restoreColor(slot?: AllColorIndex): void { this._restoreColor(slot); this._onChangeColors.fire(this.colors); } - private _restoreColor(slot: ColorIndex | undefined): void { + private _restoreColor(slot: AllColorIndex | undefined): void { // unset slot restores all ansi colors if (slot === undefined) { for (let i = 0; i < this._restoreColors.ansi.length; ++i) { @@ -190,13 +190,13 @@ export class ThemeService extends Disposable implements IThemeService { return; } switch (slot) { - case ColorIndexValue.FOREGROUND: + case SpecialColorIndex.FOREGROUND: this._colors.foreground = this._restoreColors.foreground; break; - case ColorIndexValue.BACKGROUND: + case SpecialColorIndex.BACKGROUND: this._colors.background = this._restoreColors.background; break; - case ColorIndexValue.CURSOR: + case SpecialColorIndex.CURSOR: this._colors.cursor = this._restoreColors.cursor; break; default: diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index 9df46838..8f9a988f 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -5,7 +5,7 @@ import { assert } from 'chai'; import { InputHandler } from 'common/InputHandler'; -import { IBufferLine, IAttributeData, IColorEvent, ColorIndex, ColorRequestType, ColorIndexValue } from 'common/Types'; +import { IBufferLine, IAttributeData, IColorEvent, ColorIndex, ColorRequestType, SpecialColorIndex } from 'common/Types'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { CellData } from 'common/buffer/CellData'; import { Attributes, BgFlags, UnderlineStyle } from 'common/buffer/Constants'; @@ -2002,87 +2002,87 @@ describe('InputHandler', () => { inputHandler.onColor(ev => stack.push(ev)); // single foreground query --> color undefined await inputHandler.parseP('\x1b]10;?\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndexValue.FOREGROUND }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: SpecialColorIndex.FOREGROUND }]]); stack.length = 0; // OSC with multiple values maps to OSC 10 & OSC 11 & OSC 12 await inputHandler.parseP('\x1b]10;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndexValue.FOREGROUND }], [{ type: ColorRequestType.REPORT, index: ColorIndexValue.BACKGROUND }], [{ type: ColorRequestType.REPORT, index: ColorIndexValue.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: SpecialColorIndex.FOREGROUND }], [{ type: ColorRequestType.REPORT, index: SpecialColorIndex.BACKGROUND }], [{ type: ColorRequestType.REPORT, index: SpecialColorIndex.CURSOR }]]); stack.length = 0; // set foreground color events await inputHandler.parseP('\x1b]10;rgb:01/02/03\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndexValue.FOREGROUND, color: [1, 2, 3] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: SpecialColorIndex.FOREGROUND, color: [1, 2, 3] }]]); stack.length = 0; await inputHandler.parseP('\x1b]10;#aabbcc\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndexValue.FOREGROUND, color: [170, 187, 204] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: SpecialColorIndex.FOREGROUND, color: [170, 187, 204] }]]); stack.length = 0; // set FG, BG and cursor color at once await inputHandler.parseP('\x1b]10;rgb:aa/bb/cc;#001122;rgb:12/34/56\x07'); assert.deepEqual(stack, [ - [{ type: ColorRequestType.SET, index: ColorIndexValue.FOREGROUND, color: [170, 187, 204] }], - [{ type: ColorRequestType.SET, index: ColorIndexValue.BACKGROUND, color: [0, 17, 34] }], - [{ type: ColorRequestType.SET, index: ColorIndexValue.CURSOR, color: [18, 52, 86] }] + [{ type: ColorRequestType.SET, index: SpecialColorIndex.FOREGROUND, color: [170, 187, 204] }], + [{ type: ColorRequestType.SET, index: SpecialColorIndex.BACKGROUND, color: [0, 17, 34] }], + [{ type: ColorRequestType.SET, index: SpecialColorIndex.CURSOR, color: [18, 52, 86] }] ]); }); it('110: restore FG color', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); await inputHandler.parseP('\x1b]110\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: ColorIndexValue.FOREGROUND }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]]); }); it('11: BG set & query events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); // single background query --> color undefined await inputHandler.parseP('\x1b]11;?\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndexValue.BACKGROUND }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: SpecialColorIndex.BACKGROUND }]]); stack.length = 0; // OSC 11 with multiple values creates only BG and cursor event await inputHandler.parseP('\x1b]11;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndexValue.BACKGROUND }], [{ type: ColorRequestType.REPORT, index: ColorIndexValue.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: SpecialColorIndex.BACKGROUND }], [{ type: ColorRequestType.REPORT, index: SpecialColorIndex.CURSOR }]]); stack.length = 0; // set background color events await inputHandler.parseP('\x1b]11;rgb:01/02/03\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndexValue.BACKGROUND, color: [1, 2, 3] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: SpecialColorIndex.BACKGROUND, color: [1, 2, 3] }]]); stack.length = 0; await inputHandler.parseP('\x1b]11;#aabbcc\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndexValue.BACKGROUND, color: [170, 187, 204] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: SpecialColorIndex.BACKGROUND, color: [170, 187, 204] }]]); stack.length = 0; // set BG and cursor color at once await inputHandler.parseP('\x1b]11;#001122;rgb:12/34/56\x07'); assert.deepEqual(stack, [ - [{ type: ColorRequestType.SET, index: ColorIndexValue.BACKGROUND, color: [0, 17, 34] }], - [{ type: ColorRequestType.SET, index: ColorIndexValue.CURSOR, color: [18, 52, 86] }] + [{ type: ColorRequestType.SET, index: SpecialColorIndex.BACKGROUND, color: [0, 17, 34] }], + [{ type: ColorRequestType.SET, index: SpecialColorIndex.CURSOR, color: [18, 52, 86] }] ]); }); it('111: restore BG color', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); await inputHandler.parseP('\x1b]111\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: ColorIndexValue.BACKGROUND }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]]); }); it('12: cursor color set & query events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); // single cursor query --> color undefined await inputHandler.parseP('\x1b]12;?\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndexValue.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: SpecialColorIndex.CURSOR }]]); stack.length = 0; // OSC 12 with multiple values creates only cursor event await inputHandler.parseP('\x1b]12;?;?;?;?\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: ColorIndexValue.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.REPORT, index: SpecialColorIndex.CURSOR }]]); stack.length = 0; // set cursor color events await inputHandler.parseP('\x1b]12;rgb:01/02/03\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndexValue.CURSOR, color: [1, 2, 3] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: SpecialColorIndex.CURSOR, color: [1, 2, 3] }]]); stack.length = 0; await inputHandler.parseP('\x1b]12;#aabbcc\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: ColorIndexValue.CURSOR, color: [170, 187, 204] }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: SpecialColorIndex.CURSOR, color: [170, 187, 204] }]]); }); it('112: restore cursor color', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); await inputHandler.parseP('\x1b]112\x07'); - assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: ColorIndexValue.CURSOR }]]); + assert.deepEqual(stack, [[{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]]); }); }); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index be1277b0..fb8862a0 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -4,7 +4,7 @@ * @license MIT */ -import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, ColorIndexValue } from 'common/Types'; +import { IInputHandler, IAttributeData, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from 'common/Types'; import { C0, C1 } from 'common/data/EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from 'common/data/Charsets'; import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser'; @@ -2988,7 +2988,7 @@ export class InputHandler extends Disposable implements IInputHandler { } // special colors - OSC 10 | 11 | 12 - private _specialColors = [ColorIndexValue.FOREGROUND, ColorIndexValue.BACKGROUND, ColorIndexValue.CURSOR]; + private _specialColors = [SpecialColorIndex.FOREGROUND, SpecialColorIndex.BACKGROUND, SpecialColorIndex.CURSOR]; /** * Apply colors requests for special colors in OSC 10 | 11 | 12. @@ -3090,7 +3090,7 @@ export class InputHandler extends Disposable implements IInputHandler { * @vt: #Y OSC 110 "Restore default foreground color" "OSC 110 BEL" "Restore default foreground to themed color." */ public restoreFgColor(data: string): boolean { - this._onColor.fire([{ type: ColorRequestType.RESTORE, index: ColorIndexValue.FOREGROUND }]); + this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.FOREGROUND }]); return true; } @@ -3100,7 +3100,7 @@ export class InputHandler extends Disposable implements IInputHandler { * @vt: #Y OSC 111 "Restore default background color" "OSC 111 BEL" "Restore default background to themed color." */ public restoreBgColor(data: string): boolean { - this._onColor.fire([{ type: ColorRequestType.RESTORE, index: ColorIndexValue.BACKGROUND }]); + this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.BACKGROUND }]); return true; } @@ -3110,7 +3110,7 @@ export class InputHandler extends Disposable implements IInputHandler { * @vt: #Y OSC 112 "Restore default cursor color" "OSC 112 BEL" "Restore default cursor to themed color." */ public restoreCursorColor(data: string): boolean { - this._onColor.fire([{ type: ColorRequestType.RESTORE, index: ColorIndexValue.CURSOR }]); + this._onColor.fire([{ type: ColorRequestType.RESTORE, index: SpecialColorIndex.CURSOR }]); return true; } diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 6268b77a..8fc7fe35 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -420,25 +420,25 @@ type Enumerate = Acc['length'] exte : Enumerate; type IntRange = Exclude, Enumerate>; -type ColorIndex = IntRange<0, 259>; // number from 0 to 258 - -export const enum ColorIndexValue { +type ColorIndex = IntRange<0, 256>; // number from 0 to 255 +type AllColorIndex = ColorIndex | SpecialColorIndex; +export const enum SpecialColorIndex { FOREGROUND = 256, BACKGROUND = 257, CURSOR = 258 } export interface IColorReportRequest { type: ColorRequestType.REPORT; - index: ColorIndex; + index: AllColorIndex; } export interface IColorSetRequest { type: ColorRequestType.SET; - index: ColorIndex; + index: AllColorIndex; color: IColorRGB; } export interface IColorRestoreRequest { type: ColorRequestType.RESTORE; - index?: ColorIndex; + index?: SpecialColorIndex; } export type IColorEvent = (IColorReportRequest | IColorSetRequest | IColorRestoreRequest)[];