From 5b4d794f7a1621b642f46135298747990532b2b5 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 29 Dec 2025 06:17:36 -0800 Subject: [PATCH] Report underline attributes in demo cell inspector --- .../components/window/cellInspectorWindow.ts | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/demo/client/components/window/cellInspectorWindow.ts b/demo/client/components/window/cellInspectorWindow.ts index 8d3b0330..6a6f67d7 100644 --- a/demo/client/components/window/cellInspectorWindow.ts +++ b/demo/client/components/window/cellInspectorWindow.ts @@ -8,6 +8,25 @@ import type { IControlWindow } from '../controlBar'; import type { Terminal, IBufferCell } from '@xterm/xterm'; import type { AddonCollection } from '../../types'; +// Underline style values from common/buffer/Constants.ts +const enum UnderlineStyle { + NONE = 0, + SINGLE = 1, + DOUBLE = 2, + CURLY = 3, + DOTTED = 4, + DASHED = 5 +} + +// Internal interface for accessing extended attribute data +interface IAttributeDataInternal { + getUnderlineStyle(): number; + getUnderlineColor(): number; + isUnderlineColorDefault(): boolean; + isUnderlineColorPalette(): boolean; + isUnderlineColorRGB(): boolean; +} + export class CellInspectorWindow extends BaseWindow implements IControlWindow { public readonly id = 'cell-inspector'; public readonly label = 'Cell Inspector'; @@ -157,7 +176,23 @@ export class CellInspectorWindow extends BaseWindow implements IControlWindow { if (cell.isBold()) attrs.push('bold (1)'); if (cell.isDim()) attrs.push('dim (2)'); if (cell.isItalic()) attrs.push('italic (3)'); - if (cell.isUnderline()) attrs.push('underline (4)'); + if (cell.isUnderline()) { + const cellData = cell as unknown as IAttributeDataInternal; + const style = cellData.getUnderlineStyle(); + const styleName = this._getUnderlineStyleName(style); + attrs.push(`underline ${styleName} (4:${style})`); + + // Show underline color if not default + if (!cellData.isUnderlineColorDefault()) { + const color = cellData.getUnderlineColor(); + const colorStr = this._formatUnderlineColor( + color, + cellData.isUnderlineColorPalette(), + cellData.isUnderlineColorRGB() + ); + attrs.push(`underline color: ${colorStr}`); + } + } if (cell.isBlink()) attrs.push('blink (5)'); if (cell.isInverse()) attrs.push('inverse (7)'); if (cell.isInvisible()) attrs.push('invisible (8)'); @@ -215,4 +250,29 @@ export class CellInspectorWindow extends BaseWindow implements IControlWindow { } return `unknown(${color})`; } + + private _getUnderlineStyleName(style: UnderlineStyle): string { + switch (style) { + case UnderlineStyle.NONE: return 'none'; + case UnderlineStyle.SINGLE: return 'single'; + case UnderlineStyle.DOUBLE: return 'double'; + case UnderlineStyle.CURLY: return 'curly'; + case UnderlineStyle.DOTTED: return 'dotted'; + case UnderlineStyle.DASHED: return 'dashed'; + default: return 'unknown'; + } + } + + private _formatUnderlineColor(color: number, isPalette: boolean, isRGB: boolean): string { + if (isPalette) { + return `palette(${color}) (58;5;${color})`; + } + if (isRGB) { + const r = (color >> 16) & 0xFF; + const g = (color >> 8) & 0xFF; + const b = color & 0xFF; + return `#${color.toString(16).toUpperCase().padStart(6, '0')} (58;2;${r};${g};${b})`; + } + return `unknown(${color})`; + } }