From ef268e029d75ee58fb5a78c203278dfb98d212c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Wed, 9 Nov 2016 14:50:43 +0100 Subject: vis: improve `r` in normal and replace mode In normal mode `r` was previously implemented as `R`. However this does not work when the replacement key is `` 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 --- config.def.h | 2 +- main.c | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/config.def.h b/config.def.h index 150551b..1ae941f 100644 --- a/config.def.h +++ b/config.def.h @@ -288,7 +288,7 @@ static const KeyBinding bindings_visual[] = { { "J", ACTION(JOIN_LINES) }, { "gJ", ACTION(JOIN_LINES_TRIM) }, { "o", ACTION(SELECTION_FLIP) }, - { "r", ALIAS("c") }, + { "r", ACTION(REPLACE_CHAR) }, { "s", ALIAS("c") }, { "", ACTION(CURSORS_ALIGN_INDENT_RIGHT) }, { "", ACTION(CURSORS_ALIGN_INDENT_LEFT) }, diff --git a/main.c b/main.c index fa4308d..e439b30 100644 --- a/main.c +++ b/main.c @@ -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, ""); return next; } -- cgit v1.2.3