diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 541547f8..68550c9f 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -1078,4 +1078,31 @@ describe('InputHandler', () => { }); }); }); + describe('DECSTBM - scroll margins', () => { + let term: TestTerminal; + beforeEach(() => { + term = new TestTerminal({cols: 10, rows: 10}); + }); + it('should default to whole viewport', () => { + term.writeSync('\x1b[r'); + assert.equal(term.buffer.scrollTop, 0); + assert.equal(term.buffer.scrollBottom, 9); + term.writeSync('\x1b[3;7r'); + assert.equal(term.buffer.scrollTop, 2); + assert.equal(term.buffer.scrollBottom, 6); + term.writeSync('\x1b[0;0r'); + assert.equal(term.buffer.scrollTop, 0); + assert.equal(term.buffer.scrollBottom, 9); + }); + it('should clamp bottom', () => { + term.writeSync('\x1b[3;1000r'); + assert.equal(term.buffer.scrollTop, 2); + assert.equal(term.buffer.scrollBottom, 9); + }); + it('should only apply for top < bottom', () => { + term.writeSync('\x1b[7;2r'); + assert.equal(term.buffer.scrollTop, 0); + assert.equal(term.buffer.scrollBottom, 9); + }); + }); }); diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 5fae95f9..ca4fa2da 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1904,10 +1904,19 @@ export class InputHandler extends Disposable implements IInputHandler { if (collect) { return; } - this._terminal.buffer.scrollTop = (params.params[0] || 1) - 1; - this._terminal.buffer.scrollBottom = (params.length > 1 && params.params[1] && params.params[1] <= this._terminal.rows ? params.params[1] : this._terminal.rows) - 1; - this._terminal.buffer.x = 0; - this._terminal.buffer.y = 0; + + const top = params.params[0] || 1; + let bottom: number; + + if (params.length < 2 || (bottom = params.params[1]) > this._terminal.rows || bottom === 0) { + bottom = this._terminal.rows; + } + + if (bottom > top) { + this._terminal.buffer.scrollTop = top - 1; + this._terminal.buffer.scrollBottom = bottom - 1; + this._setCursor(0, 0); + } }