diff options
| author | WormHeamer | 2026-01-03 05:10:36 -0500 |
|---|---|---|
| committer | WormHeamer | 2026-01-03 05:10:36 -0500 |
| commit | 66915d847415bd4803d8dcade82b5fb267b88b5a (patch) | |
| tree | 89a138e94d6d0e4f1206ab92a772e554dff877a7 | |
| parent | 2bbd0fe917d49d5d3e3fbee63808aa487172130b (diff) | |
word v bigword, K to view man page
| -rw-r--r-- | main.c | 78 | ||||
| -rw-r--r-- | txt.h | 24 |
2 files changed, 102 insertions, 0 deletions
@@ -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); @@ -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 |
