diff options
| -rw-r--r-- | README | 4 | ||||
| -rw-r--r-- | config.def.h | 8 | ||||
| -rw-r--r-- | text-motions.c | 63 |
3 files changed, 42 insertions, 33 deletions
@@ -346,9 +346,7 @@ and their current support in vis. /{text} (to next match of text in forward direction) ?{text} (to next match of text in backward direction) - There is currently no distinction between what vim calls a WORD and - a word, only the former is implemented. Though infrastructure for - the latter also exists. + An empty line is currently neither a word nor a WORD. The semantics of a paragraph and a sentence is also not always 100% the same as in vim. diff --git a/config.def.h b/config.def.h index 474657c..bed3c80 100644 --- a/config.def.h +++ b/config.def.h @@ -120,13 +120,13 @@ static KeyBinding vis_movements[] = { { { NONE('g'), NONE('_') }, movement, { .i = MOVE_LINE_FINISH } }, { { NONE('$') }, movement, { .i = MOVE_LINE_LASTCHAR } }, { { NONE('%') }, movement, { .i = MOVE_BRACKET_MATCH } }, - { { NONE('b') }, movement, { .i = MOVE_LONGWORD_START_PREV } }, + { { NONE('b') }, movement, { .i = MOVE_WORD_START_PREV } }, { { NONE('B') }, movement, { .i = MOVE_LONGWORD_START_PREV } }, - { { NONE('w') }, movement, { .i = MOVE_LONGWORD_START_NEXT } }, + { { NONE('w') }, movement, { .i = MOVE_WORD_START_NEXT } }, { { NONE('W') }, movement, { .i = MOVE_LONGWORD_START_NEXT } }, - { { NONE('g'), NONE('e') }, movement, { .i = MOVE_LONGWORD_END_PREV } }, + { { NONE('g'), NONE('e') }, movement, { .i = MOVE_WORD_END_PREV } }, { { NONE('g'), NONE('E') }, movement, { .i = MOVE_LONGWORD_END_PREV } }, - { { NONE('e') }, movement, { .i = MOVE_LONGWORD_END_NEXT } }, + { { NONE('e') }, movement, { .i = MOVE_WORD_END_NEXT } }, { { NONE('E') }, movement, { .i = MOVE_LONGWORD_END_NEXT } }, { { NONE('{') }, movement, { .i = MOVE_PARAGRAPH_PREV } }, { { NONE('}') }, movement, { .i = MOVE_PARAGRAPH_NEXT } }, diff --git a/text-motions.c b/text-motions.c index 0d121fd..997d3c1 100644 --- a/text-motions.c +++ b/text-motions.c @@ -20,7 +20,7 @@ // TODO: specify this per file type? static int is_word_boundry(int c) { - return !(('0' <= c && c <= '9') || + return ISASCII(c) && !(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')); } @@ -158,73 +158,84 @@ size_t text_line_next(Text *txt, size_t pos) { return it.pos; } -size_t text_word_boundry_start_next(Text *txt, size_t pos, int (*isboundry)(int)) { +static size_t text_customword_start_next(Text *txt, size_t pos, int (*isboundry)(int)) { char c; Iterator it = text_iterator_get(txt, pos); - text_iterator_byte_next(&it, NULL); - while (text_iterator_byte_get(&it, &c) && !isboundry(c)) - text_iterator_byte_next(&it, NULL); - while (text_iterator_byte_get(&it, &c) && isboundry(c)) - text_iterator_byte_next(&it, NULL); + if (!text_iterator_byte_get(&it, &c)) + return pos; + if (isboundry(c)) + while (isboundry(c) && !isspace(c) && text_iterator_char_next(&it, &c)); + else + while (!isboundry(c) && text_iterator_char_next(&it, &c)); + while (isspace(c) && text_iterator_char_next(&it, &c)); return it.pos; } -size_t text_word_boundry_start_prev(Text *txt, size_t pos, int (*isboundry)(int)) { +static size_t text_customword_start_prev(Text *txt, size_t pos, int (*isboundry)(int)) { char c; Iterator it = text_iterator_get(txt, pos); - while (text_iterator_byte_prev(&it, &c) && isboundry(c)); - do pos = it.pos; while (text_iterator_char_prev(&it, &c) && !isboundry(c)); + while (text_iterator_char_prev(&it, &c) && isspace(c)); + if (isboundry(c)) + do pos = it.pos; while (text_iterator_char_prev(&it, &c) && isboundry(c) && !isspace(c)); + else + do pos = it.pos; while (text_iterator_char_prev(&it, &c) && !isboundry(c)); return pos; } -size_t text_word_boundry_end_next(Text *txt, size_t pos, int (*isboundry)(int)) { +static size_t text_customword_end_next(Text *txt, size_t pos, int (*isboundry)(int)) { char c; Iterator it = text_iterator_get(txt, pos); - while (text_iterator_char_next(&it, &c) && isboundry(c)); - do pos = it.pos; while (text_iterator_char_next(&it, &c) && !isboundry(c)); + while (text_iterator_char_next(&it, &c) && isspace(c)); + if (isboundry(c)) + do pos = it.pos; while (text_iterator_char_next(&it, &c) && isboundry(c) && !isspace(c)); + else + do pos = it.pos; while (text_iterator_char_next(&it, &c) && !isboundry(c)); return pos; } -size_t text_word_boundry_end_prev(Text *txt, size_t pos, int (*isboundry)(int)) { +static size_t text_customword_end_prev(Text *txt, size_t pos, int (*isboundry)(int)) { char c; Iterator it = text_iterator_get(txt, pos); - while (text_iterator_byte_get(&it, &c) && !isboundry(c)) - text_iterator_byte_prev(&it, NULL); - while (text_iterator_char_prev(&it, &c) && isboundry(c)); + if (!text_iterator_byte_get(&it, &c)) + return pos; + if (isboundry(c)) + while (isboundry(c) && !isspace(c) && text_iterator_char_prev(&it, &c)); + else + while (!isboundry(c) && text_iterator_char_prev(&it, &c)); + while (isspace(c) && text_iterator_char_prev(&it, &c)); return it.pos; } size_t text_longword_end_next(Text *txt, size_t pos) { - return text_word_boundry_end_next(txt, pos, isspace); + return text_customword_end_next(txt, pos, isspace); } size_t text_longword_end_prev(Text *txt, size_t pos) { - return text_word_boundry_end_prev(txt, pos, isspace); + return text_customword_end_prev(txt, pos, isspace); } size_t text_longword_start_next(Text *txt, size_t pos) { - return text_word_boundry_start_next(txt, pos, isspace); + return text_customword_start_next(txt, pos, isspace); } size_t text_longword_start_prev(Text *txt, size_t pos) { - return text_word_boundry_start_prev(txt, pos, isspace); + return text_customword_start_prev(txt, pos, isspace); } -// TODO: this actually doesn't work that way -> rewrite size_t text_word_end_next(Text *txt, size_t pos) { - return text_word_boundry_end_next(txt, pos, is_word_boundry); + return text_customword_end_next(txt, pos, is_word_boundry); } size_t text_word_end_prev(Text *txt, size_t pos) { - return text_word_boundry_end_prev(txt, pos, is_word_boundry); + return text_customword_end_prev(txt, pos, is_word_boundry); } size_t text_word_start_next(Text *txt, size_t pos) { - return text_word_boundry_start_next(txt, pos, is_word_boundry); + return text_customword_start_next(txt, pos, is_word_boundry); } size_t text_word_start_prev(Text *txt, size_t pos) { - return text_word_boundry_start_prev(txt, pos, is_word_boundry); + return text_customword_start_prev(txt, pos, is_word_boundry); } static size_t text_paragraph_sentence_next(Text *txt, size_t pos, bool sentence) { |
