Implement backwards/forwards searching
All checks were successful
timw4mail/scroll/pipeline/head This commit looks good
All checks were successful
timw4mail/scroll/pipeline/head This commit looks good
This commit is contained in:
parent
e21944b4a4
commit
85dbd506c6
@ -1,10 +1,53 @@
|
||||
import Row from './row.ts';
|
||||
import { arrayInsert } from './fns.ts';
|
||||
import { getRuntime } from './runtime.ts';
|
||||
import { Position } from './types.ts';
|
||||
import { Position, SearchDirection } from './types.ts';
|
||||
import { KeyCommand } from './ansi.ts';
|
||||
|
||||
class Search {
|
||||
public lastMatch: number = -1;
|
||||
public current: number = -1;
|
||||
public direction: SearchDirection = SearchDirection.Forward;
|
||||
|
||||
public 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;
|
||||
}
|
||||
|
||||
public 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;
|
||||
}
|
||||
}
|
||||
|
||||
export class Document {
|
||||
#rows: Row[];
|
||||
#search: Search;
|
||||
|
||||
/**
|
||||
* Has the document been modified?
|
||||
@ -13,6 +56,7 @@ export class Document {
|
||||
|
||||
private constructor() {
|
||||
this.#rows = [];
|
||||
this.#search = new Search();
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
@ -53,15 +97,24 @@ export class Document {
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
public resetFind() {
|
||||
this.#search = new Search();
|
||||
}
|
||||
|
||||
public find(
|
||||
q: string,
|
||||
offset: Position = Position.default(),
|
||||
key: string,
|
||||
): Position | null {
|
||||
let i = offset.y;
|
||||
this.#search.parseInput(key);
|
||||
|
||||
let i = 0;
|
||||
for (; i < this.numRows; i++) {
|
||||
const possible = this.#rows[i].find(q, offset.x);
|
||||
const current = this.#search.getNextRow(this.numRows);
|
||||
|
||||
const possible = this.#rows[current].find(q);
|
||||
if (possible !== null) {
|
||||
return Position.at(possible, i);
|
||||
this.#search.lastMatch = current;
|
||||
return Position.at(possible, current);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,14 +302,15 @@ class Editor {
|
||||
const savedOffset = Position.from(this.#offset);
|
||||
|
||||
const query = await this.prompt(
|
||||
'Search: %s (ESC to cancel)',
|
||||
'Search: %s (Use ESC/Arrows/Enter)',
|
||||
(query: string, key: string) => {
|
||||
if (key === KeyCommand.Enter || key === KeyCommand.Escape) {
|
||||
this.#document.resetFind();
|
||||
return;
|
||||
}
|
||||
|
||||
if (query !== null && query.length > 0) {
|
||||
const pos = this.#document.find(query);
|
||||
const pos = this.#document.find(query, key);
|
||||
if (pos !== null) {
|
||||
this.#cursor = pos;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user