Merge branch 'master' into master
This commit is contained in:
commit
d1ecaac55c
139
README.md
139
README.md
@ -4,11 +4,13 @@ Insert or delete brackets, parens, quotes in pair.
|
|||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
copy plugin/auto-pairs.vim to ~/.vim/plugin
|
|
||||||
|
|
||||||
or if you are using `pathogen`:
|
* Manual
|
||||||
|
* Copy `plugin/auto-pairs.vim` to `~/.vim/plugin`
|
||||||
```git clone git://github.com/jiangmiao/auto-pairs.git ~/.vim/bundle/auto-pairs```
|
* [Pathogen](https://github.com/tpope/vim-pathogen)
|
||||||
|
* `git clone git://github.com/jiangmiao/auto-pairs.git ~/.vim/bundle/auto-pairs`
|
||||||
|
* [Vundle](https://github.com/VundleVim/Vundle.vim)
|
||||||
|
* `Plugin 'jiangmiao/auto-pairs'`
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
@ -57,13 +59,6 @@ Features
|
|||||||
|
|
||||||
* Fast Wrap
|
* Fast Wrap
|
||||||
|
|
||||||
input: |'hello' (press (<M-e> at |)
|
|
||||||
output: ('hello')
|
|
||||||
|
|
||||||
wrap string, only support c style string
|
|
||||||
input: |'h\\el\'lo' (press (<M-e> at |)
|
|
||||||
output ('h\\ello\'')
|
|
||||||
|
|
||||||
input: |[foo, bar()] (press (<M-e> at |)
|
input: |[foo, bar()] (press (<M-e> at |)
|
||||||
output: ([foo, bar()])
|
output: ([foo, bar()])
|
||||||
|
|
||||||
@ -89,25 +84,6 @@ Features
|
|||||||
|
|
||||||
}|
|
}|
|
||||||
|
|
||||||
* Support ``` ''' and """
|
|
||||||
|
|
||||||
input:
|
|
||||||
'''
|
|
||||||
|
|
||||||
output:
|
|
||||||
'''|'''
|
|
||||||
|
|
||||||
* Delete Repeated Pairs in one time
|
|
||||||
|
|
||||||
input: """|""" (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
input: {{|}} (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
input: [[[[[[|]]]]]] (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
* Fly Mode
|
* Fly Mode
|
||||||
|
|
||||||
input: if(a[3)
|
input: if(a[3)
|
||||||
@ -137,6 +113,11 @@ Features
|
|||||||
|
|
||||||
See Fly Mode section for details
|
See Fly Mode section for details
|
||||||
|
|
||||||
|
* Multibyte Pairs
|
||||||
|
|
||||||
|
Support any multibyte pairs such as <!-- -->, <% %>, """ """
|
||||||
|
See multibyte pairs section for details
|
||||||
|
|
||||||
Fly Mode
|
Fly Mode
|
||||||
--------
|
--------
|
||||||
Fly Mode will always force closed-pair jumping instead of inserting. only for ")", "}", "]"
|
Fly Mode will always force closed-pair jumping instead of inserting. only for ")", "}", "]"
|
||||||
@ -264,6 +245,14 @@ Options
|
|||||||
Map <M-(> <M-)> <M-[> <M-]> <M-{> <M-}> <M-"> <M-'> to
|
Map <M-(> <M-)> <M-[> <M-]> <M-{> <M-}> <M-"> <M-'> to
|
||||||
move character under the cursor to the pair.
|
move character under the cursor to the pair.
|
||||||
|
|
||||||
|
* g:AutoPairsWildClosedPair
|
||||||
|
|
||||||
|
Default: ']'
|
||||||
|
|
||||||
|
Jump over following closed pair
|
||||||
|
for pair {'begin': 'end//n]'}, e is not mapped, use wild closed pair ] to jump over 'end'
|
||||||
|
use <M-b> to back insert ] after jumping
|
||||||
|
|
||||||
Buffer Level Pairs Setting
|
Buffer Level Pairs Setting
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
@ -273,6 +262,96 @@ eg:
|
|||||||
|
|
||||||
" When the filetype is FILETYPE then make AutoPairs only match for parenthesis
|
" When the filetype is FILETYPE then make AutoPairs only match for parenthesis
|
||||||
au Filetype FILETYPE let b:AutoPairs = {"(": ")"}
|
au Filetype FILETYPE let b:AutoPairs = {"(": ")"}
|
||||||
|
au FileType php let b:AutoPairs = AutoPairsDefine({'<?' : '?>', '<?php': '?>'})
|
||||||
|
|
||||||
|
Multibyte Pairs
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The default pairs is {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
||||||
|
You could also define multibyte pairs such as <!-- -->, <% %> and so on
|
||||||
|
|
||||||
|
* Function AutoPairsDefine(addPairs:dict[, removeOpenPairList:list])
|
||||||
|
|
||||||
|
add or delete pairs base on g:AutoPairs
|
||||||
|
|
||||||
|
eg:
|
||||||
|
au FileType html let b:AutoPairs = AutoPairsDefine({'<!--' : '-->'}, ['{'])
|
||||||
|
add <!-- --> pair and remove '{' for html file
|
||||||
|
|
||||||
|
the pair implict start with \V, so if want to match start of line ^ should be write in \^ vim comment {'\^"': ''}
|
||||||
|
|
||||||
|
* General usage
|
||||||
|
|
||||||
|
au FileType php let b:AutoPairs = AutoPairsDefine({'<?' : '?>', '<?php': '?>'})
|
||||||
|
|
||||||
|
the first key of closed pair ? will be mapped
|
||||||
|
|
||||||
|
pairs: '<?' : '?>', '<?php': '?>'
|
||||||
|
input: <?
|
||||||
|
output: <?|?>
|
||||||
|
|
||||||
|
input: <?php
|
||||||
|
output: <?php|?>
|
||||||
|
|
||||||
|
input: he<?php|?> (press <BS> at|)
|
||||||
|
output: he|
|
||||||
|
|
||||||
|
input: <?php|?> (press ? at|)
|
||||||
|
output: <?php?>|
|
||||||
|
|
||||||
|
pair: '[[':']]'
|
||||||
|
input: [[|]] (press <BS>)
|
||||||
|
output: | ([[ and ]] will be deleted the [['s priority is higher than [ for it's longer)
|
||||||
|
|
||||||
|
* Modifier
|
||||||
|
|
||||||
|
The text after // in close pair is modifiers
|
||||||
|
|
||||||
|
n - do not map the first charactor of closed pair
|
||||||
|
|
||||||
|
for 'begin' 'end' pair, e is a charactor, if map e to jump will be annoy, so use modifier 'n' to skip key map
|
||||||
|
|
||||||
|
au FileType ruby let b:AutoPairs = AutoPairsDefine({'begin': 'end//n]'})
|
||||||
|
|
||||||
|
|
||||||
|
input: begin
|
||||||
|
output: begin|end
|
||||||
|
|
||||||
|
input: begin|end (press <BS> on |)
|
||||||
|
output: |
|
||||||
|
|
||||||
|
input: begin|end (press e on |)
|
||||||
|
output: begineend (will not jump for e is not mapped)
|
||||||
|
|
||||||
|
* Advanced usage
|
||||||
|
|
||||||
|
au FileType rust let b:AutoPairs = AutoPairsDefine({'\w\zs<': '>'})
|
||||||
|
|
||||||
|
if press < after a word will generate the pair
|
||||||
|
|
||||||
|
when use regexp MUST use \zs to prevent catching
|
||||||
|
if use '\w<' without \zs, for text hello<|> press <BS> on | will output 'hell', the 'o' has been deleted
|
||||||
|
|
||||||
|
pair: '\w\zs<': '>'
|
||||||
|
input: h <
|
||||||
|
output: h <
|
||||||
|
|
||||||
|
input: h<
|
||||||
|
output: h<|>
|
||||||
|
|
||||||
|
input: h<|> press <BS>
|
||||||
|
output: h|
|
||||||
|
|
||||||
|
pair: '\w<': '>' (WRONG pair which missed \zs)
|
||||||
|
input: h<|> press <BS>
|
||||||
|
output: | (charactor 'h' is deleted)
|
||||||
|
|
||||||
|
|
||||||
|
the 'begin' 'end' pair write in
|
||||||
|
|
||||||
|
au FileType ruby let b:AutoPairs = AutoPairsDefine({'\v(^|[^\w])\zsbegin': 'end//n'})
|
||||||
|
|
||||||
|
will be better, only auto pair when at start of line or follow non-word text
|
||||||
|
|
||||||
TroubleShooting
|
TroubleShooting
|
||||||
---------------
|
---------------
|
||||||
|
@ -178,7 +178,7 @@ System Shortcuts:
|
|||||||
<M-b>: BackInsert (|g:AutoPairsShortcutBackInsert|)
|
<M-b>: BackInsert (|g:AutoPairsShortcutBackInsert|)
|
||||||
|
|
||||||
|
|
||||||
To rebind keys <M-p>, <M-e> or <M-n> or in case of conflicts conflicts with
|
To rebind keys <M-p>, <M-e> or <M-n> or in case of conflicts with
|
||||||
another keys:
|
another keys:
|
||||||
|
|
||||||
let g:AutoPairsShortcutToggle = '<another key>'
|
let g:AutoPairsShortcutToggle = '<another key>'
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
" Insert or delete brackets, parens, quotes in pairs.
|
" Insert or delete brackets, parens, quotes in pairs.
|
||||||
" Maintainer: JiangMiao <jiangfriend@gmail.com>
|
" Maintainer: JiangMiao <jiangfriend@gmail.com>
|
||||||
" Contributor: camthompson
|
" Contributor: camthompson
|
||||||
" Last Change: 2017-06-17
|
" Last Change: 2019-01-15
|
||||||
" Version: 1.3.3
|
" Version: 2.0.0
|
||||||
" Homepage: http://www.vim.org/scripts/script.php?script_id=3599
|
" Homepage: http://www.vim.org/scripts/script.php?script_id=3599
|
||||||
" Repository: https://github.com/jiangmiao/auto-pairs
|
" Repository: https://github.com/jiangmiao/auto-pairs
|
||||||
" License: MIT
|
" License: MIT
|
||||||
@ -16,10 +16,6 @@ if !exists('g:AutoPairs')
|
|||||||
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
||||||
end
|
end
|
||||||
|
|
||||||
if !exists('g:AutoPairsParens')
|
|
||||||
let g:AutoPairsParens = {'(':')', '[':']', '{':'}'}
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsMapBS')
|
if !exists('g:AutoPairsMapBS')
|
||||||
let g:AutoPairsMapBS = 1
|
let g:AutoPairsMapBS = 1
|
||||||
end
|
end
|
||||||
@ -33,6 +29,10 @@ if !exists('g:AutoPairsMapCR')
|
|||||||
let g:AutoPairsMapCR = 1
|
let g:AutoPairsMapCR = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if !exists('g:AutoPairsWildClosedPair')
|
||||||
|
let g:AutoPairsWildClosedPair = ']'
|
||||||
|
end
|
||||||
|
|
||||||
if !exists('g:AutoPairsMapSpace')
|
if !exists('g:AutoPairsMapSpace')
|
||||||
let g:AutoPairsMapSpace = 1
|
let g:AutoPairsMapSpace = 1
|
||||||
end
|
end
|
||||||
@ -91,278 +91,302 @@ let s:Left = s:Go."\<LEFT>"
|
|||||||
let s:Right = s:Go."\<RIGHT>"
|
let s:Right = s:Go."\<RIGHT>"
|
||||||
|
|
||||||
|
|
||||||
" Will auto generated {']' => '[', ..., '}' => '{'}in initialize.
|
|
||||||
let g:AutoPairsClosedPairs = {}
|
|
||||||
|
|
||||||
|
|
||||||
function! AutoPairsInsert(key)
|
" unicode len
|
||||||
if !b:autopairs_enabled
|
func! s:ulen(s)
|
||||||
return a:key
|
return len(split(a:s, '\zs'))
|
||||||
end
|
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("\<DEL>", s:ulen(a:s))
|
||||||
|
endf
|
||||||
|
|
||||||
|
func! s:backspace(s)
|
||||||
|
return repeat("\<BS>", s:ulen(a:s))
|
||||||
|
endf
|
||||||
|
|
||||||
|
func! s:getline()
|
||||||
let line = getline('.')
|
let line = getline('.')
|
||||||
let pos = col('.') - 1
|
let pos = col('.') - 1
|
||||||
let before = strpart(line, 0, pos)
|
let before = strpart(line, 0, pos)
|
||||||
let after = strpart(line, pos)
|
let after = strpart(line, pos)
|
||||||
let next_chars = split(after, '\zs')
|
let afterline = after
|
||||||
let current_char = get(next_chars, 0, '')
|
if a:0 == 0 && g:AutoPairsMultilineClose
|
||||||
let next_char = get(next_chars, 1, '')
|
let n = line('$')
|
||||||
let prev_chars = split(before, '\zs')
|
let i = line('.')+1
|
||||||
let prev_char = get(prev_chars, -1, '')
|
while i <= n
|
||||||
|
let line = getline(i)
|
||||||
let eol = 0
|
let after = after.' '.line
|
||||||
if col('$') - col('.') <= 1
|
if !(line =~ '\v^\s*$')
|
||||||
let eol = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
" Ignore auto close if prev character is \
|
|
||||||
if prev_char == '\'
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
|
|
||||||
" The key is difference open-pair, then it means only for ) ] } by default
|
|
||||||
if !has_key(b:AutoPairs, a:key)
|
|
||||||
let b:autopairs_saved_pair = [a:key, getpos('.')]
|
|
||||||
|
|
||||||
" Skip the character if current character is the same as input
|
|
||||||
if current_char == a:key
|
|
||||||
return s:Right
|
|
||||||
end
|
|
||||||
|
|
||||||
" Skip the character if closed pair is next character
|
|
||||||
if current_char == ' ' && next_char == a:key
|
|
||||||
" Remove the space we added if the pair is empty
|
|
||||||
if has_key(b:AutoPairsClosedPairs, a:key)
|
|
||||||
let end_of_prevchar_index = matchend(before, '\S\ze\s*$')
|
|
||||||
if end_of_prevchar_index > -1
|
|
||||||
let end_of_prevchar = get(prev_chars, end_of_prevchar_index-1, '')
|
|
||||||
if end_of_prevchar == b:AutoPairsClosedPairs[a:key]
|
|
||||||
return "\<DEL>".s:Right
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
return s:Right.s:Right
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !g:AutoPairsFlyMode
|
|
||||||
" Skip the character if closed pair is next character
|
|
||||||
if current_char == ''
|
|
||||||
if g:AutoPairsMultilineClose
|
|
||||||
let next_lineno = line('.')+1
|
|
||||||
let next_line = getline(nextnonblank(next_lineno))
|
|
||||||
let next_char = matchstr(next_line, '\s*\zs.')
|
|
||||||
else
|
|
||||||
let next_char = matchstr(line, '\s*\zs.')
|
|
||||||
end
|
|
||||||
if next_char == a:key
|
|
||||||
return "\<ESC>e^a"
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Fly Mode, and the key is closed-pairs, search closed-pair and jump
|
|
||||||
if g:AutoPairsFlyMode && has_key(b:AutoPairsClosedPairs, a:key)
|
|
||||||
let n = stridx(after, a:key)
|
|
||||||
if n != -1
|
|
||||||
return repeat(s:Right, n+1)
|
|
||||||
end
|
|
||||||
if search(a:key, 'W')
|
|
||||||
" force break the '.' when jump to different line
|
|
||||||
return "\<Right>"
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Insert directly if the key is not an open key
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
|
|
||||||
let open = a:key
|
|
||||||
let close = b:AutoPairs[open]
|
|
||||||
|
|
||||||
if current_char == close && open == close
|
|
||||||
return s:Right
|
|
||||||
end
|
|
||||||
|
|
||||||
" Ignore auto close ' if follows a word
|
|
||||||
" MUST after closed check. 'hello|'
|
|
||||||
if a:key == "'" && prev_char =~ '\v\w'
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
|
|
||||||
" 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
|
|
||||||
return repeat(a:key, 4) . repeat(s:Left, 3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
" Keep quote number is odd.
|
|
||||||
" Because quotes should be matched in the same line in most of situation
|
|
||||||
if g:AutoPairsSmartQuotes && open == close
|
|
||||||
" Remove \\ \" \'
|
|
||||||
let cleaned_line = substitute(line, '\v(\\.)', '', 'g')
|
|
||||||
let n = quotes_num
|
|
||||||
let pos = 0
|
|
||||||
while 1
|
|
||||||
let pos = stridx(cleaned_line, open, pos)
|
|
||||||
if pos == -1
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
let n = n + 1
|
let i = i+1
|
||||||
let pos = pos + 1
|
|
||||||
endwhile
|
endwhile
|
||||||
if n % 2 == 1
|
end
|
||||||
return a:key
|
return [before, after, afterline]
|
||||||
|
endf
|
||||||
|
|
||||||
|
" split text to two part
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
for [open, close] in items(a:pairs)
|
||||||
|
let r[open] = close
|
||||||
|
endfor
|
||||||
|
if a:0 > 1
|
||||||
|
for open in a:1
|
||||||
|
unlet r[open]
|
||||||
|
endfor
|
||||||
|
end
|
||||||
|
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] in b:AutoPairsList
|
||||||
|
if a:key == g:AutoPairsWildClosedPair || close[0] == a:key
|
||||||
|
" the close pair is in the same line
|
||||||
|
let m = matchstr(afterline, '^\v\s*\V'.close)
|
||||||
|
if m != ''
|
||||||
|
if before =~ '\V'.open.'\v\s*$' && m[0] =~ '\v\s'
|
||||||
|
" remove the space we inserted if the text in pairs is blank
|
||||||
|
return "\<DEL>".s:right(m[1:])
|
||||||
|
else
|
||||||
|
return s:right(m)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if open != close
|
||||||
|
let m = s:matchend(after, '^\v\s*\zs\V'.close)
|
||||||
|
if len(m) > 0
|
||||||
|
" skip close pair greedy
|
||||||
|
call search(m[1], 'We')
|
||||||
|
return "\<Right>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" check open pairs
|
||||||
|
let text=before.a:key
|
||||||
|
for [open, close] in b:AutoPairsList
|
||||||
|
let m = s:matchend(text, open)
|
||||||
|
if len(m) > 0
|
||||||
|
" process the open pair
|
||||||
|
|
||||||
|
" remove inserted pair
|
||||||
|
" eg: if the pairs include < > and <!-- -->
|
||||||
|
" when <!-- is detected the inserted pair < > should be clean up
|
||||||
|
" <?php ?> should backspace 4 times php and <?
|
||||||
|
let target = m[1]
|
||||||
|
let openPair = m[2]
|
||||||
|
let text = before
|
||||||
|
let i = 0
|
||||||
|
while len(text) >= len(target) && target != text
|
||||||
|
let found = 0
|
||||||
|
" delete pair
|
||||||
|
for [o, c] in b:AutoPairsList
|
||||||
|
let m = s:matchend(text, o)
|
||||||
|
if len(m) > 0
|
||||||
|
let found = 1
|
||||||
|
let text = m[1]
|
||||||
|
let i = i + 1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
endfor
|
||||||
|
if !found
|
||||||
|
" delete charactor
|
||||||
|
let m = s:matchend(text, '\v.')
|
||||||
|
if len(m) == 0
|
||||||
|
break
|
||||||
|
end
|
||||||
|
let i = i + 1
|
||||||
|
let text = m[1]
|
||||||
|
end
|
||||||
|
endwhile
|
||||||
|
let bs = repeat("\<BS>", i)
|
||||||
|
if bs != ''
|
||||||
|
call feedkeys(bs)
|
||||||
|
end
|
||||||
|
call feedkeys(openPair.close.s:left(close), "n")
|
||||||
|
return ""
|
||||||
|
" return m.close.s:left(close)
|
||||||
|
end
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" Fly Mode, and the key is closed-pairs, search closed-pair and jump
|
||||||
|
if g:AutoPairsFlyMode && a:key =~ '\v[\}\]\)]'
|
||||||
|
if search(a:key, 'We')
|
||||||
|
return "\<Right>"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return open.close.s:Left
|
return a:key
|
||||||
endfunction
|
endf
|
||||||
|
|
||||||
function! AutoPairsDelete()
|
func! AutoPairsDelete()
|
||||||
if !b:autopairs_enabled
|
if !b:autopairs_enabled
|
||||||
return "\<BS>"
|
return "\<BS>"
|
||||||
end
|
end
|
||||||
|
|
||||||
let line = getline('.')
|
let [before, after, ig] = s:getline()
|
||||||
let pos = col('.') - 1
|
for [open, close] in b:AutoPairsList
|
||||||
let current_char = get(split(strpart(line, pos), '\zs'), 0, '')
|
let b = matchstr(before, '\V'.open.'\v\s?$')
|
||||||
let prev_chars = split(strpart(line, 0, pos), '\zs')
|
let a = matchstr(after, '^\v\s*\V'.close)
|
||||||
let prev_char = get(prev_chars, -1, '')
|
if b != '' && a != ''
|
||||||
let pprev_char = get(prev_chars, -2, '')
|
if b[-1:-1] == ' '
|
||||||
|
if a[0] == ' '
|
||||||
if pprev_char == '\'
|
return "\<BS>\<DELETE>"
|
||||||
return "\<BS>"
|
else
|
||||||
end
|
|
||||||
|
|
||||||
" Delete last two spaces in parens, work with MapSpace
|
|
||||||
if has_key(b:AutoPairs, pprev_char) && prev_char == ' ' && current_char == ' '
|
|
||||||
return "\<BS>\<DEL>"
|
|
||||||
endif
|
|
||||||
|
|
||||||
" 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
|
|
||||||
|
|
||||||
|
|
||||||
if has_key(b:AutoPairs, prev_char)
|
|
||||||
let close = b:AutoPairs[prev_char]
|
|
||||||
if match(line,'^\s*'.close, col('.')-1) != -1
|
|
||||||
" Delete (|___)
|
|
||||||
let space = matchstr(line, '^\s*', col('.')-1)
|
|
||||||
return "\<BS>". repeat("\<DEL>", len(space)+1)
|
|
||||||
elseif match(line, '^\s*$', col('.')-1) != -1
|
|
||||||
" Delete (|__\n___)
|
|
||||||
let nline = getline(line('.')+1)
|
|
||||||
if nline =~ '^\s*'.close
|
|
||||||
if &filetype == 'vim' && prev_char == '"'
|
|
||||||
" Keep next line's comment
|
|
||||||
return "\<BS>"
|
return "\<BS>"
|
||||||
end
|
end
|
||||||
|
|
||||||
let space = matchstr(nline, '^\s*')
|
|
||||||
return "\<BS>\<DEL>". repeat("\<DEL>", len(space)+1)
|
|
||||||
end
|
end
|
||||||
|
return repeat("\<BS>", s:ulen(b)).repeat("\<DELETE>", s:ulen(a))
|
||||||
end
|
end
|
||||||
end
|
endfor
|
||||||
|
|
||||||
return "\<BS>"
|
return "\<BS>"
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsJump()
|
|
||||||
call search('["\]'')}]','W')
|
|
||||||
endfunction
|
|
||||||
" 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
|
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
|
|
||||||
|
|
||||||
" Fast wrap the word in brackets
|
" Fast wrap the word in brackets
|
||||||
function! AutoPairsFastWrap()
|
func! AutoPairsFastWrap()
|
||||||
let line = getline('.')
|
let c = @"
|
||||||
let current_char = line[col('.')-1]
|
|
||||||
let next_char = line[col('.')]
|
|
||||||
let open_pair_pattern = '\v[({\[''"]'
|
|
||||||
let at_end = col('.') >= col('$') - 1
|
|
||||||
normal! x
|
normal! x
|
||||||
" Skip blank
|
let [before, after, ig] = s:getline()
|
||||||
if next_char =~ '\v\s' || at_end
|
if after[0] =~ '\v[\{\[\(\<]'
|
||||||
call search('\v\S', 'W')
|
normal! %
|
||||||
let line = getline('.')
|
normal! p
|
||||||
let next_char = line[col('.')-1]
|
|
||||||
end
|
|
||||||
|
|
||||||
if has_key(b:AutoPairs, next_char)
|
|
||||||
let followed_open_pair = next_char
|
|
||||||
let inputed_close_pair = current_char
|
|
||||||
let followed_close_pair = b:AutoPairs[next_char]
|
|
||||||
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')
|
|
||||||
end
|
|
||||||
return s:Right.inputed_close_pair.s:Left
|
|
||||||
else
|
else
|
||||||
normal! he
|
for [open, close] in b:AutoPairsList
|
||||||
return s:Right.current_char.s:Left
|
if after =~ '^\s*\V'.open
|
||||||
|
call search(close, 'We')
|
||||||
|
normal! p
|
||||||
|
let @" = c
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
endfor
|
||||||
|
if after[1:1] =~ '\v[a-zA-Z0-9_]'
|
||||||
|
normal! e
|
||||||
|
normal! p
|
||||||
|
else
|
||||||
|
normal! p
|
||||||
|
end
|
||||||
end
|
end
|
||||||
endfunction
|
let @" = c
|
||||||
|
return ""
|
||||||
|
endf
|
||||||
|
|
||||||
function! AutoPairsMap(key)
|
func! AutoPairsJump()
|
||||||
|
call search('["\]'')}]','W')
|
||||||
|
endf
|
||||||
|
|
||||||
|
func! AutoPairsMoveCharacter(key)
|
||||||
|
let c = getline(".")[col(".")-1]
|
||||||
|
let escaped_key = substitute(a:key, "'", "''", 'g')
|
||||||
|
return "\<DEL>\<ESC>:call search("."'".escaped_key."'".")\<CR>a".c."\<LEFT>"
|
||||||
|
endf
|
||||||
|
|
||||||
|
func! 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 ''
|
||||||
|
endf
|
||||||
|
|
||||||
|
func! AutoPairsReturn()
|
||||||
|
if b:autopairs_enabled == 0
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
let before = getline(line('.')-1)
|
||||||
|
let after = getline('.')
|
||||||
|
let cmd = ''
|
||||||
|
for [open, close] in b:AutoPairsList
|
||||||
|
" before =~ '\V'.open.'\v\s*$' &&
|
||||||
|
if after =~ '^\s*\V'.close
|
||||||
|
if g:AutoPairsCenterLine && winline() * 3 >= winheight(0) * 2
|
||||||
|
" Recenter before adding new line to avoid replacing line content
|
||||||
|
let cmd = "zz"
|
||||||
|
end
|
||||||
|
|
||||||
|
" If equalprg has been set, then avoid call =
|
||||||
|
" https://github.com/jiangmiao/auto-pairs/issues/24
|
||||||
|
if &equalprg != ''
|
||||||
|
return "\<ESC>".cmd."O"
|
||||||
|
endif
|
||||||
|
|
||||||
|
" conflict with javascript and coffee
|
||||||
|
" javascript need indent new line
|
||||||
|
" coffeescript forbid indent new line
|
||||||
|
if &filetype == 'coffeescript' || &filetype == 'coffee'
|
||||||
|
return "\<ESC>".cmd."k==o"
|
||||||
|
else
|
||||||
|
return "\<ESC>".cmd."=ko"
|
||||||
|
endif
|
||||||
|
end
|
||||||
|
endfor
|
||||||
|
return ''
|
||||||
|
endf
|
||||||
|
|
||||||
|
func! AutoPairsSpace()
|
||||||
|
if !b:autopairs_enabled
|
||||||
|
return "\<SPACE>"
|
||||||
|
end
|
||||||
|
|
||||||
|
let [before, after, ig] = s:getline()
|
||||||
|
|
||||||
|
for [open, close] in b:AutoPairsList
|
||||||
|
if before =~ '\V'.open.'\v$' && after =~ '^\V'.close
|
||||||
|
return "\<SPACE>\<SPACE>".s:Left
|
||||||
|
end
|
||||||
|
endfor
|
||||||
|
return "\<SPACE>"
|
||||||
|
endf
|
||||||
|
|
||||||
|
func! AutoPairsMap(key)
|
||||||
" | is special key which separate map command from text
|
" | is special key which separate map command from text
|
||||||
let key = a:key
|
let key = a:key
|
||||||
if key == '|'
|
if key == '|'
|
||||||
@ -372,9 +396,9 @@ function! AutoPairsMap(key)
|
|||||||
" use expr will cause search() doesn't work
|
" use expr will cause search() doesn't work
|
||||||
execute 'inoremap <buffer> <silent> '.key." <C-R>=AutoPairsInsert('".escaped_key."')<CR>"
|
execute 'inoremap <buffer> <silent> '.key." <C-R>=AutoPairsInsert('".escaped_key."')<CR>"
|
||||||
|
|
||||||
endfunction
|
endf
|
||||||
|
|
||||||
function! AutoPairsToggle()
|
func! AutoPairsToggle()
|
||||||
if b:autopairs_enabled
|
if b:autopairs_enabled
|
||||||
let b:autopairs_enabled = 0
|
let b:autopairs_enabled = 0
|
||||||
echo 'AutoPairs Disabled.'
|
echo 'AutoPairs Disabled.'
|
||||||
@ -383,92 +407,51 @@ function! AutoPairsToggle()
|
|||||||
echo 'AutoPairs Enabled.'
|
echo 'AutoPairs Enabled.'
|
||||||
end
|
end
|
||||||
return ''
|
return ''
|
||||||
endfunction
|
endf
|
||||||
|
|
||||||
function! AutoPairsMoveCharacter(key)
|
func! s:sortByLength(i1, i2)
|
||||||
let c = getline(".")[col(".")-1]
|
return len(a:i2[0])-len(a:i1[0])
|
||||||
let escaped_key = substitute(a:key, "'", "''", 'g')
|
endf
|
||||||
return "\<DEL>\<ESC>:call search("."'".escaped_key."'".")\<CR>a".c."\<LEFT>"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsReturn()
|
func! AutoPairsInit()
|
||||||
if b:autopairs_enabled == 0
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
let line = getline('.')
|
|
||||||
let pline = getline(line('.')-1)
|
|
||||||
let prev_char = pline[strlen(pline)-1]
|
|
||||||
let cmd = ''
|
|
||||||
let cur_char = line[col('.')-1]
|
|
||||||
if has_key(b:AutoPairs, prev_char) && b:AutoPairs[prev_char] == cur_char
|
|
||||||
if g:AutoPairsCenterLine && winline() * 3 >= winheight(0) * 2
|
|
||||||
" Recenter before adding new line to avoid replacing line content
|
|
||||||
let cmd = "zz"
|
|
||||||
end
|
|
||||||
|
|
||||||
" If equalprg has been set, then avoid call =
|
|
||||||
" https://github.com/jiangmiao/auto-pairs/issues/24
|
|
||||||
if &equalprg != ''
|
|
||||||
return "\<ESC>".cmd."O"
|
|
||||||
endif
|
|
||||||
|
|
||||||
" conflict with javascript and coffee
|
|
||||||
" javascript need indent new line
|
|
||||||
" coffeescript forbid indent new line
|
|
||||||
if &filetype == 'coffeescript' || &filetype == 'coffee'
|
|
||||||
return "\<ESC>".cmd."k==o"
|
|
||||||
else
|
|
||||||
return "\<ESC>".cmd."=ko"
|
|
||||||
endif
|
|
||||||
end
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsSpace()
|
|
||||||
let line = getline('.')
|
|
||||||
let prev_char = line[col('.')-2]
|
|
||||||
let cmd = ''
|
|
||||||
let cur_char =line[col('.')-1]
|
|
||||||
if has_key(g:AutoPairsParens, prev_char) && g:AutoPairsParens[prev_char] == cur_char
|
|
||||||
let cmd = "\<SPACE>".s:Left
|
|
||||||
endif
|
|
||||||
return "\<SPACE>".cmd
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
function! AutoPairsInit()
|
|
||||||
let b:autopairs_loaded = 1
|
let b:autopairs_loaded = 1
|
||||||
if !exists('b:autopairs_enabled')
|
if !exists('b:autopairs_enabled')
|
||||||
let b:autopairs_enabled = 1
|
let b:autopairs_enabled = 1
|
||||||
end
|
end
|
||||||
let b:AutoPairsClosedPairs = {}
|
|
||||||
|
|
||||||
if !exists('b:AutoPairs')
|
if !exists('b:AutoPairs')
|
||||||
let b:AutoPairs = g:AutoPairs
|
let b:AutoPairs = g:AutoPairs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if !exists('b:AutoPairsMoveCharacter')
|
if !exists('b:AutoPairsMoveCharacter')
|
||||||
let b:AutoPairsMoveCharacter = g:AutoPairsMoveCharacter
|
let b:AutoPairsMoveCharacter = g:AutoPairsMoveCharacter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let b:AutoPairsList = []
|
||||||
|
|
||||||
" buffer level map pairs keys
|
" buffer level map pairs keys
|
||||||
for [open, close] in items(b:AutoPairs)
|
for [open, close] in items(b:AutoPairs)
|
||||||
call AutoPairsMap(open)
|
let o = open[len(open)-1]
|
||||||
if open != close
|
let m = matchlist(close, '\v(.*)//(.*)$')
|
||||||
call AutoPairsMap(close)
|
let mapclose = 1
|
||||||
|
if len(m) > 0
|
||||||
|
if m[1] =~ 'n'
|
||||||
|
let mapclose = 0
|
||||||
|
end
|
||||||
|
let close = m[1]
|
||||||
end
|
end
|
||||||
let b:AutoPairsClosedPairs[close] = open
|
let c = close[0]
|
||||||
|
call AutoPairsMap(o)
|
||||||
|
if o != c && c != '' && mapclose
|
||||||
|
call AutoPairsMap(c)
|
||||||
|
end
|
||||||
|
let b:AutoPairsList += [[open, close]]
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
" sort pairs by length, longer pair should have higher priority
|
||||||
|
let b:AutoPairsList = sort(b:AutoPairsList, "s:sortByLength")
|
||||||
|
|
||||||
for key in split(b:AutoPairsMoveCharacter, '\s*')
|
for key in split(b:AutoPairsMoveCharacter, '\s*')
|
||||||
let escaped_key = substitute(key, "'", "''", 'g')
|
let escaped_key = substitute(key, "'", "''", 'g')
|
||||||
execute 'inoremap <silent> <buffer> <M-'.key."> <C-R>=AutoPairsMoveCharacter('".escaped_key."')<CR>"
|
execute 'inoremap <silent> <buffer> <M-'.key."> <C-R>=AutoPairsMoveCharacter('".escaped_key."')<CR>"
|
||||||
@ -512,15 +495,29 @@ function! AutoPairsInit()
|
|||||||
execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
|
execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
|
||||||
end
|
end
|
||||||
|
|
||||||
endfunction
|
if &keymap != ''
|
||||||
|
let l:imsearch = &imsearch
|
||||||
|
let l:iminsert = &iminsert
|
||||||
|
let l:imdisable = &imdisable
|
||||||
|
execute 'setlocal keymap=' . &keymap
|
||||||
|
execute 'setlocal imsearch=' . l:imsearch
|
||||||
|
execute 'setlocal iminsert=' . l:iminsert
|
||||||
|
if l:imdisable
|
||||||
|
execute 'setlocal imdisable'
|
||||||
|
else
|
||||||
|
execute 'setlocal noimdisable'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function! s:ExpandMap(map)
|
endf
|
||||||
|
|
||||||
|
func! s:ExpandMap(map)
|
||||||
let map = a:map
|
let map = a:map
|
||||||
let map = substitute(map, '\(<Plug>\w\+\)', '\=maparg(submatch(1), "i")', 'g')
|
let map = substitute(map, '\(<Plug>\w\+\)', '\=maparg(submatch(1), "i")', 'g')
|
||||||
return map
|
return map
|
||||||
endfunction
|
endf
|
||||||
|
|
||||||
function! AutoPairsTryInit()
|
func! AutoPairsTryInit()
|
||||||
if exists('b:autopairs_loaded')
|
if exists('b:autopairs_loaded')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -583,7 +580,7 @@ function! AutoPairsTryInit()
|
|||||||
end
|
end
|
||||||
endif
|
endif
|
||||||
call AutoPairsInit()
|
call AutoPairsInit()
|
||||||
endfunction
|
endf
|
||||||
|
|
||||||
" Always silent the command
|
" Always silent the command
|
||||||
inoremap <silent> <SID>AutoPairsReturn <C-R>=AutoPairsReturn()<CR>
|
inoremap <silent> <SID>AutoPairsReturn <C-R>=AutoPairsReturn()<CR>
|
||||||
|
Loading…
Reference in New Issue
Block a user