mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
fix overscan issue and enable linkify of partial shown matches
This commit is contained in:
+23
-3
@@ -371,8 +371,8 @@ export class Buffer implements IBuffer {
|
||||
this.markers.splice(this.markers.indexOf(marker), 1);
|
||||
}
|
||||
|
||||
public iterator(trimRight: boolean, startIndex?: number, endIndex?: number): IBufferStringIterator {
|
||||
return new BufferStringIterator(this, trimRight, startIndex, endIndex);
|
||||
public iterator(trimRight: boolean, startIndex?: number, endIndex?: number, startOverscan?: number, endOverscan?: number): IBufferStringIterator {
|
||||
return new BufferStringIterator(this, trimRight, startIndex, endIndex, startOverscan, endOverscan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,6 +401,18 @@ export class Marker extends EventEmitter implements IMarker {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator to get unwrapped content strings from the buffer.
|
||||
* The iterator returns at least the string data between the borders
|
||||
* `startIndex` and `endIndex` (exclusive) and will expand the lines
|
||||
* by `startOverscan` to the top and by `endOverscan` to the bottom,
|
||||
* if no new line was found in between.
|
||||
* It will never read/return string data beyond `startIndex - startOverscan`
|
||||
* or `endIndex + endOverscan`. Therefore the first and last line might be truncated.
|
||||
* It is possible to always get the full string for the first and last line as well
|
||||
* by setting the overscan values to the actual buffer length, but not recommended
|
||||
* since it might return the whole buffer within a single string in a worst case scenario.
|
||||
*/
|
||||
export class BufferStringIterator implements IBufferStringIterator {
|
||||
private _current: number;
|
||||
|
||||
@@ -408,7 +420,9 @@ export class BufferStringIterator implements IBufferStringIterator {
|
||||
private _buffer: IBuffer,
|
||||
private _trimRight: boolean,
|
||||
private _startIndex: number = 0,
|
||||
private _endIndex: number = _buffer.lines.length
|
||||
private _endIndex: number = _buffer.lines.length,
|
||||
private _startOverscan: number = 0,
|
||||
private _endOverscan: number = 0
|
||||
) {
|
||||
this._current = this._startIndex;
|
||||
}
|
||||
@@ -419,6 +433,12 @@ export class BufferStringIterator implements IBufferStringIterator {
|
||||
|
||||
public next(): IBufferStringIteratorResult {
|
||||
const range = this._buffer.getWrappedRangeForLine(this._current);
|
||||
if (range.first < this._startIndex - this._startOverscan) {
|
||||
range.first = this._startIndex - this._startOverscan;
|
||||
}
|
||||
if (range.last > this._endIndex + this._endOverscan) {
|
||||
range.last = this._endIndex + this._endOverscan;
|
||||
}
|
||||
let result = '';
|
||||
for (let i = range.first; i <= range.last; ++i) {
|
||||
// TODO: always apply trimRight after fixing #1685
|
||||
|
||||
+18
-13
@@ -21,6 +21,12 @@ export class Linkifier extends EventEmitter implements ILinkifier {
|
||||
*/
|
||||
protected static readonly TIME_BEFORE_LINKIFY = 200;
|
||||
|
||||
/**
|
||||
* Limit of the unwrapping line expansion (overscan) at the top and bottom
|
||||
* of the actual viewport.
|
||||
*/
|
||||
protected static readonly OVERSCAN_LIMIT = 5;
|
||||
|
||||
protected _linkMatchers: ILinkMatcher[] = [];
|
||||
|
||||
private _mouseZoneManager: IMouseZoneManager;
|
||||
@@ -88,11 +94,17 @@ export class Linkifier extends EventEmitter implements ILinkifier {
|
||||
return;
|
||||
}
|
||||
|
||||
// iterate over the range of unwrapped content strings within start..end (excluding)
|
||||
// _doLinkifyRow gets full unwrapped lines with the start row as buffer offset for every matcher
|
||||
// for wrapped content over several rows the iterator might return rows outside the viewport
|
||||
// we skip those later in _doLinkifyRow
|
||||
const iterator = this._terminal.buffer.iterator(false, absoluteRowIndexStart, this._terminal.buffer.ydisp + this._rowsToLinkify.end + 1);
|
||||
// Iterate over the range of unwrapped content strings within start..end (excluding).
|
||||
// _doLinkifyRow gets full unwrapped lines with the start row as buffer offset for every matcher.
|
||||
// The unwrapping is needed to also match content that got wrapped at the right side.
|
||||
// To avoid a worst case szenario where the whole buffer contains just a single unwrapped string
|
||||
// we limit this line expansion beyond the actual viewport to -5 and +5 real buffer lines (overscan).
|
||||
// This comes with the tradeoff that match longer than 5 buffer lines will not match anymore at the
|
||||
// viewport borders.
|
||||
const iterator = this._terminal.buffer.iterator(
|
||||
false, absoluteRowIndexStart, this._terminal.buffer.ydisp + this._rowsToLinkify.end + 1,
|
||||
Linkifier.OVERSCAN_LIMIT, Linkifier.OVERSCAN_LIMIT);
|
||||
console.log('linkify rows', absoluteRowIndexStart, this._terminal.buffer.ydisp + this._rowsToLinkify.end + 1);
|
||||
while (iterator.hasNext()) {
|
||||
const lineData: IBufferStringIteratorResult = iterator.next();
|
||||
for (let i = 0; i < this._linkMatchers.length; i++) {
|
||||
@@ -204,14 +216,6 @@ export class Linkifier extends EventEmitter implements ILinkifier {
|
||||
// get the buffer index as [absolute row, col] for the match
|
||||
const bufferIndex = this._terminal.buffer.stringIndexToBufferIndex(rowIndex, stringIndex);
|
||||
|
||||
// skip rows outside of the viewport
|
||||
if (bufferIndex[0] - this._terminal.buffer.ydisp < 0) {
|
||||
continue;
|
||||
}
|
||||
if (bufferIndex[0] - this._terminal.buffer.ydisp > this._terminal.rows) {
|
||||
break;
|
||||
}
|
||||
|
||||
const line = this._terminal.buffer.lines.get(bufferIndex[0]);
|
||||
const char = line.get(bufferIndex[1]);
|
||||
let fg: number | undefined;
|
||||
@@ -254,6 +258,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
|
||||
x2 = this._terminal.cols;
|
||||
y2--;
|
||||
}
|
||||
console.log(x1, y1, x2, y2);
|
||||
|
||||
this._mouseZoneManager.add(new MouseZone(
|
||||
x1 + 1,
|
||||
|
||||
+1
-1
@@ -296,7 +296,7 @@ export interface IBuffer {
|
||||
nextStop(x?: number): number;
|
||||
prevStop(x?: number): number;
|
||||
stringIndexToBufferIndex(lineIndex: number, stringIndex: number): number[];
|
||||
iterator(trimRight: boolean, startIndex?: number, endIndex?: number): IBufferStringIterator;
|
||||
iterator(trimRight: boolean, startIndex?: number, endIndex?: number, startOverscan?: number, endOverscan?: number): IBufferStringIterator;
|
||||
}
|
||||
|
||||
export interface IBufferSet extends IEventEmitter {
|
||||
|
||||
Reference in New Issue
Block a user