diff options
| -rw-r--r-- | config.def.h | 2 | ||||
| -rw-r--r-- | main.c | 6 | ||||
| -rw-r--r-- | text-objects.c | 56 | ||||
| -rw-r--r-- | text-objects.h | 2 | ||||
| -rw-r--r-- | vis-text-objects.c | 1 | ||||
| -rw-r--r-- | vis.h | 1 |
6 files changed, 68 insertions, 0 deletions
diff --git a/config.def.h b/config.def.h index f5957ac..b7a797e 100644 --- a/config.def.h +++ b/config.def.h @@ -123,6 +123,8 @@ static const KeyBinding bindings_textobjects[] = { { "ie", ACTION(TEXT_OBJECT_ENTIRE_INNER) }, { "if", ACTION(TEXT_OBJECT_FUNCTION_INNER) }, { "il", ACTION(TEXT_OBJECT_LINE_INNER) }, + { "i<Tab>", ACTION(TEXT_OBJECT_INDENTATION) }, + { "a<Tab>", ACTION(TEXT_OBJECT_INDENTATION) }, { "gn", ACTION(TEXT_OBJECT_SEARCH_FORWARD) }, { "gN", ACTION(TEXT_OBJECT_SEARCH_BACKWARD) }, { 0 /* empty last element, array terminator */ }, @@ -272,6 +272,7 @@ enum { VIS_ACTION_TEXT_OBJECT_FUNCTION_INNER, VIS_ACTION_TEXT_OBJECT_LINE_OUTER, VIS_ACTION_TEXT_OBJECT_LINE_INNER, + VIS_ACTION_TEXT_OBJECT_INDENTATION, VIS_ACTION_TEXT_OBJECT_SEARCH_FORWARD, VIS_ACTION_TEXT_OBJECT_SEARCH_BACKWARD, VIS_ACTION_MOTION_CHARWISE, @@ -1060,6 +1061,11 @@ static const KeyAction vis_action[] = { "The whole line, excluding leading and trailing whitespace", textobj, { .i = VIS_TEXTOBJECT_INNER_LINE } }, + [VIS_ACTION_TEXT_OBJECT_INDENTATION] = { + "text-object-indentation", + "All adjacent lines with the same indentation level as the current one", + textobj, { .i = VIS_TEXTOBJECT_INDENTATION } + }, [VIS_ACTION_TEXT_OBJECT_SEARCH_FORWARD] = { "text-object-search-forward", "The next search match in forward direction", diff --git a/text-objects.c b/text-objects.c index d1abecb..db7ff63 100644 --- a/text-objects.c +++ b/text-objects.c @@ -359,6 +359,62 @@ Filerange text_object_search_backward(Text *txt, size_t pos, Regex *regex) { return text_range_empty(); } +Filerange text_object_indentation(Text *txt, size_t pos) { + char c; + size_t bol = text_line_begin(txt, pos); + size_t sol = text_line_start(txt, bol); + size_t start = bol; + size_t end = text_line_next(txt, bol); + size_t line_indent = sol - bol; + bool line_empty = text_byte_get(txt, bol, &c) && (c == '\r' || c == '\n'); + + char *buf = text_bytes_alloc0(txt, bol, line_indent); + char *tmp = malloc(line_indent); + + if (!buf || !tmp) { + free(buf); + free(tmp); + return text_range_empty(); + } + + while ((bol = text_line_begin(txt, text_line_prev(txt, start))) != start) { + sol = text_line_start(txt, bol); + size_t indent = sol - bol; + if (indent < line_indent) + break; + bool empty = text_byte_get(txt, bol, &c) && (c == '\r' || c == '\n'); + if (line_empty && !empty) + break; + if (line_indent == 0 && empty) + break; + text_bytes_get(txt, bol, line_indent, tmp); + if (memcmp(buf, tmp, line_indent)) + break; + start = bol; + } + + do { + bol = end; + sol = text_line_start(txt, bol); + size_t indent = sol - bol; + if (indent < line_indent) + break; + bool empty = text_byte_get(txt, bol, &c) && (c == '\r' || c == '\n'); + if (line_empty && !empty) + break; + if (line_indent == 0 && empty) + break; + text_bytes_get(txt, bol, line_indent, tmp); + if (memcmp(buf, tmp, line_indent)) + break; + end = text_line_next(txt, bol); + } while (bol != end); + + free(buf); + free(tmp); + return text_range_new(start, end); +} + Filerange text_range_linewise(Text *txt, Filerange *rin) { Filerange rout = *rin; rout.start = text_line_begin(txt, rin->start); diff --git a/text-objects.h b/text-objects.h index 72e9a8c..5656a8a 100644 --- a/text-objects.h +++ b/text-objects.h @@ -51,6 +51,8 @@ Filerange text_object_filename(Text*, size_t pos); /* match a search term in either forward or backward direction */ Filerange text_object_search_forward(Text*, size_t pos, Regex*); Filerange text_object_search_backward(Text*, size_t pos, Regex*); +/* match all lines with same indendation level than the current one */ +Filerange text_object_indentation(Text*, size_t pos); /* extend a range to cover whole lines */ Filerange text_range_linewise(Text*, Filerange*); diff --git a/vis-text-objects.c b/vis-text-objects.c index 93dc8d4..8ee2416 100644 --- a/vis-text-objects.c +++ b/vis-text-objects.c @@ -44,6 +44,7 @@ const TextObject vis_textobjects[] = { [VIS_TEXTOBJECT_INNER_FUNCTION] = { .txt = text_object_function_inner, }, [VIS_TEXTOBJECT_OUTER_LINE] = { .txt = text_object_line, }, [VIS_TEXTOBJECT_INNER_LINE] = { .txt = text_object_line_inner, }, + [VIS_TEXTOBJECT_INDENTATION] = { .txt = text_object_indentation, }, [VIS_TEXTOBJECT_SEARCH_FORWARD] = { .vis = search_forward, .type = SPLIT }, [VIS_TEXTOBJECT_SEARCH_BACKWARD] = { .vis = search_backward, .type = SPLIT }, }; @@ -300,6 +300,7 @@ enum VisTextObject { VIS_TEXTOBJECT_INNER_FUNCTION, VIS_TEXTOBJECT_OUTER_LINE, VIS_TEXTOBJECT_INNER_LINE, + VIS_TEXTOBJECT_INDENTATION, VIS_TEXTOBJECT_SEARCH_FORWARD, VIS_TEXTOBJECT_SEARCH_BACKWARD, VIS_TEXTOBJECT_INVALID, |
