Skip to content

tpope/vim-repeat

master
Switch branches/tags
Code

Latest commit

My automated tests run Vim in silent batch mode (:help -s-ex), these also cover repeat of mappings via repeat.vim. Unfortunately, the combination of feedkeys() and :execute used in the repeat.vim implementation to return a potential caught error cause the line where the repeat mapping is executed to be increased, so for me the tests fail in a really strange way. The same problem can occur if someone uses repeats in silent batch mode (e.g. through a recorded macro) - though the source of the problem would be even harder to track down there - in my test run it at least was easily reproducible.

I raised this as a potential Vim bug in vim/vim#7153, but Bram explained that it's a side effect of Ex mode (where empty lines make the cursor go to the next line, and as repeat#run() returns the empty String on the happy path, that's an empty line being executed). Recommendation from Bram is to pass the "x" flag for immediate execution to feedkeys() (which avoids the problem). However, in the context of repeat.vim this would mean that any errors resulting from the repeat mapping invocation would have to be caught inside repeat#run(), because they would then execute within the function's context, and not after it. Also, the "x" flag would not be supported by old Vim 7.3 and earlier.

Instead, I chose to avoid the problem by replacing the :execute with a more straightforward :call (actually an :if that tests a returned Boolean success flag), so instead of the clever direct execution of the returned :echoerr command, the error message instead is retrieved from a script-local variable via a new repeat#errmsg() getter. I use this idiom in all of my plugins through a set of utility functions (https://github.com/inkarkat/vim-ingo-library/blob/5bb32fd27aa37a767d92ed29eb76dd48a7b0c7d2/autoload/ingo/err.vim#L38-L41), too.
So by adding a little (well encapsulated) variable and getter, this problem can be avoided without touching the sensitive feedkeys() and try...catch logic within the plugin.
24afe92

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 

repeat.vim

If you've ever tried using the . command after a plugin map, you were likely disappointed to discover it only repeated the last native command inside that map, rather than the map as a whole. That disappointment ends today. Repeat.vim remaps . in a way that plugins can tap into it.

The following plugins support repeat.vim:

Adding support to a plugin is generally as simple as the following command at the end of your map functions.

silent! call repeat#set("\<Plug>MyWonderfulMap", v:count)

Installation

Install using your favorite package manager, or use Vim's built-in package support:

mkdir -p ~/.vim/pack/tpope/start
cd ~/.vim/pack/tpope/start
git clone https://tpope.io/vim/repeat.git

Contributing

See the contribution guidelines for pathogen.vim.

Self-Promotion

Like repeat.vim? Follow the repository on GitHub and vote for it on vim.org. And if you're feeling especially charitable, follow tpope on Twitter and GitHub.

License

Copyright (c) Tim Pope. Distributed under the same terms as Vim itself. See :help license.