Skip to content

Commit 065eb13

Browse files
authored
Merge pull request #2751 from jerch/underline_core
Underline styles and colors - core part
2 parents 3ea9a75 + 07862c2 commit 065eb13

9 files changed

Lines changed: 846 additions & 177 deletions

File tree

src/common/InputHandler.test.ts

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { InputHandler } from 'common/InputHandler';
88
import { IBufferLine, IAttributeData } from 'common/Types';
99
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
1010
import { CellData } from 'common/buffer/CellData';
11-
import { Attributes } from 'common/buffer/Constants';
11+
import { Attributes, UnderlineStyle } from 'common/buffer/Constants';
1212
import { AttributeData } from 'common/buffer/AttributeData';
1313
import { Params } from 'common/parser/Params';
1414
import { MockCoreService, MockBufferService, MockDirtyRowService, MockOptionsService, MockLogService, MockCoreMouseService, MockCharsetService, MockUnicodeService } from 'common/TestUtils.test';
@@ -1468,6 +1468,181 @@ describe('InputHandler', () => {
14681468
});
14691469
});
14701470

1471+
describe('extended underline style support (SGR 4)', () => {
1472+
beforeEach(() => {
1473+
bufferService.resize(10, 5);
1474+
});
1475+
it('4 | 24', () => {
1476+
inputHandler.parse('\x1b[4m');
1477+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.SINGLE);
1478+
inputHandler.parse('\x1b[24m');
1479+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1480+
});
1481+
it('21 | 24', () => {
1482+
inputHandler.parse('\x1b[21m');
1483+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DOUBLE);
1484+
inputHandler.parse('\x1b[24m');
1485+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1486+
});
1487+
it('4:1 | 4:0', () => {
1488+
inputHandler.parse('\x1b[4:1m');
1489+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.SINGLE);
1490+
inputHandler.parse('\x1b[4:0m');
1491+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1492+
inputHandler.parse('\x1b[4:1m');
1493+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.SINGLE);
1494+
inputHandler.parse('\x1b[24m');
1495+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1496+
});
1497+
it('4:2 | 4:0', () => {
1498+
inputHandler.parse('\x1b[4:2m');
1499+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DOUBLE);
1500+
inputHandler.parse('\x1b[4:0m');
1501+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1502+
inputHandler.parse('\x1b[4:2m');
1503+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DOUBLE);
1504+
inputHandler.parse('\x1b[24m');
1505+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1506+
});
1507+
it('4:3 | 4:0', () => {
1508+
inputHandler.parse('\x1b[4:3m');
1509+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.CURLY);
1510+
inputHandler.parse('\x1b[4:0m');
1511+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1512+
inputHandler.parse('\x1b[4:3m');
1513+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.CURLY);
1514+
inputHandler.parse('\x1b[24m');
1515+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1516+
});
1517+
it('4:4 | 4:0', () => {
1518+
inputHandler.parse('\x1b[4:4m');
1519+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DOTTED);
1520+
inputHandler.parse('\x1b[4:0m');
1521+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1522+
inputHandler.parse('\x1b[4:4m');
1523+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DOTTED);
1524+
inputHandler.parse('\x1b[24m');
1525+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1526+
});
1527+
it('4:5 | 4:0', () => {
1528+
inputHandler.parse('\x1b[4:5m');
1529+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DASHED);
1530+
inputHandler.parse('\x1b[4:0m');
1531+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1532+
inputHandler.parse('\x1b[4:5m');
1533+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DASHED);
1534+
inputHandler.parse('\x1b[24m');
1535+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.NONE);
1536+
});
1537+
it('4:x --> 4 should revert to single underline', () => {
1538+
inputHandler.parse('\x1b[4:5m');
1539+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.DASHED);
1540+
inputHandler.parse('\x1b[4m');
1541+
assert.equal(inputHandler.curAttrData.getUnderlineStyle(), UnderlineStyle.SINGLE);
1542+
});
1543+
});
1544+
describe('underline colors (SGR 58 & SGR 59)', () => {
1545+
beforeEach(() => {
1546+
bufferService.resize(10, 5);
1547+
});
1548+
it('defaults to FG color', () => {
1549+
for (const s of ['', '\x1b[30m', '\x1b[38;510m', '\x1b[38;2;1;2;3m']) {
1550+
inputHandler.parse(s);
1551+
assert.equal(inputHandler.curAttrData.getUnderlineColor(), inputHandler.curAttrData.getFgColor());
1552+
assert.equal(inputHandler.curAttrData.getUnderlineColorMode(), inputHandler.curAttrData.getFgColorMode());
1553+
assert.equal(inputHandler.curAttrData.isUnderlineColorRGB(), inputHandler.curAttrData.isFgRGB());
1554+
assert.equal(inputHandler.curAttrData.isUnderlineColorPalette(), inputHandler.curAttrData.isFgPalette());
1555+
assert.equal(inputHandler.curAttrData.isUnderlineColorDefault(), inputHandler.curAttrData.isFgDefault());
1556+
}
1557+
});
1558+
it('correctly sets P256/RGB colors', () => {
1559+
inputHandler.parse('\x1b[4m');
1560+
inputHandler.parse('\x1b[58;5;123m');
1561+
assert.equal(inputHandler.curAttrData.getUnderlineColor(), 123);
1562+
assert.equal(inputHandler.curAttrData.getUnderlineColorMode(), Attributes.CM_P256);
1563+
assert.equal(inputHandler.curAttrData.isUnderlineColorRGB(), false);
1564+
assert.equal(inputHandler.curAttrData.isUnderlineColorPalette(), true);
1565+
assert.equal(inputHandler.curAttrData.isUnderlineColorDefault(), false);
1566+
inputHandler.parse('\x1b[58;2::1:2:3m');
1567+
assert.equal(inputHandler.curAttrData.getUnderlineColor(), (1 << 16) | (2 << 8) | 3);
1568+
assert.equal(inputHandler.curAttrData.getUnderlineColorMode(), Attributes.CM_RGB);
1569+
assert.equal(inputHandler.curAttrData.isUnderlineColorRGB(), true);
1570+
assert.equal(inputHandler.curAttrData.isUnderlineColorPalette(), false);
1571+
assert.equal(inputHandler.curAttrData.isUnderlineColorDefault(), false);
1572+
});
1573+
it('P256/RGB persistence', () => {
1574+
const cell = new CellData();
1575+
inputHandler.parse('\x1b[4m');
1576+
inputHandler.parse('\x1b[58;5;123m');
1577+
assert.equal(inputHandler.curAttrData.getUnderlineColor(), 123);
1578+
assert.equal(inputHandler.curAttrData.getUnderlineColorMode(), Attributes.CM_P256);
1579+
assert.equal(inputHandler.curAttrData.isUnderlineColorRGB(), false);
1580+
assert.equal(inputHandler.curAttrData.isUnderlineColorPalette(), true);
1581+
assert.equal(inputHandler.curAttrData.isUnderlineColorDefault(), false);
1582+
inputHandler.parse('ab');
1583+
bufferService.buffer!.lines.get(0)!.loadCell(1, cell);
1584+
assert.equal(cell.getUnderlineColor(), 123);
1585+
assert.equal(cell.getUnderlineColorMode(), Attributes.CM_P256);
1586+
assert.equal(cell.isUnderlineColorRGB(), false);
1587+
assert.equal(cell.isUnderlineColorPalette(), true);
1588+
assert.equal(cell.isUnderlineColorDefault(), false);
1589+
1590+
inputHandler.parse('\x1b[4:0m');
1591+
assert.equal(inputHandler.curAttrData.getUnderlineColor(), inputHandler.curAttrData.getFgColor());
1592+
assert.equal(inputHandler.curAttrData.getUnderlineColorMode(), inputHandler.curAttrData.getFgColorMode());
1593+
assert.equal(inputHandler.curAttrData.isUnderlineColorRGB(), inputHandler.curAttrData.isFgRGB());
1594+
assert.equal(inputHandler.curAttrData.isUnderlineColorPalette(), inputHandler.curAttrData.isFgPalette());
1595+
assert.equal(inputHandler.curAttrData.isUnderlineColorDefault(), inputHandler.curAttrData.isFgDefault());
1596+
inputHandler.parse('a');
1597+
bufferService.buffer!.lines.get(0)!.loadCell(1, cell);
1598+
assert.equal(cell.getUnderlineColor(), 123);
1599+
assert.equal(cell.getUnderlineColorMode(), Attributes.CM_P256);
1600+
assert.equal(cell.isUnderlineColorRGB(), false);
1601+
assert.equal(cell.isUnderlineColorPalette(), true);
1602+
assert.equal(cell.isUnderlineColorDefault(), false);
1603+
bufferService.buffer!.lines.get(0)!.loadCell(2, cell);
1604+
assert.equal(cell.getUnderlineColor(), inputHandler.curAttrData.getFgColor());
1605+
assert.equal(cell.getUnderlineColorMode(), inputHandler.curAttrData.getFgColorMode());
1606+
assert.equal(cell.isUnderlineColorRGB(), inputHandler.curAttrData.isFgRGB());
1607+
assert.equal(cell.isUnderlineColorPalette(), inputHandler.curAttrData.isFgPalette());
1608+
assert.equal(cell.isUnderlineColorDefault(), inputHandler.curAttrData.isFgDefault());
1609+
1610+
inputHandler.parse('\x1b[4m');
1611+
inputHandler.parse('\x1b[58;2::1:2:3m');
1612+
assert.equal(inputHandler.curAttrData.getUnderlineColor(), (1 << 16) | (2 << 8) | 3);
1613+
assert.equal(inputHandler.curAttrData.getUnderlineColorMode(), Attributes.CM_RGB);
1614+
assert.equal(inputHandler.curAttrData.isUnderlineColorRGB(), true);
1615+
assert.equal(inputHandler.curAttrData.isUnderlineColorPalette(), false);
1616+
assert.equal(inputHandler.curAttrData.isUnderlineColorDefault(), false);
1617+
inputHandler.parse('a');
1618+
inputHandler.parse('\x1b[24m');
1619+
bufferService.buffer!.lines.get(0)!.loadCell(1, cell);
1620+
assert.equal(cell.getUnderlineColor(), 123);
1621+
assert.equal(cell.getUnderlineColorMode(), Attributes.CM_P256);
1622+
assert.equal(cell.isUnderlineColorRGB(), false);
1623+
assert.equal(cell.isUnderlineColorPalette(), true);
1624+
assert.equal(cell.isUnderlineColorDefault(), false);
1625+
bufferService.buffer!.lines.get(0)!.loadCell(3, cell);
1626+
assert.equal(cell.getUnderlineColor(), (1 << 16) | (2 << 8) | 3);
1627+
assert.equal(cell.getUnderlineColorMode(), Attributes.CM_RGB);
1628+
assert.equal(cell.isUnderlineColorRGB(), true);
1629+
assert.equal(cell.isUnderlineColorPalette(), false);
1630+
assert.equal(cell.isUnderlineColorDefault(), false);
1631+
1632+
// eAttrs in buffer pos 0 and 1 should be the same object
1633+
assert.equal(
1634+
(bufferService.buffer!.lines.get(0)! as any)._extendedAttrs[0],
1635+
(bufferService.buffer!.lines.get(0)! as any)._extendedAttrs[1]
1636+
);
1637+
// should not have written eAttr for pos 2 in the buffer
1638+
assert.equal((bufferService.buffer!.lines.get(0)! as any)._extendedAttrs[2], undefined);
1639+
// eAttrs in buffer pos 1 and pos 3 must be different objs
1640+
assert.notEqual(
1641+
(bufferService.buffer!.lines.get(0)! as any)._extendedAttrs[1],
1642+
(bufferService.buffer!.lines.get(0)! as any)._extendedAttrs[3]
1643+
);
1644+
});
1645+
});
14711646
describe('DECSTR', () => {
14721647
beforeEach(() => {
14731648
bufferService.resize(10, 5);

0 commit comments

Comments
 (0)