use libui; use libui::list; use encoding::utf8; use io; use fmt; use os; use strings; use unix::tty; type mainUI = struct { list: list::listwidget, }; fn globalrunehandler(ui: *libui::ttyui, r: rune) bool = { if (r == 'q') { return true; }; return false; }; fn runehandler(l: *list::listwidget, r: rune) bool = { switch (r) { case 'j' => list::down(l); case 'k' => list::up(l); case 'l' => // to print properly suspend the ui, print, then resume libui::suspend(&l.ui); fmt::println(l.items[l.cursor])!; libui::resume(&l.ui); return true; case 'g' => list::top(l); //l.cursor = 0; case 'G' => list::bottom(l); //l.cursor = len(l.items) - 1; case '/' => // TODO add commandline support fmt::fprintln(os::stderr, "searching")!; let c = l.cursor; if (list::search(l, "workspace") != c) { fmt::fprintln(os::stderr, "changed")!; }; case '\n' => // Enter seems to crash for now (compiler bug) 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; }; export fn main() void = { let in = match (io::drain(os::stdin)) { case let in: []u8 => yield in; case let e: io::error => fmt::fatal(io::strerror(e)); }; defer free(in); let sin = strings::fromutf8(in); sin = strings::trim(sin, '\n'); let items = strings::split(sin, "\n"); defer free(items); let ui = libui::init(); defer libui::finish(&ui); let l = list::newlist(ui, items...); libui::addlistener(&ui, &globalrunehandler); list::addlistener(&l, &runehandler); libui::clear(l.ui); match (list::print(&l)) { case void => yield; case let e: io::error => fmt::fprintln(os::stderr, io::strerror(e))!; return; case let e: tty::error => fmt::fprintln(os::stderr, tty::strerror(e))!; return; }; for (true) { let r = match (libui::scan(ui)) { case let r: rune => yield r; case utf8::invalid => fmt::fprintln(os::stderr, "Invalid utf8 sequence")!; break; case io::EOF => fmt::fprintln(os::stderr, "EOF")!; break; case let e: io::error => fmt::fprintln(os::stderr, io::strerror(e))!; break; }; if (libui::notify(&ui, r)) { break; }; if (list::notify(&l, r)) { break; }; }; };