├── README.markdown └── autoload └── repeat.vim /README.markdown: -------------------------------------------------------------------------------- 1 | # repeat.vim 2 | 3 | If you've ever tried using the `.` command after a plugin map, you were 4 | likely disappointed to discover it only repeated the last native command 5 | inside that map, rather than the map as a whole. That disappointment 6 | ends today. Repeat.vim remaps `.` in a way that plugins can tap into 7 | it. 8 | 9 | The following plugins support repeat.vim: 10 | 11 | * [surround.vim](https://github.com/tpope/vim-surround) 12 | * [speeddating.vim](https://github.com/tpope/vim-speeddating) 13 | * [unimpaired.vim](https://github.com/tpope/vim-unimpaired) 14 | * [vim-easyclip](https://github.com/svermeulen/vim-easyclip) 15 | * [vim-radical](https://github.com/glts/vim-radical) 16 | 17 | Adding support to a plugin is generally as simple as the following 18 | command at the end of your map functions. 19 | 20 | silent! call repeat#set("\MyWonderfulMap", v:count) 21 | 22 | ## Installation 23 | 24 | Install using your favorite package manager, or use Vim's built-in package 25 | support: 26 | 27 | mkdir -p ~/.vim/pack/tpope/start 28 | cd ~/.vim/pack/tpope/start 29 | git clone https://tpope.io/vim/repeat.git 30 | 31 | ## Contributing 32 | 33 | See the contribution guidelines for 34 | [pathogen.vim](https://github.com/tpope/vim-pathogen#readme). 35 | 36 | ## Self-Promotion 37 | 38 | Like repeat.vim? Follow the repository on 39 | [GitHub](https://github.com/tpope/vim-repeat) and vote for it on 40 | [vim.org](http://www.vim.org/scripts/script.php?script_id=2136). And if 41 | you're feeling especially charitable, follow [tpope](http://tpo.pe/) on 42 | [Twitter](http://twitter.com/tpope) and 43 | [GitHub](https://github.com/tpope). 44 | 45 | ## License 46 | 47 | Copyright (c) Tim Pope. Distributed under the same terms as Vim itself. 48 | See `:help license`. 49 | -------------------------------------------------------------------------------- /autoload/repeat.vim: -------------------------------------------------------------------------------- 1 | " repeat.vim - Let the repeat command repeat plugin maps 2 | " Maintainer: Tim Pope 3 | " Version: 1.2 4 | " GetLatestVimScripts: 2136 1 :AutoInstall: repeat.vim 5 | 6 | " Installation: 7 | " Place in either ~/.vim/plugin/repeat.vim (to load at start up) or 8 | " ~/.vim/autoload/repeat.vim (to load automatically as needed). 9 | " 10 | " License: 11 | " Copyright (c) Tim Pope. Distributed under the same terms as Vim itself. 12 | " See :help license 13 | " 14 | " Developers: 15 | " Basic usage is as follows: 16 | " 17 | " silent! call repeat#set("\MappingToRepeatCommand",3) 18 | " 19 | " The first argument is the mapping that will be invoked when the |.| key is 20 | " pressed. Typically, it will be the same as the mapping the user invoked. 21 | " This sequence will be stuffed into the input queue literally. Thus you must 22 | " encode special keys by prefixing them with a backslash inside double quotes. 23 | " 24 | " The second argument is the default count. This is the number that will be 25 | " prefixed to the mapping if no explicit numeric argument was given. The 26 | " value of the v:count variable is usually correct and it will be used if the 27 | " second parameter is omitted. If your mapping doesn't accept a numeric 28 | " argument and you never want to receive one, pass a value of -1. 29 | " 30 | " Make sure to call the repeat#set function _after_ making changes to the 31 | " file. 32 | " 33 | " For mappings that use a register and want the same register used on 34 | " repetition, use: 35 | " 36 | " silent! call repeat#setreg("\MappingToRepeatCommand", v:register) 37 | " 38 | " This function can (and probably needs to be) called before making changes to 39 | " the file (as those typically clear v:register). Therefore, the call sequence 40 | " in your mapping will look like this: 41 | " 42 | " nnoremap MyMap 43 | " \ :execute 'silent! call repeat#setreg("\Plug>MyMap", v:register)' 44 | " \ call MyFunction(v:register, ...) 45 | " \ silent! call repeat#set("\Plug>MyMap") 46 | 47 | if exists("g:loaded_repeat") || &cp || v:version < 800 48 | finish 49 | endif 50 | let g:loaded_repeat = 1 51 | 52 | let g:repeat_tick = -1 53 | let g:repeat_reg = ['', ''] 54 | 55 | " Special function to avoid spurious repeats in a related, naturally repeating 56 | " mapping when your repeatable mapping doesn't increase b:changedtick. 57 | function! repeat#invalidate() 58 | autocmd! repeat_custom_motion 59 | let g:repeat_tick = -1 60 | endfunction 61 | 62 | function! repeat#set(sequence,...) 63 | let g:repeat_sequence = a:sequence 64 | let g:repeat_count = a:0 ? a:1 : v:count 65 | let g:repeat_tick = b:changedtick 66 | augroup repeat_custom_motion 67 | autocmd! 68 | autocmd CursorMoved let g:repeat_tick = b:changedtick | autocmd! repeat_custom_motion 69 | augroup END 70 | endfunction 71 | 72 | function! repeat#setreg(sequence,register) 73 | let g:repeat_reg = [a:sequence, a:register] 74 | endfunction 75 | 76 | 77 | function! s:default_register() 78 | let values = split(&clipboard, ',') 79 | if index(values, 'unnamedplus') != -1 80 | return '+' 81 | elseif index(values, 'unnamed') != -1 82 | return '*' 83 | else 84 | return '"' 85 | endif 86 | endfunction 87 | 88 | function! repeat#run(count) 89 | let s:errmsg = '' 90 | try 91 | if g:repeat_tick == b:changedtick 92 | let r = '' 93 | if g:repeat_reg[0] ==# g:repeat_sequence && !empty(g:repeat_reg[1]) 94 | " Take the original register, unless another (non-default, we 95 | " unfortunately cannot detect no vs. a given default register) 96 | " register has been supplied to the repeat command (as an 97 | " explicit override). 98 | let regname = v:register ==# s:default_register() ? g:repeat_reg[1] : v:register 99 | if regname ==# '=' 100 | " This causes a re-evaluation of the expression on repeat, which 101 | " is what we want. 102 | let r = '"=' . getreg('=', 1) . "\" 103 | else 104 | let r = '"' . regname 105 | endif 106 | endif 107 | 108 | let c = g:repeat_count 109 | let s = g:repeat_sequence 110 | let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : '')) 111 | call feedkeys(s, 'i') 112 | call feedkeys(r . cnt, 'ni') 113 | else 114 | call feedkeys((a:count ? a:count : '') . '.', 'ni') 115 | endif 116 | catch /^Vim(normal):/ 117 | let s:errmsg = v:errmsg 118 | return 0 119 | endtry 120 | return 1 121 | endfunction 122 | function! repeat#errmsg() 123 | return s:errmsg 124 | endfunction 125 | 126 | function! repeat#wrap(command,count) 127 | let foldopen = &foldopen =~# 'undo\|all' ? 'zv' : '' 128 | let preserve = g:repeat_tick == b:changedtick ? ":let g:repeat_tick = b:changedtick\r" : '' 129 | return (a:count ? a:count : '') . a:command . preserve . foldopen 130 | endfunction 131 | 132 | nnoremap (RepeatDot) :if !repeat#run(v:count)echoerr repeat#errmsg()endif 133 | nmap