diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -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; |
