diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2020-12-28 15:17:36 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2020-12-28 15:17:36 +0100 |
| commit | adf65e1dca8d3c0381133be8446eebddf412d772 (patch) | |
| tree | d15dd7a68c597ca9be6ca92ea363578e501391cc | |
| parent | 0b082239bc60f0a6a3cb743b38a63684652ae649 (diff) | |
| download | vis-adf65e1dca8d3c0381133be8446eebddf412d772.tar.gz vis-adf65e1dca8d3c0381133be8446eebddf412d772.tar.xz | |
vis: implement multiline to/till motions
These are currently not mapped by default but can be enabled by mappings
using their virtual key names.
| -rw-r--r-- | main.c | 26 | ||||
| -rw-r--r-- | vis-motions.c | 58 | ||||
| -rw-r--r-- | vis.h | 4 |
3 files changed, 87 insertions, 1 deletions
@@ -94,7 +94,7 @@ static const char *gotoline(Vis*, const char *keys, const Arg *arg); /* make the current action use the operator indicated by arg->i */ static const char *operator(Vis*, const char *keys, const Arg *arg); /* blocks to read a key and performs movement indicated by arg->i which - * should be one of VIS_MOVE_{TO,TILL}_LINE_{RIGHT,LEFT}*/ + * should be one of VIS_MOVE_{TO,TILL}_{,LINE}_{RIGHT,LEFT}*/ static const char *movement_key(Vis*, const char *keys, const Arg *arg); /* perform the movement as indicated by arg->i */ static const char *movement(Vis*, const char *keys, const Arg *arg); @@ -220,8 +220,12 @@ enum { VIS_ACTION_TOTILL_REVERSE, VIS_ACTION_PROMPT_SEARCH_FORWARD, VIS_ACTION_PROMPT_SEARCH_BACKWARD, + VIS_ACTION_TILL_LEFT, + VIS_ACTION_TILL_RIGHT, VIS_ACTION_TILL_LINE_LEFT, VIS_ACTION_TILL_LINE_RIGHT, + VIS_ACTION_TO_LEFT, + VIS_ACTION_TO_RIGHT, VIS_ACTION_TO_LINE_LEFT, VIS_ACTION_TO_LINE_RIGHT, VIS_ACTION_REGISTER, @@ -718,6 +722,16 @@ static const KeyAction vis_action[] = { VIS_HELP("Search backward") prompt_show, { .s = "?" } }, + [VIS_ACTION_TILL_LEFT] = { + "vis-motion-till-left", + VIS_HELP("Till after the occurrence of character to the left") + movement_key, { .i = VIS_MOVE_TILL_LEFT } + }, + [VIS_ACTION_TILL_RIGHT] = { + "vis-motion-till-right", + VIS_HELP("Till before the occurrence of character to the right") + movement_key, { .i = VIS_MOVE_TILL_RIGHT } + }, [VIS_ACTION_TILL_LINE_LEFT] = { "vis-motion-till-line-left", VIS_HELP("Till after the occurrence of character to the left on the current line") @@ -728,6 +742,16 @@ static const KeyAction vis_action[] = { VIS_HELP("Till before the occurrence of character to the right on the current line") movement_key, { .i = VIS_MOVE_TILL_LINE_RIGHT } }, + [VIS_ACTION_TO_LEFT] = { + "vis-motion-to-left", + VIS_HELP("To the first occurrence of character to the left") + movement_key, { .i = VIS_MOVE_TO_LEFT } + }, + [VIS_ACTION_TO_RIGHT] = { + "vis-motion-to-right", + VIS_HELP("To the first occurrence of character to the right") + movement_key, { .i = VIS_MOVE_TO_RIGHT } + }, [VIS_ACTION_TO_LINE_LEFT] = { "vis-motion-to-line-left", VIS_HELP("To the first occurrence of character to the left on the current line") diff --git a/vis-motions.c b/vis-motions.c index 9658f9f..6178f5a 100644 --- a/vis-motions.c +++ b/vis-motions.c @@ -112,6 +112,32 @@ static size_t longword_next(Vis *vis, Text *txt, size_t pos) { VIS_MOVE_LONGWORD_END_NEXT, isspace); } +static size_t to_right(Vis *vis, Text *txt, size_t pos) { + char c; + size_t hit = text_find_next(txt, pos+1, vis->search_char); + if (!text_byte_get(txt, hit, &c) || c != vis->search_char[0]) + return pos; + return hit; +} + +static size_t till_right(Vis *vis, Text *txt, size_t pos) { + size_t hit = to_right(vis, txt, pos+1); + if (hit != pos) + return text_char_prev(txt, hit); + return pos; +} + +static size_t to_left(Vis *vis, Text *txt, size_t pos) { + return text_find_prev(txt, pos, vis->search_char); +} + +static size_t till_left(Vis *vis, Text *txt, size_t pos) { + size_t hit = to_left(vis, txt, pos-1); + if (hit != pos-1) + return text_char_next(txt, hit); + return pos; +} + static size_t to_line_right(Vis *vis, Text *txt, size_t pos) { char c; if (pos == text_line_end(txt, pos)) @@ -294,8 +320,12 @@ bool vis_motion(Vis *vis, enum VisMotion motion, ...) { } break; } + case VIS_MOVE_TO_RIGHT: + case VIS_MOVE_TO_LEFT: case VIS_MOVE_TO_LINE_RIGHT: case VIS_MOVE_TO_LINE_LEFT: + case VIS_MOVE_TILL_RIGHT: + case VIS_MOVE_TILL_LEFT: case VIS_MOVE_TILL_LINE_RIGHT: case VIS_MOVE_TILL_LINE_LEFT: { @@ -314,12 +344,24 @@ bool vis_motion(Vis *vis, enum VisMotion motion, ...) { break; case VIS_MOVE_TOTILL_REVERSE: switch (vis->last_totill) { + case VIS_MOVE_TO_RIGHT: + motion = VIS_MOVE_TO_LEFT; + break; + case VIS_MOVE_TO_LEFT: + motion = VIS_MOVE_TO_RIGHT; + break; case VIS_MOVE_TO_LINE_RIGHT: motion = VIS_MOVE_TO_LINE_LEFT; break; case VIS_MOVE_TO_LINE_LEFT: motion = VIS_MOVE_TO_LINE_RIGHT; break; + case VIS_MOVE_TILL_RIGHT: + motion = VIS_MOVE_TILL_LEFT; + break; + case VIS_MOVE_TILL_LEFT: + motion = VIS_MOVE_TILL_RIGHT; + break; case VIS_MOVE_TILL_LINE_RIGHT: motion = VIS_MOVE_TILL_LINE_LEFT; break; @@ -515,6 +557,14 @@ const Movement vis_motions[] = { .txt = lastline, .type = LINEWISE|LINEWISE_INCLUSIVE|JUMP|IDEMPOTENT, }, + [VIS_MOVE_TO_LEFT] = { + .vis = to_left, + .type = COUNT_EXACT, + }, + [VIS_MOVE_TO_RIGHT] = { + .vis = to_right, + .type = INCLUSIVE|COUNT_EXACT, + }, [VIS_MOVE_TO_LINE_LEFT] = { .vis = to_line_left, .type = COUNT_EXACT, @@ -523,6 +573,14 @@ const Movement vis_motions[] = { .vis = to_line_right, .type = INCLUSIVE|COUNT_EXACT, }, + [VIS_MOVE_TILL_LEFT] = { + .vis = till_left, + .type = COUNT_EXACT, + }, + [VIS_MOVE_TILL_RIGHT] = { + .vis = till_right, + .type = INCLUSIVE|COUNT_EXACT, + }, [VIS_MOVE_TILL_LINE_LEFT] = { .vis = till_line_left, .type = COUNT_EXACT, @@ -491,8 +491,12 @@ enum VisMotion { VIS_MOVE_PARENTHESIS_START, VIS_MOVE_PARENTHESIS_END, VIS_MOVE_BRACKET_MATCH, + VIS_MOVE_TO_LEFT, + VIS_MOVE_TO_RIGHT, VIS_MOVE_TO_LINE_LEFT, VIS_MOVE_TO_LINE_RIGHT, + VIS_MOVE_TILL_LEFT, + VIS_MOVE_TILL_RIGHT, VIS_MOVE_TILL_LINE_LEFT, VIS_MOVE_TILL_LINE_RIGHT, VIS_MOVE_FILE_BEGIN, |
