]> git.proxmox.com Git - mirror_xterm.js.git/blobdiff - src/xterm.js
Fix turning from alt screen to normal screen and vice versa. Fix https://github.com...
[mirror_xterm.js.git] / src / xterm.js
index 30d7148f0be3b1958188bc700fd25219952620ca..5fb5ea743c256f7f6f0e285326c183bccf525b60 100644 (file)
@@ -142,34 +142,17 @@ function Terminal(options) {
     this.on('data', options.handler);
   }
 
-  /**
-   * The scroll position of the y cursor, ie. ybase + y = the y position within the entire
-   * buffer
-   */
-  this.ybase = 0;
-
-  /**
-   * The scroll position of the viewport
-   */
-  this.ydisp = 0;
-
-  /**
-   * The cursor's x position after ybase
-   */
-  this.x = 0;
-
-  /**
-   * The cursor's y position after ybase
-   */
-  this.y = 0;
-
   this.cursorState = 0;
   this.cursorHidden = false;
   this.convertEol;
   this.queue = '';
+<<<<<<< HEAD
   this.scrollTop = 0;
   this.scrollBottom = this.rows - 1;
   this.customKeyEventHandler = null;
+=======
+  this.customKeydownHandler = null;
+>>>>>>> Move `scrollTop` and `scrollBottom` into `Buffer`
   this.cursorBlinkInterval = null;
 
   // modes
@@ -178,7 +161,6 @@ function Terminal(options) {
   this.originMode = false;
   this.insertMode = false;
   this.wraparoundMode = true; // defaults: xterm - true, vt100 - false
-  this.normal = null;
 
   // charset
   this.charset = null;
@@ -245,10 +227,12 @@ function Terminal(options) {
   this.surrogate_high = '';
 
   // Create the terminal's buffers and set the current buffer
-  this.buffers = new BufferSet(this);
-  this.buffer = this.buffers.active;  // Convenience shortcut;
+  if (!this.buffers) {
+    this.buffers = new BufferSet(this);
+    this.buffer = this.buffers.active;  // Convenience shortcut;
+  }
   this.buffers.on('activate', function (buffer) {
-    this.buffer = buffer;
+    this._terminal.buffer = buffer;
   });
 
   /**
@@ -265,7 +249,6 @@ function Terminal(options) {
     this.selectionManager.setBuffer(this.buffer.lines);
   }
 
-  this.tabs;
   this.setupStops();
 
   // Store if user went browsing history in scrollback
@@ -440,10 +423,10 @@ Terminal.prototype.setOption = function(key, value) {
       if (this.options[key] !== value) {
         if (this.buffer.length > value) {
           const amountToTrim = this.buffer.lines.length - value;
-          const needsRefresh = (this.ydisp - amountToTrim < 0);
+          const needsRefresh = (this.buffer.ydisp - amountToTrim < 0);
           this.buffer.lines.trimStart(amountToTrim);
-          this.ybase = Math.max(this.ybase - amountToTrim, 0);
-          this.ydisp = Math.max(this.ydisp - amountToTrim, 0);
+          this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0);
+          this.buffer.ydisp = Math.max(this.buffer.ydisp - amountToTrim, 0);
           if (needsRefresh) {
             this.refresh(0, this.rows - 1);
           }
@@ -733,8 +716,7 @@ Terminal.prototype.open = function(parent, focus) {
 
   this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);
   this.renderer = new Renderer(this);
-<<<<<<< HEAD
-  this.selectionManager = new SelectionManager(this, this.lines, this.rowContainer, this.charMeasure);
+  this.selectionManager = new SelectionManager(this, this.buffer.lines, this.rowContainer, this.charMeasure);
   this.selectionManager.on('refresh', data => {
     this.renderer.refreshSelection(data.start, data.end);
   });
@@ -746,10 +728,6 @@ Terminal.prototype.open = function(parent, focus) {
     this.textarea.focus();
     this.textarea.select();
   });
-=======
-  this.selectionManager = new SelectionManager(this, this.buffer.lines, this.rowContainer, this.charMeasure);
-  this.selectionManager.on('refresh', data => this.renderer.refreshSelection(data.start, data.end));
->>>>>>> Create `terminal.buffer` convenience attribute
   this.on('scroll', () => this.selectionManager.refresh());
   this.viewportElement.addEventListener('scroll', () => this.selectionManager.refresh());
 
@@ -1169,7 +1147,7 @@ Terminal.prototype.queueLinkification = function(start, end) {
 Terminal.prototype.showCursor = function() {
   if (!this.cursorState) {
     this.cursorState = 1;
-    this.refresh(this.y, this.y);
+    this.refresh(this.buffer.y, this.buffer.y);
   }
 };
 
@@ -1184,24 +1162,24 @@ Terminal.prototype.scroll = function(isWrapped) {
   // Make room for the new row in lines
   if (this.buffer.lines.length === this.buffer.lines.maxLength) {
     this.buffer.lines.trimStart(1);
-    this.ybase--;
-    if (this.ydisp !== 0) {
-      this.ydisp--;
+    this.buffer.ybase--;
+    if (this.buffer.ydisp !== 0) {
+      this.buffer.ydisp--;
     }
   }
 
-  this.ybase++;
+  this.buffer.ybase++;
 
   // TODO: Why is this done twice?
   if (!this.userScrolling) {
-    this.ydisp = this.ybase;
+    this.buffer.ydisp = this.buffer.ybase;
   }
 
   // last line
-  row = this.ybase + this.rows - 1;
+  row = this.buffer.ybase + this.rows - 1;
 
   // subtract the bottom scroll region
-  row -= this.rows - 1 - this.scrollBottom;
+  row -= this.rows - 1 - this.buffer.scrollBottom;
 
   if (row === this.buffer.lines.length) {
     // Optimization: pushing is faster than splicing when they amount to the same behavior
@@ -1211,19 +1189,19 @@ Terminal.prototype.scroll = function(isWrapped) {
     this.buffer.lines.splice(row, 0, this.blankLine(undefined, isWrapped));
   }
 
-  if (this.scrollTop !== 0) {
-    if (this.ybase !== 0) {
-      this.ybase--;
+  if (this.buffer.scrollTop !== 0) {
+    if (this.buffer.ybase !== 0) {
+      this.buffer.ybase--;
       if (!this.userScrolling) {
-        this.ydisp = this.ybase;
+        this.buffer.ydisp = this.buffer.ybase;
       }
     }
-    this.buffer.lines.splice(this.ybase + this.scrollTop, 1);
+    this.buffer.lines.splice(this.buffer.ybase + this.buffer.scrollTop, 1);
   }
 
   // this.maxRange();
-  this.updateRange(this.scrollTop);
-  this.updateRange(this.scrollBottom);
+  this.updateRange(this.buffer.scrollTop);
+  this.updateRange(this.buffer.scrollBottom);
 
   /**
    * This event is emitted whenever the terminal is scrolled.
@@ -1231,7 +1209,7 @@ Terminal.prototype.scroll = function(isWrapped) {
    *
    * @event scroll
    */
-  this.emit('scroll', this.ydisp);
+  this.emit('scroll', this.buffer.ydisp);
 };
 
 /**
@@ -1243,24 +1221,24 @@ Terminal.prototype.scroll = function(isWrapped) {
  */
 Terminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {
   if (disp < 0) {
-    if (this.ydisp === 0) {
+    if (this.buffer.ydisp === 0) {
       return;
     }
     this.userScrolling = true;
-  } else if (disp + this.ydisp >= this.ybase) {
+  } else if (disp + this.buffer.ydisp >= this.buffer.ybase) {
     this.userScrolling = false;
   }
 
-  const oldYdisp = this.ydisp;
-  this.ydisp = Math.max(Math.min(this.ydisp + disp, this.ybase), 0);
+  const oldYdisp = this.buffer.ydisp;
+  this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0);
 
   // No change occurred, don't trigger scroll/refresh
-  if (oldYdisp === this.ydisp) {
+  if (oldYdisp === this.buffer.ydisp) {
     return;
   }
 
   if (!suppressScrollEvent) {
-    this.emit('scroll', this.ydisp);
+    this.emit('scroll', this.buffer.ydisp);
   }
 
   this.refresh(0, this.rows - 1);
@@ -1278,14 +1256,14 @@ Terminal.prototype.scrollPages = function(pageCount) {
  * Scrolls the display of the terminal to the top.
  */
 Terminal.prototype.scrollToTop = function() {
-  this.scrollDisp(-this.ydisp);
+  this.scrollDisp(-this.buffer.ydisp);
 };
 
 /**
  * Scrolls the display of the terminal to the bottom.
  */
 Terminal.prototype.scrollToBottom = function() {
-  this.scrollDisp(this.ybase - this.ydisp);
+  this.scrollDisp(this.buffer.ybase - this.buffer.ydisp);
 };
 
 /**
@@ -1329,8 +1307,8 @@ Terminal.prototype.innerWrite = function() {
       this.xoffSentToCatchUp = false;
     }
 
-    this.refreshStart = this.y;
-    this.refreshEnd = this.y;
+    this.refreshStart = this.buffer.y;
+    this.refreshEnd = this.buffer.y;
 
     // HACK: Set the parser state based on it's state at the time of return.
     // This works around the bug #662 which saw the parser state reset in the
@@ -1340,7 +1318,7 @@ Terminal.prototype.innerWrite = function() {
     var state = this.parser.parse(data);
     this.parser.setState(state);
 
-    this.updateRange(this.y);
+    this.updateRange(this.buffer.y);
     this.refresh(this.refreshStart, this.refreshEnd);
   }
   if (this.writeBuffer.length > 0) {
@@ -1493,7 +1471,7 @@ Terminal.prototype.keyDown = function(ev) {
   this.restartCursorBlinking();
 
   if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {
-    if (this.ybase !== this.ydisp) {
+    if (this.buffer.ybase !== this.buffer.ydisp) {
       this.scrollToBottom();
     }
     return false;
@@ -1988,16 +1966,16 @@ Terminal.prototype.resize = function(x, y) {
   if (j < y) {
     el = this.element;
     while (j++ < y) {
-      // y is rows, not this.y
-      if (this.buffer.lines.length < y + this.ybase) {
-        if (this.ybase > 0 && this.buffer.lines.length <= this.ybase + this.y + addToY + 1) {
+      // y is rows, not this.buffer.y
+      if (this.buffer.lines.length < y + this.buffer.ybase) {
+        if (this.buffer.ybase > 0 && this.buffer.lines.length <= this.buffer.ybase + this.buffer.y + addToY + 1) {
           // There is room above the buffer and there are no empty elements below the line,
           // scroll up
-          this.ybase--;
+          this.buffer.ybase--;
           addToY++;
-          if (this.ydisp > 0) {
+          if (this.buffer.ydisp > 0) {
             // Viewport is at the top of the buffer, must increase downwards
-            this.ydisp--;
+            this.buffer.ydisp--;
           }
         } else {
           // Add a blank line if there is no buffer left at the top to scroll to, or if there
@@ -2011,14 +1989,14 @@ Terminal.prototype.resize = function(x, y) {
     }
   } else { // (j > y)
     while (j-- > y) {
-      if (this.buffer.lines.length > y + this.ybase) {
-        if (this.buffer.lines.length > this.ybase + this.y + 1) {
+      if (this.buffer.lines.length > y + this.buffer.ybase) {
+        if (this.buffer.lines.length > this.buffer.ybase + this.buffer.y + 1) {
           // The line is a blank line below the cursor, remove it
           this.buffer.lines.pop();
         } else {
           // The line is the cursor, scroll down
-          this.ybase++;
-          this.ydisp++;
+          this.buffer.ybase++;
+          this.buffer.ydisp++;
         }
       }
       if (this.children.length > y) {
@@ -2031,26 +2009,24 @@ Terminal.prototype.resize = function(x, y) {
   this.rows = y;
 
   // Make sure that the cursor stays on screen
-  if (this.y >= y) {
-    this.y = y - 1;
+  if (this.buffer.y >= y) {
+    this.buffer.y = y - 1;
   }
   if (addToY) {
-    this.y += addToY;
+    this.buffer.y += addToY;
   }
 
-  if (this.x >= x) {
-    this.x = x - 1;
+  if (this.buffer.x >= x) {
+    this.buffer.x = x - 1;
   }
 
-  this.scrollTop = 0;
-  this.scrollBottom = y - 1;
+  this.buffer.scrollTop = 0;
+  this.buffer.scrollBottom = y - 1;
 
   this.charMeasure.measure();
 
   this.refresh(0, this.rows - 1);
 
-  this.normal = null;
-
   this.geometry = [this.cols, this.rows];
   this.emit('resize', {terminal: this, cols: x, rows: y});
 };
@@ -2086,16 +2062,16 @@ Terminal.prototype.maxRange = function() {
  */
 Terminal.prototype.setupStops = function(i) {
   if (i != null) {
-    if (!this.tabs[i]) {
+    if (!this.buffer.tabs[i]) {
       i = this.prevStop(i);
     }
   } else {
-    this.tabs = {};
+    this.buffer.tabs = {};
     i = 0;
   }
 
   for (; i < this.cols; i += this.getOption('tabStopWidth')) {
-    this.tabs[i] = true;
+    this.buffer.tabs[i] = true;
   }
 };
 
@@ -2105,8 +2081,8 @@ Terminal.prototype.setupStops = function(i) {
  * @param {number} x The position to move the cursor to the previous tab stop.
  */
 Terminal.prototype.prevStop = function(x) {
-  if (x == null) x = this.x;
-  while (!this.tabs[--x] && x > 0);
+  if (x == null) x = this.buffer.x;
+  while (!this.buffer.tabs[--x] && x > 0);
   return x >= this.cols
     ? this.cols - 1
   : x < 0 ? 0 : x;
@@ -2118,8 +2094,8 @@ Terminal.prototype.prevStop = function(x) {
  * @param {number} x The position to move the cursor one tab stop forward.
  */
 Terminal.prototype.nextStop = function(x) {
-  if (x == null) x = this.x;
-  while (!this.tabs[++x] && x < this.cols);
+  if (x == null) x = this.buffer.x;
+  while (!this.buffer.tabs[++x] && x < this.cols);
   return x >= this.cols
     ? this.cols - 1
   : x < 0 ? 0 : x;
@@ -2132,7 +2108,7 @@ Terminal.prototype.nextStop = function(x) {
  * @param {number} y The line in which to operate.
  */
 Terminal.prototype.eraseRight = function(x, y) {
-  var line = this.buffer.lines.get(this.ybase + y);
+  var line = this.buffer.lines.get(this.buffer.ybase + y);
   if (!line) {
     return;
   }
@@ -2151,7 +2127,7 @@ Terminal.prototype.eraseRight = function(x, y) {
  * @param {number} y The line in which to operate.
  */
 Terminal.prototype.eraseLeft = function(x, y) {
-  var line = this.buffer.lines.get(this.ybase + y);
+  var line = this.buffer.lines.get(this.buffer.ybase + y);
   if (!line) {
     return;
   }
@@ -2167,20 +2143,20 @@ Terminal.prototype.eraseLeft = function(x, y) {
  * Clears the entire buffer, making the prompt line the new first line.
  */
 Terminal.prototype.clear = function() {
-  if (this.ybase === 0 && this.y === 0) {
+  if (this.buffer.ybase === 0 && this.buffer.y === 0) {
     // Don't clear if it's already clear
     return;
   }
-  this.buffer.lines.set(0, this.buffer.lines.get(this.ybase + this.y));
+  this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y));
   this.buffer.lines.length = 1;
-  this.ydisp = 0;
-  this.ybase = 0;
-  this.y = 0;
+  this.buffer.ydisp = 0;
+  this.buffer.ybase = 0;
+  this.buffer.y = 0;
   for (var i = 1; i < this.rows; i++) {
     this.buffer.lines.push(this.blankLine());
   }
   this.refresh(0, this.rows - 1);
-  this.emit('scroll', this.ydisp);
+  this.emit('scroll', this.buffer.ydisp);
 };
 
 /**
@@ -2257,7 +2233,7 @@ Terminal.prototype.handler = function(data) {
   }
 
   // Input is being sent to the terminal, the terminal should focus the prompt.
-  if (this.ybase !== this.ydisp) {
+  if (this.buffer.ybase !== this.buffer.ydisp) {
     this.scrollToBottom();
   }
   this.emit('data', data);
@@ -2287,14 +2263,14 @@ Terminal.prototype.handleTitle = function(title) {
  * ESC D Index (IND is 0x84).
  */
 Terminal.prototype.index = function() {
-  this.y++;
-  if (this.y > this.scrollBottom) {
-    this.y--;
+  this.buffer.y++;
+  if (this.buffer.y > this.buffer.scrollBottom) {
+    this.buffer.y--;
     this.scroll();
   }
   // If the end of the line is hit, prevent this action from wrapping around to the next line.
-  if (this.x >= this.cols) {
-    this.x--;
+  if (this.buffer.x >= this.cols) {
+    this.buffer.x--;
   }
 };
 
@@ -2306,16 +2282,16 @@ Terminal.prototype.index = function() {
  */
 Terminal.prototype.reverseIndex = function() {
   var j;
-  if (this.y === this.scrollTop) {
+  if (this.buffer.y === this.buffer.scrollTop) {
     // possibly move the code below to term.reverseScroll();
     // test: echo -ne '\e[1;1H\e[44m\eM\e[0m'
     // blankLine(true) is xterm/linux behavior
-    this.buffer.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);
-    this.buffer.lines.set(this.y + this.ybase, this.blankLine(true));
-    this.updateRange(this.scrollTop);
-    this.updateRange(this.scrollBottom);
+    this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, this.rows - 1, 1);
+    this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.blankLine(true));
+    this.updateRange(this.buffer.scrollTop);
+    this.updateRange(this.buffer.scrollBottom);
   } else {
-    this.y--;
+    this.buffer.y--;
   }
 };
 
@@ -2328,9 +2304,13 @@ Terminal.prototype.reset = function() {
   this.options.cols = this.cols;
   var customKeyEventHandler = this.customKeyEventHandler;
   var cursorBlinkInterval = this.cursorBlinkInterval;
+  var inputHandler = this.inputHandler;
+  var buf = this.buffers;
   Terminal.call(this, this.options);
   this.customKeyEventHandler = customKeyEventHandler;
   this.cursorBlinkInterval = cursorBlinkInterval;
+  this.inputHandler = inputHandler;
+  this.buffers = buf;
   this.refresh(0, this.rows - 1);
   this.viewport.syncScrollArea();
 };
@@ -2340,7 +2320,7 @@ Terminal.prototype.reset = function() {
  * ESC H Tab Set (HTS is 0x88).
  */
 Terminal.prototype.tabSet = function() {
-  this.tabs[this.x] = true;
+  this.buffer.tabs[this.buffer.x] = true;
 };
 
 /**