From 2228cd72cf7c6f326e4e41179e88d37595ca4abc Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 22 Nov 2021 14:16:08 +0000 Subject: [PATCH] patch 8.2.3644: count for 'operatorfunc' in Visual mode is not redone Problem: Count for 'operatorfunc' in Visual mode is not redone. Solution: Add the count to the redo buffer. (closes #9174) --- src/normal.c | 26 +++++++++++++++++++++++--- src/ops.c | 14 ++++++++++---- src/proto/normal.pro | 1 + src/testdir/test_normal.vim | 24 ++++++++++++++++++++++-- src/version.c | 2 ++ 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/normal.c b/src/normal.c index aab336a5fe905..56fae51dacf25 100644 --- a/src/normal.c +++ b/src/normal.c @@ -380,8 +380,10 @@ static const struct nv_cmd // Number of commands in nv_cmds[]. #define NV_CMDS_SIZE ARRAY_LENGTH(nv_cmds) +#ifndef PROTO // cproto doesn't like this // Sorted index of commands in nv_cmds[]. static short nv_cmd_idx[NV_CMDS_SIZE]; +#endif // The highest index for which // nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char] @@ -1696,6 +1698,23 @@ prep_redo( int cmd3, int cmd4, int cmd5) +{ + prep_redo_num2(regname, num, cmd1, cmd2, 0L, cmd3, cmd4, cmd5); +} + +/* + * Prepare for redo of any command with extra count after "cmd2". + */ + void +prep_redo_num2( + int regname, + long num1, + int cmd1, + int cmd2, + long num2, + int cmd3, + int cmd4, + int cmd5) { ResetRedobuff(); if (regname != 0) // yank from specified buffer @@ -1703,13 +1722,14 @@ prep_redo( AppendCharToRedobuff('"'); AppendCharToRedobuff(regname); } - if (num) - AppendNumberToRedobuff(num); - + if (num1 != 0) + AppendNumberToRedobuff(num1); if (cmd1 != NUL) AppendCharToRedobuff(cmd1); if (cmd2 != NUL) AppendCharToRedobuff(cmd2); + if (num2 != 0) + AppendNumberToRedobuff(num2); if (cmd3 != NUL) AppendCharToRedobuff(cmd3); if (cmd4 != NUL) diff --git a/src/ops.c b/src/ops.c index aa3b5dec4cd3d..d6190641da552 100644 --- a/src/ops.c +++ b/src/ops.c @@ -3764,6 +3764,8 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) oap->motion_force, cap->cmdchar, cap->nchar); else if (cap->cmdchar != ':' && cap->cmdchar != K_COMMAND) { + int opchar = get_op_char(oap->op_type); + int extra_opchar = get_extra_op_char(oap->op_type); int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL; // reverse what nv_replace() did @@ -3771,10 +3773,14 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) nchar = CAR; else if (nchar == REPLACE_NL_NCHAR) nchar = NL; - prep_redo(oap->regname, 0L, NUL, 'v', - get_op_char(oap->op_type), - get_extra_op_char(oap->op_type), - nchar); + + if (opchar == 'g' && extra_opchar == '@') + // also repeat the count for 'operatorfunc' + prep_redo_num2(oap->regname, 0L, NUL, 'v', + cap->count0, opchar, extra_opchar, nchar); + else + prep_redo(oap->regname, 0L, NUL, 'v', + opchar, extra_opchar, nchar); } if (!redo_VIsual_busy) { diff --git a/src/proto/normal.pro b/src/proto/normal.pro index 30f360b935316..ad0e95ab5c957 100644 --- a/src/proto/normal.pro +++ b/src/proto/normal.pro @@ -10,6 +10,7 @@ void restore_visual_mode(void); int find_ident_under_cursor(char_u **text, int find_type); int find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char_u **text, int *textcol, int find_type); void prep_redo(int regname, long num, int cmd1, int cmd2, int cmd3, int cmd4, int cmd5); +void prep_redo_num2(int regname, long num1, int cmd1, int cmd2, long num2, int cmd3, int cmd4, int cmd5); void clearop(oparg_T *oap); void clearopbeep(oparg_T *oap); void may_clear_cmdline(void); diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim index fd2e2ecf1c0b8..e17aca4128d73 100644 --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -363,7 +363,7 @@ func Test_normal08_fold() bw! endfunc -func Test_normal09_operatorfunc() +func Test_normal09a_operatorfunc() " Test operatorfunc call Setup_NewWindow() " Add some spaces for counting @@ -457,7 +457,7 @@ func Test_normal09_operatorfunc() bw! endfunc -func Test_normal09a_operatorfunc() +func Test_normal09b_operatorfunc() " Test operatorfunc call Setup_NewWindow() " Add some spaces for counting @@ -484,6 +484,26 @@ func Test_normal09a_operatorfunc() unlet! g:opt endfunc +func OperatorfuncRedo(_) + let g:opfunc_count = v:count +endfunc + +func Test_normal09c_operatorfunc() + " Test redoing operatorfunc + new + call setline(1, 'some text') + set operatorfunc=OperatorfuncRedo + normal v3g@ + call assert_equal(3, g:opfunc_count) + let g:opfunc_count = 0 + normal . + call assert_equal(3, g:opfunc_count) + + bw! + unlet g:opfunc_count + set operatorfunc= +endfunc + func Test_normal10_expand() " Test for expand() 10new diff --git a/src/version.c b/src/version.c index cf05293909ad3..67b26345227e2 100644 --- a/src/version.c +++ b/src/version.c @@ -757,6 +757,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 3644, /**/ 3643, /**/