]> git.proxmox.com Git - mirror_xterm.js.git/commitdiff
Create `terminal.buffer` convenience attribute
authorParis Kasidiaris <paris@sourcelair.com>
Sun, 18 Jun 2017 16:16:48 +0000 (19:16 +0300)
committerParis Kasidiaris <pariskasidiaris@gmail.com>
Sun, 16 Jul 2017 00:47:15 +0000 (03:47 +0300)
src/BufferSet.ts
src/InputHandler.ts
src/Renderer.ts
src/Viewport.ts
src/xterm.js

index e09ba96bf375b91b0faff0f8c214de983cb6b934..e115fe001c7d8a87da509eca2c2dcd1171e79825 100644 (file)
@@ -4,13 +4,15 @@
 
 import { ITerminal } from './Interfaces';
 import { Buffer } from './Buffer';
+import { EventEmitter } from './EventEmitter';
 
-export class BufferSet {
+export class BufferSet extends EventEmitter {
   private _normal: Buffer;
   private _alt: Buffer;
   private _activeBuffer: Buffer;
 
   constructor(private _terminal: ITerminal) {
+    super();
     this._normal = new Buffer(this._terminal);
     this._alt = new Buffer(this._terminal);
     this._activeBuffer = this._normal;
@@ -36,9 +38,11 @@ export class BufferSet {
 
   public activateNormalBuffer(): void {
     this._activeBuffer = this._normal;
+    this.emit('activate', this._normal);
   }
 
   public activateAltBuffer(): void {
-    this._activeBuffer = this._normal;
+    this._activeBuffer = this._alt;
+    this.emit('activate', this._alt);
   }
 }
index 52e5b4a11c77fae2d9d5f201f813000141ae2a21..0e4c276fae12ab58eed17b46a65d93ddd256d2ca 100644 (file)
@@ -33,15 +33,15 @@ export class InputHandler implements IInputHandler {
       // FIXME: needs handling after cursor jumps
       if (!ch_width && this._terminal.x) {
         // dont overflow left
-        if (this._terminal.lines.get(row)[this._terminal.x - 1]) {
-          if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {
+        if (this._terminal.buffer.lines.get(row)[this._terminal.x - 1]) {
+          if (!this._terminal.buffer.lines.get(row)[this._terminal.x - 1][2]) {
 
             // found empty cell after fullwidth, need to go 2 cells back
-            if (this._terminal.lines.get(row)[this._terminal.x - 2])
-              this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;
+            if (this._terminal.buffer.lines.get(row)[this._terminal.x - 2])
+              this._terminal.buffer.lines.get(row)[this._terminal.x - 2][1] += char;
 
           } else {
-            this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;
+            this._terminal.buffer.lines.get(row)[this._terminal.x - 1][1] += char;
           }
           this._terminal.updateRange(this._terminal.y);
         }
@@ -77,25 +77,25 @@ export class InputHandler implements IInputHandler {
         for (let moves = 0; moves < ch_width; ++moves) {
           // remove last cell, if it's width is 0
           // we have to adjust the second last cell as well
-          const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();
+          const removed = this._terminal.buffer.lines.get(this._terminal.y + this._terminal.ybase).pop();
           if (removed[2] === 0
-              && this._terminal.lines.get(row)[this._terminal.cols - 2]
-              && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2) {
-            this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];
+              && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2]
+              && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2][2] === 2) {
+            this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];
           }
 
           // insert empty cell at cursor
-          this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);
+          this._terminal.buffer.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);
         }
       }
 
-      this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];
+      this._terminal.buffer.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];
       this._terminal.x++;
       this._terminal.updateRange(this._terminal.y);
 
       // fullwidth char - set next cell width to zero and advance cursor
       if (ch_width === 2) {
-        this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];
+        this._terminal.buffer.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];
         this._terminal.x++;
       }
     }
@@ -194,8 +194,8 @@ export class InputHandler implements IInputHandler {
     ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm
 
     while (param-- && j < this._terminal.cols) {
-      this._terminal.lines.get(row).splice(j++, 0, ch);
-      this._terminal.lines.get(row).pop();
+      this._terminal.buffer.lines.get(row).splice(j++, 0, ch);
+      this._terminal.buffer.lines.get(row).pop();
     }
   }
 
@@ -392,9 +392,9 @@ export class InputHandler implements IInputHandler {
         break;
       case 3:
         // Clear scrollback (everything not in viewport)
-        const scrollBackSize = this._terminal.lines.length - this._terminal.rows;
+        const scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows;
         if (scrollBackSize > 0) {
-          this._terminal.lines.trimStart(scrollBackSize);
+          this._terminal.buffer.lines.trimStart(scrollBackSize);
           this._terminal.ybase = Math.max(this._terminal.ybase - scrollBackSize, 0);
           this._terminal.ydisp = Math.max(this._terminal.ydisp - scrollBackSize, 0);
           // Force a scroll event to refresh viewport
@@ -446,9 +446,9 @@ export class InputHandler implements IInputHandler {
     j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;
 
     while (param--) {
-      if (this._terminal.lines.length === this._terminal.lines.maxLength) {
+      if (this._terminal.buffer.lines.length === this._terminal.buffer.lines.maxLength) {
         // Trim the start of lines to make room for the new line
-        this._terminal.lines.trimStart(1);
+        this._terminal.buffer.lines.trimStart(1);
         this._terminal.ybase--;
         this._terminal.ydisp--;
         row--;
@@ -456,8 +456,8 @@ export class InputHandler implements IInputHandler {
       }
       // test: echo -e '\e[44m\e[1L\e[0m'
       // blankLine(true) - xterm/linux behavior
-      this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));
-      this._terminal.lines.splice(j, 1);
+      this._terminal.buffer.lines.splice(row, 0, this._terminal.blankLine(true));
+      this._terminal.buffer.lines.splice(j, 1);
     }
 
     // this.maxRange();
@@ -482,16 +482,16 @@ export class InputHandler implements IInputHandler {
     j = this._terminal.rows - 1 + this._terminal.ybase - j;
 
     while (param--) {
-      if (this._terminal.lines.length === this._terminal.lines.maxLength) {
+      if (this._terminal.buffer.lines.length === this._terminal.buffer.lines.maxLength) {
         // Trim the start of lines to make room for the new line
-        this._terminal.lines.trimStart(1);
+        this._terminal.buffer.lines.trimStart(1);
         this._terminal.ybase -= 1;
         this._terminal.ydisp -= 1;
       }
       // test: echo -e '\e[44m\e[1M\e[0m'
       // blankLine(true) - xterm/linux behavior
-      this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));
-      this._terminal.lines.splice(row, 1);
+      this._terminal.buffer.lines.splice(j + 1, 0, this._terminal.blankLine(true));
+      this._terminal.buffer.lines.splice(row, 1);
     }
 
     // this.maxRange();
@@ -515,8 +515,8 @@ export class InputHandler implements IInputHandler {
     ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm
 
     while (param--) {
-      this._terminal.lines.get(row).splice(this._terminal.x, 1);
-      this._terminal.lines.get(row).push(ch);
+      this._terminal.buffer.lines.get(row).splice(this._terminal.x, 1);
+      this._terminal.buffer.lines.get(row).push(ch);
     }
   }
 
@@ -526,8 +526,8 @@ export class InputHandler implements IInputHandler {
   public scrollUp(params: number[]): void {
     let param = params[0] || 1;
     while (param--) {
-      this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);
-      this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());
+      this._terminal.buffer.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);
+      this._terminal.buffer.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());
     }
     // this.maxRange();
     this._terminal.updateRange(this._terminal.scrollTop);
@@ -540,8 +540,8 @@ export class InputHandler implements IInputHandler {
   public scrollDown(params: number[]): void {
     let param = params[0] || 1;
     while (param--) {
-      this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);
-      this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());
+      this._terminal.buffer.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);
+      this._terminal.buffer.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());
     }
     // this.maxRange();
     this._terminal.updateRange(this._terminal.scrollTop);
@@ -565,7 +565,7 @@ export class InputHandler implements IInputHandler {
     ch = [this._terminal.eraseAttr(), ' ', 1]; // xterm
 
     while (param-- && j < this._terminal.cols) {
-      this._terminal.lines.get(row)[j++] = ch;
+      this._terminal.buffer.lines.get(row)[j++] = ch;
     }
   }
 
@@ -615,7 +615,7 @@ export class InputHandler implements IInputHandler {
    */
   public repeatPrecedingCharacter(params: number[]): void {
     let param = params[0] || 1
-      , line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y)
+      , line = this._terminal.buffer.lines.get(this._terminal.ybase + this._terminal.y)
       , ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];
 
     while (param--) {
@@ -949,7 +949,7 @@ export class InputHandler implements IInputHandler {
         case 1047: // alt screen buffer
           if (!this._terminal.normal) {
             let normal = {
-              lines: this._terminal.lines,
+              lines: this._terminal.buffers.normal.lines,
               ybase: this._terminal.ybase,
               ydisp: this._terminal.ydisp,
               x: this._terminal.x,
@@ -1128,7 +1128,7 @@ export class InputHandler implements IInputHandler {
         case 47: // normal screen buffer
         case 1047: // normal screen buffer - clearing it first
           if (this._terminal.normal) {
-            this._terminal.lines = this._terminal.normal.lines;
+            this._terminal.buffers.activateNormalBuffer();
             this._terminal.ybase = this._terminal.normal.ybase;
             this._terminal.ydisp = this._terminal.normal.ydisp;
             this._terminal.x = this._terminal.normal.x;
@@ -1138,7 +1138,7 @@ export class InputHandler implements IInputHandler {
             this._terminal.tabs = this._terminal.normal.tabs;
             this._terminal.normal = null;
             // Ensure the selection manager has the correct buffer
-            this._terminal.selectionManager.setBuffer(this._terminal.lines);
+            this._terminal.selectionManager.setBuffer(this._terminal.buffer.lines);
             // if (params === 1049) {
             //   this.x = this.savedX;
             //   this.y = this.savedY;
index f057a912bb7fe86a35d1dc7a88605db0b2486a7e..3d4d918b0ca840fd2b2691921af0b22e959c9fb2 100644 (file)
@@ -141,7 +141,7 @@ export class Renderer {
     for (; y <= end; y++) {
       let row = y + this._terminal.ydisp;
 
-      let line = this._terminal.lines.get(row);
+      let line = this._terminal.buffer.lines.get(row);
 
       let x;
       if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp) &&
index 5be6bffdfbb411bec5c91ea05538fcc5d2903b5d..a92836ff65b6a5ed225031cf8cff10bf43f2af10 100644 (file)
@@ -68,9 +68,9 @@ export class Viewport {
    * Updates dimensions and synchronizes the scroll area if necessary.
    */
   public syncScrollArea(): void {
-    if (this.lastRecordedBufferLength !== this.terminal.lines.length) {
+    if (this.lastRecordedBufferLength !== this.terminal.buffer.lines.length) {
       // If buffer height changed
-      this.lastRecordedBufferLength = this.terminal.lines.length;
+      this.lastRecordedBufferLength = this.terminal.buffer.lines.length;
       this.refresh();
     } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {
       // If viewport height changed
index 4b540576e613bf35a1f28abc47bd1a7f4fb8a683..30d7148f0be3b1958188bc700fd25219952620ca 100644 (file)
@@ -244,19 +244,25 @@ function Terminal(options) {
   // leftover surrogate high from previous write invocation
   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;
+  this.buffers.on('activate', function (buffer) {
+    this.buffer = buffer;
+  });
+
   /**
    * An array of all lines in the entire buffer, including the prompt. The lines are array of
    * characters which are 2-length arrays where [0] is an attribute and [1] is the character.
    */
-  this.lines = new CircularList(this.scrollback);
   var i = this.rows;
+
   while (i--) {
-    this.lines.push(this.blankLine());
+    this.buffer.lines.push(this.blankLine());
   }
   // Ensure the selection manager has the correct buffer
   if (this.selectionManager) {
-    this.selectionManager.setBuffer(this.lines);
+    this.selectionManager.setBuffer(this.buffer.lines);
   }
 
   this.tabs;
@@ -432,17 +438,17 @@ Terminal.prototype.setOption = function(key, value) {
       }
 
       if (this.options[key] !== value) {
-        if (this.lines.length > value) {
-          const amountToTrim = this.lines.length - value;
+        if (this.buffer.length > value) {
+          const amountToTrim = this.buffer.lines.length - value;
           const needsRefresh = (this.ydisp - amountToTrim < 0);
-          this.lines.trimStart(amountToTrim);
+          this.buffer.lines.trimStart(amountToTrim);
           this.ybase = Math.max(this.ybase - amountToTrim, 0);
           this.ydisp = Math.max(this.ydisp - amountToTrim, 0);
           if (needsRefresh) {
             this.refresh(0, this.rows - 1);
           }
         }
-        this.lines.maxLength = value;
+        this.buffer.lines.maxLength = value;
         this.viewport.syncScrollArea();
       }
       break;
@@ -727,6 +733,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.on('refresh', data => {
     this.renderer.refreshSelection(data.start, data.end);
@@ -739,6 +746,10 @@ 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());
 
@@ -1171,8 +1182,8 @@ Terminal.prototype.scroll = function(isWrapped) {
   var row;
 
   // Make room for the new row in lines
-  if (this.lines.length === this.lines.maxLength) {
-    this.lines.trimStart(1);
+  if (this.buffer.lines.length === this.buffer.lines.maxLength) {
+    this.buffer.lines.trimStart(1);
     this.ybase--;
     if (this.ydisp !== 0) {
       this.ydisp--;
@@ -1192,12 +1203,12 @@ Terminal.prototype.scroll = function(isWrapped) {
   // subtract the bottom scroll region
   row -= this.rows - 1 - this.scrollBottom;
 
-  if (row === this.lines.length) {
+  if (row === this.buffer.lines.length) {
     // Optimization: pushing is faster than splicing when they amount to the same behavior
-    this.lines.push(this.blankLine(undefined, isWrapped));
+    this.buffer.lines.push(this.blankLine(undefined, isWrapped));
   } else {
     // add our new line
-    this.lines.splice(row, 0, this.blankLine(undefined, isWrapped));
+    this.buffer.lines.splice(row, 0, this.blankLine(undefined, isWrapped));
   }
 
   if (this.scrollTop !== 0) {
@@ -1207,7 +1218,7 @@ Terminal.prototype.scroll = function(isWrapped) {
         this.ydisp = this.ybase;
       }
     }
-    this.lines.splice(this.ybase + this.scrollTop, 1);
+    this.buffer.lines.splice(this.ybase + this.scrollTop, 1);
   }
 
   // this.maxRange();
@@ -1960,10 +1971,10 @@ Terminal.prototype.resize = function(x, y) {
   j = this.cols;
   if (j < x) {
     ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?
-    i = this.lines.length;
+    i = this.buffer.lines.length;
     while (i--) {
-      while (this.lines.get(i).length < x) {
-        this.lines.get(i).push(ch);
+      while (this.buffer.lines.get(i).length < x) {
+        this.buffer.lines.get(i).push(ch);
       }
     }
   }
@@ -1978,8 +1989,8 @@ Terminal.prototype.resize = function(x, y) {
     el = this.element;
     while (j++ < y) {
       // y is rows, not this.y
-      if (this.lines.length < y + this.ybase) {
-        if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {
+      if (this.buffer.lines.length < y + this.ybase) {
+        if (this.ybase > 0 && this.buffer.lines.length <= this.ybase + this.y + addToY + 1) {
           // There is room above the buffer and there are no empty elements below the line,
           // scroll up
           this.ybase--;
@@ -1991,7 +2002,7 @@ Terminal.prototype.resize = function(x, y) {
         } else {
           // Add a blank line if there is no buffer left at the top to scroll to, or if there
           // are blank lines after the cursor
-          this.lines.push(this.blankLine());
+          this.buffer.lines.push(this.blankLine());
         }
       }
       if (this.children.length < y) {
@@ -2000,10 +2011,10 @@ Terminal.prototype.resize = function(x, y) {
     }
   } else { // (j > y)
     while (j-- > y) {
-      if (this.lines.length > y + this.ybase) {
-        if (this.lines.length > this.ybase + this.y + 1) {
+      if (this.buffer.lines.length > y + this.ybase) {
+        if (this.buffer.lines.length > this.ybase + this.y + 1) {
           // The line is a blank line below the cursor, remove it
-          this.lines.pop();
+          this.buffer.lines.pop();
         } else {
           // The line is the cursor, scroll down
           this.ybase++;
@@ -2121,7 +2132,7 @@ Terminal.prototype.nextStop = function(x) {
  * @param {number} y The line in which to operate.
  */
 Terminal.prototype.eraseRight = function(x, y) {
-  var line = this.lines.get(this.ybase + y);
+  var line = this.buffer.lines.get(this.ybase + y);
   if (!line) {
     return;
   }
@@ -2140,7 +2151,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.lines.get(this.ybase + y);
+  var line = this.buffer.lines.get(this.ybase + y);
   if (!line) {
     return;
   }
@@ -2160,13 +2171,13 @@ Terminal.prototype.clear = function() {
     // Don't clear if it's already clear
     return;
   }
-  this.lines.set(0, this.lines.get(this.ybase + this.y));
-  this.lines.length = 1;
+  this.buffer.lines.set(0, this.buffer.lines.get(this.ybase + this.y));
+  this.buffer.lines.length = 1;
   this.ydisp = 0;
   this.ybase = 0;
   this.y = 0;
   for (var i = 1; i < this.rows; i++) {
-    this.lines.push(this.blankLine());
+    this.buffer.lines.push(this.blankLine());
   }
   this.refresh(0, this.rows - 1);
   this.emit('scroll', this.ydisp);
@@ -2299,8 +2310,8 @@ Terminal.prototype.reverseIndex = function() {
     // 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.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);
-    this.lines.set(this.y + this.ybase, this.blankLine(true));
+    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);
   } else {