aboutsummaryrefslogtreecommitdiff
path: root/libui/list/list.ha
diff options
context:
space:
mode:
Diffstat (limited to 'libui/list/list.ha')
-rw-r--r--libui/list/list.ha63
1 files changed, 62 insertions, 1 deletions
diff --git a/libui/list/list.ha b/libui/list/list.ha
index 16e2ecc..7b181c4 100644
--- a/libui/list/list.ha
+++ b/libui/list/list.ha
@@ -5,11 +5,15 @@ use strings;
use io;
use strio;
use unix::tty;
+use regex;
+use fnmatch;
use wcwidth;
+use set;
export type listwidget = struct {
ui: libui::ttyui,
items: []str,
+ marked: set::set,
cursor: size,
listeners: []listener,
frame: frame,
@@ -40,6 +44,7 @@ export fn newlist(ui: libui::ttyui, items: str...) listwidget = {
let w = listwidget {
ui = ui,
items = items,
+ marked = set::set {...},
cursor = 0z,
listeners = [],
frame = frame {
@@ -83,9 +88,13 @@ export fn print(list: *listwidget) (void | io::error | tty::error) = {
strio::concat(&st, truncitem)?;
strio::concat(&st, "\x1B[0m")?;
//libui::print(list.ui, strings::concat("\x1B[31;1m> ", list.items[i], "\x1B[0m"));
- } else {
+ } else if (set::contains(list.marked, i) is size){
+ strio::concat(&st, "\x1B[46;1m\x1B[30m")?;
strio::concat(&st, truncitem)?;
+ strio::concat(&st, "\x1B[0m")?;
//libui::print(list.ui, list.items[i]);
+ } else {
+ strio::concat(&st, truncitem)?;
};
strio::concat(&st, "\r\n")?;
};
@@ -182,3 +191,55 @@ export fn rsearch(l: *listwidget, s: str) size = {
};
return l.cursor;
};
+
+// Toggles marking the currently selected item.
+export fn tmark(l: *listwidget) void = {
+ if (!set::add(&l.marked, l.cursor)) {
+ set::del(&l.marked, l.cursor);
+ };
+};
+
+// Clears all marked items.
+export fn clearmarked(l: *listwidget) void = {
+ set::clear(&l.marked);
+};
+
+// Marks items that contain s (case sensitive).
+export fn containsmark(l: *listwidget, s: str) void = {
+ for (let i = 0z; i < len(l.items); i += 1) {
+ if (strings::contains(l.items[i], s)) {
+ set::add(&l.marked, i);
+ };
+ };
+};
+
+// Marks items based on fnmatch (globbing).
+export fn fnmatchmark(l: *listwidget, s: str) void = {
+ for (let i = 0z; i < len(l.items); i += 1) {
+ if (fnmatch::fnmatch(s, l.items[i])) {
+ set::add(&l.marked, i);
+ };
+ };
+};
+
+// Marks items according to a regular expression (POSIX ERE).
+export fn regexmark(l: *listwidget, re: *regex::regex) void = {
+ for (let i = 0z; i < len(l.items); i += 1) {
+ if (regex::test(re, l.items[i])) {
+ set::add(&l.marked, i);
+ };
+ };
+};
+
+// Returns the selected item or marked items if there are any.
+export fn selected(l: listwidget) (str | []str) = {
+ if (len(l.marked.items) > 0) {
+ let result: []str = [];
+ for (let i = 0z; i < len(l.marked.items); i += 1) {
+ append(result, l.items[l.marked.items[i]]);
+ };
+ return result;
+ } else {
+ return l.items[l.cursor];
+ };
+};