]>
Commit | Line | Data |
---|---|---|
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: |