]> git.r.bdr.sh - rbdr/dotfiles/blob - vim/plugin/endwise.vim
dca90ff69a0c70207d82a26daf1335c7d8211b06
[rbdr/dotfiles] / vim / plugin / endwise.vim
1 " endwise.vim - EndWise
2 " Author: Tim Pope <http://tpo.pe/>
3 " Version: 1.0
4 " License: Same as Vim itself. See :help license
5 " GetLatestVimScripts: 2386 1 :AutoInstall: endwise.vim
6
7 if exists("g:loaded_endwise") || &cp
8 finish
9 endif
10 let g:loaded_endwise = 1
11
12 augroup endwise " {{{1
13 autocmd!
14 autocmd FileType lua
15 \ let b:endwise_addition = '\=submatch(0)=="{" ? "}" : "end"' |
16 \ let b:endwise_words = 'function,do,then' |
17 \ let b:endwise_pattern = '^\s*\zs\%(function\|do\|then\)\>\%(.*[^.:@$]\<end\>\)\@!\|\<then\|do\ze\%(\s*|.*|\)\=\s*$' |
18 \ let b:endwise_syngroups = 'luaFunction,luaStatement,luaCond'
19 autocmd FileType ruby
20 \ let b:endwise_addition = '\=submatch(0)=="{" ? "}" : "end"' |
21 \ let b:endwise_words = 'module,class,def,if,unless,case,while,until,begin,do' |
22 \ let b:endwise_pattern = '^\s*\zs\%(module\|class\|def\|if\|unless\|case\|while\|until\|for\|\|begin\)\>\%(.*[^.:@$]\<end\>\)\@!\|\<do\ze\%(\s*|.*|\)\=\s*$' |
23 \ let b:endwise_syngroups = 'rubyModule,rubyClass,rubyDefine,rubyControl,rubyConditional,rubyRepeat'
24 autocmd FileType sh,zsh
25 \ let b:endwise_addition = '\=submatch(0)=="if" ? "fi" : submatch(0)=="case" ? "esac" : "done"' |
26 \ let b:endwise_words = 'if,until,case,do' |
27 \ let b:endwise_pattern = '\%(^\s*\zs\%(if\|case\)\>\ze\|\zs\<do\ze$\|^\s*\zsdo\s*\ze$\)' |
28 \ let b:endwise_syngroups = 'shConditional,shLoop,shIf,shFor,shRepeat,shCaseEsac,zshConditional,zshRepeat,zshDelimiter'
29 autocmd FileType vb,vbnet,aspvbs
30 \ let b:endwise_addition = 'End &' |
31 \ let b:endwise_words = 'Function,Sub,Class,Module,Enum,Namespace' |
32 \ let b:endwise_pattern = '\%(\<End\>.*\)\@<!\<&\>' |
33 \ let b:endwise_syngroups = 'vbStatement,vbnetStorage,vbnetProcedure,vbnet.*Words,AspVBSStatement'
34 autocmd FileType vim
35 \ let b:endwise_addition = 'end&' |
36 \ let b:endwise_words = 'fu\%[nction],wh\%[ile],if,for,try' |
37 \ let b:endwise_syngroups = 'vimFuncKey,vimNotFunc,vimCommand'
38 augroup END " }}}1
39
40 " Maps {{{1
41
42 if maparg("<Plug>DiscretionaryEnd") == ""
43 inoremap <silent> <SID>DiscretionaryEnd <C-R>=<SID>crend(0)<CR>
44 inoremap <silent> <SID>AlwaysEnd <C-R>=<SID>crend(1)<CR>
45 imap <script> <Plug>DiscretionaryEnd <SID>DiscretionaryEnd
46 imap <script> <Plug>AlwaysEnd <SID>AlwaysEnd
47 endif
48 if maparg('<CR>','i') =~# '<C-R>=.*crend(.)<CR>\|<\%(Plug\|SID\)>.*End'
49 " Already mapped
50 elseif maparg('<CR>','i') =~ '<CR>'
51 exe "imap <script> <C-X><CR> ".maparg('<CR>','i')."<SID>AlwaysEnd"
52 exe "imap <script> <CR> ".maparg('<CR>','i')."<SID>DiscretionaryEnd"
53 elseif maparg('<CR>','i') =~ '<Plug>delimitMateCR'
54 exe "imap <C-X><CR> ".maparg('<CR>', 'i')."<Plug>AlwaysEnd"
55 exe "imap <CR> ".maparg('<CR>', 'i')."<Plug>DiscretionaryEnd"
56 else
57 imap <C-X><CR> <CR><Plug>AlwaysEnd
58 imap <CR> <CR><Plug>DiscretionaryEnd
59 endif
60
61 if maparg('<M-o>','i') == ''
62 inoremap <M-o> <C-O>o
63 endif
64
65 " }}}1
66
67 " Code {{{1
68
69 function! s:mysearchpair(beginpat,endpat,synpat)
70 let g:endwise_syntaxes = ""
71 let s:lastline = line('.')
72 call s:synname()
73 let line = searchpair(a:beginpat,'',a:endpat,'Wn','<SID>synname() !~# "^'.substitute(a:synpat,'\\','\\\\','g').'$"',line('.')+50)
74 return line
75 endfunction
76
77 function! s:crend(always)
78 let n = ""
79 if !exists("b:endwise_addition") || !exists("b:endwise_words") || !exists("b:endwise_syngroups")
80 return n
81 end
82 let synpat = '\%('.substitute(b:endwise_syngroups,',','\\|','g').'\)'
83 let wordchoice = '\%('.substitute(b:endwise_words,',','\\|','g').'\)'
84 if exists("b:endwise_pattern")
85 let beginpat = substitute(b:endwise_pattern,'&',substitute(wordchoice,'\\','\\&','g'),'g')
86 else
87 let beginpat = '\<'.wordchoice.'\>'
88 endif
89 let lnum = line('.') - 1
90 let space = matchstr(getline(lnum),'^\s*')
91 let col = match(getline(lnum),beginpat) + 1
92 let word = matchstr(getline(lnum),beginpat)
93 let endword = substitute(word,'.*',b:endwise_addition,'')
94 let y = n.endword."\<C-O>O"
95 let endpat = '\<'.endword.'\>'
96 if a:always
97 return y
98 elseif col <= 0 || synIDattr(synID(lnum,col,1),'name') !~ '^'.synpat.'$'
99 return n
100 elseif getline('.') !~ '^\s*#\=$'
101 return n
102 endif
103 let line = s:mysearchpair(beginpat,endpat,synpat)
104 " even is false if no end was found, or if the end found was less
105 " indented than the current line
106 let even = strlen(matchstr(getline(line),'^\s*')) >= strlen(space)
107 if line == 0
108 let even = 0
109 endif
110 if !even && line == line('.') + 1
111 return y
112 endif
113 if even
114 return n
115 endif
116 return y
117 endfunction
118
119 function! s:synname()
120 " Checking this helps to force things to stay in sync
121 while s:lastline < line('.')
122 let s = synIDattr(synID(s:lastline,indent(s:lastline)+1,1),'name')
123 let s:lastline = nextnonblank(s:lastline + 1)
124 endwhile
125
126 let s = synIDattr(synID(line('.'),col('.'),1),'name')
127 let g:endwise_syntaxes = g:endwise_syntaxes . line('.').','.col('.')."=".s."\n"
128 let s:lastline = line('.')
129 return s
130 endfunction
131
132 " }}}1
133
134 " vim:set sw=2 sts=2: