More work on findNext

This commit is contained in:
Daniel Imms
2017-06-12 21:59:46 -07:00
parent 8d12881a1c
commit 280b698a50
3 changed files with 60 additions and 10 deletions
+2
View File
@@ -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
View File
@@ -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
+3
View File
@@ -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.
*/