]> git.r.bdr.sh - rbdr/dotfiles/blob - vim/plugin/delimitMate.vim
95ebf19152bc72e65f2f03ea32a1baa389fd1efa
[rbdr/dotfiles] / vim / plugin / delimitMate.vim
1 " File: plugin/delimitMate.vim
2 " Version: 2.6
3 " Modified: 2011-01-14
4 " Description: This plugin provides auto-completion for quotes, parens, etc.
5 " Maintainer: Israel Chauca F. <israelchauca@gmail.com>
6 " Manual: Read ":help delimitMate".
7 " ============================================================================
8
9 " Initialization: {{{
10
11 if exists("g:loaded_delimitMate") || &cp
12 " User doesn't want this plugin or compatible is set, let's get out!
13 finish
14 endif
15 let g:loaded_delimitMate = 1
16
17 if exists("s:loaded_delimitMate") && !exists("g:delimitMate_testing")
18 " Don't define the functions if they already exist: just do the work
19 " (unless we are testing):
20 call s:DelimitMateDo()
21 finish
22 endif
23
24 if v:version < 700
25 echoerr "delimitMate: this plugin requires vim >= 7!"
26 finish
27 endif
28
29 let s:loaded_delimitMate = 1
30 let delimitMate_version = "2.6"
31
32 function! s:option_init(name, default) "{{{
33 let b = exists("b:delimitMate_" . a:name)
34 let g = exists("g:delimitMate_" . a:name)
35 let prefix = "_l_delimitMate_"
36
37 if !b && !g
38 let sufix = a:default
39 elseif !b && g
40 exec "let sufix = g:delimitMate_" . a:name
41 else
42 exec "let sufix = b:delimitMate_" . a:name
43 endif
44 if exists("b:" . prefix . a:name)
45 exec "unlockvar! b:" . prefix . a:name
46 endif
47 exec "let b:" . prefix . a:name . " = " . string(sufix)
48 exec "lockvar! b:" . prefix . a:name
49 endfunction "}}}
50
51 function! s:init() "{{{
52 " Initialize variables:
53
54 " autoclose
55 call s:option_init("autoclose", 1)
56
57 " matchpairs
58 call s:option_init("matchpairs", string(&matchpairs)[1:-2])
59 call s:option_init("matchpairs_list", split(b:_l_delimitMate_matchpairs, ','))
60 call s:option_init("left_delims", split(b:_l_delimitMate_matchpairs, ':.,\='))
61 call s:option_init("right_delims", split(b:_l_delimitMate_matchpairs, ',\=.:'))
62
63 " quotes
64 call s:option_init("quotes", "\" ' `")
65 call s:option_init("quotes_list", split(b:_l_delimitMate_quotes))
66
67 " nesting_quotes
68 call s:option_init("nesting_quotes", [])
69
70 " excluded_regions
71 call s:option_init("excluded_regions", "Comment")
72 call s:option_init("excluded_regions_list", split(b:_l_delimitMate_excluded_regions, ',\s*'))
73 let enabled = len(b:_l_delimitMate_excluded_regions_list) > 0
74 call s:option_init("excluded_regions_enabled", enabled)
75
76 " excluded filetypes
77 call s:option_init("excluded_ft", "")
78
79 " expand_space
80 if exists("b:delimitMate_expand_space") && type(b:delimitMate_expand_space) == type("")
81 echom "b:delimitMate_expand_space is '".b:delimitMate_expand_space."' but it must be either 1 or 0!"
82 echom "Read :help 'delimitMate_expand_space' for more details."
83 unlet b:delimitMate_expand_space
84 let b:delimitMate_expand_space = 1
85 endif
86 if exists("g:delimitMate_expand_space") && type(g:delimitMate_expand_space) == type("")
87 echom "delimitMate_expand_space is '".g:delimitMate_expand_space."' but it must be either 1 or 0!"
88 echom "Read :help 'delimitMate_expand_space' for more details."
89 unlet g:delimitMate_expand_space
90 let g:delimitMate_expand_space = 1
91 endif
92 call s:option_init("expand_space", 0)
93
94 " expand_cr
95 if exists("b:delimitMate_expand_cr") && type(b:delimitMate_expand_cr) == type("")
96 echom "b:delimitMate_expand_cr is '".b:delimitMate_expand_cr."' but it must be either 1 or 0!"
97 echom "Read :help 'delimitMate_expand_cr' for more details."
98 unlet b:delimitMate_expand_cr
99 let b:delimitMate_expand_cr = 1
100 endif
101 if exists("g:delimitMate_expand_cr") && type(g:delimitMate_expand_cr) == type("")
102 echom "delimitMate_expand_cr is '".g:delimitMate_expand_cr."' but it must be either 1 or 0!"
103 echom "Read :help 'delimitMate_expand_cr' for more details."
104 unlet g:delimitMate_expand_cr
105 let g:delimitMate_expand_cr = 1
106 endif
107 if ((&backspace !~ 'eol' || &backspace !~ 'start') && &backspace != 2) &&
108 \ ((exists('b:delimitMate_expand_cr') && b:delimitMate_expand_cr == 1) ||
109 \ (exists('g:delimitMate_expand_cr') && g:delimitMate_expand_cr == 1))
110 echom "delimitMate: There seems to be some incompatibility with your settings that may interfer with the expansion of <CR>. See :help 'delimitMate_expand_cr' for details."
111 endif
112 call s:option_init("expand_cr", 0)
113
114 " smart_matchpairs
115 call s:option_init("smart_matchpairs", '^\%(\w\|\!\|£\|\$\|_\|["'']\s*\S\)')
116
117 " smart_quotes
118 call s:option_init("smart_quotes", 1)
119
120 " apostrophes
121 call s:option_init("apostrophes", "")
122 call s:option_init("apostrophes_list", split(b:_l_delimitMate_apostrophes, ":\s*"))
123
124 " tab2exit
125 call s:option_init("tab2exit", 1)
126
127 " balance_matchpairs
128 call s:option_init("balance_matchpairs", 0)
129
130 let b:_l_delimitMate_buffer = []
131
132 endfunction "}}} Init()
133
134 "}}}
135
136 " Functions: {{{
137
138 function! s:Map() "{{{
139 " Set mappings:
140 try
141 let save_cpo = &cpo
142 let save_keymap = &keymap
143 let save_iminsert = &iminsert
144 let save_imsearch = &imsearch
145 set keymap=
146 set cpo&vim
147 if b:_l_delimitMate_autoclose
148 call s:AutoClose()
149 else
150 call s:NoAutoClose()
151 endif
152 call s:ExtraMappings()
153 finally
154 let &cpo = save_cpo
155 let &keymap = save_keymap
156 let &iminsert = save_iminsert
157 let &imsearch = save_imsearch
158 endtry
159
160 let b:delimitMate_enabled = 1
161
162 endfunction "}}} Map()
163
164 function! s:Unmap() " {{{
165 let imaps =
166 \ b:_l_delimitMate_right_delims +
167 \ b:_l_delimitMate_left_delims +
168 \ b:_l_delimitMate_quotes_list +
169 \ b:_l_delimitMate_apostrophes_list +
170 \ ['<BS>', '<S-BS>', '<Del>', '<CR>', '<Space>', '<S-Tab>', '<Esc>'] +
171 \ ['<Up>', '<Down>', '<Left>', '<Right>', '<LeftMouse>', '<RightMouse>'] +
172 \ ['<Home>', '<End>', '<PageUp>', '<PageDown>', '<S-Down>', '<S-Up>', '<C-G>g']
173
174 for map in imaps
175 if maparg(map, "i") =~? 'delimitMate'
176 if map == '|'
177 let map = '<Bar>'
178 endif
179 exec 'silent! iunmap <buffer> ' . map
180 endif
181 endfor
182
183 if !has('gui_running')
184 silent! iunmap <C-[>OC
185 endif
186
187 let b:delimitMate_enabled = 0
188 endfunction " }}} s:Unmap()
189
190 function! s:TestMappingsDo() "{{{
191 %d
192 if !exists("g:delimitMate_testing")
193 silent call delimitMate#TestMappings()
194 else
195 let temp_varsDM = [b:_l_delimitMate_expand_space, b:_l_delimitMate_expand_cr, b:_l_delimitMate_autoclose]
196 for i in [0,1]
197 let b:delimitMate_expand_space = i
198 let b:delimitMate_expand_cr = i
199 for a in [0,1]
200 let b:delimitMate_autoclose = a
201 call s:init()
202 call s:Unmap()
203 call s:Map()
204 call delimitMate#TestMappings()
205 call append(line('$'),'')
206 endfor
207 endfor
208 let b:delimitMate_expand_space = temp_varsDM[0]
209 let b:delimitMate_expand_cr = temp_varsDM[1]
210 let b:delimitMate_autoclose = temp_varsDM[2]
211 unlet temp_varsDM
212 endif
213 normal gg
214 g/\%^$/d
215 endfunction "}}}
216
217 function! s:DelimitMateDo(...) "{{{
218
219 " First, remove all magic, if needed:
220 if exists("b:delimitMate_enabled") && b:delimitMate_enabled == 1
221 call s:Unmap()
222 endif
223
224 " Check if this file type is excluded:
225 if exists("g:delimitMate_excluded_ft") &&
226 \ index(split(g:delimitMate_excluded_ft, ','), &filetype, 0, 1) >= 0
227
228 " Finish here:
229 return 1
230 endif
231
232 " Check if user tried to disable using b:loaded_delimitMate
233 if exists("b:loaded_delimitMate")
234 return 1
235 endif
236
237 " Initialize settings:
238 call s:init()
239
240 " Now, add magic:
241 call s:Map()
242
243 if a:0 > 0
244 echo "delimitMate has been reset."
245 endif
246 endfunction "}}}
247
248 function! s:DelimitMateSwitch() "{{{
249 if exists("b:delimitMate_enabled") && b:delimitMate_enabled
250 call s:Unmap()
251 echo "delimitMate has been disabled."
252 else
253 call s:Unmap()
254 call s:init()
255 call s:Map()
256 echo "delimitMate has been enabled."
257 endif
258 endfunction "}}}
259
260 function! s:Finish() " {{{
261 if exists('g:delimitMate_loaded')
262 return delimitMate#Finish(1)
263 endif
264 return ''
265 endfunction " }}}
266
267 function! s:FlushBuffer() " {{{
268 if exists('g:delimitMate_loaded')
269 return delimitMate#FlushBuffer()
270 endif
271 return ''
272 endfunction " }}}
273
274 "}}}
275
276 " Mappers: {{{
277 function! s:NoAutoClose() "{{{
278 " inoremap <buffer> ) <C-R>=delimitMate#SkipDelim('\)')<CR>
279 for delim in b:_l_delimitMate_right_delims + b:_l_delimitMate_quotes_list
280 if delim == '|'
281 let delim = '<Bar>'
282 endif
283 exec 'inoremap <silent> <Plug>delimitMate' . delim . ' <C-R>=delimitMate#SkipDelim("' . escape(delim,'"') . '")<CR>'
284 exec 'silent! imap <unique> <buffer> '.delim.' <Plug>delimitMate'.delim
285 endfor
286 endfunction "}}}
287
288 function! s:AutoClose() "{{{
289 " Add matching pair and jump to the midle:
290 " inoremap <silent> <buffer> ( ()<Left>
291 let i = 0
292 while i < len(b:_l_delimitMate_matchpairs_list)
293 let ld = b:_l_delimitMate_left_delims[i] == '|' ? '<bar>' : b:_l_delimitMate_left_delims[i]
294 let rd = b:_l_delimitMate_right_delims[i] == '|' ? '<bar>' : b:_l_delimitMate_right_delims[i]
295 exec 'inoremap <silent> <Plug>delimitMate' . ld . ' ' . ld . '<C-R>=delimitMate#ParenDelim("' . escape(rd, '|') . '")<CR>'
296 exec 'silent! imap <unique> <buffer> '.ld.' <Plug>delimitMate'.ld
297 let i += 1
298 endwhile
299
300 " Exit from inside the matching pair:
301 for delim in b:_l_delimitMate_right_delims
302 exec 'inoremap <silent> <Plug>delimitMate' . delim . ' <C-R>=delimitMate#JumpOut("\' . delim . '")<CR>'
303 exec 'silent! imap <unique> <buffer> ' . delim . ' <Plug>delimitMate'. delim
304 endfor
305
306 " Add matching quote and jump to the midle, or exit if inside a pair of matching quotes:
307 " inoremap <silent> <buffer> " <C-R>=delimitMate#QuoteDelim("\"")<CR>
308 for delim in b:_l_delimitMate_quotes_list
309 if delim == '|'
310 let delim = '<Bar>'
311 endif
312 exec 'inoremap <silent> <Plug>delimitMate' . delim . ' <C-R>=delimitMate#QuoteDelim("\' . delim . '")<CR>'
313 exec 'silent! imap <unique> <buffer> ' . delim . ' <Plug>delimitMate' . delim
314 endfor
315
316 " Try to fix the use of apostrophes (kept for backward compatibility):
317 " inoremap <silent> <buffer> n't n't
318 for map in b:_l_delimitMate_apostrophes_list
319 exec "inoremap <silent> " . map . " " . map
320 exec 'silent! imap <unique> <buffer> ' . map . ' <Plug>delimitMate' . map
321 endfor
322 endfunction "}}}
323
324 function! s:ExtraMappings() "{{{
325 " If pair is empty, delete both delimiters:
326 inoremap <silent> <Plug>delimitMateBS <C-R>=delimitMate#BS()<CR>
327 if !hasmapto('<Plug>delimitMateBS','i')
328 silent! imap <unique> <buffer> <BS> <Plug>delimitMateBS
329 endif
330 " If pair is empty, delete closing delimiter:
331 inoremap <silent> <expr> <Plug>delimitMateS-BS delimitMate#WithinEmptyPair() ? "\<C-R>=delimitMate#Del()\<CR>" : "\<S-BS>"
332 if !hasmapto('<Plug>delimitMateS-BS','i')
333 silent! imap <unique> <buffer> <S-BS> <Plug>delimitMateS-BS
334 endif
335 " Expand return if inside an empty pair:
336 inoremap <silent> <Plug>delimitMateCR <C-R>=delimitMate#ExpandReturn()<CR>
337 if b:_l_delimitMate_expand_cr != 0 && !hasmapto('<Plug>delimitMateCR', 'i')
338 silent! imap <unique> <buffer> <CR> <Plug>delimitMateCR
339 endif
340 " Expand space if inside an empty pair:
341 inoremap <silent> <Plug>delimitMateSpace <C-R>=delimitMate#ExpandSpace()<CR>
342 if b:_l_delimitMate_expand_space != 0 && !hasmapto('<Plug>delimitMateSpace', 'i')
343 silent! imap <unique> <buffer> <Space> <Plug>delimitMateSpace
344 endif
345 " Jump over any delimiter:
346 inoremap <silent> <Plug>delimitMateS-Tab <C-R>=delimitMate#JumpAny("\<S-Tab>")<CR>
347 if b:_l_delimitMate_tab2exit && !hasmapto('<Plug>delimitMateS-Tab', 'i')
348 silent! imap <unique> <buffer> <S-Tab> <Plug>delimitMateS-Tab
349 endif
350 " Change char buffer on Del:
351 inoremap <silent> <Plug>delimitMateDel <C-R>=delimitMate#Del()<CR>
352 if !hasmapto('<Plug>delimitMateDel', 'i')
353 silent! imap <unique> <buffer> <Del> <Plug>delimitMateDel
354 endif
355 " Flush the char buffer on movement keystrokes or when leaving insert mode:
356 for map in ['Esc', 'Left', 'Right', 'Home', 'End']
357 exec 'inoremap <silent> <Plug>delimitMate'.map.' <C-R>=<SID>Finish()<CR><'.map.'>'
358 if !hasmapto('<Plug>delimitMate'.map, 'i')
359 exec 'silent! imap <unique> <buffer> <'.map.'> <Plug>delimitMate'.map
360 endif
361 endfor
362 " Except when pop-up menu is active:
363 for map in ['Up', 'Down', 'PageUp', 'PageDown', 'S-Down', 'S-Up']
364 exec 'inoremap <silent> <expr> <Plug>delimitMate'.map.' pumvisible() ? "\<'.map.'>" : "\<C-R>=\<SID>Finish()\<CR>\<'.map.'>"'
365 if !hasmapto('<Plug>delimitMate'.map, 'i')
366 exec 'silent! imap <unique> <buffer> <'.map.'> <Plug>delimitMate'.map
367 endif
368 endfor
369 " Avoid ambiguous mappings:
370 for map in ['LeftMouse', 'RightMouse']
371 exec 'inoremap <silent> <Plug>delimitMateM'.map.' <C-R>=delimitMate#Finish(1)<CR><'.map.'>'
372 if !hasmapto('<Plug>delimitMate'.map, 'i')
373 exec 'silent! imap <unique> <buffer> <'.map.'> <Plug>delimitMateM'.map
374 endif
375 endfor
376
377 " Jump over next delimiters
378 inoremap <buffer> <Plug>delimitMateJumpMany <C-R>=len(b:_l_delimitMate_buffer) ? delimitMate#Finish(0) : delimitMate#JumpMany()<CR>
379 if !hasmapto('<Plug>delimitMateJumpMany')
380 imap <silent> <buffer> <C-G>g <Plug>delimitMateJumpMany
381 endif
382
383 " The following simply creates an ambiguous mapping so vim fully processes
384 " the escape sequence for terminal keys, see 'ttimeout' for a rough
385 " explanation, this just forces it to work
386 if !has('gui_running')
387 imap <silent> <C-[>OC <RIGHT>
388 endif
389 endfunction "}}}
390
391 "}}}
392
393 " Commands: {{{
394
395 call s:DelimitMateDo()
396
397 " Let me refresh without re-loading the buffer:
398 command! -bar DelimitMateReload call s:DelimitMateDo(1)
399
400 " Quick test:
401 command! -bar DelimitMateTest silent call s:TestMappingsDo()
402
403 " Switch On/Off:
404 command! -bar DelimitMateSwitch call s:DelimitMateSwitch()
405 "}}}
406
407 " Autocommands: {{{
408
409 augroup delimitMate
410 au!
411 " Run on file type change.
412 "autocmd VimEnter * autocmd FileType * call <SID>DelimitMateDo()
413 autocmd FileType * call <SID>DelimitMateDo()
414
415 " Run on new buffers.
416 autocmd BufNewFile,BufRead,BufEnter *
417 \ if !exists('b:delimitMate_was_here') |
418 \ call <SID>DelimitMateDo() |
419 \ let b:delimitMate_was_here = 1 |
420 \ endif
421
422 " Flush the char buffer:
423 autocmd InsertEnter * call <SID>FlushBuffer()
424 autocmd BufEnter *
425 \ if mode() == 'i' |
426 \ call <SID>FlushBuffer() |
427 \ endif
428
429 augroup END
430
431 "}}}
432
433 " GetLatestVimScripts: 2754 1 :AutoInstall: delimitMate.vim
434 " vim:foldmethod=marker:foldcolumn=4