Skip to content

Commit

Permalink
Add text object to cover lines with same indentation level
Browse files Browse the repository at this point in the history
By default it is mapped to i<Tab> and a<Tab> however there
is currently no difference between the inner and regular
version.
  • Loading branch information
martanne committed Feb 15, 2016
1 parent c7ab22b commit 44c8e46
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config.def.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */ },
Expand Down
6 changes: 6 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down
56 changes: 56 additions & 0 deletions text-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions text-objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand Down
1 change: 1 addition & 0 deletions vis-text-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
};
Expand Down
1 change: 1 addition & 0 deletions vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 44c8e46

Please sign in to comment.