Turn Vim functions into operators easily. So OP.
- Turn any function into a Vim operator (your function receives the text as its first argument)
- Return a string to replace the text, or return nothing to leave the buffer alone
- Automatically handles dot-repeat
- Works with motions, text objects, visual mode, linewise and blockwise
- Leaves your registers and marks as it found them
- Helper for a quick operator mapping
- Want to map multiple functions into an operator? No problem. Use a popup menu helper to manage multiple operators
Your function receives the text covered by the motion as its first argument. What it returns decides what happens next:
- Return a string and it replaces the text you operated on.
- Return nothing and the buffer is left alone. Use this for operators that act on text rather than transform it: search for it, send it somewhere, count it.
" Transform: the returned string replaces the text
function! Shout(text)
return toupper(a:text)
endfunction
" Action: returns nothing, so the buffer is untouched
function! Measure(text)
echo "That was " .. strchars(a:text) .. " characters"
endfunctionReturning an empty string deletes the text. Anything that isn't a string (a number, a list) is ignored and leaves the buffer unchanged.
Your registers survive: the operator restores the unnamed register, the yank
register, and the numbered delete stack, so using it never disturbs your yank
history. An operator that changes nothing also leaves the `[ and `]
marks untouched.
call Operatorify#Mapper('go', 'MyFunction')The mapper follows the convention that repeating the last character of the key creates a line operator.
gooperates on a motiongoooperates on the current linegoin visual mode operates on the selection
If you want to create your own set of mapping:
" Create mappings
nnoremap <expr> <Plug>MyFunction Operatorify#Wrapper('MyFunction')
nnoremap <expr> <Plug>MyFunctionLine Operatorify#Wrapper('MyFunction') .. '_'
" Map to keys
nmap go <Plug>MyFunction
nmap goo <Plug>MyFunctionLineYou can customize the appearance and behavior of the popup menu:
let g:operatorify_options = {
\ 'callback': 'PopupCallback',
\ 'border': [0,0,0,0],
\ 'padding': [0,1,0,0],
\ 'pos': 'topleft',
\ 'moved': [0, 0, 0],
\ 'scrollbar': 1,
\ 'maxheight': 5,
\ 'fixed': 1,
\ 'highlight': 'Normal',
\ 'minwidth': 25
\ }You can manage multiple operators through a popup menu. By default, this is mapped to gl:
" Define your functions
function! ToUpper(text)
return toupper(a:text)
endfunction
function! ToLower(text)
return tolower(a:text)
endfunction
" Set up the list
let g:operatorify_list = ['ToUpper', 'ToLower']
" Default mapping is gl, but you can change it
" You can run it as a command too
nnoremap <leader>o :call Operatorify#Lister()<CR>Functions in the list follow the same rule as any other operator function: return a string to replace the text, or return nothing to leave the buffer alone.
To disable the default mapping, add this to your vimrc:
let g:operatorify_no_mappings = 1Plug 'iggredible/vim-operatorify'Source the file, then run :PlugInstall.
Should work with other plugin managers.
:help operatorifyfunction! ToggleCase(text)
return a:text =~# '\u' ? tolower(a:text) : toupper(a:text)
endfunction
call Operatorify#Mapper('gt', 'ToggleCase')
" gt{motion} - toggle case of motion
" gtt - toggle case of current line
" gt - toggle case of visual selection" Define text transformation functions
let g:operatorify_list = [
\ 'ToUpper',
\ 'ToLower',
\ 'Capitalize',
\ 'CamelCase',
\ 'SnakeCase'
\ ]
" Map to gz
call Operatorify#Mapper('gz', 'Operatorify#Lister')Distributed under the same terms as Vim itself. See :help license.