Save cursor and restore more modes

Fixes #1526
This commit is contained in:
Daniel Imms
2025-12-30 04:49:54 -08:00
parent a5af434e3e
commit 857c4529cd
8 changed files with 59 additions and 5 deletions
+4
View File
@@ -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);
+22
View File
@@ -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]));
+9 -3
View File
@@ -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;
}
+11 -2
View File
@@ -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 {
+4
View File
@@ -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]);
+4
View File
@@ -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[];
+4
View File
@@ -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 = [];
+1
View File
@@ -116,6 +116,7 @@ export interface ICharsetService {
charset: ICharset | undefined;
readonly glevel: number;
readonly charsets: (ICharset | undefined)[];
reset(): void;