summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/il.ha59
-rw-r--r--tui/widget/list/scrolllist.ha18
2 files changed, 77 insertions, 0 deletions
diff --git a/cmd/il.ha b/cmd/il.ha
index ce4b89b..abbde84 100644
--- a/cmd/il.ha
+++ b/cmd/il.ha
@@ -5,6 +5,7 @@ use bufio;
use os;
use strings;
use fmt;
+use io;
export fn main() void = {
const scanner = bufio::newscanner(os::stdin);
@@ -28,6 +29,9 @@ export fn main() void = {
vl.layout.print(&vl);
+ let term: (str | void) = void;
+ defer if (term is str) free(term as str) else void;
+ let revsearch = false;
for (true) {
const r = tui::read(&state)!;
if (r == 'j') {
@@ -55,6 +59,61 @@ export fn main() void = {
fmt::println(li.items[li.cursor])!;
break;
};
+ if (r == '/' || r == '?') {
+ revsearch = r == '?';
+ term = search(&state, &li, r as rune);
+ if (revsearch) prevsearch(&li, term) else nextsearch(&li, term);
+ };
+ if (r == 'n') {
+ if (revsearch) prevsearch(&li, term) else nextsearch(&li, term);
+ };
+ if (r == 'N') {
+ if (!revsearch) prevsearch(&li, term) else nextsearch(&li, term);
+ };
vl.layout.print(&vl);
};
};
+
+fn search(state: *tui::tui, li: *list::scrolllist, prefix: (str | rune) = '/') (str | void) = {
+ tui::unraw(state);
+ defer tui::raw(state)!;
+ fmt::fprint(state.out, prefix)!;
+ const uline = match (bufio::read_line(state.out)!) {
+ case let u: []u8 =>
+ yield u;
+ case io::EOF =>
+ return;
+ };
+ defer free(uline);
+ return strings::dup(strings::fromutf8(uline)!);
+};
+
+fn nextsearch(li: *list::scrolllist, term: (str | void)) void = {
+ const term = match (term) {
+ case let term: str =>
+ yield term;
+ case void =>
+ return;
+ };
+ for (let i = li.cursor + 1; i < len(li.items); i += 1) {
+ if (strings::contains(li.items[i], term)) {
+ list::setcursor(li, i: u16);
+ return;
+ };
+ };
+};
+
+fn prevsearch(li: *list::scrolllist, term: (str | void)) void = {
+ const term = match (term) {
+ case let term: str =>
+ yield term;
+ case void =>
+ return;
+ };
+ for (let i: int = li.cursor: int - 1; i >= 0; i -= 1) {
+ if (strings::contains(li.items[i], term)) {
+ list::setcursor(li, i: u16);
+ return;
+ };
+ };
+};
diff --git a/tui/widget/list/scrolllist.ha b/tui/widget/list/scrolllist.ha
index 3aaad87..d08c7d7 100644
--- a/tui/widget/list/scrolllist.ha
+++ b/tui/widget/list/scrolllist.ha
@@ -115,6 +115,24 @@ export fn bottom(li: *scrolllist) void = {
li.frame.start = len(li.items): u16 - sz;
};
+export fn setcursor(li: *scrolllist, newpos: u16) void = {
+ li.cursor = newpos;
+ reframe(li);
+};
+
+fn reframe(li: *scrolllist) void = {
+ if (li.cursor > li.frame.end) {
+ const diff = li.frame.end - li.frame.start;
+ li.frame.start = li.cursor;
+ li.frame.end = li.frame.start + diff;
+ };
+ if (li.cursor < li.frame.start) {
+ const diff = li.frame.end - li.frame.start;
+ li.frame.end = li.cursor;
+ li.frame.start = li.frame.end - diff;
+ };
+};
+
fn stylesscrolllist(widget: *widget::widget, txt: str, idx: size) str = {
const list = widget: *scrolllist;
const idx = idx + list.frame.start;