" Insert or delete brackets, parens, quotes in pairs. " Maintainer: JiangMiao " Contributor: camthompson " Last Change: 2019-01-15 " Version: 2.0.0 " Homepage: http://www.vim.org/scripts/script.php?script_id=3599 " Repository: https://github.com/jiangmiao/auto-pairs " License: MIT if exists('g:AutoPairsLoaded') || &cp finish end let g:AutoPairsLoaded = 1 if !exists('g:AutoPairs') let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '```':'```', '"""':'"""', "'''":"'''"} end if !exists('g:AutoPairsMapBS') let g:AutoPairsMapBS = 1 end " Map as the same BS if !exists('g:AutoPairsMapCh') let g:AutoPairsMapCh = 1 end if !exists('g:AutoPairsMapCR') let g:AutoPairsMapCR = 1 end if !exists('g:AutoPairsWildClosedPair') let g:AutoPairsWildClosedPair = ']' end if !exists('g:AutoPairsMapSpace') let g:AutoPairsMapSpace = 1 end if !exists('g:AutoPairsCenterLine') let g:AutoPairsCenterLine = 1 end if !exists('g:AutoPairsShortcutToggle') let g:AutoPairsShortcutToggle = '' end if !exists('g:AutoPairsShortcutFastWrap') let g:AutoPairsShortcutFastWrap = '' end if !exists('g:AutoPairsMoveCharacter') let g:AutoPairsMoveCharacter = "()[]{}\"'" end if !exists('g:AutoPairsShortcutJump') let g:AutoPairsShortcutJump = '' endif " 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') let g:AutoPairsFlyMode = 0 endif " When skipping the closed pair, look at the current and " next line as well. if !exists('g:AutoPairsMultilineClose') let g:AutoPairsMultilineClose = 1 endif " Work with Fly Mode, insert pair where jumped if !exists('g:AutoPairsShortcutBackInsert') let g:AutoPairsShortcutBackInsert = '' endif if !exists('g:AutoPairsSmartQuotes') let g:AutoPairsSmartQuotes = 1 endif " 7.4.849 support U to avoid breaking '.' " Issue talk: https://github.com/jiangmiao/auto-pairs/issues/3 " Vim note: https://github.com/vim/vim/releases/tag/v7.4.849 if v:version > 704 || v:version == 704 && has("patch849") let s:Go = "\U" else let s:Go = "" endif let s:Left = s:Go."\" let s:Right = s:Go."\" " unicode len func! s:ulen(s) return len(split(a:s, '\zs')) endf func! s:left(s) return repeat(s:Left, s:ulen(a:s)) endf func! s:right(s) return repeat(s:Right, s:ulen(a:s)) endf func! s:delete(s) return repeat("\", s:ulen(a:s)) endf func! s:backspace(s) return repeat("\", s:ulen(a:s)) endf func! s:getline() let line = getline('.') let pos = col('.') - 1 let before = strpart(line, 0, pos) let after = strpart(line, pos) let afterline = after if g:AutoPairsMultilineClose let n = line('$') let i = line('.')+1 while i <= n let line = getline(i) let after = after.' '.line if !(line =~ '\v^\s*$') break end let i = i+1 endwhile end return [before, after, afterline] endf " split text to two part " returns [orig, text_before_open, open] func! s:matchend(text, open) let m = matchstr(a:text, '\V'.a:open.'\v$') if m == "" return [] end return [a:text, strpart(a:text, 0, len(a:text)-len(m)), m] endf " returns [orig, close, text_after_close] func! s:matchbegin(text, close) let m = matchstr(a:text, '^\V'.a:close) if m == "" return [] end return [a:text, m, strpart(a:text, len(m), len(a:text)-len(m))] endf " add or delete pairs base on g:AutoPairs " AutoPairsDefine(addPairs:dict[, removeOpenPairList:list]) " " eg: " au FileType html let b:AutoPairs = AutoPairsDefine({''}, ['{']) " add pair and remove '{' for html file func! AutoPairsDefine(pairs, ...) let r = copy(g:AutoPairs) if a:0 > 0 for open in a:1 unlet r[open] endfor end for [open, close] in items(a:pairs) let r[open] = close endfor return r endf func! AutoPairsInsert(key) if !b:autopairs_enabled return a:key end let b:autopairs_saved_pair = [a:key, getpos('.')] let [before, after, afterline] = s:getline() " Ignore auto close if prev character is \ if before[-1:-1] == '\' return a:key end " check close pairs for [open, close, opt] in b:AutoPairsList if close == '' continue end if a:key == g:AutoPairsWildClosedPair || opt['mapclose'] && close[0] == a:key " the close pair is in the same line let m = matchstr(after, '^\v\s*\zs\V'.close) if m != '' if b:autopairs_return_pos == line('.') && getline('.') =~ '\v^\s*$' normal! ddk$ elseif col('.') > 1 normal! h elseif line('.') > 1 normal! k$ else return s:right(m) break end call search(m, 'We') return "\" break end end endfor " check open pairs for [open, close, opt] in b:AutoPairsList let ms = s:matchend(before.a:key, open) if len(ms) > 0 " process the open pair " remove inserted pair " eg: if the pairs include < > and " when