5 // import { ITerminal } from '../../Interfaces';
6 // import { translateBufferLineToString } from '../../utils/BufferLine';
8 interface ISearchResult {
15 * A class that knows how to search the terminal and how to display the results.
17 export class SearchHelper {
18 constructor(private _terminal: any, private _translateBufferLineToString: any) {
19 // TODO: Search for multiple instances on 1 line
20 // TODO: Don't use the actual selection, instead use a "find selection" so multiple instances can be highlighted
21 // TODO: Highlight other instances in the viewport
22 // TODO: Support regex, case sensitivity, etc.
26 * Find the next instance of the term, then scroll to and select it. If it
27 * doesn't exist, do nothing.
28 * @param term Tne search term.
29 * @return Whether a result was found.
31 public findNext(term: string): boolean {
32 if (!term || term.length === 0) {
36 let result: ISearchResult;
38 let startRow = this._terminal.buffer.ydisp;
39 if (this._terminal.selectionManager.selectionEnd) {
40 // Start from the selection end if there is a selection
41 startRow = this._terminal.selectionManager.selectionEnd[1];
44 // Search from ydisp + 1 to end
45 for (let y = startRow + 1; y < this._terminal.buffer.ybase + this._terminal.rows; y++) {
46 result = this._findInLine(term, y);
52 // Search from the top to the current ydisp
54 for (let y = 0; y < startRow; y++) {
55 result = this._findInLine(term, y);
62 // Set selection and scroll if a result was found
63 return this._selectResult(result);
67 * Find the previous instance of the term, then scroll to and select it. If it
68 * doesn't exist, do nothing.
69 * @param term Tne search term.
70 * @return Whether a result was found.
72 public findPrevious(term: string): boolean {
73 if (!term || term.length === 0) {
77 let result: ISearchResult;
79 let startRow = this._terminal.buffer.ydisp;
80 if (this._terminal.selectionManager.selectionStart) {
81 // Start from the selection end if there is a selection
82 startRow = this._terminal.selectionManager.selectionStart[1];
85 // Search from ydisp + 1 to end
86 for (let y = startRow - 1; y >= 0; y--) {
87 result = this._findInLine(term, y);
93 // Search from the top to the current ydisp
95 for (let y = this._terminal.buffer.ybase + this._terminal.rows - 1; y > startRow; y--) {
96 result = this._findInLine(term, y);
103 // Set selection and scroll if a result was found
104 return this._selectResult(result);
108 * Searches a line for a search term.
109 * @param term Tne search term.
110 * @param y The line to search.
111 * @return The search result if it was found.
113 private _findInLine(term: string, y: number): ISearchResult {
114 const bufferLine = this._terminal.buffer.lines.get(y);
115 const lowerStringLine = this._translateBufferLineToString(bufferLine, true).toLowerCase();
116 const lowerTerm = term.toLowerCase();
117 const searchIndex = lowerStringLine.indexOf(lowerTerm);
118 if (searchIndex >= 0) {
128 * Selects and scrolls to a result.
129 * @param result The result to select.
130 * @return Whethera result was selected.
132 private _selectResult(result: ISearchResult): boolean {
136 this._terminal.selectionManager.setSelection(result.col, result.row, result.term.length);
137 this._terminal.scrollDisp(result.row - this._terminal.buffer.ydisp, false);