" File: plugin/delimitMate.vim " Version: 2.7 " Modified: 2013-07-15 " Description: This plugin provides auto-completion for quotes, parens, etc. " Maintainer: Israel Chauca F. " Manual: Read ":help delimitMate". " ============================================================================ " Initialization: {{{ if exists("g:loaded_delimitMate") || &cp " User doesn't want this plugin or compatible is set, let's get out! finish endif let g:loaded_delimitMate = 1 let save_cpo = &cpo set cpo&vim if v:version < 700 echoerr "delimitMate: this plugin requires vim >= 7!" finish endif let s:loaded_delimitMate = 1 let delimitMate_version = "2.8" "}}} " Functions: {{{ function! s:option_init(name, default) "{{{ let b = exists("b:delimitMate_" . a:name) let g = exists("g:delimitMate_" . a:name) " Find value to use. if !b && !g let value = a:default elseif b exec "let value = b:delimitMate_" . a:name else exec "let value = g:delimitMate_" . a:name endif call s:set(a:name, value) endfunction "}}} function! s:init() "{{{ " Initialize variables: " autoclose call s:option_init("autoclose", 1) " matchpairs call s:option_init("matchpairs", string(&matchpairs)[1:-2]) call s:option_init("matchpairs_list", map(split(s:get('matchpairs'), '.:.\zs,\ze.:.'), 'split(v:val, ''^.\zs:\ze.$'')')) let pairs = s:get('matchpairs_list') if len(filter(pairs, 'v:val[0] ==# v:val[1]')) echohl ErrorMsg echom 'delimitMate: each member of a pair in delimitMate_matchpairs must be different from each other.' echom 'delimitMate: invalid pairs: ' . join(map(pairs, 'join(v:val, ":")'), ', ') echohl Normal return 0 endif call s:option_init("left_delims", map(copy(s:get('matchpairs_list')), 'v:val[0]')) call s:option_init("right_delims", map(copy(s:get('matchpairs_list')), 'v:val[1]')) " quotes call s:option_init("quotes", "\" ' `") call s:option_init("quotes_list",split(s:get('quotes'), '\s\+')) " nesting_quotes call s:option_init("nesting_quotes", []) " excluded_regions call s:option_init("excluded_regions", "Comment") call s:option_init("excluded_regions_list", split(s:get('excluded_regions'), ',\s*')) let enabled = len(s:get('excluded_regions_list')) > 0 call s:option_init("excluded_regions_enabled", enabled) " expand_space if exists("b:delimitMate_expand_space") && type(b:delimitMate_expand_space) == type("") echom "b:delimitMate_expand_space is '".b:delimitMate_expand_space."' but it must be either 1 or 0!" echom "Read :help 'delimitMate_expand_space' for more details." unlet b:delimitMate_expand_space let b:delimitMate_expand_space = 1 endif if exists("g:delimitMate_expand_space") && type(g:delimitMate_expand_space) == type("") echom "delimitMate_expand_space is '".g:delimitMate_expand_space."' but it must be either 1 or 0!" echom "Read :help 'delimitMate_expand_space' for more details." unlet g:delimitMate_expand_space let g:delimitMate_expand_space = 1 endif call s:option_init("expand_space", 0) " expand_cr if exists("b:delimitMate_expand_cr") && type(b:delimitMate_expand_cr) == type("") echom "b:delimitMate_expand_cr is '".b:delimitMate_expand_cr."' but it must be either 1 or 0!" echom "Read :help 'delimitMate_expand_cr' for more details." unlet b:delimitMate_expand_cr let b:delimitMate_expand_cr = 1 endif if exists("g:delimitMate_expand_cr") && type(g:delimitMate_expand_cr) == type("") echom "delimitMate_expand_cr is '".g:delimitMate_expand_cr."' but it must be either 1 or 0!" echom "Read :help 'delimitMate_expand_cr' for more details." unlet g:delimitMate_expand_cr let g:delimitMate_expand_cr = 1 endif if ((&backspace !~ 'eol' || &backspace !~ 'start') && &backspace != 2) && \ ((exists('b:delimitMate_expand_cr') && b:delimitMate_expand_cr == 1) || \ (exists('g:delimitMate_expand_cr') && g:delimitMate_expand_cr == 1)) echom "delimitMate: There seems to be some incompatibility with your settings that may interfer with the expansion of . See :help 'delimitMate_expand_cr' for details." endif call s:option_init("expand_cr", 0) " expand_in_quotes call s:option_init('expand_inside_quotes', 0) " jump_expansion call s:option_init("jump_expansion", 0) " smart_matchpairs call s:option_init("smart_matchpairs", '^\%(\w\|\!\|[£$]\|[^[:punct:][:space:]]\)') " smart_quotes " XXX: backward compatibility. Ugly, should go the way of the dodo soon. let quotes = escape(join(s:get('quotes_list'), ''), '\-^[]') let default_smart_quotes = '\%(\w\|[^[:punct:][:space:]' . quotes . ']\|\%(\\\\\)*\\\)\%#\|\%#\%(\w\|[^[:space:][:punct:]' . quotes . ']\)' if exists('g:delimitMate_smart_quotes') && type(g:delimitMate_smart_quotes) == type(0) if g:delimitMate_smart_quotes unlet g:delimitMate_smart_quotes else unlet g:delimitMate_smart_quotes let g:delimitMate_smart_quotes = '' endif endif if exists('b:delimitMate_smart_quotes') && type(b:delimitMate_smart_quotes) == type(0) if b:delimitMate_smart_quotes unlet b:delimitMate_smart_quotes if exists('g:delimitMate_smart_quotes') && type(g:delimitMate_smart_quotes) && g:delimitMate_smart_quotes let b:delimitMate_smart_quotes = default_smart_quotes endif else unlet b:delimitMate_smart_quotes let b:delimitMate_smart_quotes = '' endif endif call s:option_init("smart_quotes", default_smart_quotes) " apostrophes call s:option_init("apostrophes", "") call s:option_init("apostrophes_list", split(s:get('apostrophes'), ":\s*")) " tab2exit call s:option_init("tab2exit", 1) " balance_matchpairs call s:option_init("balance_matchpairs", 0) " eol marker call s:option_init("insert_eol_marker", 1) call s:option_init("eol_marker", "") " Everything is fine. return 1 endfunction "}}} Init() function! s:get(...) " {{{ return call('delimitMate#Get', a:000) endfunction " }}} function! s:set(...) " {{{ return call('delimitMate#Set', a:000) endfunction " }}} function! s:Map() "{{{ " Set mappings: try let save_keymap = &keymap let save_iminsert = &iminsert let save_imsearch = &imsearch let save_cpo = &cpo set keymap= set cpo&vim silent! doautocmd User delimitMate_map if s:get('autoclose') call s:AutoClose() else call s:NoAutoClose() endif call s:ExtraMappings() finally let &cpo = save_cpo let &keymap = save_keymap let &iminsert = save_iminsert let &imsearch = save_imsearch endtry let b:delimitMate_enabled = 1 endfunction "}}} Map() function! s:Unmap() " {{{ let imaps = \ s:get('right_delims', []) + \ s:get('left_delims', []) + \ s:get('quotes_list', []) + \ s:get('apostrophes_list', []) + \ ['', '', '', '', '', '', '', ''] + \ ['', '', '', '', '', ''] + \ ['', ''] + \ ['', '', '', '', '', '', 'g'] for map in imaps if maparg(map, "i") =~# '^delimitMate' if map == '|' let map = '' endif exec 'silent! iunmap ' . map endif endfor silent! doautocmd User delimitMate_unmap let b:delimitMate_enabled = 0 endfunction " }}} s:Unmap() function! s:test() "{{{ if &modified let confirm = input("Modified buffer, type \"yes\" to write and proceed " \ . "with test: ") ==? 'yes' if !confirm return endif endif call delimitMate#Test() g/\%^$/d 0 endfunction "}}} function! s:setup(...) "{{{ let swap = a:0 && a:1 == 2 let enable = a:0 && a:1 let disable = a:0 && !a:1 " First, remove all magic, if needed: if get(b:, 'delimitMate_enabled', 0) call s:Unmap() " Switch if swap echo "delimitMate is disabled." return endif endif if disable " Just disable the mappings. return endif if !a:0 " Check if this file type is excluded: if exists("g:delimitMate_excluded_ft") && \ index(split(g:delimitMate_excluded_ft, ','), &filetype, 0, 1) >= 0 " Finish here: return 1 endif " Check if user tried to disable using b:loaded_delimitMate if exists("b:loaded_delimitMate") return 1 endif endif " Initialize settings: if ! s:init() " Something went wrong. return endif if enable || swap || !get(g:, 'delimitMate_offByDefault', 0) " Now, add magic: call s:Map() if a:0 echo "delimitMate is enabled." endif endif endfunction "}}} function! s:TriggerAbb() "{{{ if v:version < 703 \ || ( v:version == 703 && !has('patch489') ) \ || pumvisible() return '' endif return "\" endfunction "}}} function! s:NoAutoClose() "{{{ " inoremap ) =delimitMate#SkipDelim('\)') for delim in s:get('right_delims') + s:get('quotes_list') if delim == '|' let delim = '' endif exec 'inoremap delimitMate' . delim . ' =TriggerAbb().delimitMate#SkipDelim("' . escape(delim,'"') . '")' exec 'silent! imap '.delim.' delimitMate'.delim endfor endfunction "}}} function! s:AutoClose() "{{{ " Add matching pair and jump to the midle: " inoremap ( () let i = 0 while i < len(s:get('matchpairs_list')) let ld = s:get('left_delims')[i] == '|' ? '' : s:get('left_delims')[i] let rd = s:get('right_delims')[i] == '|' ? '' : s:get('right_delims')[i] exec 'inoremap delimitMate' . ld \. ' TriggerAbb().delimitMate#ParenDelim("' . escape(rd, '|') . '")' exec 'silent! imap '.ld \.' delimitMate'.ld let i += 1 endwhile " Exit from inside the matching pair: for delim in s:get('right_delims') let delim = delim == '|' ? '' : delim exec 'inoremap delimitMate' . delim \. ' TriggerAbb().delimitMate#JumpOut("\' . delim . '")' exec 'silent! imap ' . delim \. ' delimitMate'. delim endfor " Add matching quote and jump to the midle, or exit if inside a pair of matching quotes: " inoremap " =delimitMate#QuoteDelim("\"") for delim in s:get('quotes_list') if delim == '|' let delim = '' endif exec 'inoremap delimitMate' . delim \. ' TriggerAbb()."=delimitMate#QuoteDelim(\"\\\' . delim . '\")"' exec 'silent! imap ' . delim \. ' delimitMate' . delim endfor " Try to fix the use of apostrophes (kept for backward compatibility): " inoremap n't n't for map in s:get('apostrophes_list') exec "inoremap " . map . " " . map exec 'silent! imap ' . map . ' delimitMate' . map endfor endfunction "}}} function! s:ExtraMappings() "{{{ " If pair is empty, delete both delimiters: inoremap delimitMateBS =delimitMate#BS() if !hasmapto('delimitMateBS','i') if empty(maparg('', 'i')) silent! imap delimitMateBS endif if empty(maparg('', 'i')) silent! imap delimitMateBS endif endif " If pair is empty, delete closing delimiter: inoremap delimitMateS-BS delimitMate#WithinEmptyPair() ? "\" : "\" if !hasmapto('delimitMateS-BS','i') && maparg('', 'i') == '' silent! imap delimitMateS-BS endif " Expand return if inside an empty pair: inoremap delimitMateCR TriggerAbb()."\=delimitMate#ExpandReturn()\" if s:get('expand_cr') && !hasmapto('delimitMateCR', 'i') && maparg('', 'i') == '' silent! imap delimitMateCR endif " Expand space if inside an empty pair: inoremap delimitMateSpace TriggerAbb()."\=delimitMate#ExpandSpace()\" if s:get('expand_space') && !hasmapto('delimitMateSpace', 'i') && maparg('', 'i') == '' silent! imap delimitMateSpace endif " Jump over any delimiter: inoremap delimitMateS-Tab TriggerAbb()."\=delimitMate#JumpAny()\" if s:get('tab2exit') && !hasmapto('delimitMateS-Tab', 'i') && maparg('', 'i') == '' silent! imap delimitMateS-Tab endif " Jump over next delimiters inoremap delimitMateJumpMany TriggerAbb()."\=delimitMate#JumpMany()\" if !hasmapto('delimitMateJumpMany', 'i') && maparg("g", 'i') == '' imap g delimitMateJumpMany endif endfunction "}}} "}}} " Commands: {{{ " Let me refresh without re-loading the buffer: command! -bar DelimitMateReload call s:setup(1) " Quick test: command! -bar DelimitMateTest call s:test() " Switch On/Off: command! -bar DelimitMateSwitch call s:setup(2) " Enable mappings: command! -bar DelimitMateOn call s:setup(1) " Disable mappings: command! -bar DelimitMateOff call s:setup(0) "}}} " Autocommands: {{{ augroup delimitMate au! " Run on file type change. au FileType * call setup() " Run on new buffers. au BufNewFile,BufRead,BufEnter,CmdwinEnter * \ if !exists('b:delimitMate_was_here') | \ call setup() | \ let b:delimitMate_was_here = 1 | \ endif augroup END "}}} " This is for the default buffer when it does not have a filetype. call s:setup() let &cpo = save_cpo " GetLatestVimScripts: 2754 1 :AutoInstall: delimitMate.vim " vim:foldmethod=marker:foldcolumn=4:ts=2:sw=2