2011-05-24 07:31:55 -04:00
|
|
|
" Insert or delete brackets, parens, quotes in pairs.
|
2011-05-22 13:11:23 -04:00
|
|
|
" Maintainer: JiangMiao <jiangfriend@gmail.com>
|
2011-12-29 08:42:43 -05:00
|
|
|
" Contributor: camthompson
|
2013-02-16 01:02:32 -05:00
|
|
|
" Last Change: 2013-02-16
|
|
|
|
" Version: 1.3.0
|
2011-06-07 00:40:51 -04:00
|
|
|
" Homepage: http://www.vim.org/scripts/script.php?script_id=3599
|
2011-05-22 13:11:23 -04:00
|
|
|
" Repository: https://github.com/jiangmiao/auto-pairs
|
2013-03-17 07:32:25 -04:00
|
|
|
" License: MIT
|
2011-05-22 13:11:23 -04:00
|
|
|
|
|
|
|
if exists('g:AutoPairsLoaded') || &cp
|
|
|
|
finish
|
|
|
|
end
|
|
|
|
let g:AutoPairsLoaded = 1
|
|
|
|
|
|
|
|
if !exists('g:AutoPairs')
|
2012-01-17 00:14:56 -05:00
|
|
|
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
2011-05-22 13:11:23 -04:00
|
|
|
end
|
2011-12-14 04:00:45 -05:00
|
|
|
|
|
|
|
if !exists('g:AutoPairsParens')
|
|
|
|
let g:AutoPairsParens = {'(':')', '[':']', '{':'}'}
|
|
|
|
end
|
|
|
|
|
2011-06-07 00:40:51 -04:00
|
|
|
if !exists('g:AutoPairsMapBS')
|
|
|
|
let g:AutoPairsMapBS = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
if !exists('g:AutoPairsMapCR')
|
|
|
|
let g:AutoPairsMapCR = 1
|
|
|
|
end
|
|
|
|
|
2011-12-13 16:56:46 -05:00
|
|
|
if !exists('g:AutoPairsMapSpace')
|
|
|
|
let g:AutoPairsMapSpace = 1
|
|
|
|
end
|
|
|
|
|
2011-06-07 00:40:51 -04:00
|
|
|
if !exists('g:AutoPairsCenterLine')
|
|
|
|
let g:AutoPairsCenterLine = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
if !exists('g:AutoPairsShortcutToggle')
|
|
|
|
let g:AutoPairsShortcutToggle = '<M-p>'
|
|
|
|
end
|
|
|
|
|
2011-06-09 14:36:51 -04:00
|
|
|
if !exists('g:AutoPairsShortcutFastWrap')
|
|
|
|
let g:AutoPairsShortcutFastWrap = '<M-e>'
|
|
|
|
end
|
|
|
|
|
2012-03-20 01:13:39 -04:00
|
|
|
if !exists('g:AutoPairsShortcutJump')
|
|
|
|
let g:AutoPairsShortcutJump = '<M-n>'
|
|
|
|
endif
|
|
|
|
|
2012-05-13 21:54:25 -04:00
|
|
|
" Fly mode will for closed pair to jump to closed pair instead of insert.
|
|
|
|
" also support AutoPairsBackInsert to insert pairs where jumped.
|
|
|
|
if !exists('g:AutoPairsFlyMode')
|
2012-05-16 12:16:58 -04:00
|
|
|
let g:AutoPairsFlyMode = 0
|
2012-05-13 21:54:25 -04:00
|
|
|
endif
|
2011-05-24 07:07:26 -04:00
|
|
|
|
2012-05-13 21:54:25 -04:00
|
|
|
" Work with Fly Mode, insert pair where jumped
|
|
|
|
if !exists('g:AutoPairsShortcutBackInsert')
|
|
|
|
let g:AutoPairsShortcutBackInsert = '<M-b>'
|
|
|
|
endif
|
|
|
|
|
2013-03-04 01:19:13 -05:00
|
|
|
if !exists('g:AutoPairsSmartQuotes')
|
|
|
|
let g:AutoPairsSmartQuotes = 1
|
|
|
|
endif
|
|
|
|
|
2012-05-13 21:54:25 -04:00
|
|
|
|
2012-05-14 03:22:43 -04:00
|
|
|
" Will auto generated {']' => '[', ..., '}' => '{'}in initialize.
|
2012-05-13 21:54:25 -04:00
|
|
|
let g:AutoPairsClosedPairs = {}
|
2011-05-24 07:07:26 -04:00
|
|
|
|
2011-05-22 13:11:23 -04:00
|
|
|
|
|
|
|
function! AutoPairsInsert(key)
|
2011-06-07 00:40:51 -04:00
|
|
|
if !b:autopairs_enabled
|
|
|
|
return a:key
|
|
|
|
end
|
|
|
|
|
2011-05-22 13:11:23 -04:00
|
|
|
let line = getline('.')
|
2012-10-09 03:00:34 -04:00
|
|
|
let pos = col('.') - 1
|
2013-03-04 09:04:15 -05:00
|
|
|
let before = strpart(line, 0, pos)
|
|
|
|
let after = strpart(line, pos)
|
|
|
|
let next_chars = split(after, '\zs')
|
2012-10-09 03:00:34 -04:00
|
|
|
let current_char = get(next_chars, 0, '')
|
|
|
|
let next_char = get(next_chars, 1, '')
|
2013-03-04 09:04:15 -05:00
|
|
|
let prev_chars = split(before, '\zs')
|
2012-10-09 03:00:34 -04:00
|
|
|
let prev_char = get(prev_chars, -1, '')
|
2011-05-22 13:11:23 -04:00
|
|
|
|
2011-06-07 00:40:51 -04:00
|
|
|
let eol = 0
|
|
|
|
if col('$') - col('.') <= 1
|
|
|
|
let eol = 1
|
|
|
|
end
|
|
|
|
|
2011-05-22 13:11:23 -04:00
|
|
|
" Ignore auto close if prev character is \
|
|
|
|
if prev_char == '\'
|
|
|
|
return a:key
|
|
|
|
end
|
|
|
|
|
2012-05-13 21:54:25 -04:00
|
|
|
" The key is difference open-pair, then it means only for ) ] } by default
|
2012-12-23 11:53:22 -05:00
|
|
|
if !has_key(b:AutoPairs, a:key)
|
2012-05-14 07:01:22 -04:00
|
|
|
let b:autopairs_saved_pair = [a:key, getpos('.')]
|
2011-12-21 05:26:26 -05:00
|
|
|
|
2011-12-14 04:00:45 -05:00
|
|
|
" Skip the character if current character is the same as input
|
|
|
|
if current_char == a:key
|
|
|
|
return "\<Right>"
|
|
|
|
end
|
|
|
|
|
2012-05-14 07:01:22 -04:00
|
|
|
if !g:AutoPairsFlyMode
|
|
|
|
" Skip the character if next character is space
|
|
|
|
if current_char == ' ' && next_char == a:key
|
|
|
|
return "\<Right>\<Right>"
|
|
|
|
end
|
|
|
|
|
|
|
|
" Skip the character if closed pair is next character
|
|
|
|
if current_char == ''
|
|
|
|
let next_lineno = line('.')+1
|
|
|
|
let next_line = getline(nextnonblank(next_lineno))
|
|
|
|
let next_char = matchstr(next_line, '\s*\zs.')
|
|
|
|
if next_char == a:key
|
|
|
|
return "\<ESC>e^a"
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2012-05-13 21:54:25 -04:00
|
|
|
" Fly Mode, and the key is closed-pairs, search closed-pair and jump
|
2012-12-23 11:53:22 -05:00
|
|
|
if g:AutoPairsFlyMode && has_key(b:AutoPairsClosedPairs, a:key)
|
2012-05-14 04:06:43 -04:00
|
|
|
if search(a:key, 'W')
|
2012-05-13 21:54:25 -04:00
|
|
|
return "\<Right>"
|
2012-05-14 04:06:43 -04:00
|
|
|
endif
|
2012-05-13 21:54:25 -04:00
|
|
|
endif
|
|
|
|
|
2013-03-04 01:19:13 -05:00
|
|
|
" Insert directly if the key is not an open key
|
2011-05-22 13:11:23 -04:00
|
|
|
return a:key
|
|
|
|
end
|
|
|
|
|
|
|
|
let open = a:key
|
2012-12-23 11:53:22 -05:00
|
|
|
let close = b:AutoPairs[open]
|
2011-05-22 13:11:23 -04:00
|
|
|
|
2011-05-24 14:37:25 -04:00
|
|
|
if current_char == close && open == close
|
|
|
|
return "\<Right>"
|
|
|
|
end
|
|
|
|
|
2011-12-30 03:05:37 -05:00
|
|
|
" Ignore auto close ' if follows a word
|
|
|
|
" MUST after closed check. 'hello|'
|
|
|
|
if a:key == "'" && prev_char =~ '\v\w'
|
|
|
|
return a:key
|
|
|
|
end
|
|
|
|
|
2012-01-17 00:17:21 -05:00
|
|
|
" support for ''' ``` and """
|
|
|
|
if open == close
|
|
|
|
" The key must be ' " `
|
|
|
|
let pprev_char = line[col('.')-3]
|
|
|
|
if pprev_char == open && prev_char == open
|
|
|
|
" Double pair found
|
2013-02-12 01:02:25 -05:00
|
|
|
return repeat(a:key, 4) . repeat("\<LEFT>", 3)
|
2012-01-17 00:17:21 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-03-04 09:04:15 -05:00
|
|
|
let quotes_num = 0
|
|
|
|
" Ignore comment line for vim file
|
|
|
|
if &filetype == 'vim' && a:key == '"'
|
|
|
|
if before =~ '^\s*$'
|
|
|
|
return a:key
|
|
|
|
end
|
|
|
|
if before =~ '^\s*"'
|
|
|
|
let quotes_num = -1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-03-04 01:19:13 -05:00
|
|
|
" Keep quote number is odd.
|
|
|
|
" Because quotes should be matched in the same line in most of situation
|
|
|
|
if g:AutoPairsSmartQuotes && open == close
|
2013-03-04 09:04:15 -05:00
|
|
|
" Remove \\ \" \'
|
2013-03-04 01:19:13 -05:00
|
|
|
let cleaned_line = substitute(line, '\v(\\.)', '', 'g')
|
2013-03-04 09:04:15 -05:00
|
|
|
let n = quotes_num
|
2013-03-04 01:19:13 -05:00
|
|
|
let pos = 0
|
|
|
|
while 1
|
|
|
|
let pos = stridx(cleaned_line, open, pos)
|
|
|
|
if pos == -1
|
|
|
|
break
|
|
|
|
end
|
|
|
|
let n = n + 1
|
|
|
|
let pos = pos + 1
|
|
|
|
endwhile
|
|
|
|
if n % 2 == 1
|
|
|
|
return a:key
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2011-12-29 08:42:43 -05:00
|
|
|
return open.close."\<Left>"
|
2011-05-22 13:11:23 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! AutoPairsDelete()
|
2012-11-28 14:19:04 -05:00
|
|
|
if !b:autopairs_enabled
|
2012-12-01 00:06:08 -05:00
|
|
|
return "\<BS>"
|
2012-11-28 14:19:04 -05:00
|
|
|
end
|
|
|
|
|
2011-05-22 13:11:23 -04:00
|
|
|
let line = getline('.')
|
2012-10-09 03:00:34 -04:00
|
|
|
let pos = col('.') - 1
|
|
|
|
let current_char = get(split(strpart(line, pos), '\zs'), 0, '')
|
|
|
|
let prev_chars = split(strpart(line, 0, pos), '\zs')
|
|
|
|
let prev_char = get(prev_chars, -1, '')
|
|
|
|
let pprev_char = get(prev_chars, -2, '')
|
2011-05-22 13:11:23 -04:00
|
|
|
|
|
|
|
if pprev_char == '\'
|
|
|
|
return "\<BS>"
|
|
|
|
end
|
|
|
|
|
2011-12-14 04:00:45 -05:00
|
|
|
" Delete last two spaces in parens, work with MapSpace
|
2012-12-23 11:53:22 -05:00
|
|
|
if has_key(b:AutoPairs, pprev_char) && prev_char == ' ' && current_char == ' '
|
2011-12-14 04:00:45 -05:00
|
|
|
return "\<BS>\<DEL>"
|
|
|
|
endif
|
|
|
|
|
2013-02-12 01:02:25 -05:00
|
|
|
" Delete Repeated Pair eg: '''|''' [[|]] {{|}}
|
|
|
|
if has_key(b:AutoPairs, prev_char)
|
|
|
|
let times = 0
|
|
|
|
let p = -1
|
|
|
|
while get(prev_chars, p, '') == prev_char
|
|
|
|
let p = p - 1
|
|
|
|
let times = times + 1
|
|
|
|
endwhile
|
|
|
|
|
|
|
|
let close = b:AutoPairs[prev_char]
|
|
|
|
let left = repeat(prev_char, times)
|
|
|
|
let right = repeat(close, times)
|
|
|
|
|
|
|
|
let before = strpart(line, pos-times, times)
|
|
|
|
let after = strpart(line, pos, times)
|
|
|
|
if left == before && right == after
|
|
|
|
return repeat("\<BS>\<DEL>", times)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-12-23 11:53:22 -05:00
|
|
|
if has_key(b:AutoPairs, prev_char)
|
|
|
|
let close = b:AutoPairs[prev_char]
|
2011-05-22 13:11:23 -04:00
|
|
|
if match(line,'^\s*'.close, col('.')-1) != -1
|
2013-02-12 01:02:25 -05:00
|
|
|
" Delete (|___)
|
2011-11-13 03:47:49 -05:00
|
|
|
let space = matchstr(line, '^\s*', col('.')-1)
|
|
|
|
return "\<BS>". repeat("\<DEL>", len(space)+1)
|
2012-11-28 14:19:04 -05:00
|
|
|
elseif match(line, '^\s*$', col('.')-1) != -1
|
2013-02-12 01:02:25 -05:00
|
|
|
" Delete (|__\n___)
|
2012-03-03 11:59:38 -05:00
|
|
|
let nline = getline(line('.')+1)
|
|
|
|
if nline =~ '^\s*'.close
|
2013-03-16 23:58:28 -04:00
|
|
|
if &filetype == 'vim' && prev_char == '"'
|
|
|
|
" Keep next line's comment
|
|
|
|
return "\<BS>"
|
|
|
|
end
|
|
|
|
|
2012-03-03 11:59:38 -05:00
|
|
|
let space = matchstr(nline, '^\s*')
|
|
|
|
return "\<BS>\<DEL>". repeat("\<DEL>", len(space)+1)
|
|
|
|
end
|
2011-05-22 13:11:23 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return "\<BS>"
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! AutoPairsJump()
|
2012-03-20 01:13:39 -04:00
|
|
|
call search('["\]'')}]','W')
|
2011-05-22 13:11:23 -04:00
|
|
|
endfunction
|
2012-05-23 00:46:42 -04:00
|
|
|
" string_chunk cannot use standalone
|
|
|
|
let s:string_chunk = '\v%(\\\_.|[^\1]|[\r\n]){-}'
|
|
|
|
let s:ss_pattern = '\v''' . s:string_chunk . ''''
|
|
|
|
let s:ds_pattern = '\v"' . s:string_chunk . '"'
|
|
|
|
|
|
|
|
func! s:RegexpQuote(str)
|
|
|
|
return substitute(a:str, '\v[\[\{\(\<\>\)\}\]]', '\\&', 'g')
|
|
|
|
endf
|
|
|
|
|
|
|
|
func! s:RegexpQuoteInSquare(str)
|
|
|
|
return substitute(a:str, '\v[\[\]]', '\\&', 'g')
|
|
|
|
endf
|
|
|
|
|
|
|
|
" Search next open or close pair
|
|
|
|
func! s:FormatChunk(open, close)
|
|
|
|
let open = s:RegexpQuote(a:open)
|
|
|
|
let close = s:RegexpQuote(a:close)
|
|
|
|
let open2 = s:RegexpQuoteInSquare(a:open)
|
|
|
|
let close2 = s:RegexpQuoteInSquare(a:close)
|
|
|
|
if open == close
|
|
|
|
return '\v'.open.s:string_chunk.close
|
|
|
|
else
|
|
|
|
return '\v%(' . s:ss_pattern . '|' . s:ds_pattern . '|' . '[^'.open2.close2.']|[\r\n]' . '){-}(['.open2.close2.'])'
|
|
|
|
end
|
|
|
|
endf
|
2011-05-22 13:11:23 -04:00
|
|
|
|
2011-06-07 00:40:51 -04:00
|
|
|
" Fast wrap the word in brackets
|
2011-06-09 14:26:22 -04:00
|
|
|
function! AutoPairsFastWrap()
|
2011-05-24 07:07:26 -04:00
|
|
|
let line = getline('.')
|
|
|
|
let current_char = line[col('.')-1]
|
2011-06-07 00:40:51 -04:00
|
|
|
let next_char = line[col('.')]
|
2012-05-23 00:46:42 -04:00
|
|
|
let open_pair_pattern = '\v[({\[''"]'
|
|
|
|
let at_end = col('.') >= col('$') - 1
|
|
|
|
normal x
|
|
|
|
" Skip blank
|
|
|
|
if next_char =~ '\v\s' || at_end
|
|
|
|
call search('\v\S', 'W')
|
|
|
|
let line = getline('.')
|
|
|
|
let next_char = line[col('.')-1]
|
2011-05-24 07:07:26 -04:00
|
|
|
end
|
|
|
|
|
2012-12-23 11:53:22 -05:00
|
|
|
if has_key(b:AutoPairs, next_char)
|
2012-05-23 00:46:42 -04:00
|
|
|
let followed_open_pair = next_char
|
|
|
|
let inputed_close_pair = current_char
|
2012-12-23 11:53:22 -05:00
|
|
|
let followed_close_pair = b:AutoPairs[next_char]
|
2012-05-23 00:46:42 -04:00
|
|
|
if followed_close_pair != followed_open_pair
|
|
|
|
" TODO replace system searchpair to skip string and nested pair.
|
|
|
|
" eg: (|){"hello}world"} will transform to ({"hello})world"}
|
|
|
|
call searchpair('\V'.followed_open_pair, '', '\V'.followed_close_pair, 'W')
|
|
|
|
else
|
|
|
|
call search(s:FormatChunk(followed_open_pair, followed_close_pair), 'We')
|
2011-06-10 05:48:35 -04:00
|
|
|
end
|
2012-05-23 00:46:42 -04:00
|
|
|
return "\<RIGHT>".inputed_close_pair."\<LEFT>"
|
|
|
|
else
|
2013-03-02 06:06:01 -05:00
|
|
|
normal he
|
2012-05-23 00:46:42 -04:00
|
|
|
return "\<RIGHT>".current_char."\<LEFT>"
|
2011-06-09 14:23:47 -04:00
|
|
|
end
|
2011-05-24 07:07:26 -04:00
|
|
|
endfunction
|
|
|
|
|
2011-05-22 13:11:23 -04:00
|
|
|
function! AutoPairsMap(key)
|
2013-02-17 22:23:05 -05:00
|
|
|
" | is special key which separate map command from text
|
|
|
|
let key = a:key
|
|
|
|
if key == '|'
|
|
|
|
let key = '<BAR>'
|
|
|
|
end
|
|
|
|
let escaped_key = substitute(key, "'", "''", 'g')
|
2012-05-14 07:01:22 -04:00
|
|
|
" use expr will cause search() doesn't work
|
2013-02-17 22:23:05 -05:00
|
|
|
execute 'inoremap <buffer> <silent> '.key." <C-R>=AutoPairsInsert('".escaped_key."')<CR>"
|
2011-05-22 13:11:23 -04:00
|
|
|
endfunction
|
|
|
|
|
2011-06-07 00:40:51 -04:00
|
|
|
function! AutoPairsToggle()
|
|
|
|
if b:autopairs_enabled
|
|
|
|
let b:autopairs_enabled = 0
|
|
|
|
echo 'AutoPairs Disabled.'
|
|
|
|
else
|
|
|
|
let b:autopairs_enabled = 1
|
|
|
|
echo 'AutoPairs Enabled.'
|
|
|
|
end
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! AutoPairsReturn()
|
2012-08-30 02:59:44 -04:00
|
|
|
if b:autopairs_enabled == 0
|
|
|
|
return ''
|
|
|
|
end
|
2011-06-07 00:40:51 -04:00
|
|
|
let line = getline('.')
|
2012-01-24 06:34:25 -05:00
|
|
|
let pline = getline(line('.')-1)
|
|
|
|
let prev_char = pline[strlen(pline)-1]
|
2011-06-07 00:40:51 -04:00
|
|
|
let cmd = ''
|
|
|
|
let cur_char = line[col('.')-1]
|
2012-12-23 11:53:22 -05:00
|
|
|
if has_key(b:AutoPairs, prev_char) && b:AutoPairs[prev_char] == cur_char
|
2012-08-11 10:29:33 -04:00
|
|
|
if g:AutoPairsCenterLine && winline() * 3 >= winheight(0) * 2
|
2012-08-30 02:59:44 -04:00
|
|
|
" Use \<BS> instead of \<ESC>cl will cause the placeholder deleted
|
|
|
|
" incorrect. because <C-O>zz won't leave Normal mode.
|
|
|
|
" Use \<DEL> is a bit wierd. the character before cursor need to be deleted.
|
|
|
|
let cmd = " \<C-O>zz\<ESC>cl"
|
2011-06-07 00:40:51 -04:00
|
|
|
end
|
2012-10-18 12:05:10 -04:00
|
|
|
|
2012-10-24 12:59:21 -04:00
|
|
|
" If equalprg has been set, then avoid call =
|
2012-10-18 12:05:10 -04:00
|
|
|
" https://github.com/jiangmiao/auto-pairs/issues/24
|
|
|
|
if &equalprg != ''
|
|
|
|
return "\<ESC>O".cmd
|
|
|
|
endif
|
|
|
|
|
2011-12-14 04:00:45 -05:00
|
|
|
" conflict with javascript and coffee
|
2011-12-14 00:17:27 -05:00
|
|
|
" javascript need indent new line
|
|
|
|
" coffeescript forbid indent new line
|
2012-05-13 21:54:25 -04:00
|
|
|
if &filetype == 'coffeescript' || &filetype == 'coffee'
|
2012-01-24 06:34:25 -05:00
|
|
|
return "\<ESC>k==o".cmd
|
2011-12-14 00:17:27 -05:00
|
|
|
else
|
2012-01-24 06:34:25 -05:00
|
|
|
return "\<ESC>=ko".cmd
|
2011-12-14 00:17:27 -05:00
|
|
|
endif
|
2011-06-07 00:40:51 -04:00
|
|
|
end
|
2012-01-24 06:34:25 -05:00
|
|
|
return ''
|
2011-06-07 00:40:51 -04:00
|
|
|
endfunction
|
|
|
|
|
2011-12-13 16:56:46 -05:00
|
|
|
function! AutoPairsSpace()
|
|
|
|
let line = getline('.')
|
|
|
|
let prev_char = line[col('.')-2]
|
|
|
|
let cmd = ''
|
|
|
|
let cur_char =line[col('.')-1]
|
2011-12-14 04:00:45 -05:00
|
|
|
if has_key(g:AutoPairsParens, prev_char) && g:AutoPairsParens[prev_char] == cur_char
|
|
|
|
let cmd = "\<SPACE>\<LEFT>"
|
2011-12-13 16:56:46 -05:00
|
|
|
endif
|
|
|
|
return "\<SPACE>".cmd
|
|
|
|
endfunction
|
|
|
|
|
2012-05-13 21:54:25 -04:00
|
|
|
function! AutoPairsBackInsert()
|
|
|
|
if exists('b:autopairs_saved_pair')
|
|
|
|
let pair = b:autopairs_saved_pair[0]
|
|
|
|
let pos = b:autopairs_saved_pair[1]
|
|
|
|
call setpos('.', pos)
|
|
|
|
return pair
|
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
2011-05-22 13:11:23 -04:00
|
|
|
function! AutoPairsInit()
|
2011-11-13 03:39:45 -05:00
|
|
|
let b:autopairs_loaded = 1
|
2011-06-07 00:40:51 -04:00
|
|
|
let b:autopairs_enabled = 1
|
2012-12-23 11:53:22 -05:00
|
|
|
let b:AutoPairsClosedPairs = {}
|
|
|
|
|
|
|
|
if !exists('b:AutoPairs')
|
|
|
|
let b:AutoPairs = g:AutoPairs
|
|
|
|
end
|
2012-01-24 06:34:25 -05:00
|
|
|
|
|
|
|
" buffer level map pairs keys
|
2012-12-23 11:53:22 -05:00
|
|
|
for [open, close] in items(b:AutoPairs)
|
2011-05-22 13:11:23 -04:00
|
|
|
call AutoPairsMap(open)
|
|
|
|
if open != close
|
|
|
|
call AutoPairsMap(close)
|
|
|
|
end
|
2012-12-23 11:53:22 -05:00
|
|
|
let b:AutoPairsClosedPairs[close] = open
|
2011-05-22 13:11:23 -04:00
|
|
|
endfor
|
|
|
|
|
2012-01-24 06:34:25 -05:00
|
|
|
" Still use <buffer> level mapping for <BS> <SPACE>
|
2011-06-07 00:40:51 -04:00
|
|
|
if g:AutoPairsMapBS
|
2012-05-14 23:26:53 -04:00
|
|
|
" Use <C-R> instead of <expr> for issue #14 sometimes press BS output strange words
|
2012-05-14 23:03:05 -04:00
|
|
|
execute 'inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>'
|
2011-06-07 00:40:51 -04:00
|
|
|
end
|
|
|
|
|
2011-12-13 16:56:46 -05:00
|
|
|
if g:AutoPairsMapSpace
|
2012-05-14 23:03:05 -04:00
|
|
|
execute 'inoremap <buffer> <silent> <SPACE> <C-R>=AutoPairsSpace()<CR>'
|
2011-12-13 16:56:46 -05:00
|
|
|
end
|
|
|
|
|
2012-03-20 01:13:39 -04:00
|
|
|
if g:AutoPairsShortcutFastWrap != ''
|
|
|
|
execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutFastWrap.' <C-R>=AutoPairsFastWrap()<CR>'
|
|
|
|
end
|
|
|
|
|
2012-05-13 21:54:25 -04:00
|
|
|
if g:AutoPairsShortcutBackInsert != ''
|
|
|
|
execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutBackInsert.' <C-R>=AutoPairsBackInsert()<CR>'
|
|
|
|
end
|
|
|
|
|
2012-03-20 01:13:39 -04:00
|
|
|
if g:AutoPairsShortcutToggle != ''
|
|
|
|
" use <expr> to ensure showing the status when toggle
|
|
|
|
execute 'inoremap <buffer> <silent> <expr> '.g:AutoPairsShortcutToggle.' AutoPairsToggle()'
|
|
|
|
execute 'noremap <buffer> <silent> '.g:AutoPairsShortcutToggle.' :call AutoPairsToggle()<CR>'
|
2011-05-22 13:11:23 -04:00
|
|
|
end
|
2012-03-20 01:13:39 -04:00
|
|
|
|
|
|
|
if g:AutoPairsShortcutJump != ''
|
|
|
|
execute 'inoremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' <ESC>:call AutoPairsJump()<CR>a'
|
|
|
|
execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
|
|
|
|
end
|
|
|
|
|
2011-05-22 13:11:23 -04:00
|
|
|
endfunction
|
|
|
|
|
2013-03-23 04:56:21 -04:00
|
|
|
function! s:ExpandMap(map, sid)
|
2012-05-14 04:06:43 -04:00
|
|
|
let map = a:map
|
2013-03-23 04:56:21 -04:00
|
|
|
let map = substitute(map, '\(<Plug>\w\+\)', '\=maparg(submatch(1), "i")', 'g')
|
|
|
|
let map = substitute(map, '<SID>', '<SNR>' . a:sid . '_', 'g')
|
2012-05-14 04:06:43 -04:00
|
|
|
return map
|
|
|
|
endfunction
|
|
|
|
|
2012-12-23 11:53:22 -05:00
|
|
|
function! AutoPairsTryInit()
|
2011-11-13 03:39:45 -05:00
|
|
|
if exists('b:autopairs_loaded')
|
|
|
|
return
|
2012-05-14 03:22:43 -04:00
|
|
|
end
|
2012-12-23 11:53:22 -05:00
|
|
|
|
2012-05-14 03:22:43 -04:00
|
|
|
" for auto-pairs starts with 'a', so the priority is higher than supertab and vim-endwise
|
|
|
|
"
|
2012-05-14 03:26:40 -04:00
|
|
|
" vim-endwise doesn't support <Plug>AutoPairsReturn
|
|
|
|
" when use <Plug>AutoPairsReturn will cause <Plug> isn't expanded
|
2012-05-14 03:22:43 -04:00
|
|
|
"
|
2012-05-14 03:26:40 -04:00
|
|
|
" supertab doesn't support <SID>AutoPairsReturn
|
2012-05-14 03:22:43 -04:00
|
|
|
" when use <SID>AutoPairsReturn will cause Duplicated <CR>
|
|
|
|
"
|
2012-05-14 04:06:43 -04:00
|
|
|
" and when load after vim-endwise will cause unexpected endwise inserted.
|
|
|
|
" so always load AutoPairs at last
|
2012-05-14 03:22:43 -04:00
|
|
|
|
|
|
|
" Buffer level keys mapping
|
|
|
|
" comptible with other plugin
|
|
|
|
if g:AutoPairsMapCR
|
2013-03-23 04:56:21 -04:00
|
|
|
let info = maparg('<CR>', 'i', 0, 1)
|
|
|
|
if !empty(info)
|
|
|
|
let old_cr = info['rhs']
|
|
|
|
if old_cr !~ 'AutoPairsReturn'
|
|
|
|
let old_cr = s:ExpandMap(old_cr, info['sid'])
|
|
|
|
if info['expr']
|
|
|
|
" remap <expr> to <SID>OldCR to avoid mix expr and non-expr mode
|
|
|
|
let name = '<SID>AutoPairsOldCRWrapper'
|
|
|
|
execute 'inoremap <expr> <script> '. name . ' ' . old_cr
|
|
|
|
let old_cr = name
|
|
|
|
end
|
|
|
|
end
|
2012-05-14 04:06:43 -04:00
|
|
|
else
|
2013-03-23 04:56:21 -04:00
|
|
|
let old_cr = '<CR>'
|
|
|
|
end
|
2012-07-05 02:40:41 -04:00
|
|
|
|
2012-05-14 03:22:43 -04:00
|
|
|
if old_cr !~ 'AutoPairsReturn'
|
2013-03-23 04:56:21 -04:00
|
|
|
" Alawys slient mapping
|
2012-07-06 05:44:57 -04:00
|
|
|
execute 'inoremap <script> <buffer> <silent> <CR> '.old_cr.'<SID>AutoPairsReturn'
|
2012-05-14 03:22:43 -04:00
|
|
|
end
|
2011-11-13 03:39:45 -05:00
|
|
|
endif
|
2012-05-14 03:22:43 -04:00
|
|
|
call AutoPairsInit()
|
2011-11-13 03:39:45 -05:00
|
|
|
endfunction
|
|
|
|
|
2012-03-06 10:12:55 -05:00
|
|
|
" Always silent the command
|
|
|
|
inoremap <silent> <SID>AutoPairsReturn <C-R>=AutoPairsReturn()<CR>
|
2012-05-14 02:23:22 -04:00
|
|
|
imap <script> <Plug>AutoPairsReturn <SID>AutoPairsReturn
|
2012-01-24 06:34:25 -05:00
|
|
|
|
|
|
|
|
2012-12-23 11:53:22 -05:00
|
|
|
au BufEnter * :call AutoPairsTryInit()
|