diff options
| author | Julian Hurst <julian.hurst92@gmail.com> | 2022-05-17 00:13:56 +0200 |
|---|---|---|
| committer | Julian Hurst <julian.hurst92@gmail.com> | 2022-05-17 00:13:56 +0200 |
| commit | a421424dda24a25f5e8c0387fff54296d821e8bb (patch) | |
| tree | c5be79562fb49f2ea44611f3ebaf853e06251118 | |
| parent | dbf800f59831852ace25f95d92875fe360735566 (diff) | |
| download | ilhare-a421424dda24a25f5e8c0387fff54296d821e8bb.tar.gz | |
Add list::setitems, sorting and decouple handlers from main.ha
| -rw-r--r-- | handlers.ha | 200 | ||||
| -rw-r--r-- | libui/widget/list/list.ha | 12 | ||||
| -rw-r--r-- | main.ha | 183 |
3 files changed, 215 insertions, 180 deletions
diff --git a/handlers.ha b/handlers.ha new file mode 100644 index 0000000..ef374ef --- /dev/null +++ b/handlers.ha @@ -0,0 +1,200 @@ +use libui; +use libui::widget; +use libui::widget::list; +use sort; +use slices; +use encoding::utf8; +use fmt; +use bufio; +use os; +use regex; +use io; +use strings; +use unix::tty; + +let itemscopy: []str = []; + +fn globalrunehandler(ui: *libui::ttyui, r: rune) bool = { + if (r == 'q') { + return true; + }; + return false; +}; + +fn runehandler(l: *widget::widget, r: rune) bool = { + const l = l: *list::listwidget; + switch (r) { + case 'j' => + list::down(l); + case 'k' => + list::up(l); + case 'd' => + list::pagedown(l); + case 'u' => + list::pageup(l); + case 'l' => + // to print properly suspend the ui, print, then resume + libui::suspend(&l.ui); + //fmt::println(l.items[l.cursor])!; + match (list::selected(*l)) { + case let s: str => + fmt::println(s)!; + case let s: []str => + defer free(s); + const out = strings::join("\n", s...); + defer free(out); + fmt::println(out)!; + }; + libui::resume(&l.ui); + return true; + case 'g' => + list::top(l); + case 'G' => + list::bottom(l); + case 'n' => + if (searchforward) { + list::search(l, searchterm); + } else { + list::rsearch(l, searchterm); + }; + case 'N' => + if (searchforward) { + list::rsearch(l, searchterm); + } else { + list::search(l, searchterm); + }; + case '?' => + // TODO add commandline support maybe + libui::suspend(&l.ui); + fmt::fprint(l.ui.f, '?')!; + let line = match (bufio::scanline(l.ui.f)) { + case let s: []u8 => + yield s; + case io::EOF => + fmt::fprintln(os::stderr, "EOF")!; + return true; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + return true; + }; + //defer free(line); + searchterm = strings::fromutf8(line); + searchforward = false; + let c = l.cursor; + list::rsearch(l, searchterm); + libui::resume(&l.ui); + case '/' => + // TODO add commandline support maybe + libui::suspend(&l.ui); + fmt::fprint(l.ui.f, '/')!; + let line = match (bufio::scanline(l.ui.f)) { + case let s: []u8 => + yield s; + case io::EOF => + fmt::fprintln(os::stderr, "EOF")!; + return true; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + return true; + }; + //defer free(line); + searchterm = strings::fromutf8(line); + searchforward = true; + let c = l.cursor; + list::search(l, searchterm); + libui::resume(&l.ui); + case 'o' => + // order + sort::strings(l.items); + case 'O' => + // reverse order + sort::strings(l.items); + slices::reverse(l.items: []void, size(str)); + case 'p' => + list::setitems(l, itemscopy...); + case 's' => + // TODO add commandline support maybe + libui::suspend(&l.ui); + fmt::fprint(l.ui.f, "s: ")!; + let line = match (bufio::scanline(l.ui.f)) { + case let s: []u8 => + yield s; + case io::EOF => + fmt::fprintln(os::stderr, "EOF")!; + return true; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + return true; + }; + defer free(line); + list::containsmark(l, strings::fromutf8(line)); + libui::resume(&l.ui); + case 'S' => + // TODO add commandline support maybe + libui::suspend(&l.ui); + fmt::fprint(l.ui.f, "S: ")!; + let line = match (bufio::scanline(l.ui.f)) { + case let s: []u8 => + yield s; + case io::EOF => + fmt::fprintln(os::stderr, "EOF")!; + return true; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + return true; + }; + defer free(line); + list::fnmatchmark(l, strings::fromutf8(line)); + libui::resume(&l.ui); + case 'r' => + // TODO add commandline support maybe + libui::suspend(&l.ui); + fmt::fprint(l.ui.f, "r: ")!; + let line = match (bufio::scanline(l.ui.f)) { + case let s: []u8 => + yield s; + case io::EOF => + fmt::fprintln(os::stderr, "EOF")!; + return true; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + return true; + }; + defer free(line); + match (regex::compile(strings::fromutf8(line))) { + case let re: regex::regex => + list::regexmark(l, &re); + regex::finish(&re); + case let e: regex::error => + fmt::fprintln(os::stderr, regex::strerror(e))!; + }; + libui::resume(&l.ui); + case ' ' => + list::tmark(l); + list::down(l); + case 'c' => + list::clearmarked(l); + case '\n' => + // For some reason enter doesn't send r == '\n' + fmt::fprintln(os::stderr, "This is not detected")!; + yield; + case => + let us = utf8::encoderune(r); + if (len(us) > 0 && us[0] == 13u8) { + fmt::fprintln(os::stderr, "newline")!; + }; + yield; + }; + libui::clear(l.ui); + match (list::print(l)) { + case void => + yield; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + return true; + case let e: tty::error => + fmt::fprintln(os::stderr, tty::strerror(e))!; + return true; + }; + return false; +}; diff --git a/libui/widget/list/list.ha b/libui/widget/list/list.ha index 8500482..efed759 100644 --- a/libui/widget/list/list.ha +++ b/libui/widget/list/list.ha @@ -79,6 +79,18 @@ export fn finish(list: *widget::widget) void = { widget::finishcommon(list); }; +// Set the list's items. If the length of the given items is smaller than the +// list's current items, the cursor will be set to 0z and [[reframe]] will be +// called to reset the frame. +export fn setitems(list: *listwidget, items: str...) void = { + const reset = len(items) < len(list.items); + list.items = strings::dupall(items); + if (reset) { + list.cursor = 0z; + reframe(list); + }; +}; + // Add a listener to the given list. //export fn addlistener(list: *listwidget, l: listener) void = { //append(list.listeners, l); @@ -9,8 +9,6 @@ use os; use strings; use unix::tty; use unix::signal; -use bufio; -use regex; let u: mainUI = mainUI {...}; @@ -21,182 +19,6 @@ type mainUI = struct { list: *list::listwidget, }; -fn globalrunehandler(ui: *libui::ttyui, r: rune) bool = { - if (r == 'q') { - return true; - }; - return false; -}; - -fn runehandler(l: *widget::widget, r: rune) bool = { - const l = l: *list::listwidget; - switch (r) { - case 'j' => - list::down(l); - case 'k' => - list::up(l); - case 'd' => - list::pagedown(l); - case 'u' => - list::pageup(l); - case 'l' => - // to print properly suspend the ui, print, then resume - libui::suspend(&l.ui); - //fmt::println(l.items[l.cursor])!; - match (list::selected(*l)) { - case let s: str => - fmt::println(s)!; - case let s: []str => - defer free(s); - const out = strings::join("\n", s...); - defer free(out); - fmt::println(out)!; - }; - libui::resume(&l.ui); - return true; - case 'g' => - list::top(l); - case 'G' => - list::bottom(l); - case 'n' => - if (searchforward) { - list::search(l, searchterm); - } else { - list::rsearch(l, searchterm); - }; - case 'N' => - if (searchforward) { - list::rsearch(l, searchterm); - } else { - list::search(l, searchterm); - }; - case '?' => - // TODO add commandline support maybe - libui::suspend(&l.ui); - fmt::fprint(l.ui.f, '?')!; - let line = match (bufio::scanline(l.ui.f)) { - case let s: []u8 => - yield s; - case io::EOF => - fmt::fprintln(os::stderr, "EOF")!; - return true; - case let e: io::error => - fmt::fprintln(os::stderr, io::strerror(e))!; - return true; - }; - //defer free(line); - searchterm = strings::fromutf8(line); - searchforward = false; - let c = l.cursor; - list::rsearch(l, searchterm); - libui::resume(&l.ui); - case '/' => - // TODO add commandline support maybe - libui::suspend(&l.ui); - fmt::fprint(l.ui.f, '/')!; - let line = match (bufio::scanline(l.ui.f)) { - case let s: []u8 => - yield s; - case io::EOF => - fmt::fprintln(os::stderr, "EOF")!; - return true; - case let e: io::error => - fmt::fprintln(os::stderr, io::strerror(e))!; - return true; - }; - //defer free(line); - searchterm = strings::fromutf8(line); - searchforward = true; - let c = l.cursor; - list::search(l, searchterm); - libui::resume(&l.ui); - case 's' => - // TODO add commandline support maybe - libui::suspend(&l.ui); - fmt::fprint(l.ui.f, "s: ")!; - let line = match (bufio::scanline(l.ui.f)) { - case let s: []u8 => - yield s; - case io::EOF => - fmt::fprintln(os::stderr, "EOF")!; - return true; - case let e: io::error => - fmt::fprintln(os::stderr, io::strerror(e))!; - return true; - }; - defer free(line); - list::containsmark(l, strings::fromutf8(line)); - libui::resume(&l.ui); - case 'S' => - // TODO add commandline support maybe - libui::suspend(&l.ui); - fmt::fprint(l.ui.f, "S: ")!; - let line = match (bufio::scanline(l.ui.f)) { - case let s: []u8 => - yield s; - case io::EOF => - fmt::fprintln(os::stderr, "EOF")!; - return true; - case let e: io::error => - fmt::fprintln(os::stderr, io::strerror(e))!; - return true; - }; - defer free(line); - list::fnmatchmark(l, strings::fromutf8(line)); - libui::resume(&l.ui); - case 'r' => - // TODO add commandline support maybe - libui::suspend(&l.ui); - fmt::fprint(l.ui.f, "r: ")!; - let line = match (bufio::scanline(l.ui.f)) { - case let s: []u8 => - yield s; - case io::EOF => - fmt::fprintln(os::stderr, "EOF")!; - return true; - case let e: io::error => - fmt::fprintln(os::stderr, io::strerror(e))!; - return true; - }; - defer free(line); - match (regex::compile(strings::fromutf8(line))) { - case let re: regex::regex => - list::regexmark(l, &re); - regex::finish(&re); - case let e: regex::error => - fmt::fprintln(os::stderr, regex::strerror(e))!; - }; - libui::resume(&l.ui); - case ' ' => - list::tmark(l); - list::down(l); - case 'c' => - list::clearmarked(l); - case '\n' => - // For some reason enter doesn't send r == '\n' - fmt::fprintln(os::stderr, "This is not detected")!; - yield; - case => - let us = utf8::encoderune(r); - if (len(us) > 0 && us[0] == 13u8) { - fmt::fprintln(os::stderr, "newline")!; - }; - yield; - }; - libui::clear(l.ui); - match (list::print(l)) { - case void => - yield; - case let e: io::error => - fmt::fprintln(os::stderr, io::strerror(e))!; - return true; - case let e: tty::error => - fmt::fprintln(os::stderr, tty::strerror(e))!; - return true; - }; - return false; -}; - fn sighandler(sig: int, info: *signal::siginfo, ucontext: *void) void = { switch (sig) { case signal::SIGWINCH => @@ -221,7 +43,9 @@ export fn main() void = { defer free(in); let sin = strings::fromutf8(in); sin = strings::trim(sin, '\n'); - let items = strings::split(sin, "\n"); + let items = strings::split(sin, "\n"); // freed by list::finish + itemscopy = strings::dupall(items); + defer strings::freeall(itemscopy); let ui = libui::init(); defer libui::finish(&ui); @@ -230,7 +54,6 @@ export fn main() void = { widget::addlistener(&l, &runehandler); let layout = layout::newlayout(&l); - defer layout::finishall(&layout); //defer free(searchterm); |
