aboutsummaryrefslogtreecommitdiff
path: root/libui
diff options
context:
space:
mode:
Diffstat (limited to 'libui')
-rw-r--r--libui/libui.ha17
-rw-r--r--libui/list/list.ha31
2 files changed, 43 insertions, 5 deletions
diff --git a/libui/libui.ha b/libui/libui.ha
index 0546d24..6ad33d1 100644
--- a/libui/libui.ha
+++ b/libui/libui.ha
@@ -17,6 +17,7 @@ export type ttyui = struct {
listeners: []listener,
};
+// Initializes the UI and returns a ttyui.
export fn init() ttyui = {
let f = match (tty::open()) {
case let f: io::file =>
@@ -43,28 +44,36 @@ export fn init() ttyui = {
};
};
+// Returns the window size for the given ttyui.
export fn getwinsize(ui: ttyui) (tty::ttysize | tty::error) = {
return tty::winsize(ui.f);
};
+// Suspend the UI. To restore it, use [[resume]].
export fn suspend(ui: *ttyui) void = {
tty::termios_restore(&ui.term);
};
+// Resumes the UI after a [[suspend]].
export fn resume(ui: *ttyui) void = {
tty::makeraw(&ui.term)!;
+ tty::noecho(&ui.term)!;
};
+// Restores the UI state and closes and frees the resources associated with the
+// given ttyui.
export fn finish(ui: *ttyui) void = {
tty::termios_restore(&ui.term);
io::close(ui.f)!;
free(ui.listeners);
};
+// Scans a rune. A convenience function for [[bufio::scanrune]].
export fn scan(ui: ttyui) (rune | utf8::invalid | io::EOF | io::error) = {
return bufio::scanrune(ui.f);
};
+// Notify (call) the ttyui's listeners with the ttyui and r as a parameter.
export fn notify(ui: *ttyui, r: rune) bool = {
for (let i = 0z; i < len(ui.listeners); i += 1) {
if (ui.listeners[i](ui, r)) {
@@ -94,17 +103,17 @@ fn loop(ui: *ttyui) void = {
};
};
+// Add a listener to the given ttyui.
export fn addlistener(ui: *ttyui, l: listener) void = {
append(ui.listeners, l);
};
-
+// Print a string or rune to the ttyui.
export fn print(ui: ttyui, arg: (str | rune)) void = {
- fmt::fprintf(ui.f, "{}\r\n", arg)!;
+ fmt::fprintf(ui.f, "{}\r", arg)!;
};
+// Clear the ttyui.
export fn clear(ui: ttyui) void = {
fmt::fprintf(ui.f, "\x1B[2J\x1B[1;1H\r")!;
};
-
-//export @symbol("wcwidth") fn wcwidth(r: rune) int;
diff --git a/libui/list/list.ha b/libui/list/list.ha
index 6cbafd7..16e2ecc 100644
--- a/libui/list/list.ha
+++ b/libui/list/list.ha
@@ -29,6 +29,7 @@ export type ttysize = struct {
export type listener = *fn(l: *listwidget, r: rune) bool;
+// Create a new list with the given items.
export fn newlist(ui: libui::ttyui, items: str...) listwidget = {
let sz = libui::getwinsize(ui)!;
let rows: (u16 | size) = if (sz.rows - 2 < len(items)) {
@@ -53,10 +54,13 @@ export fn newlist(ui: libui::ttyui, items: str...) listwidget = {
return w;
};
+// Add a listener to the given list.
export fn addlistener(list: *listwidget, l: listener) void = {
append(list.listeners, l);
};
+// Print the list's items while truncating the items to not be wider than the
+// list.sz.cols.
export fn print(list: *listwidget) (void | io::error | tty::error) = {
//let sz = libui::getwinsize(list.ui)?;
//let rows: (u16 | size) = if (sz.rows - 2 < len(list.items)) {
@@ -90,6 +94,8 @@ export fn print(list: *listwidget) (void | io::error | tty::error) = {
libui::print(list.ui, s);
};
+// Notify (call) the listwidget's listeners with the listwidget and r as a
+// parameter.
export fn notify(l: *listwidget, r: rune) bool = {
for (let i = 0z; i < len(l.listeners); i += 1) {
if (l.listeners[i](l, r)) {
@@ -99,6 +105,7 @@ export fn notify(l: *listwidget, r: rune) bool = {
return false;
};
+// Move the list's cursor down one item. Returns the new cursor.
export fn down(l: *listwidget) size = {
if (l.cursor < len(l.items) - 1) {
l.cursor += 1;
@@ -107,6 +114,7 @@ export fn down(l: *listwidget) size = {
return l.cursor;
};
+// Move the list's cursor up one item. Returns the new cursor.
export fn up(l: *listwidget) size = {
if (l.cursor > 0) {
l.cursor -= 1;
@@ -115,6 +123,8 @@ export fn up(l: *listwidget) size = {
return l.cursor;
};
+// Reset the list's frame based on the cursor. Returns whether the frame was
+// updated.
fn reframe(l: *listwidget) bool = {
let reframed: bool = false;
if (l.cursor < l.frame.start) {
@@ -130,6 +140,7 @@ fn reframe(l: *listwidget) bool = {
return reframed;
};
+// Move the list's cursor to the top (first item). Returns the new cursor.
export fn top(l: *listwidget) size = {
l.cursor = 0;
l.frame.start = 0;
@@ -137,6 +148,7 @@ export fn top(l: *listwidget) size = {
return l.cursor;
};
+// Move the list's cursor to the bottom (last item). Returns the new cursor.
export fn bottom(l: *listwidget) size = {
l.cursor = len(l.items) - 1;
l.frame.end = len(l.items): u16;
@@ -144,11 +156,28 @@ export fn bottom(l: *listwidget) size = {
return l.cursor;
};
+// Forward search through the list's items for an item containing s. Returns the
+// new cursor.
export fn search(l: *listwidget, s: str) size = {
- for (let i = 0z; i < len(l.items); i += 1) {
+ for (let i = l.cursor + 1; i < len(l.items); i += 1) {
if (strings::contains(l.items[i], s)) {
l.cursor = i;
reframe(l);
+ return l.cursor;
+ };
+ };
+ return l.cursor;
+};
+
+// Backwards search through the list's items for an item containing s. Returns
+// the new cursor.
+export fn rsearch(l: *listwidget, s: str) size = {
+ // size wraps to max value for size when < 0
+ for (let i = l.cursor: int - 1; i >= 0; i -= 1) {
+ if (strings::contains(l.items[i], s)) {
+ l.cursor = i: size;
+ reframe(l);
+ return l.cursor;
};
};
return l.cursor;