diff --git a/src/xterm.js b/src/xterm.js index bc3f2262..abf9618c 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -1307,6 +1307,28 @@ Terminal.prototype.scrollDisp = function(disp, suppressScrollEvent) { this.refresh(0, this.rows - 1); }; +/** + * Scroll the display of the terminal by a number of pages. + * @param {number} pageCount The number of pages to scroll (negative scrolls up). + */ +Terminal.prototype.scrollPages = function(pageCount) { + this.scrollDisp(pageCount * (this.rows - 1)); +} + +/** + * Scrolls the display of the terminal to the top. + */ +Terminal.prototype.scrollToTop = function() { + this.scrollDisp(-this.ydisp); +} + +/** + * Scrolls the display of the terminal to the bottom. + */ +Terminal.prototype.scrollToBottom = function() { + this.scrollDisp(this.ybase - this.ydisp); +} + /** * Writes text to the terminal. * @param {string} text The text to write to the terminal. diff --git a/test/test.js b/test/test.js index b5dc20ec..eb34a44e 100644 --- a/test/test.js +++ b/test/test.js @@ -88,6 +88,101 @@ describe('xterm.js', function() { }); }); + describe('scroll', function() { + describe('scrollDisp', function() { + var startYDisp; + beforeEach(function() { + for (var i = 0; i < xterm.rows * 2; i++) { + xterm.writeln('test'); + } + startYDisp = xterm.rows + 1; + }); + it('should scroll a single line', function() { + assert.equal(xterm.ydisp, startYDisp); + xterm.scrollDisp(-1); + assert.equal(xterm.ydisp, startYDisp - 1); + xterm.scrollDisp(1); + assert.equal(xterm.ydisp, startYDisp); + }); + it('should scroll multiple lines', function() { + assert.equal(xterm.ydisp, startYDisp); + xterm.scrollDisp(-5); + assert.equal(xterm.ydisp, startYDisp - 5); + xterm.scrollDisp(5); + assert.equal(xterm.ydisp, startYDisp); + }); + it('should not scroll beyond the bounds of the buffer', function() { + assert.equal(xterm.ydisp, startYDisp); + xterm.scrollDisp(1); + assert.equal(xterm.ydisp, startYDisp); + for (var i = 0; i < startYDisp; i++) { + xterm.scrollDisp(-1); + } + assert.equal(xterm.ydisp, 0); + xterm.scrollDisp(-1); + assert.equal(xterm.ydisp, 0); + }); + }); + + describe('scrollPages', function() { + var startYDisp; + beforeEach(function() { + for (var i = 0; i < xterm.rows * 3; i++) { + xterm.writeln('test'); + } + startYDisp = (xterm.rows * 2) + 1; + }); + it('should scroll a single page', function() { + assert.equal(xterm.ydisp, startYDisp); + xterm.scrollPages(-1); + assert.equal(xterm.ydisp, startYDisp - (xterm.rows - 1)); + xterm.scrollPages(1); + assert.equal(xterm.ydisp, startYDisp); + }); + it('should scroll a multiple pages', function() { + assert.equal(xterm.ydisp, startYDisp); + xterm.scrollPages(-2); + assert.equal(xterm.ydisp, startYDisp - (xterm.rows - 1) * 2); + xterm.scrollPages(2); + assert.equal(xterm.ydisp, startYDisp); + }); + }); + + describe('scrollToTop', function() { + beforeEach(function() { + for (var i = 0; i < xterm.rows * 3; i++) { + xterm.writeln('test'); + } + }); + it('should scroll to the top', function() { + assert.notEqual(xterm.ydisp, 0); + xterm.scrollToTop(); + assert.equal(xterm.ydisp, 0); + }); + }); + + describe('scrollToBottom', function() { + var startYDisp; + beforeEach(function() { + for (var i = 0; i < xterm.rows * 3; i++) { + xterm.writeln('test'); + } + startYDisp = (xterm.rows * 2) + 1; + }); + it('should scroll to the bottom', function() { + xterm.scrollDisp(-1); + xterm.scrollToBottom(); + assert.equal(xterm.ydisp, startYDisp); + xterm.scrollPages(-1); + xterm.scrollToBottom(); + assert.equal(xterm.ydisp, startYDisp); + xterm.scrollToTop(); + xterm.scrollToBottom(); + assert.equal(xterm.ydisp, startYDisp); + }); + }); + }); + describe('evaluateKeyEscapeSequence', function() { it('should return the correct escape sequence for unmodified keys', function() { // Backspace