diff --git a/config.def.h b/config.def.h index 5d53e41d8..31d7dacfe 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) }, + { "gn", ACTION(TEXT_OBJECT_SEARCH_FORWARD) }, + { "gN", ACTION(TEXT_OBJECT_SEARCH_BACKWARD) }, { 0 /* empty last element, array terminator */ }, }; @@ -235,6 +237,8 @@ static const KeyBinding bindings_normal[] = { { "", ALIAS("$") }, { "gf", ACTION(OPEN_FILE_UNDER_CURSOR) }, { "gf", ACTION(OPEN_FILE_UNDER_CURSOR_NEW_WINDOW) }, + { "gn", ALIAS("vgn") }, + { "gN", ALIAS("vgN") }, { 0 /* empty last element, array terminator */ }, }; diff --git a/main.c b/main.c index ee81e49fa..30e559a8b 100644 --- a/main.c +++ b/main.c @@ -269,6 +269,8 @@ enum { VIS_ACTION_TEXT_OBJECT_FUNCTION_INNER, VIS_ACTION_TEXT_OBJECT_LINE_OUTER, VIS_ACTION_TEXT_OBJECT_LINE_INNER, + VIS_ACTION_TEXT_OBJECT_SEARCH_FORWARD, + VIS_ACTION_TEXT_OBJECT_SEARCH_BACKWARD, VIS_ACTION_MOTION_CHARWISE, VIS_ACTION_MOTION_LINEWISE, VIS_ACTION_UNICODE_INFO, @@ -1050,6 +1052,16 @@ static KeyAction vis_action[] = { "The whole line, excluding leading and trailing whitespace", textobj, { .i = VIS_TEXTOBJECT_INNER_LINE } }, + [VIS_ACTION_TEXT_OBJECT_SEARCH_FORWARD] = { + "text-object-search-forward", + "The next search match in forward direction", + textobj, { .i = VIS_TEXTOBJECT_SEARCH_FORWARD } + }, + [VIS_ACTION_TEXT_OBJECT_SEARCH_BACKWARD] = { + "text-object-search-backward", + "The next search match in backward direction", + textobj, { .i = VIS_TEXTOBJECT_SEARCH_BACKWARD } + }, [VIS_ACTION_MOTION_CHARWISE] = { "motion-charwise", "Force motion to be charwise", diff --git a/text-objects.c b/text-objects.c index a0ffe3ceb..a6d22303b 100644 --- a/text-objects.c +++ b/text-objects.c @@ -340,6 +340,26 @@ Filerange text_object_filename(Text *txt, size_t pos) { return text_object_range(txt, pos, is_filename_boundary); } +Filerange text_object_search_forward(Text *txt, size_t pos, Regex *regex) { + size_t start = pos; + size_t end = text_size(txt); + RegexMatch match[1]; + bool found = start < end && !text_search_range_forward(txt, start, end - start, regex, 1, match, 0); + if (found) + return text_range_new(match[0].start, match[0].end); + return text_range_empty(); +} + +Filerange text_object_search_backward(Text *txt, size_t pos, Regex *regex) { + size_t start = 0; + size_t end = pos; + RegexMatch match[1]; + bool found = !text_search_range_backward(txt, start, end, regex, 1, match, 0); + if (found) + return text_range_new(match[0].start, match[0].end); + return text_range_empty(); +} + 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 e94d7c379..72e9a8c39 100644 --- a/text-objects.h +++ b/text-objects.h @@ -48,6 +48,9 @@ Filerange text_object_range(Text*, size_t pos, int (*isboundary)(int)); /* a number in either decimal, hex or octal format */ Filerange text_object_number(Text*, size_t pos); 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*); /* 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 a4fe36f41..14f299dff 100644 --- a/vis-text-objects.c +++ b/vis-text-objects.c @@ -9,6 +9,14 @@ void vis_textobject(Vis *vis, enum VisTextObject id) { } } +static Filerange search_forward(Vis *vis, Text *txt, size_t pos) { + return text_object_search_forward(txt, pos, vis->search_pattern); +} + +static Filerange search_backward(Vis *vis, Text *txt, size_t pos) { + return text_object_search_backward(txt, pos, vis->search_pattern); +} + TextObject vis_textobjects[] = { [VIS_TEXTOBJECT_INNER_WORD] = { .txt = text_object_word }, [VIS_TEXTOBJECT_OUTER_WORD] = { .txt = text_object_word_outer }, @@ -36,5 +44,7 @@ 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_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 04277e73d..519d32753 100644 --- a/vis.h +++ b/vis.h @@ -300,6 +300,8 @@ enum VisTextObject { VIS_TEXTOBJECT_INNER_FUNCTION, VIS_TEXTOBJECT_OUTER_LINE, VIS_TEXTOBJECT_INNER_LINE, + VIS_TEXTOBJECT_SEARCH_FORWARD, + VIS_TEXTOBJECT_SEARCH_BACKWARD, VIS_TEXTOBJECT_INVALID, };