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 Row from './row.ts';
|
||||||
import { arrayInsert } from './fns.ts';
|
import { arrayInsert } from './fns.ts';
|
||||||
import { getRuntime } from './runtime.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 {
|
export class Document {
|
||||||
#rows: Row[];
|
#rows: Row[];
|
||||||
|
#search: Search;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has the document been modified?
|
* Has the document been modified?
|
||||||
@ -13,6 +56,7 @@ export class Document {
|
|||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
this.#rows = [];
|
this.#rows = [];
|
||||||
|
this.#search = new Search();
|
||||||
this.dirty = false;
|
this.dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,15 +97,24 @@ export class Document {
|
|||||||
this.dirty = false;
|
this.dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public resetFind() {
|
||||||
|
this.#search = new Search();
|
||||||
|
}
|
||||||
|
|
||||||
public find(
|
public find(
|
||||||
q: string,
|
q: string,
|
||||||
offset: Position = Position.default(),
|
key: string,
|
||||||
): Position | null {
|
): Position | null {
|
||||||
let i = offset.y;
|
this.#search.parseInput(key);
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
for (; i < this.numRows; i++) {
|
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) {
|
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 savedOffset = Position.from(this.#offset);
|
||||||
|
|
||||||
const query = await this.prompt(
|
const query = await this.prompt(
|
||||||
'Search: %s (ESC to cancel)',
|
'Search: %s (Use ESC/Arrows/Enter)',
|
||||||
(query: string, key: string) => {
|
(query: string, key: string) => {
|
||||||
if (key === KeyCommand.Enter || key === KeyCommand.Escape) {
|
if (key === KeyCommand.Enter || key === KeyCommand.Escape) {
|
||||||
|
this.#document.resetFind();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query !== null && query.length > 0) {
|
if (query !== null && query.length > 0) {
|
||||||
const pos = this.#document.find(query);
|
const pos = this.#document.find(query, key);
|
||||||
if (pos !== null) {
|
if (pos !== null) {
|
||||||
this.#cursor = pos;
|
this.#cursor = pos;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user