sponsor Vim development Vim logo Vim Book Ad

visualrepeat : Repeat command extended to visual mode.

 script karma  Rating 69/18, Downloaded by 3778  Comments, bugs, improvements  Vim wiki

created by
Ingo Karkat
 
script type
utility
 
description
DESCRIPTION
This plugin defines repetition of Vim built-in normal mode commands via .
for visual mode. Additionally, it offers functions like the popular repeat.vim
plugin that allow mappings to be repeated in visual mode, too.

VISUAL MODE REPETITION
This extends the built-in normal mode repeat . to visual mode.

VISUAL MODE MAPPING REPETITION
Like with repeat.vim for normal mode, visual mode mappings can register a
<Plug> mapping to be used for visual mode repetition.

Likewise, normal mode mappings can (in addition to the repeat.vim registration
of a normal mode mapping) register a visual mode mapping with visualrepeat.vim
that will be repeated in visual mode.

Operator-pending mappings end with g@ and repeat naturally; i.e. Vim
re-applies the 'opfunc' on the equivalent text (but at the current cursor
position). But without a call to repeat#set(), it is impossible to repeat this
operator-pending mapping to the current visual selection. Plugins cannot call
repeat#set() in their operator-pending mapping, because then Vim's built-in
repeat would be circumvented, the full mapping ending with g@ would be
re-executed, and the repetition would then wait for the {motion}, what is not
wanted.
Therefore, this plugin offers a separate visualrepeat#set() function that can
be invoked for operator-pending mappings. It can also be invoked for
normal-mode mappings that have already called repeat#set(), and may override
that mapping with a special repeat mapping for visual mode repeats. Together
with the remapped {Visual}. command, this allows repetition - similar to what
the built-in Vim commands do - across normal, operator-pending and visual
mode.

SOURCE
- Based on vimtip #1142, Repeat last command and put cursor at start of change
    http://vim.wikia.com/wiki/Repeat_last_command_and_put_cursor_at_start_of_change
- The client interface and implementation has been based on repeat.vim
  (vimscript #2136) by Tim Pope.

RELATED WORKS
- repeat.vim (vimscript #2136) has been the basis for this plugin and should
  be used in conjunction with visualrepeat.vim. (Otherwise, you'd have visual
  mode repeat, but no repeat in normal mode.)

USAGE
{Visual}.               Repeat last change in all visually selected lines.
                        - characterwise: Start from cursor position.
                        - linewise: Each line separately, starting from the
                          current column (usually the first in this mode).
                        - blockwise: Only the selected text. This is
                          implemented by temporarily duplicating the selection
                          to separate lines and repeating over those, starting
                          from the first column.

                        Note: If the last normal mode command included a
                        {motion} (e.g. g~e), the repetition will also move
                        exactly over this {motion}, NOT the visual selection!
                        It is thus best to repeat commands that work on the
                        entire line (e.g. g~$).

{Visual}g.              Repeat last built-in command in all visually selected
                        lines. Skips any plugin repeat actions; only repeats
                        the last Vim command.
 
install details
INSTALLATION
The code is hosted in a Git repo at
    https://github.com/inkarkat/vim-visualrepeat
You can use your favorite plugin manager, or "git clone" into a directory used
for Vim packages. Releases are on the "stable" branch, the latest unstable
development snapshot on "master".

This script is also packaged as a vimball. If you have the "gunzip"
decompressor in your PATH, simply edit the *.vmb.gz package in Vim; otherwise,
decompress the archive first, e.g. using WinZip. Inside Vim, install by
sourcing the vimball or via the :UseVimball command.
    vim visualrepeat*.vmb.gz
    :so %
To uninstall, use the :RmVimball command.

DEPENDENCIES
- Requires Vim 7.0 or higher.
- repeat.vim (vimscript #2136) plugin (highly recommended)
- ingo-library.vim plugin (vimscript #4433), version 1.013 or higher;
  optional, for blockwise repeat only

INTEGRATION
This plugin is meant to be used together with repeat.vim.

This plugin has helper functions that plugins with cross-repeat functionality
can use in their normal mode repeat mappings of repeated visual mode mappings.
With this, you save work and allow for a consistent user experience.
Define your normal mode repeat mapping like this:
    nnoremap <silent> <Plug>(MyPluginVisual)
    \ :<C-u>execute 'normal!' visualrepeat#reapply#VisualMode(0)<Bar>
    \call MyPlugin#Operator('visual', "\<lt>Plug>(MyPluginVisual)")<CR>
If your plugin uses a passed [count] (i.e. the count is not only used to
determine the text area the mapping is applied to), you need to define a
mapping:
    vnoremap <silent> <expr> <SID>(ReapplyRepeatCount) visualrepeat#reapply#RepeatCount()
and apply the function followed by the mapping like this:
    nnoremap <silent> <script> <Plug>(MyPluginVisual)
    \ :<C-u>execute 'normal!' visualrepeat#reapply#VisualMode(1)<CR>
    \<SID>(ReapplyRepeatCount)
    \:<C-u>call MyPlugin#Operator('visual', v:count, "\<lt>Plug>(MyPluginVisual)")<CR>
If you want to support running without visualrepeat.vim, too, provide a
wrapper that defaults to 1v:
    function! s:VisualMode()
        let l:keys = "1v\<Esc>"
        silent! let l:keys = visualrepeat#reapply#VisualMode(0)
        return l:keys
    endfunction
    nnoremap <silent> <Plug>(MyPluginVisual)
    \ :<C-u>execute 'normal!' <SID>VisualMode()<Bar>
    \call MyPlugin#Operator('visual', "\<lt>Plug>(MyPluginVisual)")<CR>
 

rate this script Life Changing Helpful Unfulfilling 
script versions (upload new version)

Click on the package to download.

package script version date Vim version user release notes
visualrepeat-1.32.vmb.gz 1.32 2020-02-24 7.0 Ingo Karkat - BUG: visualrepeat#reapply#VisualMode() mistakenly adds the next full line when restoring a linewise visual selection (to a smaller target).
- Use :normal for Vim 7.3.100..7.4.601 and feedkeys(..., 'i') for newer versions, aligning the used mechanism with what repeat.vim uses.
visualrepeat-1.31.vmb.gz 1.31 2019-03-18 7.0 Ingo Karkat - ENH: Add g. mapping that forces built-in repeat; i.e. skips any custom repeat.vim or visualrepeat.vim actions. This can be useful if a plugin offers a special repeat for visual mode, but a built-in repeat on each selected line may make sense, too. For example, my KeepText.vim plugin would keep the entire linewise selection; forcing a built-in repeat (of the custom operator) would reapply e.g. a <Leader>ka" to all selected lines instead.
- Factor out ingo#buffer#temprange#Call() into ingo-library. *** You need to update the optional dependency to ingo-library (vimscript #4433) version 1.018! ***
- ENH: Make an explicit register on repeat override g:repeat_reg. As with built-in commands, this allows to override the original register on repeat, e.g. "a. uses register a instead of the original one. One limitation is that we cannot detect whether no or the default register has been given, so an override from a non-default to the default register (e.g. via "".) is not possible.
visualrepeat-1.30.vmb.gz 1.30 2013-11-15 7.0 Ingo Karkat - ENH: When repeating over multiple lines / a blockwise selection, keep track of added or deleted lines, and only repeat exactly on the selected lines. Thanks to Israel Chauca for sending a patch!
- When a repeat on a blockwise selection has introduced additional lines, append those properly indented instead of omitting them.
- With linewise and blockwise repeat, set the change marks '[,'] to the changed selection. With the latter, one previously got "E19: Mark has invalid line number" due to the removed temporary range.
visualrepeat-1.20.vmb.gz 1.20 2013-11-14 7.0 Ingo Karkat - ENH: Implement blockwise repeat through temporarily moving the block to a temporary range at the end of the buffer, like the vis.vim plugin. This feature requires the ingo-library. *** You need to separately install ingo-library (vimscript #4433) version 1.013 (or higher)! ***
visualrepeat-1.10.vmb.gz 1.10 2013-09-05 7.0 Ingo Karkat - Check for existence of actual visual mode mapping; do not accept a select mode mapping, because we're applying it to a visual selection.
- Pass through a [count] to the :normal . command.
- Add visualrepeat#reapply#VisualMode() and visualrepeat#reapply#RepeatCount() helper functions that plugins can use in their normal mode repeat mappings of repeated visual mode mappings.
- Minor: Make substitute() robust against 'ignorecase'.
- ENH: Use the current cursor virtual column when repeating in linewise visual mode. Inspired by http://stackoverflow.com/questions/18610564/vim-is-possible-to-use-dot-command-in-visual-block-mode
- Abort further commands on error by using echoerr inside the mapping.
visualrepeat-1.03.vmb.gz 1.03 2013-02-21 7.0 Ingo Karkat REGRESSION: Fix in 1.02 does not repeat recorded register when the mappings in repeat.vim and visualrepeat.vim differ.
visualrepeat-1.02.vmb.gz 1.02 2012-12-27 7.0 Ingo Karkat BUG: "E121: Undefined variable: g:repeat_sequence" when using visual repeat of a mapping using registers without having used repeat.vim beforehand.
visualrepeat.vba.gz 1.01 2012-04-05 7.0 Ingo Karkat FIX: Avoid error about undefined g:repeat_reg when (a proper version of)
repeat.vim isn't available.
visualrepeat.vba.gz 1.00 2011-12-14 7.0 Ingo Karkat Initial upload
ip used for rating: 34.230.84.106

If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
   
Vim at Github