import Document from './document.ts'; import { KeyCommand } from './ansi.ts'; import Option, { None } from './option.ts'; import { Position } from './types.ts'; enum SearchDirection { Forward = 1, Backward = -1, } export class Search { private lastMatch: number = -1; private current: number = -1; private direction: SearchDirection = SearchDirection.Forward; public parent: Option = None; private parseInput(key: string) { switch (key) { case KeyCommand.ArrowRight: case KeyCommand.ArrowDown: this.direction = SearchDirection.Forward; break; case KeyCommand.ArrowLeft: case KeyCommand.ArrowUp: this.direction = SearchDirection.Backward; break; default: this.lastMatch = -1; this.direction = SearchDirection.Forward; } if (this.lastMatch === -1) { this.direction = SearchDirection.Forward; } this.current = this.lastMatch; } private getNextRow(rowCount: number): number { this.current += this.direction; if (this.current === -1) { this.current = rowCount - 1; } else if (this.current === rowCount) { this.current = 0; } return this.current; } public search(q: string, key: string): Option { if (this.parent.isNone()) { return None; } const parent = this.parent.unwrap(); this.parseInput(key); let i = 0; for (; i < parent.numRows; i++) { const current = this.getNextRow(parent.numRows); const row = parent.row(current); if (row === null) { continue; } const possible = row.find(q); if (possible.isSome()) { this.lastMatch = current; return possible.map((p: number) => Position.at(p, current)); } } return None; } }