diff options
-rw-r--r-- | src/nvim/ops.c | 12 | ||||
-rw-r--r-- | src/nvim/testdir/test_normal.vim | 33 | ||||
-rw-r--r-- | test/functional/ui/mode_spec.lua | 20 |
3 files changed, 61 insertions, 4 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index f61c978f3c..f1814291b8 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2483,8 +2483,14 @@ int op_change(oparg_T *oap) fix_indent(); } + // Reset finish_op now, don't want it set inside edit(). + const bool save_finish_op = finish_op; + finish_op = false; + retval = edit(NUL, false, (linenr_T)1); + finish_op = save_finish_op; + // In Visual block mode, handle copying the new text to all lines of the // block. // Don't repeat the insert when Insert mode ended with CTRL-C. @@ -5635,8 +5641,6 @@ bool set_ref_in_opfunc(int copyID) static void op_function(const oparg_T *oap) FUNC_ATTR_NONNULL_ALL { - const TriState save_virtual_op = virtual_op; - const bool save_finish_op = finish_op; const pos_T orig_start = curbuf->b_op_start; const pos_T orig_end = curbuf->b_op_end; @@ -5663,9 +5667,11 @@ static void op_function(const oparg_T *oap) // Reset virtual_op so that 'virtualedit' can be changed in the // function. + const TriState save_virtual_op = virtual_op; virtual_op = kNone; // Reset finish_op so that mode() returns the right value. + const bool save_finish_op = finish_op; finish_op = false; typval_T rettv; @@ -6205,8 +6211,6 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) // Restore linebreak, so that when the user edits it looks as before. restore_lbr(lbr_saved); - // Reset finish_op now, don't want it set inside edit(). - finish_op = false; if (op_change(oap)) { // will call edit() cap->retval |= CA_COMMAND_BUSY; } diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 0d75644920..e5756bd505 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -3713,4 +3713,37 @@ func Test_normal_count_out_of_range() bwipe! endfunc +" Test that mouse shape is restored to Normal mode after failed "c" operation. +func Test_mouse_shape_after_failed_change() + CheckFeature mouseshape + CheckCanRunGui + + let lines =<< trim END + set mouseshape+=o:busy + setlocal nomodifiable + let g:mouse_shapes = [] + + func SaveMouseShape(timer) + let g:mouse_shapes += [getmouseshape()] + endfunc + + func SaveAndQuit(timer) + call writefile(g:mouse_shapes, 'Xmouseshapes') + quit + endfunc + + call timer_start(50, {_ -> feedkeys('c')}) + call timer_start(100, 'SaveMouseShape') + call timer_start(150, {_ -> feedkeys('c')}) + call timer_start(200, 'SaveMouseShape') + call timer_start(250, 'SaveAndQuit') + END + call writefile(lines, 'Xmouseshape.vim', 'D') + call RunVim([], [], "-g -S Xmouseshape.vim") + sleep 300m + call assert_equal(['busy', 'arrow'], readfile('Xmouseshapes')) + + call delete('Xmouseshapes') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/functional/ui/mode_spec.lua b/test/functional/ui/mode_spec.lua index 9390f268b3..cf4eb034e0 100644 --- a/test/functional/ui/mode_spec.lua +++ b/test/functional/ui/mode_spec.lua @@ -17,6 +17,7 @@ describe('ui mode_change event', function() [1] = {bold=true, reverse=true}, [2] = {bold=true}, [3] = {reverse=true}, + [4] = {background=Screen.colors.Red, foreground=Screen.colors.White}, -- ErrorMsg }) end) @@ -43,6 +44,25 @@ describe('ui mode_change event', function() {0:~ }| | ]], mode="normal"} + + screen:try_resize(50, 4) + command('set nomodifiable') + + feed('c') + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }| + | + ]], mode="operator"} + + feed('c') + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }| + {4:E21: Cannot make changes, 'modifiable' is off} | + ]], mode="normal"} end) it('works in insert mode', function() |