summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-12-31 04:08:48 -0500
committerWormHeamer2025-12-31 04:08:48 -0500
commit46519df810cc4e7515faed081c4dbd078e4597e6 (patch)
tree3f54f9dc9a13dec3f7a582e939375958b5fd0968 /main.c
parentdd5a0fd131968ff9020183134a84e482c13a2ae2 (diff)
add prev_func(), next_func(), [/]
Diffstat (limited to 'main.c')
-rw-r--r--main.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/main.c b/main.c
index 5425ea4..626e066 100644
--- a/main.c
+++ b/main.c
@@ -136,6 +136,78 @@ TxtLoc prev_word(TxtLoc l) {
return l;
}
+static inline u32 bracket_opp(u32 c) {
+ switch (c) {
+ case '{': return '}';
+ case '}': return '{';
+ case '[': return ']';
+ case ']': return '[';
+ case '(': return ')';
+ case ')': return '(';
+ default:
+ return c;
+ }
+}
+
+static inline int bracket_dir(u32 c) {
+ switch (c) {
+ case '{': case '[': case '(': return 1;
+ case '}': case ']': case ')': return -1;
+ default:
+ return 0;
+ }
+}
+
+TxtLoc match_bracket(TxtLoc l) {
+ u32 depth = 1;
+ u32 c = txt_chr(l);
+ u32 o = bracket_opp(c);
+ int dir = bracket_dir(c);
+ if (dir < 0) {
+ while (!at_start(l) && depth > 0) {
+ l = cprev(l);
+ u32 x = txt_chr(l);
+ if (x == c) depth++;
+ else if (x == o) depth--;
+ }
+ } else if (dir > 0) {
+ while (!at_end(l) && depth > 0) {
+ l = cnext(l);
+ u32 x = txt_chr(l);
+ if (x == c) depth++;
+ else if (x == o) depth--;
+ }
+
+ }
+ return l;
+}
+
+TxtLoc next_func_end(TxtLoc l) {
+ l = start_of_line(l);
+ while (!at_end(l)) {
+ l = next_line_start(l);
+ if (txt_chr(l) == '}' && txt_chr(cnext(l)) == '\n') break;
+ }
+ return l;
+}
+
+TxtLoc prev_func_end(TxtLoc l) {
+ l = start_of_line(l);
+ while (!at_start(l)) {
+ l = prev_line_start(l);
+ if (txt_chr(l) == '}' && txt_chr(cnext(l)) == '\n') break;
+ }
+ return l;
+}
+
+TxtLoc prev_func(TxtLoc l) {
+ return match_bracket(prev_func_end(l));
+}
+
+TxtLoc next_func(TxtLoc l) {
+ return match_bracket(next_func_end(match_bracket(l)));
+}
+
int empty_line(TxtLoc l) {
u8 b = txt_byte(start_of_line(l));
return b == '\n' || b == 0 /* last line of buffer */;
@@ -387,6 +459,7 @@ int motion(TxtLoc *lp, u32 c) {
vui_blit();
c = vui_key();
}
+
loop:
switch (c) {
case KEY_LEFT:
@@ -421,6 +494,12 @@ loop:
case '}':
l = next_par(l);
break;
+ case '[':
+ l = prev_func(l);
+ break;
+ case ']':
+ l = next_func(l);
+ break;
case KEY_PGUP:
for (u32 i = 0; i < LINES; i += 3) l = prev_line(l);
break;
@@ -485,6 +564,7 @@ loop:
default:
return 0;
}
+
if (e.count > 1 && (txt_before(l, last_loc) || txt_after(l, last_loc))) {
e.count--;
goto loop;