mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
#2444: Fix wrapped lines search
This commit is contained in:
@@ -12,6 +12,11 @@ export interface ISearchOptions {
|
||||
incremental?: boolean;
|
||||
}
|
||||
|
||||
export interface ISearchPosition {
|
||||
startCol: number;
|
||||
startRow: number;
|
||||
}
|
||||
|
||||
export interface ISearchResult {
|
||||
term: string;
|
||||
col: number;
|
||||
@@ -71,17 +76,23 @@ export class SearchAddon implements ITerminalAddon {
|
||||
|
||||
this._initLinesCache();
|
||||
|
||||
const searchPosition: ISearchPosition = {
|
||||
startRow,
|
||||
startCol
|
||||
};
|
||||
|
||||
// Search startRow
|
||||
let result = this._findInLine(term, startRow, startCol, searchOptions);
|
||||
let result = this._findInLine(term, searchPosition, searchOptions);
|
||||
|
||||
// Search from startRow + 1 to end
|
||||
if (!result) {
|
||||
|
||||
for (let y = startRow + 1; y < this._terminal.buffer.baseY + this._terminal.rows; y++) {
|
||||
|
||||
searchPosition.startRow = y;
|
||||
searchPosition.startCol = 0;
|
||||
// If the current line is wrapped line, increase index of column to ignore the previous scan
|
||||
// Otherwise, reset beginning column index to zero with set new unwrapped line index
|
||||
result = this._findInLine(term, y, 0, searchOptions);
|
||||
result = this._findInLine(term, searchPosition, searchOptions);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
@@ -90,7 +101,9 @@ export class SearchAddon implements ITerminalAddon {
|
||||
// If we hit the bottom and didn't search from the very top wrap back up
|
||||
if (!result && startRow !== 0) {
|
||||
for (let y = 0; y < startRow; y++) {
|
||||
result = this._findInLine(term, y, 0, searchOptions);
|
||||
searchPosition.startRow = y;
|
||||
searchPosition.startCol = 0;
|
||||
result = this._findInLine(term, searchPosition, searchOptions);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
@@ -131,21 +144,26 @@ export class SearchAddon implements ITerminalAddon {
|
||||
}
|
||||
|
||||
this._initLinesCache();
|
||||
const searchPosition: ISearchPosition = {
|
||||
startRow,
|
||||
startCol
|
||||
};
|
||||
|
||||
if (incremental) {
|
||||
result = this._findInLine(term, startRow, startCol, searchOptions, false);
|
||||
result = this._findInLine(term, searchPosition, searchOptions, false);
|
||||
if (!(result && result.row === startRow && result.col === startCol)) {
|
||||
result = this._findInLine(term, startRow, startCol, searchOptions, true);
|
||||
result = this._findInLine(term, searchPosition, searchOptions, true);
|
||||
}
|
||||
} else {
|
||||
result = this._findInLine(term, startRow, startCol, searchOptions, isReverseSearch);
|
||||
result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);
|
||||
}
|
||||
|
||||
// Search from startRow - 1 to top
|
||||
if (!result) {
|
||||
startCol = this._terminal.cols;
|
||||
searchPosition.startCol = Math.max(searchPosition.startCol, this._terminal.cols);
|
||||
for (let y = startRow - 1; y >= 0; y--) {
|
||||
result = this._findInLine(term, y, startCol, searchOptions, isReverseSearch);
|
||||
searchPosition.startRow = y;
|
||||
result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
@@ -154,7 +172,8 @@ export class SearchAddon implements ITerminalAddon {
|
||||
// If we hit the top and didn't search from the very bottom wrap back down
|
||||
if (!result && startRow !== (this._terminal.buffer.baseY + this._terminal.rows)) {
|
||||
for (let y = (this._terminal.buffer.baseY + this._terminal.rows); y > startRow; y--) {
|
||||
result = this._findInLine(term, y, startCol, searchOptions, isReverseSearch);
|
||||
searchPosition.startRow = y;
|
||||
result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
@@ -213,18 +232,28 @@ export class SearchAddon implements ITerminalAddon {
|
||||
* started on an earlier line then it is skipped since it will be properly searched when the terminal line that the
|
||||
* text starts on is searched.
|
||||
* @param term The search term.
|
||||
* @param row The line to start the search from.
|
||||
* @param col The column to start the search from.
|
||||
* @param {ISearchPosition} position The position to start the search.
|
||||
* @param searchOptions Search options.
|
||||
* @return The search result if it was found.
|
||||
*/
|
||||
protected _findInLine(term: string, row: number, col: number, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult | undefined {
|
||||
protected _findInLine(term: string, searchPosition: ISearchPosition, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult | undefined {
|
||||
const terminal = this._terminal!;
|
||||
let row = searchPosition.startRow;
|
||||
const col = searchPosition.startCol;
|
||||
|
||||
// Ignore wrapped lines, only consider on unwrapped line (first row of command string).
|
||||
const firstLine = terminal.buffer.getLine(row);
|
||||
if (firstLine && firstLine.isWrapped) {
|
||||
return;
|
||||
if (isReverseSearch) {
|
||||
searchPosition.startCol += terminal.cols;
|
||||
}
|
||||
else {
|
||||
// This will iterate until we find the line start.
|
||||
// When we find it, we will search using the calculated start column.
|
||||
searchPosition.startRow--;
|
||||
searchPosition.startCol += terminal.cols;
|
||||
return this._findInLine(term, searchPosition, searchOptions);
|
||||
}
|
||||
}
|
||||
let stringLine = this._linesCache ? this._linesCache[row] : void 0;
|
||||
if (stringLine === void 0) {
|
||||
|
||||
Reference in New Issue
Block a user