diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 06b3aa0411..b3b9cc6b44 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -35,6 +35,7 @@ #include "nvim/strings.h" #include "nvim/textformat.h" #include "nvim/textobject.h" +#include "nvim/ui.h" #include "nvim/undo.h" #include "nvim/vim_defs.h" #include "nvim/window.h" @@ -1049,12 +1050,18 @@ void format_lines(linenr_T line_count, bool avoid_fex) State = MODE_INSERT; // for open_line() smd_save = p_smd; p_smd = false; + insertchar(NUL, INSCHAR_FORMAT + (do_comments ? INSCHAR_DO_COM : 0) + (do_comments && do_comments_list ? INSCHAR_COM_LIST : 0) + (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent); + State = old_State; p_smd = smd_save; + // Cursor shape may have been updated (e.g. by :normal) in insertchar(), + // so it needs to be updated here. + ui_cursor_shape(); + second_indent = -1; // at end of par.: need to set indent of next par. need_set_indent = is_end_par; diff --git a/test/functional/ui/mode_spec.lua b/test/functional/ui/mode_spec.lua index 8c6a284cd6..69b38f3ff3 100644 --- a/test/functional/ui/mode_spec.lua +++ b/test/functional/ui/mode_spec.lua @@ -94,6 +94,46 @@ describe('ui mode_change event', function() } end) + -- oldtest: Test_indent_norm_with_gq() + it('is restored to Normal mode after "gq" indents using :normal #12309', function() + screen:try_resize(60, 6) + n.exec([[ + func Indent() + exe "normal! \" + return 0 + endfunc + + setlocal indentexpr=Indent() + call setline(1, [repeat('a', 80), repeat('b', 80)]) + ]]) + + feed('ggVG') + screen:expect { + grid = [[ + {17:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| + {17:aaaaaaaaaaaaaaaaaaaa} | + ^b{17:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb}| + {17:bbbbbbbbbbbbbbbbbbbb} | + {1:~ }| + {5:-- VISUAL LINE --} | + ]], + mode = 'visual', + } + + feed('gq') + screen:expect { + grid = [[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa | + ^bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbb | + {1:~ }| + | + ]], + mode = 'normal', + } + end) + it('works in insert mode', function() feed('i') screen:expect { diff --git a/test/old/testdir/test_indent.vim b/test/old/testdir/test_indent.vim index 0998b04443..36670a0472 100644 --- a/test/old/testdir/test_indent.vim +++ b/test/old/testdir/test_indent.vim @@ -1,5 +1,8 @@ " Test for various indent options +source shared.vim +source check.vim + func Test_preserveindent() new " Test for autoindent copying indent from the previous line @@ -303,4 +306,50 @@ func Test_indent_overflow_count2() close! endfunc +" Test that mouse shape is restored to Normal mode after using "gq" when +" 'indentexpr' executes :normal. +func Test_indent_norm_with_gq() + CheckFeature mouseshape + CheckCanRunGui + + let lines =<< trim END + func Indent() + exe "normal! \" + return 0 + endfunc + + setlocal indentexpr=Indent() + END + call writefile(lines, 'Xindentexpr.vim', 'D') + + let lines =<< trim END + vim9script + var mouse_shapes = [] + + setline(1, [repeat('a', 80), repeat('b', 80)]) + + feedkeys('ggVG') + timer_start(50, (_) => { + mouse_shapes += [getmouseshape()] + timer_start(50, (_) => { + feedkeys('gq') + timer_start(50, (_) => { + mouse_shapes += [getmouseshape()] + timer_start(50, (_) => { + writefile(mouse_shapes, 'Xmouseshapes') + quit! + }) + }) + }) + }) + END + call writefile(lines, 'Xmouseshape.vim', 'D') + + call RunVim([], [], "-g -S Xindentexpr.vim -S Xmouseshape.vim") + call WaitForAssert({-> assert_equal(['rightup-arrow', 'arrow'], + \ readfile('Xmouseshapes'))}, 300) + + call delete('Xmouseshapes') +endfunc + " vim: shiftwidth=2 sts=2 expandtab