mirror of
https://github.com/jiangmiao/auto-pairs.git
synced 2025-07-13 21:05:31 +08:00
Compare commits
52 Commits
Author | SHA1 | Date | |
---|---|---|---|
23e77decb1 | |||
a9f53155e8 | |||
c0593a61c7 | |||
f11f3e5ee3 | |||
dd1ea6b1f7 | |||
36ebfb6f29 | |||
0cabb1be77 | |||
ba81f659e7 | |||
d59bc39f75 | |||
713a33318a | |||
f8fa522790 | |||
7287467e64 | |||
0ef881effd | |||
8e9bee94c8 | |||
3c18515955 | |||
652175babc | |||
9758a447cf | |||
1c5046f8c3 | |||
4a02e2c488 | |||
28dc48fd9d | |||
27123dda7c | |||
30c9108f80 | |||
f24af6af48 | |||
0b39e635de | |||
a9365b216d | |||
559113fa2a | |||
d0d077a57d | |||
df761f3f28 | |||
1f45d88a95 | |||
49a24fc671 | |||
ff597df8e8 | |||
ab206d7a5a | |||
106578d69e | |||
eea7b44270 | |||
96f779b075 | |||
82c649c522 | |||
a01f22e5ad | |||
80c6af14a2 | |||
dceeb70a93 | |||
331060ff4b | |||
b6a478f891 | |||
48232b5e3d | |||
8026a0db4b | |||
a452553602 | |||
1d5914910a | |||
fac14bec63 | |||
207107a684 | |||
10f56aad0e | |||
6c3bcbca50 | |||
9d554d08be | |||
7e4614d6aa | |||
e62479a542 |
198
README.md
198
README.md
@ -9,12 +9,12 @@ copy plugin/auto-pairs.vim to ~/.vim/plugin
|
||||
Features
|
||||
--------
|
||||
* Insert in pair
|
||||
|
||||
|
||||
input: [
|
||||
output: [|]
|
||||
|
||||
* Delete in pair
|
||||
|
||||
|
||||
input: foo[<BS>
|
||||
output: foo
|
||||
|
||||
@ -36,6 +36,11 @@ Features
|
||||
input: '|' (press <SPACE> at |)
|
||||
output: ' |'
|
||||
|
||||
* Skip ' when inside a word
|
||||
|
||||
input: foo| (press ' at |)
|
||||
output: foo'
|
||||
|
||||
* Skip closed bracket.
|
||||
|
||||
input: []
|
||||
@ -48,12 +53,19 @@ Features
|
||||
|
||||
* Fast Wrap
|
||||
|
||||
input: |'hello' (press (<M-e> at|)
|
||||
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 |)
|
||||
output: ([foo, bar()])
|
||||
|
||||
* Quick jump to closed pair.
|
||||
|
||||
input:
|
||||
|
||||
input:
|
||||
{
|
||||
something;|
|
||||
}
|
||||
@ -65,26 +77,99 @@ 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
|
||||
|
||||
input: if(a[3)
|
||||
output: if(a[3])| (In Fly Mode)
|
||||
output: if(a[3)]) (Without Fly Mode)
|
||||
|
||||
input:
|
||||
{
|
||||
hello();|
|
||||
world();
|
||||
}
|
||||
|
||||
(press } at |)
|
||||
|
||||
output:
|
||||
{
|
||||
hello();
|
||||
world();
|
||||
}|
|
||||
|
||||
(then press <M-b> at | to do backinsert)
|
||||
output:
|
||||
{
|
||||
hello();}|
|
||||
world();
|
||||
}
|
||||
|
||||
See Fly Mode section for details
|
||||
|
||||
Fly Mode
|
||||
--------
|
||||
Fly Mode will always force closed-pair jumping instead of inserting. only for ")", "}", "]"
|
||||
|
||||
If jumps in mistake, could use AutoPairsBackInsert(Default Key: <M-b>) to jump back and insert closed pair.
|
||||
|
||||
the most situation maybe want to insert single closed pair in the string, eg ")"
|
||||
|
||||
Fly Mode is DISABLED by default.
|
||||
|
||||
add **let g:AutoPairsFlyMode = 1** .vimrc to turn it on
|
||||
|
||||
Default Options:
|
||||
|
||||
let g:AutoPairsFlyMode = 0
|
||||
let g:AutoPairsShortcutBackInsert = '<M-b>'
|
||||
|
||||
Shortcuts
|
||||
---------
|
||||
|
||||
System Shortcuts:
|
||||
<CR> : Insert new indented line after return if cursor in blank brackets or quotes.
|
||||
<BS> : Delete brackets in pair
|
||||
<M-p> : Toggle Autopairs
|
||||
<M-e> : Fast Wrap
|
||||
<M-p> : Toggle Autopairs (g:AutoPairsShortcutToggle)
|
||||
<M-e> : Fast Wrap (g:AutoPairsShortcutFastWrap)
|
||||
<M-n> : Jump to next closed pair (g:AutoPairsShortcutJump)
|
||||
<M-b> : BackInsert
|
||||
|
||||
Optional Shortcuts:
|
||||
could be turn off by let g:AutoPairsShortcuts = 0
|
||||
<M-n> jump to next closed bracket.
|
||||
<M-a> jump to end of line.
|
||||
<M-o> jump to newline with indented.
|
||||
If <M-p> <M-e> or <M-n> conflict with another keys or want to bind to another keys, add
|
||||
|
||||
let g:AutoPairShortcutToggle = '<another key>'
|
||||
|
||||
to .vimrc, it the key is empty string '', then the shortcut will be disabled.
|
||||
|
||||
Options
|
||||
-------
|
||||
* g:AutoPairs
|
||||
|
||||
Default: {'(':')', '[':']', '{':'}',"'":"'",'"':'"'}
|
||||
Default: {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
||||
|
||||
* b:AutoPairs
|
||||
|
||||
Default: g:AutoPairs
|
||||
|
||||
Buffer level pairs set.
|
||||
|
||||
* g:AutoPairsShortcutToggle
|
||||
|
||||
@ -93,21 +178,18 @@ Options
|
||||
The shortcut to toggle autopairs.
|
||||
|
||||
* g:AutoPairsShortcutFastWrap
|
||||
|
||||
|
||||
Default: '<M-e>'
|
||||
|
||||
Fast wrap the word. all pairs will be consider as a block (include <>).
|
||||
(|)'hello' after fast wrap at |, the word will be ('hello')
|
||||
(|)<hello> after fast wrap at |, the word will be (<hello>)
|
||||
|
||||
* g:AutoPairsShortcuts
|
||||
* g:AutoPairsShortcutJump
|
||||
|
||||
Default: 1
|
||||
Default: '<M-n>'
|
||||
|
||||
imap 3 shortcuts
|
||||
<M-n> jump to next closed bracket.
|
||||
<M-a> jump to end of line.
|
||||
<M-o> jump to newline with indented.
|
||||
Jump to the next closed pair
|
||||
|
||||
* g:AutoPairsMapBS
|
||||
|
||||
@ -136,9 +218,32 @@ Options
|
||||
Map <space> to insert a space after the opening character and before the closing one.
|
||||
execute 'inoremap <buffer> <silent> <CR> <C-R>=AutoPairsSpace()<CR>'
|
||||
|
||||
* g:AutoPairsFlyMode
|
||||
|
||||
Default : 0
|
||||
|
||||
set it to 1 to enable FlyMode.
|
||||
see FlyMode section for details.
|
||||
|
||||
* g:AutoPairsShortcutBackInsert
|
||||
|
||||
Default : <M-b>
|
||||
|
||||
Work with FlyMode, insert the key at the Fly Mode jumped postion
|
||||
|
||||
Buffer Level Pairs Setting
|
||||
--------------------------
|
||||
|
||||
Set b:AutoPairs before BufEnter
|
||||
|
||||
eg:
|
||||
|
||||
" When the filetype is FILETYPE then make AutoPairs only match for parenthesis
|
||||
au Filetype FILETYPE let b:AutoPairs = {"(": ")"}
|
||||
|
||||
TroubleShooting
|
||||
---------------
|
||||
The script will remap keys ([{'"}]) <BS>,
|
||||
The script will remap keys ([{'"}]) <BS>,
|
||||
If auto pairs cannot work, use :imap ( to check if the map is corrected.
|
||||
The correct map should be <C-R>=AutoPairsInsert("\(")<CR>
|
||||
Or the plugin conflict with some other plugins.
|
||||
@ -155,4 +260,53 @@ TroubleShooting
|
||||
|
||||
3. use DEL or <C-O>x to delete the character insert by plugin.
|
||||
|
||||
|
||||
|
||||
Known Issues
|
||||
-----------------------
|
||||
There are the issues I cannot fix.
|
||||
|
||||
Compatible with Vimwiki - [issue #19](https://github.com/jiangmiao/auto-pairs/issues/19)
|
||||
|
||||
Description: When works with vimwiki `<CR>` will output `<SNR>xx_CR()`
|
||||
Reason: vimwiki uses `<expr>` on mapping `<CR>` that auto-pairs cannot expanding.
|
||||
Solution A: Add
|
||||
|
||||
" Copy from vimwiki.vim s:CR function for CR remapping
|
||||
function! VimwikiCR()
|
||||
let res = vimwiki#lst#kbd_cr()
|
||||
if res == "\<CR>" && g:vimwiki_table_mappings
|
||||
let res = vimwiki#tbl#kbd_cr()
|
||||
endif
|
||||
return res
|
||||
endfunction
|
||||
autocmd filetype vimwiki inoremap <buffer> <silent> <CR> <C-R>=VimwikiCR()<CR><C-R>=AutoPairsReturn()<CR>
|
||||
|
||||
to .vimrc, it will make vimwiki and auto-pairs 'Return' feature works together.
|
||||
|
||||
Solution B: add `let g:AutoPairsMapCR = 0` to .vimrc to disable `<CR>` mapping.
|
||||
|
||||
Compatible with viki - [issue #25](https://github.com/jiangmiao/auto-pairs/issues/25)
|
||||
|
||||
Description: When works with viki `<CR>` will output viki#ExprMarkInexistentInElement('ParagraphVisible','<CR>')
|
||||
Reason: viki uses `<expr>` on mapping `<CR>` that auto-pairs cannot expanding.
|
||||
Solution A: Add
|
||||
|
||||
autocmd filetype viki inoremap <buffer> <silent> <CR> <C-R>=viki#ExprMarkInexistentInElement('ParagraphVisible',"\n")<CR><C-R>=AutoPairsReturn()<CR>`
|
||||
|
||||
to .vimrc, it will make viki and auto-pairs works together.
|
||||
|
||||
Solution B: add `let g:AutoPairsMapCR = 0` to .vimrc to disable `<CR>` mapping.
|
||||
|
||||
Remarks: Solution A need NOT add `let g:AutoPairsMapCR = 0` to .vimrc, if Solution A still cannot work, then have to use Solution B to disable auto-pairs `<CR>`.
|
||||
|
||||
Breaks '.' - [issue #3](https://github.com/jiangmiao/auto-pairs/issues/3)
|
||||
|
||||
Description: After entering insert mode and inputing `[hello` then leave insert
|
||||
mode by `<ESC>`. press '.' will insert 'hello' instead of '[hello]'.
|
||||
Reason: `[` actually equals `[]\<LEFT>` and \<LEFT> will break '.'
|
||||
Solution: none
|
||||
|
||||
Contributors
|
||||
------------
|
||||
* [camthompson](https://github.com/camthompson)
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
" Insert or delete brackets, parens, quotes in pairs.
|
||||
" Maintainer: JiangMiao <jiangfriend@gmail.com>
|
||||
" Last Change: 2011-12-13
|
||||
" Version: 1.1.3
|
||||
" Contributor: camthompson
|
||||
" Last Change: 2013-02-16
|
||||
" Version: 1.3.0
|
||||
" Homepage: http://www.vim.org/scripts/script.php?script_id=3599
|
||||
" Repository: https://github.com/jiangmiao/auto-pairs
|
||||
|
||||
@ -10,25 +11,14 @@ if exists('g:AutoPairsLoaded') || &cp
|
||||
end
|
||||
let g:AutoPairsLoaded = 1
|
||||
|
||||
" Shortcurs for
|
||||
" <M-o> newline with indetation
|
||||
" <M-a> jump to of line
|
||||
" <M-n> jmup to next pairs
|
||||
if !exists('g:AutoPairsShortcuts')
|
||||
let g:AutoPairsShortcuts = 1
|
||||
end
|
||||
|
||||
if !exists('g:AutoPairs')
|
||||
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"'}
|
||||
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
||||
end
|
||||
|
||||
if !exists('g:AutoPairsParens')
|
||||
let g:AutoPairsParens = {'(':')', '[':']', '{':'}'}
|
||||
end
|
||||
|
||||
let g:AutoExtraPairs = copy(g:AutoPairs)
|
||||
let g:AutoExtraPairs['<'] = '>'
|
||||
|
||||
if !exists('g:AutoPairsMapBS')
|
||||
let g:AutoPairsMapBS = 1
|
||||
end
|
||||
@ -53,8 +43,24 @@ if !exists('g:AutoPairsShortcutFastWrap')
|
||||
let g:AutoPairsShortcutFastWrap = '<M-e>'
|
||||
end
|
||||
|
||||
let g:AutoPairsClosedPairs = {}
|
||||
if !exists('g:AutoPairsShortcutJump')
|
||||
let g:AutoPairsShortcutJump = '<M-n>'
|
||||
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
|
||||
|
||||
" Work with Fly Mode, insert pair where jumped
|
||||
if !exists('g:AutoPairsShortcutBackInsert')
|
||||
let g:AutoPairsShortcutBackInsert = '<M-b>'
|
||||
endif
|
||||
|
||||
|
||||
" Will auto generated {']' => '[', ..., '}' => '{'}in initialize.
|
||||
let g:AutoPairsClosedPairs = {}
|
||||
|
||||
|
||||
function! AutoPairsInsert(key)
|
||||
@ -63,9 +69,12 @@ function! AutoPairsInsert(key)
|
||||
end
|
||||
|
||||
let line = getline('.')
|
||||
let prev_char = line[col('.')-2]
|
||||
let current_char = line[col('.')-1]
|
||||
let next_char = line[col('.')]
|
||||
let pos = col('.') - 1
|
||||
let next_chars = split(strpart(line, pos), '\zs')
|
||||
let current_char = get(next_chars, 0, '')
|
||||
let next_char = get(next_chars, 1, '')
|
||||
let prev_chars = split(strpart(line, 0, pos), '\zs')
|
||||
let prev_char = get(prev_chars, -1, '')
|
||||
|
||||
let eol = 0
|
||||
if col('$') - col('.') <= 1
|
||||
@ -77,62 +86,124 @@ function! AutoPairsInsert(key)
|
||||
return a:key
|
||||
end
|
||||
|
||||
|
||||
if !has_key(g:AutoPairs, a:key)
|
||||
" Skip the character if next character is space
|
||||
if current_char == ' ' && next_char == a:key
|
||||
return "\<Right>\<Right>"
|
||||
end
|
||||
|
||||
" Skip the character if next
|
||||
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
|
||||
" 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 "\<Right>"
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
" Fly Mode, and the key is closed-pairs, search closed-pair and jump
|
||||
if g:AutoPairsFlyMode && has_key(b:AutoPairsClosedPairs, a:key)
|
||||
if search(a:key, 'W')
|
||||
return "\<Right>"
|
||||
endif
|
||||
endif
|
||||
|
||||
" Input directly if the key is not an open key
|
||||
return a:key
|
||||
end
|
||||
|
||||
let open = a:key
|
||||
let close = g:AutoPairs[open]
|
||||
let close = b:AutoPairs[open]
|
||||
|
||||
if current_char == close && open == close
|
||||
return "\<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("\<LEFT>", 3)
|
||||
end
|
||||
end
|
||||
|
||||
return open.close."\<Left>"
|
||||
endfunction
|
||||
|
||||
function! AutoPairsDelete()
|
||||
if !b:autopairs_enabled
|
||||
return "\<BS>"
|
||||
end
|
||||
|
||||
let line = getline('.')
|
||||
let current_char = line[col('.')-1]
|
||||
let prev_char = line[col('.')-2]
|
||||
let pprev_char = line[col('.')-3]
|
||||
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, '')
|
||||
|
||||
if pprev_char == '\'
|
||||
return "\<BS>"
|
||||
end
|
||||
|
||||
" Delete last two spaces in parens, work with MapSpace
|
||||
if has_key(g:AutoPairs, pprev_char) && prev_char == ' ' && current_char == ' '
|
||||
if has_key(b:AutoPairs, pprev_char) && prev_char == ' ' && current_char == ' '
|
||||
return "\<BS>\<DEL>"
|
||||
endif
|
||||
|
||||
if has_key(g:AutoPairs, prev_char)
|
||||
let close = g:AutoPairs[prev_char]
|
||||
" 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
|
||||
let space = matchstr(nline, '^\s*')
|
||||
return "\<BS>\<DEL>". repeat("\<DEL>", len(space)+1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -140,41 +211,71 @@ function! AutoPairsDelete()
|
||||
endfunction
|
||||
|
||||
function! AutoPairsJump()
|
||||
call search('[{("\[\]'')}]','W')
|
||||
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
|
||||
|
||||
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
|
||||
function! AutoPairsFastWrap()
|
||||
let line = getline('.')
|
||||
let current_char = line[col('.')-1]
|
||||
let next_char = line[col('.')]
|
||||
|
||||
" Ignore EOL
|
||||
if col('.') == col('$')
|
||||
return ''
|
||||
end
|
||||
|
||||
normal! x
|
||||
if match(next_char, '\s') != -1
|
||||
call search('\S', 'W')
|
||||
let next_char = getline('.')[col('.')-1]
|
||||
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]
|
||||
end
|
||||
|
||||
if has_key(g:AutoExtraPairs, next_char)
|
||||
let close = g:AutoExtraPairs[next_char]
|
||||
call search(close, 'W')
|
||||
return "\<RIGHT>".current_char."\<LEFT>"
|
||||
else
|
||||
if match(next_char, '\w') != -1
|
||||
execute "normal! he"
|
||||
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
|
||||
execute "normal! a".current_char
|
||||
return ""
|
||||
return "\<RIGHT>".inputed_close_pair."\<LEFT>"
|
||||
else
|
||||
normal e
|
||||
return "\<RIGHT>".current_char."\<LEFT>"
|
||||
end
|
||||
endfunction
|
||||
|
||||
function! AutoPairsMap(key)
|
||||
execute 'inoremap <buffer> <silent> '.a:key.' <C-R>=AutoPairsInsert("\'.a:key.'")<CR>'
|
||||
let escaped_key = substitute(a:key, "'", "''", 'g')
|
||||
" use expr will cause search() doesn't work
|
||||
execute 'inoremap <buffer> <silent> '.a:key." <C-R>=AutoPairsInsert('".escaped_key."')<CR>"
|
||||
endfunction
|
||||
|
||||
function! AutoPairsToggle()
|
||||
@ -189,24 +290,38 @@ function! AutoPairsToggle()
|
||||
endfunction
|
||||
|
||||
function! AutoPairsReturn()
|
||||
if b:autopairs_enabled == 0
|
||||
return ''
|
||||
end
|
||||
let line = getline('.')
|
||||
let prev_char = line[col('.')-2]
|
||||
let pline = getline(line('.')-1)
|
||||
let prev_char = pline[strlen(pline)-1]
|
||||
let cmd = ''
|
||||
let cur_char = line[col('.')-1]
|
||||
if has_key(g:AutoPairs, prev_char) && g:AutoPairs[prev_char] == cur_char
|
||||
if g:AutoPairsCenterLine && winline() * 1.5 >= winheight(0)
|
||||
if has_key(b:AutoPairs, prev_char) && b:AutoPairs[prev_char] == cur_char
|
||||
if g:AutoPairsCenterLine && winline() * 3 >= winheight(0) * 2
|
||||
" 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"
|
||||
end
|
||||
|
||||
" If equalprg has been set, then avoid call =
|
||||
" https://github.com/jiangmiao/auto-pairs/issues/24
|
||||
if &equalprg != ''
|
||||
return "\<ESC>O".cmd
|
||||
endif
|
||||
|
||||
" conflict with javascript and coffee
|
||||
" javascript need indent new line
|
||||
" coffeescript forbid indent new line
|
||||
if &filetype == 'coffeescript'
|
||||
return "\<DEL>\<CR>".cur_char."\<ESC>k==o".cmd
|
||||
if &filetype == 'coffeescript' || &filetype == 'coffee'
|
||||
return "\<ESC>k==o".cmd
|
||||
else
|
||||
return "\<DEL>\<CR>".cur_char."\<ESC>=ko".cmd
|
||||
return "\<ESC>=ko".cmd
|
||||
endif
|
||||
end
|
||||
return "\<CR>"
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! AutoPairsSpace()
|
||||
@ -220,46 +335,121 @@ function! AutoPairsSpace()
|
||||
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_enabled = 1
|
||||
for [open, close] in items(g:AutoPairs)
|
||||
let b:AutoPairsClosedPairs = {}
|
||||
|
||||
if !exists('b:AutoPairs')
|
||||
let b:AutoPairs = g:AutoPairs
|
||||
end
|
||||
|
||||
" buffer level map pairs keys
|
||||
for [open, close] in items(b:AutoPairs)
|
||||
call AutoPairsMap(open)
|
||||
if open != close
|
||||
call AutoPairsMap(close)
|
||||
end
|
||||
let g:AutoPairsClosedPairs[close] = 1
|
||||
let b:AutoPairsClosedPairs[close] = open
|
||||
endfor
|
||||
|
||||
" Still use <buffer> level mapping for <BS> <SPACE>
|
||||
if g:AutoPairsMapBS
|
||||
execute 'inoremap <buffer> <silent> <expr> <BS> AutoPairsDelete()'
|
||||
end
|
||||
|
||||
if g:AutoPairsMapCR
|
||||
execute 'inoremap <buffer> <silent> <expr> <CR> AutoPairsReturn()'
|
||||
" Use <C-R> instead of <expr> for issue #14 sometimes press BS output strange words
|
||||
execute 'inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>'
|
||||
end
|
||||
|
||||
if g:AutoPairsMapSpace
|
||||
execute 'inoremap <buffer> <silent> <expr> <space> AutoPairsSpace()'
|
||||
execute 'inoremap <buffer> <silent> <SPACE> <C-R>=AutoPairsSpace()<CR>'
|
||||
end
|
||||
|
||||
execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutFastWrap.' <C-R>=AutoPairsFastWrap()<CR>'
|
||||
execute 'inoremap <buffer> <silent> <expr> '.g:AutoPairsShortcutToggle.' AutoPairsToggle()'
|
||||
execute 'noremap <buffer> <silent> '.g:AutoPairsShortcutToggle.' :call AutoPairsToggle()<CR>'
|
||||
" If the keys map conflict with your own settings, delete or change them
|
||||
if g:AutoPairsShortcuts
|
||||
execute 'inoremap <buffer> <silent> <M-n> <ESC>:call AutoPairsJump()<CR>a'
|
||||
execute 'inoremap <buffer> <silent> <M-a> <END>'
|
||||
execute 'inoremap <buffer> <silent> <M-o> <END><CR>'
|
||||
if g:AutoPairsShortcutFastWrap != ''
|
||||
execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutFastWrap.' <C-R>=AutoPairsFastWrap()<CR>'
|
||||
end
|
||||
|
||||
if g:AutoPairsShortcutBackInsert != ''
|
||||
execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutBackInsert.' <C-R>=AutoPairsBackInsert()<CR>'
|
||||
end
|
||||
|
||||
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>'
|
||||
end
|
||||
|
||||
if g:AutoPairsShortcutJump != ''
|
||||
execute 'inoremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' <ESC>:call AutoPairsJump()<CR>a'
|
||||
execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
|
||||
end
|
||||
|
||||
endfunction
|
||||
|
||||
function! AutoPairsForceInit()
|
||||
function! s:ExpandMap(map)
|
||||
let map = a:map
|
||||
if map =~ '<Plug>'
|
||||
let map = substitute(map, '\(<Plug>\w\+\)', '\=maparg(submatch(1), "i")', 'g')
|
||||
endif
|
||||
return map
|
||||
endfunction
|
||||
|
||||
function! AutoPairsTryInit()
|
||||
if exists('b:autopairs_loaded')
|
||||
return
|
||||
else
|
||||
call AutoPairsInit()
|
||||
end
|
||||
|
||||
" for auto-pairs starts with 'a', so the priority is higher than supertab and vim-endwise
|
||||
"
|
||||
" vim-endwise doesn't support <Plug>AutoPairsReturn
|
||||
" when use <Plug>AutoPairsReturn will cause <Plug> isn't expanded
|
||||
"
|
||||
" supertab doesn't support <SID>AutoPairsReturn
|
||||
" when use <SID>AutoPairsReturn will cause Duplicated <CR>
|
||||
"
|
||||
" and when load after vim-endwise will cause unexpected endwise inserted.
|
||||
" so always load AutoPairs at last
|
||||
|
||||
" Buffer level keys mapping
|
||||
" comptible with other plugin
|
||||
if g:AutoPairsMapCR
|
||||
let old_cr = maparg('<CR>', 'i')
|
||||
if old_cr == ''
|
||||
let old_cr = '<CR>'
|
||||
else
|
||||
let old_cr = s:ExpandMap(old_cr)
|
||||
endif
|
||||
|
||||
" compatible with clang_complete
|
||||
" https://github.com/jiangmiao/auto-pairs/issues/18
|
||||
let pattern = '<SNR>\d\+_HandlePossibleSelectionEnter()'
|
||||
if old_cr =~ pattern
|
||||
execute 'imap <expr> <script> <SID>AutoPairsClangCompleteCR ' . matchstr(old_cr, pattern)
|
||||
let old_cr = substitute(old_cr, pattern , '<SID>AutoPairsClangCompleteCR', '')
|
||||
endif
|
||||
|
||||
if old_cr !~ 'AutoPairsReturn'
|
||||
" generally speaking, <silent> should not be here because every plugin
|
||||
" has there own silent solution. but for some plugin which wasn't double silent
|
||||
" mapping, when maparg expand the map will lose the silent info, so <silent> always.
|
||||
" use inoremap for neocomplcache
|
||||
execute 'inoremap <script> <buffer> <silent> <CR> '.old_cr.'<SID>AutoPairsReturn'
|
||||
end
|
||||
endif
|
||||
call AutoPairsInit()
|
||||
endfunction
|
||||
|
||||
au BufEnter * :call AutoPairsForceInit()
|
||||
" Always silent the command
|
||||
inoremap <silent> <SID>AutoPairsReturn <C-R>=AutoPairsReturn()<CR>
|
||||
imap <script> <Plug>AutoPairsReturn <SID>AutoPairsReturn
|
||||
|
||||
|
||||
au BufEnter * :call AutoPairsTryInit()
|
||||
|
Reference in New Issue
Block a user