diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-11-09 14:50:43 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-11-09 14:58:31 +0100 |
| commit | ef268e029d75ee58fb5a78c203278dfb98d212c5 (patch) | |
| tree | 59297514906fdbdc9af25fd7f56a43a55d82d3c6 /main.c | |
| parent | ff45c36bab3952bb633dd0b8e6c4c90dab9f7e2a (diff) | |
| download | vis-ef268e029d75ee58fb5a78c203278dfb98d212c5.tar.gz vis-ef268e029d75ee58fb5a78c203278dfb98d212c5.tar.xz | |
vis: improve `r` in normal and replace mode
In normal mode `r<key>` was previously implemented as `R<key><Escape>`.
However this does not work when the replacement key is `<Enter>` to insert
a new line, because in replace mode new lines are not overwritten.
The count is now also respected.
Also properly support `r` in visual mode where before it was aliased to `c`.
Fix #190
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 23 |
1 files changed, 20 insertions, 3 deletions
@@ -1634,12 +1634,29 @@ static const char *replace(Vis *vis, const char *keys, const Arg *arg) { vis_keymap_disable(vis); return NULL; } + const char *next = vis_keys_next(vis, keys); if (!next) return NULL; - vis_operator(vis, VIS_OP_MODESWITCH, VIS_MODE_REPLACE); - vis_motion(vis, VIS_MOVE_NOP); - vis_keys_feed(vis, keys); + + char replacement[64]; + size_t len = next - keys; + if (len >= sizeof(replacement)) + return next; + + memcpy(replacement, keys, len); + replacement[len] = '\0'; + + if (vis_mode_get(vis) == VIS_MODE_NORMAL) { + int count = vis_count_get_default(vis, 1); + vis_operator(vis, VIS_OP_CHANGE); + vis_motion(vis, VIS_MOVE_CHAR_NEXT); + for (; count > 0; count--) + vis_keys_feed(vis, replacement); + } else { + vis_operator(vis, VIS_OP_REPLACE, replacement); + } + vis_keys_feed(vis, "<Escape>"); return next; } |
