]>
Commit | Line | Data |
---|---|---|
95cb6f30 PK |
1 | /** |
2 | * @license MIT | |
3 | */ | |
4 | ||
5 | import { ITerminal } from './Interfaces'; | |
6 | import { 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 | 15 | export 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 | } |