diff options
| author | Julian Hurst <julian.hurst@digdash.com> | 2025-03-20 12:33:37 +0100 |
|---|---|---|
| committer | Julian Hurst <julian.hurst@digdash.com> | 2025-03-20 12:33:37 +0100 |
| commit | 39b580c33ce568bb3b055df6bc4b16fa5969e77b (patch) | |
| tree | 7970422d1fd128ee6a7025c9eae480d5893d7d72 | |
| parent | 8d4bc50570fcb9654ba6fe931dc937ea476b659e (diff) | |
| parent | ddac62a2a43ee62da4f5302e9cb2958f6ff82cea (diff) | |
| download | hare-tui-39b580c33ce568bb3b055df6bc4b16fa5969e77b.tar.gz | |
Merge branch 'master' into nomem
| -rw-r--r-- | cmd/il.ha | 59 | ||||
| -rw-r--r-- | tui/widget/list/scrolllist.ha | 18 |
2 files changed, 77 insertions, 0 deletions
@@ -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; |
