summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWormHeamer2026-01-03 05:10:36 -0500
committerWormHeamer2026-01-03 05:10:36 -0500
commit66915d847415bd4803d8dcade82b5fb267b88b5a (patch)
tree89a138e94d6d0e4f1206ab92a772e554dff877a7
parent2bbd0fe917d49d5d3e3fbee63808aa487172130b (diff)
word v bigword, K to view man page
-rw-r--r--main.c78
-rw-r--r--txt.h24
2 files changed, 102 insertions, 0 deletions
diff --git a/main.c b/main.c
index 729594d..ba30adf 100644
--- a/main.c
+++ b/main.c
@@ -182,7 +182,19 @@ static inline int is_space(u32 c) {
return c <= 0x20 && c != 0;
}
+static inline int is_word_chr(u32 c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+}
+
TxtLoc next_word(TxtLoc l) {
+ while (!at_end(l) && !is_word_chr(txt_chr(l)))
+ l = cnext(l);
+ while (!at_end(l) && is_word_chr(txt_chr(l)))
+ l = cnext(l);
+ return l;
+}
+
+TxtLoc next_bigword(TxtLoc l) {
while (!at_end(l) && is_space(txt_chr(l)))
l = cnext(l);
while (!at_end(l) && !is_space(txt_chr(l)))
@@ -193,6 +205,20 @@ TxtLoc next_word(TxtLoc l) {
TxtLoc prev_word(TxtLoc l) {
while (!at_start(l)) {
TxtLoc n = bprev(l);
+ if (is_word_chr(txt_chr(n))) break;
+ l = n;
+ }
+ while (!at_start(l)) {
+ TxtLoc n = bprev(l);
+ if (!is_word_chr(txt_chr(n))) break;
+ l = n;
+ }
+ return l;
+}
+
+TxtLoc prev_bigword(TxtLoc l) {
+ while (!at_start(l)) {
+ TxtLoc n = bprev(l);
if (!is_space(txt_chr(n))) break;
l = n;
}
@@ -204,6 +230,30 @@ TxtLoc prev_word(TxtLoc l) {
return l;
}
+TxtLoc word_start(TxtLoc l) {
+ while (!at_start(l) && is_word_chr(txt_chr(l))) l = cprev(l);
+ while (!at_start(l) && !is_word_chr(txt_chr(l))) l = cnext(l);
+ return l;
+}
+
+TxtLoc word_end(TxtLoc l) {
+ while (!at_start(l) && is_word_chr(txt_chr(l))) l = cnext(l);
+ while (!at_start(l) && !is_word_chr(txt_chr(l))) l = cprev(l);
+ return l;
+}
+
+TxtLoc bigword_start(TxtLoc l) {
+ while (!at_start(l) && !is_space(txt_chr(l))) l = cprev(l);
+ while (!at_start(l) && is_space(txt_chr(l))) l = cnext(l);
+ return l;
+}
+
+TxtLoc bigword_end(TxtLoc l) {
+ while (!at_start(l) && !is_space(txt_chr(l))) l = cnext(l);
+ while (!at_start(l) && is_space(txt_chr(l))) l = cprev(l);
+ return l;
+}
+
static inline u32 bracket_opp(u32 c) {
switch (c) {
case '{': return '}';
@@ -863,6 +913,20 @@ loop:
l = prev_line(l);
break;
+ case 'K': {
+ TxtLoc a = word_start(l);
+ TxtLoc b = word_end(l);
+ TxtRange r = txt_range_incl(a, b);
+ Str s = txt_collect_range(
+ (TxtLoc) { r.t, r.p0, r.i0 },
+ (TxtLoc) { r.t, r.p1, r.i1 },
+ &e.scratch
+ );
+ Str cmd = S("man ");
+ str_cat(&cmd, s, &e.scratch);
+ shell_run_no_prompt(str_to_cstr(cmd, &e.scratch));
+ } break;
+
case KEY_LEFT | KEY_CTRL_BIT:
case 'b':
l = prev_word(l);
@@ -872,6 +936,20 @@ loop:
l = next_word(l);
break;
+ case 'B':
+ l = prev_bigword(l);
+ break;
+ case 'W':
+ l = next_bigword(l);
+ break;
+
+ case 'e':
+ l = word_end(l);
+ break;
+ case 'E':
+ l = bigword_end(l);
+ break;
+
case KEY_UP | KEY_CTRL_BIT:
case '{':
l = prev_par(l);
diff --git a/txt.h b/txt.h
index 09d1c61..3f94c6d 100644
--- a/txt.h
+++ b/txt.h
@@ -33,6 +33,12 @@ typedef struct {
} TxtLoc;
typedef struct {
+ struct Txt *t;
+ u32 p0, i0;
+ u32 p1, i1;
+} TxtRange;
+
+typedef struct {
TxtPieceTbl v[TXT_HIST_MAX];
TxtLoc cur[TXT_HIST_MAX];
u32 i, n;
@@ -146,4 +152,22 @@ static inline TxtLoc cprev(TxtLoc l) {
return l;
}
+static inline TxtRange txt_range(TxtLoc a, TxtLoc b) {
+ ASSERT(a.t == b.t);
+ if (txt_before(b, a))
+ return (TxtRange) { a.t, b.p, b.i, a.p, a.i };
+ else
+ return (TxtRange) { a.t, a.p, a.i, b.p, b.i };
+}
+
+static inline TxtRange txt_range_incl(TxtLoc a, TxtLoc b) {
+ if (txt_before(b, a)) {
+ TxtLoc t = a;
+ a = b;
+ b = t;
+ }
+ b = cnext(b);
+ return (TxtRange) { a.t, a.p, a.i, b.p, b.i };
+}
+
#endif