Skip to content

Instantly share code, notes, and snippets.

@gamefreak
Created March 4, 2012 19:23
Show Gist options
  • Save gamefreak/1974442 to your computer and use it in GitHub Desktop.
Save gamefreak/1974442 to your computer and use it in GitHub Desktop.
if exists("g:loaded_smartabbrev")
finish
endif
let g:loaded_smartabbrev=1
if !exists("g:reservedMark")
let g:reservedMark = "y"
endif
"match <cursor> preceded by 2n backslashes
let s:matchReg = '\(\\\)\@<!\(\\\\\)*\zs<cursor>'
"A bang makes the abbreviation global
"Prefix an abbrev definition with this to remove the trailing space
"Example: (in javascript)
"Sab [\ \(] iab afe forEach(function(elem, index, array) {<cr><cursor><cr>});
"so typing afe in insert mode produces
"forEach(function(elem, index, array) {
" <cursor>
"});
"and correctly indents it to the best of vim's ability
command! -bang -nargs=+ Sabbreviate exec s:MakeTemplate("<bang>", <f-args>)
command! -bang -nargs=+ SmartAbbreviate exec s:MakeTemplate("<bang>", <f-args>)
function! s:MakeTemplate(bang, ...)
if a:1 =~ "\\[.*\\]"
let cmdArgs = copy(a:000)[1:]
let keys = a:1[1:-2]
else
let cmdArgs = copy(a:000)
let keys = " \t"
end
let cmdArgs = insert(cmdArgs, "<silent>", 1)
if a:bang != "!"
let cmdArgs = insert(cmdArgs, "<buffer>", 1)
endif
let cmds = join(cmdArgs, " ")
if cmds =~ s:matchReg
"<C-\><C-o> execute 1 normal mode command without moving the cursor
"my save mark y or whatever is set to be reserved
let cmds = substitute(cmds, s:matchReg, "<C-\\\\><C-o>m".g:reservedMark, "")
"<C-o> execute 1 normal mode command
"`y jump to cursor position of reserved mark
"<C-f> fix indentation
let cmds .= "<C-o>`" . g:reservedMark . "<C-f>"
end
"Append result of expression
let cmds .= "<C-r>=Eatchar('[" . keys . "]')<cr>"
return cmds
endfunction
"Kill the space after the abbreviation
function! Eatchar(pat)
let c = nr2char(getchar())
return (c =~ a:pat) ? "" : c
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment