aboutsummaryrefslogtreecommitdiff
path: root/plugin/template.vim
blob: a6cbc591727587402d78460057745425b622a7e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
" template.vim: Vim commands to load template.
"
" This filetype plugin adds one command for the buffers:
"
"   :Template {name}
"
"       Load template named as {name} in the current buffer.
"       Template file is stored in ~/.vim/template.
"       If you are using pathogen.vim, template folder is located at following. 
"
"         ~/.vim/bundle/template-vim
"             plugin
"               template.vim # This file.
"             template
"               main.go
"               package.go
"               package.perl
"               script.perl
"

command! -nargs=1 -complete=customlist,TemplateComplete Template call s:Template(<f-args>)

if exists('g:template_vim_template_dir')
  let s:tmpldir = g:template_vim_template_dir
else
  let s:tmpldir = expand('<sfile>:p:h:h') . '/template/'
endif

function! TemplateComplete(lead, cmdline, curpos) abort
  if search('[^ \t]', 'wn')
    return map(split(globpath(join([s:tmpldir, &ft], '/'), 'snip-' . a:lead . '*.*'), "\n"), 'fnamemodify(v:val, ":t:r")[5:]')
  else
    return map(split(globpath(join([s:tmpldir, &ft], '/'), 'base-' . a:lead . '*.*'), "\n"), 'fnamemodify(v:val, ":t:r")[5:]')
  endif
endfunction

function! s:Template(name) abort
  let buffer_is_not_empty = search('[^ \t]', 'wn')
  if search('[^ \t]', 'wn')
    let fs = split(globpath(join([s:tmpldir, &ft], '/'), 'snip-' . a:name . '.*'), "\n")
  else
    let fs = split(globpath(join([s:tmpldir, &ft], '/'), 'base-' . a:name . '.*'), "\n")
  endif
  if len(fs) == 0
    echomsg 'Template '.a:name.' is not exists.'
    return
  endif
  let f = fs[0]
  if !filereadable(f)
    echomsg 'Template '.a:name.' is not exists.'
    return
  endif
  let c = join(readfile(f, "b"), "\n")
  let c = substitute(c, '{{_name_}}', expand('%:t:r:'), 'g')
  let tmp = c
  let mx = '{{_input_:\(.\{-}\)}}'
  let vars = []
  while 1
    let match = matchstr(tmp, mx)
    if len(match) == 0
      break
    endif
    let var = substitute(match, mx, '\1', 'ig')
    if index(vars, var) == -1
      call add(vars, var)
    endif
    let tmp = tmp[stridx(tmp, match) + len(match):]
  endwhile
  for var in vars
    let val = input(var . ":")
    let c = substitute(c, '\V{{_input_:'.var.'}}', '\=val', 'g')
  endfor
  let c = substitute(c, '{{_expr_:\(.\{-}\)}}', '\=eval(submatch(1))', 'g')
  if len(c) == 0
    return
  endif
  if !buffer_is_not_empty
    silent! %d _
    silent! put = c
    silent! normal! ggdd
  else
    if c[len(c)-1] == "\n"
      let c = c[:-2]
    endif
    let line = getline('.')
    let indent = matchstr(line, '^\(\s*\)')
    if line =~ '^\s*$' && line('.') != line('$')
      silent! normal dd
    endif
    let c = indent . substitute(c, "\n", "\n".indent, 'g')
    if len(indent) && (&expandtab || indent =~ '^ \+$')
      let c = substitute(c, "\t", repeat(' ', min([len(indent), &tabstop])), 'g')
    endif
    silent! put! = c
  endif
  if stridx(c, '{{_cursor_}}')
    silent! call search('{{_cursor_}}', 'w')
    silent! s/{{_cursor_}}//g
    silent! exe "normal! \<c-o>"
  endif
endfunction

" vim:ts=4:sw=4:et