aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--main.ha142
2 files changed, 74 insertions, 70 deletions
diff --git a/README.md b/README.md
index 8c16b9e..1e458e3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Building
-To build il(hare) you must first install [hare](https://harelang.org) and [hare-libtui](https://git.sr.ht/~ark/hare-libtui) then run:
+To build il(hare) you must first install [hare](https://harelang.org), [hare-libtui](https://git.sr.ht/~ark/hare-libtui) and [hare-ev](https://git.sr.ht/~sircmpwn/hare-ev) then run:
```
hare build -o il .
diff --git a/main.ha b/main.ha
index 6c67efb..b5519c7 100644
--- a/main.ha
+++ b/main.ha
@@ -12,6 +12,7 @@ use unix::signal;
use unix::poll;
use errors;
use getopt;
+use ev;
let searchterm: str = "";
let searchforward: bool = true;
@@ -42,6 +43,60 @@ fn resize(list: *list::listwidget) void = {
list::resize(list, oldsz);
};
+fn handle_signal(file: *ev::file, sig: signal::sig) void = {
+ if (sig == signal::sig::WINCH) {
+ let l = ev::getuser(file): *list::listwidget;
+ resize(l);
+ };
+};
+
+type state = struct {
+ ui: *libtui::ttyui,
+ l: *list::listwidget,
+ layout: libtui::layout::layout,
+};
+
+fn handle_ui(file: *ev::file) void = {
+ let st = ev::getuser(file): *state;
+ let r = match (libtui::scan(*st.ui)) {
+ case let r: rune =>
+ yield r;
+ case utf8::invalid =>
+ fmt::fprintln(os::stderr, "Invalid utf8 sequence")!;
+ ev::stop(ev::getloop(file));
+ return;
+ case io::EOF =>
+ fmt::fprintln(os::stderr, "EOF")!;
+ ev::stop(ev::getloop(file));
+ return;
+ case let e: io::error =>
+ fmt::fprintln(os::stderr, io::strerror(e))!;
+ ev::stop(ev::getloop(file));
+ return;
+ };
+ if (libtui::notify(st.ui, r)) {
+ ev::stop(ev::getloop(file));
+ };
+ if (list::notify(st.l, r)) {
+ ev::stop(ev::getloop(file));
+ };
+};
+
+fn handle_print(loop: *ev::loop, user: nullable *opaque) void = {
+ let st = user: *state;
+ libtui::doclear(&st.l.widget.ui);
+ match (layout::print(st.layout)) {
+ case void =>
+ yield;
+ case let e: io::error =>
+ fmt::fprintln(os::stderr, io::strerror(e))!;
+ ev::stop(loop);
+ case let e: tty::error =>
+ fmt::fprintln(os::stderr, tty::strerror(e))!;
+ ev::stop(loop);
+ };
+};
+
export fn main() void = {
const cmd = getopt::parse(os::args,
"interactive list",
@@ -103,79 +158,28 @@ export fn main() void = {
//defer free(searchterm);
//libtui::clear(l.widget.ui);
- signal::block(signal::sig::WINCH);
- let sfd = match (signal::signalfd(signal::sig::WINCH)) {
- case let sfd: io::file =>
- yield sfd;
- case let e: errors::error =>
- fmt::fatal(errors::strerror(e));
+ let loop = ev::newloop()!;
+ defer ev::finish(&loop);
+ const signal = ev::signal(&loop, &handle_signal, signal::sig::WINCH)!;
+ defer ev::close(signal);
+ ev::setuser(signal, &l);
+
+ let st = state {
+ ui = &ui,
+ l = &l,
+ layout = layout,
};
- defer io::close(sfd)!;
-
- const pollfds: [2]poll::pollfd = [poll::pollfd {
- fd = ui.f,
- events = poll::event::POLLIN,
- ...
- }, poll::pollfd {
- fd = sfd,
- events = poll::event::POLLIN,
- ...
- }];
-
- for (true) {
- libtui::doclear(&l.widget.ui);
- match (layout::print(layout)) {
- case void =>
- yield;
- case let e: io::error =>
- fmt::fatal(io::strerror(e));
- case let e: tty::error =>
- fmt::fprintln(os::stderr, tty::strerror(e))!;
- break;
- };
- let nb = match (poll::poll(pollfds, poll::INDEF)) {
- case let nb: uint =>
- yield nb;
- case let e: poll::error =>
- fmt::fprintln(os::stderr, poll::strerror(e))!;
- break;
- };
- let readin = false;
- if (nb == 0) {
- continue;
- } else {
- if (pollfds[0].revents & poll::event::POLLIN != 0) {
- readin = true;
- };
- if (pollfds[1].revents & poll::event::POLLIN != 0) {
- signal::read(pollfds[1].fd)!;
- resize(&l);
- };
- };
- if (readin) {
- let r = match (libtui::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 (libtui::notify(&ui, r)) {
- break;
- };
- if (list::notify(&l, r)) {
- break;
- };
- };
+ let mainf = ev::register(&loop, ui.f, &st)!;
+ ev::readable(mainf, &handle_ui);
+ ev::do(&loop, &handle_print, &st);
+
+ for (ev::dispatch(&loop, -1)!) {
+ ev::do(&loop, &handle_print, &st);
+ ev::readable(mainf, &handle_ui);
};
};
+
@fini fn finish() void = {
free(searchterm);
};