aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-02-11 10:32:49 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-02-11 10:32:49 +0100
commita9db1caf19d34f13319a3ebf92100c2c92015582 (patch)
tree2bf64c214e276ab4ff7fc460cb889675c93e4d48
parent979d51bcb65ccceec95f34a10fdf6446ac97473c (diff)
downloadvis-a9db1caf19d34f13319a3ebf92100c2c92015582.tar.gz
vis-a9db1caf19d34f13319a3ebf92100c2c92015582.tar.xz
vis: implement gn and gN text objects
The behaviour when no match is found is not yet optimal.
-rw-r--r--config.def.h4
-rw-r--r--main.c12
-rw-r--r--text-objects.c20
-rw-r--r--text-objects.h3
-rw-r--r--vis-text-objects.c10
-rw-r--r--vis.h2
6 files changed, 51 insertions, 0 deletions
diff --git a/config.def.h b/config.def.h
index 5d53e41..31d7dac 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[] = {
{ "<End>", ALIAS("$") },
{ "gf", ACTION(OPEN_FILE_UNDER_CURSOR) },
{ "<C-w>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 ee81e49..30e559a 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 a0ffe3c..a6d2230 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 e94d7c3..72e9a8c 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 a4fe36f..14f299d 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 04277e7..519d327 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,
};