feat(defaults): map Q and @x to repeat in Visual mode (#26495)

This commit is contained in:
Nacho Nieva 2023-12-26 20:26:18 -03:00 committed by GitHub
parent 5cb906e91c
commit c26dc1f77c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 1 deletions

View File

@ -112,6 +112,9 @@ The following changes may require adaptations in user config or plugins.
• 'termguicolors' is enabled by default when Nvim is able to determine that • 'termguicolors' is enabled by default when Nvim is able to determine that
the host terminal emulator supports 24-bit color. the host terminal emulator supports 24-bit color.
• `Q` now repeats a macro for each line of a visual selection.
• `@` now repeats the indicated macro for each line of a visual selection.
============================================================================== ==============================================================================
BREAKING CHANGES IN HEAD *news-breaking-dev* BREAKING CHANGES IN HEAD *news-breaking-dev*

View File

@ -148,10 +148,20 @@ q Stops recording.
*@@* *E748* *@@* *E748*
@@ Repeat the previous @{0-9a-z":*} [count] times. @@ Repeat the previous @{0-9a-z":*} [count] times.
*v_@-default*
{Visual}@{0-9a-z".=*+} In Visual mode, execute the contents of the register
{Visual}@@ but for each selected line.
See |visual-repeat|, |default-mappings|.
*Q* *Q*
Q Repeat the last recorded register [count] times. Q Repeat the last recorded register [count] times.
See |reg_recorded()|. See |reg_recorded()|.
*v_Q-default*
{Visual}Q In Visual mode, repeat the last recorded register for
each selected line.
See |visual-repeat|, |default-mappings|.
*:@* *:@*
:[addr]@{0-9a-z".=*+} Execute the contents of register {0-9a-z".=*+} as an Ex :[addr]@{0-9a-z".=*+} Execute the contents of register {0-9a-z".=*+} as an Ex
command. First set cursor at line [addr] (default is command. First set cursor at line [addr] (default is

View File

@ -129,6 +129,8 @@ of these in your config by simply removing the mapping, e.g. ":unmap Y".
- <C-W> |i_CTRL-W-default| - <C-W> |i_CTRL-W-default|
- <C-L> |CTRL-L-default| - <C-L> |CTRL-L-default|
- & |&-default| - & |&-default|
- Q |v_Q-default|
- @ |v_@-default|
- # |v_#-default| - # |v_#-default|
- * |v_star-default| - * |v_star-default|
- Nvim LSP client defaults |lsp-defaults| - Nvim LSP client defaults |lsp-defaults|

View File

@ -366,6 +366,20 @@ one of the last commands to extend the highlighted text, the repeating will
be applied up to the rightmost column of the longest line. Any count passed be applied up to the rightmost column of the longest line. Any count passed
to the `.` command is not used. to the `.` command is not used.
Visual mode |default-mappings| "@" and "Q" can repeat commands in a register
for all selected lines. See |v_@-default| and |v_Q-default| for details. For
example, given the text:
123(hello)321
456(world)654
456(NOT THIS)654
With register "x" containing the commands `yi(VP`, Visually selecting the
first two lines and typing `@x` produces:
hello
world
456(NOT THIS)654
============================================================================== ==============================================================================
7. Examples *visual-examples* 7. Examples *visual-examples*

View File

@ -67,6 +67,21 @@ do
--- See |&-default| --- See |&-default|
vim.keymap.set('n', '&', ':&&<CR>', { desc = ':help &-default' }) vim.keymap.set('n', '&', ':&&<CR>', { desc = ':help &-default' })
--- Use Q in visual mode to execute a macro on each line of the selection. #21422
---
--- Applies to @x and includes @@ too.
vim.keymap.set(
'x',
'Q',
':normal! @<C-R>=reg_recorded()<CR><CR>',
{ silent = true, desc = ':help v_Q-default' }
)
vim.keymap.set(
'x',
'@',
"':normal! @'.getcharstr().'<CR>'",
{ silent = true, expr = true, desc = ':help v_@-default' }
)
--- Map |gx| to call |vim.ui.open| on the identifier under the cursor --- Map |gx| to call |vim.ui.open| on the identifier under the cursor
do do
-- TODO: use vim.region() when it lands... #13896 #16843 -- TODO: use vim.region() when it lands... #13896 #16843

View File

@ -11,9 +11,11 @@ local meths = helpers.meths
local insert = helpers.insert local insert = helpers.insert
local curbufmeths = helpers.curbufmeths local curbufmeths = helpers.curbufmeths
before_each(clear)
describe('macros', function() describe('macros', function()
before_each(function()
clear({args_rm = {'--cmd'}})
end)
it('can be recorded and replayed', function() it('can be recorded and replayed', function()
feed('qiahello<esc>q') feed('qiahello<esc>q')
expect('hello') expect('hello')
@ -47,11 +49,75 @@ hello]]
feed[[G3Q]] feed[[G3Q]]
eq({'helloFOOFOO', 'hello', 'helloFOOFOOFOO'}, curbufmeths.get_lines(0, -1, false)) eq({'helloFOOFOO', 'hello', 'helloFOOFOOFOO'}, curbufmeths.get_lines(0, -1, false))
feed[[ggV3jQ]]
eq({'helloFOOFOOFOO', 'helloFOO', 'helloFOOFOOFOOFOO'}, curbufmeths.get_lines(0, -1, false))
end)
it('can be replayed with @', function()
insert [[hello
hello
hello]]
feed [[gg]]
feed [[qqAFOO<esc>q]]
eq({'helloFOO', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false))
feed[[Q]]
eq({'helloFOOFOO', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false))
feed[[G3@@]]
eq({'helloFOOFOO', 'hello', 'helloFOOFOOFOO'}, curbufmeths.get_lines(0, -1, false))
feed[[ggV2j@@]]
eq({'helloFOOFOOFOO', 'helloFOO', 'helloFOOFOOFOOFOO'}, curbufmeths.get_lines(0, -1, false))
end)
it('can be replayed with @q and @w', function()
insert [[hello
hello
hello]]
feed [[gg]]
feed [[qqAFOO<esc>qu]]
eq({'hello', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false))
feed [[qwA123<esc>qu]]
eq({'hello', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false))
feed[[V3j@q]]
eq({'helloFOO', 'helloFOO', 'helloFOO'}, curbufmeths.get_lines(0, -1, false))
feed [[gg]]
feed[[Vj@w]]
eq({'helloFOO123', 'helloFOO123', 'helloFOO'}, curbufmeths.get_lines(0, -1, false))
end)
it('can be replayed with @q and @w visual-block', function()
insert [[hello
hello
hello]]
feed [[gg]]
feed [[qqAFOO<esc>qu]]
eq({'hello', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false))
feed [[qwA123<esc>qu]]
eq({'hello', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false))
feed[[<C-v>3j@q]]
eq({'helloFOO', 'helloFOO', 'helloFOO'}, curbufmeths.get_lines(0, -1, false))
feed [[gg]]
feed[[<C-v>j@w]]
eq({'helloFOO123', 'helloFOO123', 'helloFOO'}, curbufmeths.get_lines(0, -1, false))
end) end)
end) end)
describe('immediately after a macro has finished executing,', function() describe('immediately after a macro has finished executing,', function()
before_each(function() before_each(function()
clear()
command([[let @a = 'gg0']]) command([[let @a = 'gg0']])
end) end)
@ -91,6 +157,7 @@ describe('immediately after a macro has finished executing,', function()
end) end)
describe('reg_recorded()', function() describe('reg_recorded()', function()
before_each(clear)
it('returns the correct value', function() it('returns the correct value', function()
feed [[qqyyq]] feed [[qqyyq]]
eq('q', eval('reg_recorded()')) eq('q', eval('reg_recorded()'))