mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Pull more parts out of reflow larger
This commit is contained in:
+18
-52
@@ -9,7 +9,7 @@ import { EventEmitter } from './common/EventEmitter';
|
||||
import { IMarker } from 'xterm';
|
||||
import { BufferLine } from './BufferLine';
|
||||
import { DEFAULT_COLOR } from './renderer/atlas/Types';
|
||||
import { reflowSmallerGetNewLineLengths, reflowLargerGetLinesToRemove } from './BufferReflow';
|
||||
import { reflowSmallerGetNewLineLengths, reflowLargerGetLinesToRemove, reflowLargerCreateNewLayout, reflowLargerApplyNewLayout } from './BufferReflow';
|
||||
|
||||
export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);
|
||||
export const CHAR_DATA_ATTR_INDEX = 0;
|
||||
@@ -240,62 +240,28 @@ export class Buffer implements IBuffer {
|
||||
}
|
||||
|
||||
private _reflowLarger(newCols: number): void {
|
||||
// TODO: Can toRemove be pulled out into BufferReflow?
|
||||
|
||||
// Gather all BufferLines that need to be removed from the Buffer here so that they can be
|
||||
// batched up and only committed once
|
||||
const toRemove: number[] = reflowLargerGetLinesToRemove(this.lines, newCols);
|
||||
|
||||
if (toRemove.length > 0) {
|
||||
// First iterate through the list and get the actual indexes to use for rows
|
||||
const newLayout: number[] = [];
|
||||
const countRemoved = reflowLargerCreateNewLayout(this.lines, toRemove, newLayout);
|
||||
reflowLargerApplyNewLayout(this.lines, newLayout);
|
||||
this._reflowLargerAdjustViewport(newCols, countRemoved);
|
||||
}
|
||||
}
|
||||
|
||||
let nextToRemoveIndex = 0;
|
||||
let nextToRemoveStart = toRemove[nextToRemoveIndex];
|
||||
let countRemovedSoFar = 0;
|
||||
for (let i = 0; i < this.lines.length; i++) {
|
||||
if (nextToRemoveStart === i) {
|
||||
const countToRemove = toRemove[++nextToRemoveIndex];
|
||||
|
||||
// Tell markers that there was a deletion
|
||||
this.lines.emit('delete', {
|
||||
index: i - countRemovedSoFar,
|
||||
amount: countToRemove
|
||||
} as IDeleteEvent);
|
||||
|
||||
i += countToRemove - 1;
|
||||
countRemovedSoFar += countToRemove;
|
||||
nextToRemoveStart = toRemove[++nextToRemoveIndex];
|
||||
} else {
|
||||
newLayout.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Record original lines so they don't get overridden when we rearrange the list
|
||||
const newLayoutLines: BufferLine[] = [];
|
||||
for (let i = 0; i < newLayout.length; i++) {
|
||||
newLayoutLines.push(this.lines.get(newLayout[i]) as BufferLine);
|
||||
}
|
||||
|
||||
// Rearrange the list
|
||||
for (let i = 0; i < newLayoutLines.length; i++) {
|
||||
this.lines.set(i, newLayoutLines[i]);
|
||||
}
|
||||
this.lines.length = newLayout.length;
|
||||
|
||||
// Adjust viewport based on number of items removed
|
||||
let viewportAdjustments = countRemovedSoFar;
|
||||
while (viewportAdjustments-- > 0) {
|
||||
if (this.ybase === 0) {
|
||||
this.y--;
|
||||
// Add an extra row at the bottom of the viewport
|
||||
this.lines.push(new BufferLine(newCols, FILL_CHAR_DATA));
|
||||
} else {
|
||||
if (this.ydisp === this.ybase) {
|
||||
this.ydisp--;
|
||||
}
|
||||
this.ybase--;
|
||||
private _reflowLargerAdjustViewport(newCols: number, countRemoved: number): void {
|
||||
// Adjust viewport based on number of items removed
|
||||
let viewportAdjustments = countRemoved;
|
||||
while (viewportAdjustments-- > 0) {
|
||||
if (this.ybase === 0) {
|
||||
this.y--;
|
||||
// Add an extra row at the bottom of the viewport
|
||||
this.lines.push(new BufferLine(newCols, FILL_CHAR_DATA));
|
||||
} else {
|
||||
if (this.ydisp === this.ybase) {
|
||||
this.ydisp--;
|
||||
}
|
||||
this.ybase--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-1
@@ -4,11 +4,13 @@
|
||||
*/
|
||||
|
||||
import { BufferLine } from './BufferLine';
|
||||
import { CircularList } from './common/CircularList';
|
||||
import { CircularList, IDeleteEvent } from './common/CircularList';
|
||||
import { IBufferLine } from './Types';
|
||||
import { FILL_CHAR_DATA } from './Buffer';
|
||||
|
||||
export function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, newCols: number): number[] {
|
||||
// Gather all BufferLines that need to be removed from the Buffer here so that they can be
|
||||
// batched up and only committed once
|
||||
const toRemove: number[] = [];
|
||||
|
||||
for (let y = 0; y < lines.length - 1; y++) {
|
||||
@@ -83,6 +85,45 @@ export function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, n
|
||||
return toRemove;
|
||||
}
|
||||
|
||||
export function reflowLargerCreateNewLayout(lines: CircularList<IBufferLine>, toRemove: number[], newLayout: number[]): number {
|
||||
// First iterate through the list and get the actual indexes to use for rows
|
||||
let nextToRemoveIndex = 0;
|
||||
let nextToRemoveStart = toRemove[nextToRemoveIndex];
|
||||
let countRemovedSoFar = 0;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (nextToRemoveStart === i) {
|
||||
const countToRemove = toRemove[++nextToRemoveIndex];
|
||||
|
||||
// Tell markers that there was a deletion
|
||||
lines.emit('delete', {
|
||||
index: i - countRemovedSoFar,
|
||||
amount: countToRemove
|
||||
} as IDeleteEvent);
|
||||
|
||||
i += countToRemove - 1;
|
||||
countRemovedSoFar += countToRemove;
|
||||
nextToRemoveStart = toRemove[++nextToRemoveIndex];
|
||||
} else {
|
||||
newLayout.push(i);
|
||||
}
|
||||
}
|
||||
return countRemovedSoFar;
|
||||
}
|
||||
|
||||
export function reflowLargerApplyNewLayout(lines: CircularList<IBufferLine>, newLayout: number[]): void {
|
||||
// Record original lines so they don't get overridden when we rearrange the list
|
||||
const newLayoutLines: BufferLine[] = [];
|
||||
for (let i = 0; i < newLayout.length; i++) {
|
||||
newLayoutLines.push(lines.get(newLayout[i]) as BufferLine);
|
||||
}
|
||||
|
||||
// Rearrange the list
|
||||
for (let i = 0; i < newLayoutLines.length; i++) {
|
||||
lines.set(i, newLayoutLines[i]);
|
||||
}
|
||||
lines.length = newLayout.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new line lengths for a given wrapped line. The purpose of this function it to pre-
|
||||
* compute the wrapping points since wide characters may need to be wrapped onto the following line.
|
||||
|
||||
Reference in New Issue
Block a user