diff options
| author | Qiming zhao <chemzqm@gmail.com> | 2026-09-30 22:16:27 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-30 10:16:27 -0400 |
| commit | cc4e0c8d60ede60d2a48efe322a9bd1f71198b8a (patch) | |
| tree | 764e653f90e52726c1cf149d3d69fc1bb6ec4865 /test/functional/editor/cmdatom_spec.lua | |
| parent | a8062120ad8c144d5da853a611dc9d51708f2d83 (diff) | |
| download | rneovim-cc4e0c8d60ede60d2a48efe322a9bd1f71198b8a.tar.gz rneovim-cc4e0c8d60ede60d2a48efe322a9bd1f71198b8a.tar.bz2 rneovim-cc4e0c8d60ede60d2a48efe322a9bd1f71198b8a.zip | |
fix(input): end Visual mode when aborting redo #42151
Problem:
Skipping buffer flushing in Visual mode breaks map-error and leaves failed
redo motions that raise errors stuck in Visual mode.
Solution:
Keep flushing on errors and exit Visual mode when pending redo is
discarded. Cover failed motions, unset marks, macros, and mappings.
AI-assisted
Diffstat (limited to 'test/functional/editor/cmdatom_spec.lua')
| -rw-r--r-- | test/functional/editor/cmdatom_spec.lua | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/test/functional/editor/cmdatom_spec.lua b/test/functional/editor/cmdatom_spec.lua index 4d805a794e..7c70a2d07b 100644 --- a/test/functional/editor/cmdatom_spec.lua +++ b/test/functional/editor/cmdatom_spec.lua @@ -54,6 +54,54 @@ describe('dot-repeat', function() eq({ 'acbzacbonexy', 'czacbtwo' }, get_lines()) end) + it('ends Visual mode when a replayed motion fails #41896', function() + fn.setline(1, { '1', '2', '3' }) + feed('<C-V>jI1<Esc>') + eq({ '11', '12', '3' }, get_lines()) + feed('j.') + eq({ '11', '112', '13' }, get_lines()) + feed('j.') + eq({ '11', '112', '13' }, get_lines()) + eq('n', fn.mode(1)) + -- A failed repeat does not replace the last change. + feed('k0.') + eq({ '11', '1112', '113' }, get_lines()) + eq('n', fn.mode(1)) + end) + + for _, errorbells in ipairs({ 'noerrorbells', 'errorbells' }) do + it('ends Visual mode when a replayed motion raises an error with ' .. errorbells, function() + command('set ' .. errorbells) + fn.setline(1, { 'one', 'two' }) + feed('majV`a~') + eq({ 'ONE', 'TWO' }, get_lines()) + command('delmarks a') + feed('.') + eq('E20: Mark not set', api.nvim_get_vvar('errmsg')) + eq({ 'ONE', 'TWO' }, get_lines()) + eq('n', fn.mode(1)) + end) + end + + it('still stops macros and mappings on failed Visual motions', function() + fn.setline(1, { 'one', 'two', 'three' }) + fn.setreg('q', 'Vjd') + feed('2@q') + eq({ 'three' }, get_lines()) + eq('V', fn.mode(1)) + feed('<Esc>') + command('nnoremap Q Vjd') + feed('Q') + eq({ 'three' }, get_lines()) + eq('V', fn.mode(1)) + feed('<Esc>') + -- An ordinary failed motion still leaves the selection active. + feed('vj') + eq('v', fn.mode(1)) + feed('d') + eq({ 'hree' }, get_lines()) + end) + it('of a visual op does not churn showcmd', function() local screen = Screen.new(40, 8, { ext_messages = true }) command('set showcmd') |