diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-08-20 15:42:58 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-08-24 11:10:00 +0200 |
| commit | e2d51321f7284d11d9344e22117db31372fbe7a0 (patch) | |
| tree | e3d57ccb0fb42012cf5f9024501caddc5526de08 /vis-text-objects.c | |
| parent | 349e5f4150ea9fdc27d523060e62d93f44a212ba (diff) | |
| download | vis-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.c | 60 |
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, }, |
