aboutsummaryrefslogtreecommitdiff
path: root/vis-text-objects.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-08-20 15:42:58 +0200
committerMarc André Tanner <mat@brain-dump.org>2016-08-24 11:10:00 +0200
commite2d51321f7284d11d9344e22117db31372fbe7a0 (patch)
treee3d57ccb0fb42012cf5f9024501caddc5526de08 /vis-text-objects.c
parent349e5f4150ea9fdc27d523060e62d93f44a212ba (diff)
downloadvis-e2d51321f7284d11d9344e22117db31372fbe7a0.tar.gz
vis-e2d51321f7284d11d9344e22117db31372fbe7a0.tar.xz
vis: improve unpaired text objects
For unpaired text objects delimited by ", ' or ` if there is no preceding symbol on the same line, advance starting position to first occurence on the same line. As a result ci" can be used to change the inner quotes on the same line even if the cursor is currently to the left of the opening quote. If the line contains no such symbol at all then the text objects will will continue to match across line boundaries. This behavior is different in vim where for example a ci" command on a line without any quotes has no effect. Close #358
Diffstat (limited to 'vis-text-objects.c')
-rw-r--r--vis-text-objects.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/vis-text-objects.c b/vis-text-objects.c
index 1b9f242..1140d86 100644
--- a/vis-text-objects.c
+++ b/vis-text-objects.c
@@ -48,6 +48,54 @@ static Filerange search_backward(Vis *vis, Text *txt, size_t pos) {
return range;
}
+static Filerange object_unpaired(Text *txt, size_t pos, char obj) {
+ char c;
+ bool before = false;
+ Iterator it = text_iterator_get(txt, pos), rit = it;
+
+ while (text_iterator_byte_get(&rit, &c) && c != '\n') {
+ if (c == obj) {
+ before = true;
+ break;
+ }
+ text_iterator_byte_prev(&rit, NULL);
+ }
+
+ /* if there is no previous occurence on the same line, advance starting position */
+ if (!before) {
+ while (text_iterator_byte_get(&it, &c) && c != '\n') {
+ if (c == obj) {
+ pos = it.pos;
+ break;
+ }
+ text_iterator_byte_next(&it, NULL);
+ }
+ }
+
+ switch (obj) {
+ case '"':
+ return text_object_quote(txt, pos);
+ case '\'':
+ return text_object_single_quote(txt, pos);
+ case '`':
+ return text_object_backtick(txt, pos);
+ default:
+ return text_range_empty();
+ }
+}
+
+static Filerange object_quote(Text *txt, size_t pos) {
+ return object_unpaired(txt, pos, '"');
+}
+
+static Filerange object_single_quote(Text *txt, size_t pos) {
+ return object_unpaired(txt, pos, '\'');
+}
+
+static Filerange object_backtick(Text *txt, size_t pos) {
+ return object_unpaired(txt, pos, '`');
+}
+
const TextObject vis_textobjects[] = {
[VIS_TEXTOBJECT_INNER_WORD] = { .txt = text_object_word },
[VIS_TEXTOBJECT_OUTER_WORD] = { .txt = text_object_word_outer },
@@ -63,12 +111,12 @@ const TextObject vis_textobjects[] = {
[VIS_TEXTOBJECT_INNER_ANGLE_BRACKET] = { .txt = text_object_angle_bracket, .type = INNER },
[VIS_TEXTOBJECT_OUTER_PARANTHESE] = { .txt = text_object_paranthese, .type = OUTER },
[VIS_TEXTOBJECT_INNER_PARANTHESE] = { .txt = text_object_paranthese, .type = INNER },
- [VIS_TEXTOBJECT_OUTER_QUOTE] = { .txt = text_object_quote, .type = OUTER },
- [VIS_TEXTOBJECT_INNER_QUOTE] = { .txt = text_object_quote, .type = INNER },
- [VIS_TEXTOBJECT_OUTER_SINGLE_QUOTE] = { .txt = text_object_single_quote, .type = OUTER },
- [VIS_TEXTOBJECT_INNER_SINGLE_QUOTE] = { .txt = text_object_single_quote, .type = INNER },
- [VIS_TEXTOBJECT_OUTER_BACKTICK] = { .txt = text_object_backtick, .type = OUTER },
- [VIS_TEXTOBJECT_INNER_BACKTICK] = { .txt = text_object_backtick, .type = INNER },
+ [VIS_TEXTOBJECT_OUTER_QUOTE] = { .txt = object_quote, .type = OUTER },
+ [VIS_TEXTOBJECT_INNER_QUOTE] = { .txt = object_quote, .type = INNER },
+ [VIS_TEXTOBJECT_OUTER_SINGLE_QUOTE] = { .txt = object_single_quote, .type = OUTER },
+ [VIS_TEXTOBJECT_INNER_SINGLE_QUOTE] = { .txt = object_single_quote, .type = INNER },
+ [VIS_TEXTOBJECT_OUTER_BACKTICK] = { .txt = object_backtick, .type = OUTER },
+ [VIS_TEXTOBJECT_INNER_BACKTICK] = { .txt = object_backtick, .type = INNER },
[VIS_TEXTOBJECT_OUTER_ENTIRE] = { .txt = text_object_entire, },
[VIS_TEXTOBJECT_INNER_ENTIRE] = { .txt = text_object_entire_inner, },
[VIS_TEXTOBJECT_OUTER_FUNCTION] = { .txt = text_object_function, },