Define your snippets for <filetype> in ~/.vim/snippets/<filetype>.txt and call LoadSnippets() in ~/.vim/after/<filetype>.vim. See the comment for usage.
" Snippets are collected in plain text files named after the file type.
" Example snippet:
"
" snippet for
" for (___) {
" ___
" }
"
" A snippet definition starts with the `snippet' keyword followed by the name
" of the snippet (for). The remaining lines contain the text that must be put
" (verbatim) into the buffer.
"
" Three underscores are used for placeholders. At least one placeholder must be
" present. The cursor is put at the first placeholder after expanding the
" snippet. Use CTRL-B in Insert mode to jump to the next placeholder.
"
" To expand a snippet, type its name followed by … (alt-. in macOS).
fun! LoadSnippets()
let l:file = readfile($HOME.'/.vim/snippets/'.&ft.'.txt')
let b:snippets = {}
for l:line in l:file
if l:line =~ '^snippet'
let l:key = matchstr(l:line, '^snippet\s\+\zs.\+$')
let b:snippets[l:key] = []
else
call add(b:snippets[l:key], l:line)
endif
endfor
inoremap <buffer> <c-b> <esc>gn"_c
endf
fun! ExpandSnippet()
let l:key = matchstr(getline('.'), '\S\+\%'.col('.').'c')
let l:snippet = get(b:snippets, l:key, [])
if !empty(l:snippet)
let l:indent = matchstr(getline('.'), '^\s\+')
call setline('.', l:indent . l:snippet[0])
call append('.', map(l:snippet[1:-1], { _,t -> l:indent . t}))
call search('___', 'csW')
let @/ = '___' " Enable moving to the next placeholder with gnc
normal "_3x
return ''
endif
return '…'
endf
inoremap <silent> … <c-r>=exists('b:snippets') ? ExpandSnippet() : '…'<cr>