From 7d8f698096649120b31e601332811be7868770b4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Jun 2017 19:43:18 -0700 Subject: [PATCH] Add findPrevious --- src/SearchHelper.ts | 46 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/SearchHelper.ts b/src/SearchHelper.ts index 5c90a966..4a8631d1 100644 --- a/src/SearchHelper.ts +++ b/src/SearchHelper.ts @@ -8,6 +8,10 @@ interface ISearchResult { export class SearchHelper { constructor(private _terminal: ITerminal) { + // TODO: Search for multiple instances on 1 line + // TODO: Don't use the actual selection, instead use a "find selection" so multiple instances can be highlighted + // TODO: Highlight other instances in the viewport + // TODO: Support regex, case sensitivity, etc. } /** @@ -20,7 +24,6 @@ export class SearchHelper { if (!term || term.length === 0) { return; } - // TODO: Return number of results? let result: ISearchResult; @@ -52,6 +55,47 @@ export class SearchHelper { return this._selectResult(result); } + /** + * Find the previous 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 findPrevious(term: string): boolean { + if (!term || term.length === 0) { + return; + } + + let result: ISearchResult; + + let startRow = this._terminal.ydisp; + if (this._terminal.selectionManager.selectionStart) { + // Start from the selection end if there is a selection + startRow = this._terminal.selectionManager.selectionStart[1]; + } + + // Search from ydisp + 1 to end + for (let y = startRow - 1; y >= 0; y--) { + result = this._findInLine(term, y); + if (result) { + break; + } + } + + // Search from the top to the current ydisp + if (!result) { + for (let y = this._terminal.ybase + this._terminal.rows - 1; 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);