]> git.proxmox.com Git - mirror_xterm.js.git/blame - src/Buffer.ts
Resize both buffers on resize
[mirror_xterm.js.git] / src / Buffer.ts
CommitLineData
95cb6f30
PK
1/**
2 * @license MIT
3 */
4
5import { ITerminal } from './Interfaces';
6import { CircularList } from './utils/CircularList';
7
bbafdd3d 8/**
58b9f712
PK
9 * This class represents a terminal buffer (an internal state of the terminal), where the
10 * following information is stored (in high-level):
11 * - text content of this particular buffer
12 * - cursor position
13 * - scroll position
bbafdd3d 14 */
95cb6f30 15export class Buffer {
3d20c2f2 16 public readonly lines: CircularList<[number, string, number][]>;
95cb6f30 17
604959a3
DI
18 public savedY: number;
19 public savedX: number;
20
bbafdd3d
PK
21 /**
22 * Create a new Buffer.
3d20c2f2 23 * @param {Terminal} _terminal - The terminal the Buffer will belong to
58b9f712
PK
24 * @param {number} ydisp - The scroll position of the Buffer in the viewport
25 * @param {number} ybase - The scroll position of the y cursor (ybase + y = the y position within the Buffer)
bbafdd3d
PK
26 * @param {number} y - The cursor's y position after ybase
27 * @param {number} x - The cursor's x position after ybase
28 */
29 constructor(
3d20c2f2 30 private _terminal: ITerminal,
bbafdd3d
PK
31 public ydisp: number = 0,
32 public ybase: number = 0,
33 public y: number = 0,
34 public x: number = 0,
4626e19b
PK
35 public scrollBottom: number = 0,
36 public scrollTop: number = 0,
37 public tabs: any = {},
bbafdd3d 38 ) {
3d20c2f2
DI
39 this.lines = new CircularList<[number, string, number][]>(this._terminal.scrollback);
40 this.scrollBottom = this._terminal.rows - 1;
41 }
42
43 public resize(newCols: number, newRows: number): void {
44 // Don't resize the buffer if it's empty and hasn't been used yet.
45 if (this.lines.length === 0) {
46 return;
47 }
48
49 // Deal with columns increasing (we don't do anything when columns reduce)
50 if (this._terminal.cols < newCols) {
51 const ch: [number, string, number] = [this._terminal.defAttr, ' ', 1]; // does xterm use the default attr?
52 for (let i = 0; i < this.lines.length; i++) {
53 if (this.lines.get(i) === undefined) {
54 this.lines.set(i, this._terminal.blankLine());
55 }
56 while (this.lines.get(i).length < newCols) {
57 this.lines.get(i).push(ch);
58 }
59 }
60 }
61
62 // Resize rows in both directions as needed
63 let addToY = 0;
64 if (this._terminal.rows < newRows) {
65 for (let y = this._terminal.rows; y < newRows; y++) {
66 if (this.lines.length < newRows + this.ybase) {
67 if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {
68 // There is room above the buffer and there are no empty elements below the line,
69 // scroll up
70 this.ybase--;
71 addToY++;
72 if (this.ydisp > 0) {
73 // Viewport is at the top of the buffer, must increase downwards
74 this.ydisp--;
75 }
76 } else {
77 // Add a blank line if there is no buffer left at the top to scroll to, or if there
78 // are blank lines after the cursor
79 this.lines.push(this._terminal.blankLine());
80 }
81 }
82 }
83 } else { // (this._terminal.rows >= newRows)
84 for (let y = this._terminal.rows; y > newRows; y--) {
85 if (this.lines.length > newRows + this.ybase) {
86 if (this.lines.length > this.ybase + this.y + 1) {
87 // The line is a blank line below the cursor, remove it
88 this.lines.pop();
89 } else {
90 // The line is the cursor, scroll down
91 this.ybase++;
92 this.ydisp++;
93 }
94 }
95 }
96 }
97
98 // Make sure that the cursor stays on screen
99 if (this.y >= newRows) {
100 this.y = newRows - 1;
101 }
102 if (addToY) {
103 this.y += addToY;
104 }
105
106 if (this.x >= newCols) {
107 this.x = newCols - 1;
108 }
109
110 this.scrollTop = 0;
111 this.scrollBottom = newRows - 1;
95cb6f30
PK
112 }
113}