From 6f047aa7ea900539bb278db5d2ce6ac2a41996c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 18 Jun 2019 14:40:15 +0200 Subject: [PATCH] SGR tests, fix bug in 38:5 handling --- src/InputHandler.test.ts | 150 +++++++++++++++++++++++++++++++++++++++ src/InputHandler.ts | 7 ++ 2 files changed, 157 insertions(+) diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 73365af83..ef9bdde40 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -546,4 +546,154 @@ describe('InputHandler', () => { assert.deepEqual(AttributeData.toColorRGB(term.curAttrData.getFgColor()), [5, 0, 0]); }); }); + describe('colon notation', () => { + let termColon: TestTerminal; + let termSemicolon: TestTerminal; + beforeEach(() => { + termColon = new TestTerminal(); + termSemicolon = new TestTerminal(); + }); + describe('should equal to semicolon', () => { + it('CSI 38:2::50:100:150 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2;50;100;150m'); + termColon.writeSync('\x1b[38:2::50:100:150m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 150); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38:2::50:100: m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2;50;100;m'); + termColon.writeSync('\x1b[38:2::50:100:m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38:2::50:: m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2;50;;m'); + termColon.writeSync('\x1b[38:2::50::m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 0 << 8 | 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38:2:::: m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2;;;m'); + termColon.writeSync('\x1b[38:2::::m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 0 << 16 | 0 << 8 | 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38;2::50:100:150 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2;50;100;150m'); + termColon.writeSync('\x1b[38;2::50:100:150m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 150); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38;2;50:100:150 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2;50;100;150m'); + termColon.writeSync('\x1b[38;2;50:100:150m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 150); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38;2;50;100:150 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2;50;100;150m'); + termColon.writeSync('\x1b[38;2;50;100:150m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 150); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38:5:50 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;5;50m'); + termColon.writeSync('\x1b[38:5:50m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFF, 50); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38:5: m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;5;m'); + termColon.writeSync('\x1b[38:5:m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFF, 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38;5:50 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;5;50m'); + termColon.writeSync('\x1b[38;5:50m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFF, 50); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + }); + describe('should fill early sequence end with default of 0', () => { + it('CSI 38:2 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;2m'); + termColon.writeSync('\x1b[38:2m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 0 << 16 | 0 << 8 | 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 38:5 m', () => { + termColon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.curAttrData.fg = 0xFFFFFFFF; + termSemicolon.writeSync('\x1b[38;5m'); + termColon.writeSync('\x1b[38:5m'); + assert.equal(termSemicolon.curAttrData.fg & 0xFF, 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + }); + describe('should not interfere with leading/following SGR attrs', () => { + it('CSI 1 ; 38:2::50:100:150 ; 4 m', () => { + termSemicolon.writeSync('\x1b[1;38;2;50;100;150;4m'); + termColon.writeSync('\x1b[1;38:2::50:100:150;4m'); + assert.equal(!!termSemicolon.curAttrData.isBold(), true); + assert.equal(!!termSemicolon.curAttrData.isUnderline(), true); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 150); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 1 ; 38:2::50:100: ; 4 m', () => { + termSemicolon.writeSync('\x1b[1;38;2;50;100;;4m'); + termColon.writeSync('\x1b[1;38:2::50:100:;4m'); + assert.equal(!!termSemicolon.curAttrData.isBold(), true); + assert.equal(!!termSemicolon.curAttrData.isUnderline(), true); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 1 ; 38:2::50:100 ; 4 m', () => { + termSemicolon.writeSync('\x1b[1;38;2;50;100;;4m'); + termColon.writeSync('\x1b[1;38:2::50:100;4m'); + assert.equal(!!termSemicolon.curAttrData.isBold(), true); + assert.equal(!!termSemicolon.curAttrData.isUnderline(), true); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 50 << 16 | 100 << 8 | 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 1 ; 38:2:: ; 4 m', () => { + termSemicolon.writeSync('\x1b[1;38;2;;;;4m'); + termColon.writeSync('\x1b[1;38:2::;4m'); + assert.equal(!!termSemicolon.curAttrData.isBold(), true); + assert.equal(!!termSemicolon.curAttrData.isUnderline(), true); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + it('CSI 1 ; 38;2:: ; 4 m', () => { + termSemicolon.writeSync('\x1b[1;38;2;;;;4m'); + termColon.writeSync('\x1b[1;38;2::;4m'); + assert.equal(!!termSemicolon.curAttrData.isBold(), true); + assert.equal(!!termSemicolon.curAttrData.isUnderline(), true); + assert.equal(termSemicolon.curAttrData.fg & 0xFFFFFF, 0); + assert.equal(termColon.curAttrData.fg, termSemicolon.curAttrData.fg); + }); + }); + }); }); diff --git a/src/InputHandler.ts b/src/InputHandler.ts index e831b4f45..7698c30e4 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1546,7 +1546,11 @@ export class InputHandler extends Disposable implements IInputHandler { // RGB : [ 38/48, 2, ign, r, g, b] // P256 : [ 38/48, 5, ign, v, ign, ign] const accu = [0, 0, -1, 0, 0, 0]; + + // alignment placeholder for non color space sequences let cSpace = 0; + + // return advance we took in params let advance = 0; do { @@ -1555,6 +1559,9 @@ export class InputHandler extends Disposable implements IInputHandler { const subparams = params.getSubParams(pos + advance); let i = 0; do { + if (accu[1] === 5) { + cSpace = 1; + } accu[advance + i + 1 + cSpace] = subparams[i]; } while (++i < subparams.length && i + advance + 1 + cSpace < accu.length); break;