More work on findNext
This commit is contained in:
@@ -52,6 +52,8 @@ export interface ITerminal {
|
||||
|
||||
export interface ISelectionManager {
|
||||
selectionText: string;
|
||||
selectionStart: [number, number];
|
||||
selectionEnd: [number, number];
|
||||
|
||||
setSelection(row: number, col: number, length: number);
|
||||
}
|
||||
|
||||
+55
-10
@@ -1,32 +1,77 @@
|
||||
import { ITerminal } from './Interfaces';
|
||||
|
||||
interface ISearchResult {
|
||||
term: string;
|
||||
col: number;
|
||||
row: number;
|
||||
}
|
||||
|
||||
export class SearchHelper {
|
||||
constructor(private _terminal: ITerminal) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the next instance of the term, then scroll to and select it. If it
|
||||
* doesn't exist, do nothing.
|
||||
* @param term The term to search for.
|
||||
* @return Whether a result was found.
|
||||
*/
|
||||
public findNext(term: string): void {
|
||||
public findNext(term: string): boolean {
|
||||
if (!term || term.length === 0) {
|
||||
return;
|
||||
}
|
||||
// TODO: Return number of results?
|
||||
|
||||
for (let currentLine = this._terminal.ydisp; currentLine < this._terminal.ybase + this._terminal.rows; currentLine++) {
|
||||
const bufferLine = this._terminal.lines.get(currentLine);
|
||||
const stringLine = this._translateBufferLineToString(bufferLine, true);
|
||||
const searchIndex = stringLine.indexOf(term);
|
||||
if (searchIndex >= 0) {
|
||||
console.log('found term on line: ' + currentLine);
|
||||
console.log(stringLine);
|
||||
this._terminal.selectionManager.setSelection(searchIndex, currentLine, term.length);
|
||||
let result: ISearchResult;
|
||||
|
||||
let startRow = this._terminal.ydisp;
|
||||
if (this._terminal.selectionManager.selectionEnd) {
|
||||
// Start from the selection end if there is a selection
|
||||
startRow = this._terminal.selectionManager.selectionEnd[1];
|
||||
}
|
||||
|
||||
// Search from ydisp + 1 to end
|
||||
for (let y = startRow + 1; y < this._terminal.ybase + this._terminal.rows; y++) {
|
||||
result = this._findInLine(term, y);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Search from the top to the current ydisp
|
||||
if (!result) {
|
||||
for (let y = 0; y < startRow; y++) {
|
||||
result = this._findInLine(term, y);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set selection and scroll if a result was found
|
||||
return this._selectResult(result);
|
||||
}
|
||||
|
||||
private _findInLine(term: string, y: number): ISearchResult {
|
||||
const bufferLine = this._terminal.lines.get(y);
|
||||
const stringLine = this._translateBufferLineToString(bufferLine, true);
|
||||
const searchIndex = stringLine.indexOf(term);
|
||||
if (searchIndex >= 0) {
|
||||
return {
|
||||
term,
|
||||
col: searchIndex,
|
||||
row: y
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private _selectResult(result: ISearchResult): boolean {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
this._terminal.selectionManager.setSelection(result.col, result.row, result.term.length);
|
||||
const scrollAmount = Math.max(Math.min(result.row - this._terminal.ydisp, this._terminal.ybase), 0);
|
||||
this._terminal.scrollDisp(scrollAmount, false);
|
||||
}
|
||||
|
||||
// TODO: Consolidate with SelectionManager function
|
||||
|
||||
@@ -156,6 +156,9 @@ export class SelectionManager extends EventEmitter {
|
||||
this._buffer = buffer;
|
||||
}
|
||||
|
||||
public get selectionStart(): [number, number] { return this._model.finalSelectionStart; }
|
||||
public get selectionEnd(): [number, number] { return this._model.finalSelectionEnd; }
|
||||
|
||||
/**
|
||||
* Gets whether there is an active text selection.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user