diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index cf878cbc..d6863ebe 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -233,6 +233,10 @@ export class MockBuffer implements IBuffer { public savedY!: number; public savedX!: number; public savedCharset: ICharset | undefined; + public savedCharsets: (ICharset | undefined)[] = []; + public savedGlevel: number = 0; + public savedOriginMode: boolean = false; + public savedWraparoundMode: boolean = true; public savedCurAttrData = new AttributeData(); public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string { return Buffer.prototype.translateBufferLineToString.apply(this, arguments as any); diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index d21e674f..ee12e9a0 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -199,6 +199,28 @@ describe('InputHandler', () => { assert.equal(bufferService.buffer.y, 2); assert.equal(inputHandler.curAttrData.fg, 3); }); + describe('DECSC/DECRC - save and restore cursor', () => { + it('should save and restore origin mode', async () => { + assert.equal(coreService.decPrivateModes.origin, false); + await inputHandler.parseP('\x1b[?6h'); + assert.equal(coreService.decPrivateModes.origin, true); + await inputHandler.parseP('\x1b7'); + await inputHandler.parseP('\x1b[?6l'); + assert.equal(coreService.decPrivateModes.origin, false); + await inputHandler.parseP('\x1b8'); + assert.equal(coreService.decPrivateModes.origin, true); + }); + it('should save and restore wraparound mode', async () => { + assert.equal(coreService.decPrivateModes.wraparound, true); + await inputHandler.parseP('\x1b[?7l'); + assert.equal(coreService.decPrivateModes.wraparound, false); + await inputHandler.parseP('\x1b7'); + await inputHandler.parseP('\x1b[?7h'); + assert.equal(coreService.decPrivateModes.wraparound, true); + await inputHandler.parseP('\x1b8'); + assert.equal(coreService.decPrivateModes.wraparound, false); + }); + }); describe('setCursorStyle', () => { it('should call Terminal.setOption with correct params', () => { inputHandler.setCursorStyle(Params.fromArray([0])); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index f9fbe3d7..10e69bbb 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2929,6 +2929,10 @@ export class InputHandler extends Disposable implements IInputHandler { this._activeBuffer.savedCurAttrData.fg = this._curAttrData.fg; this._activeBuffer.savedCurAttrData.bg = this._curAttrData.bg; this._activeBuffer.savedCharset = this._charsetService.charset; + this._activeBuffer.savedCharsets = this._charsetService.charsets.slice(); + this._activeBuffer.savedGlevel = this._charsetService.glevel; + this._activeBuffer.savedOriginMode = this._coreService.decPrivateModes.origin; + this._activeBuffer.savedWraparoundMode = this._coreService.decPrivateModes.wraparound; return true; } @@ -2946,10 +2950,12 @@ export class InputHandler extends Disposable implements IInputHandler { this._activeBuffer.y = Math.max(this._activeBuffer.savedY - this._activeBuffer.ybase, 0); this._curAttrData.fg = this._activeBuffer.savedCurAttrData.fg; this._curAttrData.bg = this._activeBuffer.savedCurAttrData.bg; - this._charsetService.charset = (this as any)._savedCharset; - if (this._activeBuffer.savedCharset) { - this._charsetService.charset = this._activeBuffer.savedCharset; + for (let i = 0; i < this._activeBuffer.savedCharsets.length; i++) { + this._charsetService.setgCharset(i, this._activeBuffer.savedCharsets[i]); } + this._charsetService.setgLevel(this._activeBuffer.savedGlevel); + this._coreService.decPrivateModes.origin = this._activeBuffer.savedOriginMode; + this._coreService.decPrivateModes.wraparound = this._activeBuffer.savedWraparoundMode; this._restrictCursor(); return true; } diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 70ff8fe6..ef9140e4 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -80,9 +80,18 @@ export class MockCharsetService implements ICharsetService { public serviceBrand: any; public charset: ICharset | undefined; public glevel: number = 0; + public charsets: (ICharset | undefined)[] = []; public reset(): void { } - public setgLevel(g: number): void { } - public setgCharset(g: number, charset: ICharset): void { } + public setgLevel(g: number): void { + this.glevel = g; + this.charset = this.charsets[g]; + } + public setgCharset(g: number, charset: ICharset | undefined): void { + this.charsets[g] = charset; + if (this.glevel === g) { + this.charset = charset; + } + } } export class MockCoreService implements ICoreService { diff --git a/src/common/buffer/Buffer.ts b/src/common/buffer/Buffer.ts index 21bb47dc..48236bc6 100644 --- a/src/common/buffer/Buffer.ts +++ b/src/common/buffer/Buffer.ts @@ -38,6 +38,10 @@ export class Buffer implements IBuffer { public savedX: number = 0; public savedCurAttrData = DEFAULT_ATTR_DATA.clone(); public savedCharset: ICharset | undefined = DEFAULT_CHARSET; + public savedCharsets: (ICharset | undefined)[] = []; + public savedGlevel: number = 0; + public savedOriginMode: boolean = false; + public savedWraparoundMode: boolean = true; public markers: Marker[] = []; private _nullCell: ICellData = CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); private _whitespaceCell: ICellData = CellData.fromCharData([0, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE]); diff --git a/src/common/buffer/Types.ts b/src/common/buffer/Types.ts index a59c0e17..c6e7a53f 100644 --- a/src/common/buffer/Types.ts +++ b/src/common/buffer/Types.ts @@ -22,6 +22,10 @@ export interface IBuffer { savedY: number; savedX: number; savedCharset: ICharset | undefined; + savedCharsets: (ICharset | undefined)[]; + savedGlevel: number; + savedOriginMode: boolean; + savedWraparoundMode: boolean; savedCurAttrData: IAttributeData; isCursorInViewport: boolean; markers: IMarker[]; diff --git a/src/common/services/CharsetService.ts b/src/common/services/CharsetService.ts index c5381065..bcd027a6 100644 --- a/src/common/services/CharsetService.ts +++ b/src/common/services/CharsetService.ts @@ -14,6 +14,10 @@ export class CharsetService implements ICharsetService { private _charsets: (ICharset | undefined)[] = []; + public get charsets(): (ICharset | undefined)[] { + return this._charsets; + } + public reset(): void { this.charset = undefined; this._charsets = []; diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index a73d99f3..3febd907 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -116,6 +116,7 @@ export interface ICharsetService { charset: ICharset | undefined; readonly glevel: number; + readonly charsets: (ICharset | undefined)[]; reset(): void;