aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h2
-rw-r--r--main.c6
-rw-r--r--text-objects.c56
-rw-r--r--text-objects.h2
-rw-r--r--vis-text-objects.c1
-rw-r--r--vis.h1
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 */ },
diff --git a/main.c b/main.c
index 6b746ef..2f49bff 100644
--- a/main.c
+++ b/main.c
@@ -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 },
};
diff --git a/vis.h b/vis.h
index 6652f72..2d3fcdd 100644
--- a/vis.h
+++ b/vis.h
@@ -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,