mirror of
https://github.com/jiangmiao/auto-pairs.git
synced 2025-04-21 03:48:47 +08:00
Compare commits
55 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
39f06b873a | ||
![]() |
65a9f452f2 | ||
![]() |
fcf9f00f85 | ||
![]() |
40ba005829 | ||
![]() |
1c3f4c8171 | ||
![]() |
b85ef9831e | ||
![]() |
67b3606bb7 | ||
![]() |
a5142b0e99 | ||
![]() |
f1d9a2bf63 | ||
![]() |
3413c38fe3 | ||
![]() |
0682eb08cb | ||
![]() |
f0b00a1c63 | ||
![]() |
7e10cc3b00 | ||
![]() |
453d488987 | ||
![]() |
12dc3a060e | ||
![]() |
81a4a9fe5b | ||
![]() |
c2f0eef628 | ||
![]() |
4af571e18b | ||
![]() |
179520e690 | ||
![]() |
43db4c1776 | ||
![]() |
8d2f838205 | ||
![]() |
2de4b15cc5 | ||
![]() |
d1ecaac55c | ||
![]() |
38d53d4df0 | ||
![]() |
7d721d261f | ||
![]() |
423ee192c7 | ||
![]() |
ea2fd8a2de | ||
![]() |
3c7fde2643 | ||
![]() |
bec90a4076 | ||
![]() |
1ff8be79d3 | ||
![]() |
177664ab1a | ||
![]() |
06e7d60aa2 | ||
![]() |
4d5060c80c | ||
![]() |
adf9224a41 | ||
![]() |
1884e426ca | ||
![]() |
680f4fefcd | ||
![]() |
738d1f18a8 | ||
![]() |
4ec359716a | ||
![]() |
92e5ece6a3 | ||
![]() |
cf921dadce | ||
![]() |
9086ce897a | ||
![]() |
3c290d9308 | ||
![]() |
404a121b04 | ||
![]() |
f0019fc642 | ||
![]() |
c00cc24c8e | ||
![]() |
6afc850e24 | ||
![]() |
20ec5b043f | ||
![]() |
3bd07a4eeb | ||
![]() |
ff9160e6d8 | ||
![]() |
23f1c89508 | ||
![]() |
e915d857fe | ||
![]() |
69bfaf0fdd | ||
![]() |
8451816810 | ||
![]() |
edf7ab9a9e | ||
![]() |
83e22c7e3b |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
doc/tags
|
167
README.md
167
README.md
@ -4,11 +4,13 @@ Insert or delete brackets, parens, quotes in pair.
|
||||
|
||||
Installation
|
||||
------------
|
||||
copy plugin/auto-pairs.vim to ~/.vim/plugin
|
||||
|
||||
or if you are using `pathogen`:
|
||||
|
||||
```git clone git://github.com/jiangmiao/auto-pairs.git ~/.vim/bundle/auto-pairs```
|
||||
* Manual
|
||||
* Copy `plugin/auto-pairs.vim` to `~/.vim/plugin`
|
||||
* [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
|
||||
--------
|
||||
@ -27,7 +29,10 @@ Features
|
||||
input: {|} (press <CR> at |)
|
||||
output: {
|
||||
|
|
||||
}
|
||||
} (press } to close the pair)
|
||||
output: {
|
||||
}| (the inserted blank line will be deleted)
|
||||
|
||||
|
||||
* Insert spaces before closing characters, only for [], (), {}
|
||||
|
||||
@ -57,16 +62,17 @@ Features
|
||||
|
||||
* 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 |)
|
||||
output: ([foo, bar()])
|
||||
|
||||
* Quick move char to closed pair
|
||||
|
||||
input: (|){["foo"]} (press <M-}> at |)
|
||||
output: ({["foo"]}|)
|
||||
|
||||
input: |[foo, bar()] (press (<M-]> at |)
|
||||
output: ([foo, bar()]|)
|
||||
|
||||
* Quick jump to closed pair.
|
||||
|
||||
input:
|
||||
@ -81,25 +87,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
|
||||
|
||||
input: if(a[3)
|
||||
@ -129,6 +116,11 @@ Features
|
||||
|
||||
See Fly Mode section for details
|
||||
|
||||
* Multibyte Pairs
|
||||
|
||||
Support any multibyte pairs such as <!-- -->, <% %>, """ """
|
||||
See multibyte pairs section for details
|
||||
|
||||
Fly Mode
|
||||
--------
|
||||
Fly Mode will always force closed-pair jumping instead of inserting. only for ")", "}", "]"
|
||||
@ -167,7 +159,7 @@ Options
|
||||
-------
|
||||
* g:AutoPairs
|
||||
|
||||
Default: {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
||||
Default: {'(':')', '[':']', '{':'}',"'":"'",'"':'"', "`":"`", '```':'```', '"""':'"""', "'''":"'''"}
|
||||
|
||||
* b:AutoPairs
|
||||
|
||||
@ -249,6 +241,13 @@ Options
|
||||
|
||||
Work with FlyMode, insert the key at the Fly Mode jumped postion
|
||||
|
||||
* g:AutoPairsMoveCharacter
|
||||
|
||||
Default: "()[]{}\"'"
|
||||
|
||||
Map <M-(> <M-)> <M-[> <M-]> <M-{> <M-}> <M-"> <M-'> to
|
||||
move character under the cursor to the pair.
|
||||
|
||||
Buffer Level Pairs Setting
|
||||
--------------------------
|
||||
|
||||
@ -258,6 +257,108 @@ eg:
|
||||
|
||||
" When the filetype is FILETYPE then make AutoPairs only match for parenthesis
|
||||
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 to close key
|
||||
m - close key jumps through multi line
|
||||
s - close key jumps only in the same line
|
||||
k[KEY] - map the close key to [KEY]
|
||||
|
||||
by default if open key equals close key the multi line is turn off
|
||||
|
||||
"<?": "?>" ? jumps only in the same line
|
||||
"<?": "?>//m" force ? jumping through multi line
|
||||
"<?php":"?>" ? will jump through multi line
|
||||
"<?php":"?>//s" force ? only jumping in the same line
|
||||
"<?": "?>//n" do not jump totally
|
||||
"<?": "?>//k]" use key ] to jump through ?>
|
||||
|
||||
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
|
||||
---------------
|
||||
@ -284,7 +385,7 @@ TroubleShooting
|
||||
To fix the issue, you need remap or disable the related shortcut.
|
||||
|
||||
Known Issues
|
||||
-----------------------
|
||||
------------
|
||||
Breaks '.' - [issue #3](https://github.com/jiangmiao/auto-pairs/issues/3)
|
||||
|
||||
Description: After entering insert mode and inputing `[hello` then leave insert
|
||||
|
356
doc/AutoPairs.txt
Normal file
356
doc/AutoPairs.txt
Normal file
@ -0,0 +1,356 @@
|
||||
*AutoPairs.txt* Insert or delete brackets, parens, quotes in pair
|
||||
|
||||
Author: jiangmiao
|
||||
License: MIT
|
||||
URL: https://github.com/jiangmiao/auto-pairs
|
||||
|
||||
==============================================================================
|
||||
CONTENTS *autopairs-contents*
|
||||
|
||||
1. Installation ............................. |autopairs-installation|
|
||||
2. Features ..................................... |autopairs-features|
|
||||
3. Fly Mode ..................................... |autopairs-fly-mode|
|
||||
4. Shortcuts ................................... |autopairs-shortcuts|
|
||||
5. Options ....................................... |autopairs-options|
|
||||
6. Troubleshooting ...................... |autopairs-troubleshooting|
|
||||
|
||||
==============================================================================
|
||||
1. Introduction *autopairs-installation*
|
||||
|
||||
Copy `plugin/auto-pairs.vim` to `~/.vim/plugin`.
|
||||
|
||||
Or if you are using `pathogen`: >
|
||||
|
||||
git clone git://github.com/jiangmiao/auto-pairs.git ~/.vim/bundle/auto-pairs
|
||||
|
||||
==============================================================================
|
||||
2. Features *autopairs-features*
|
||||
|
||||
Insert in pair: >
|
||||
|
||||
input: [
|
||||
output: [|]
|
||||
|
||||
Delete in pair: >
|
||||
|
||||
input: foo[<BS>]
|
||||
output: foo
|
||||
|
||||
Insert new indented line after Return: >
|
||||
|
||||
input: {|} (press <CR> at |)
|
||||
output: {
|
||||
|
|
||||
}
|
||||
|
||||
Insert spaces before closing characters, only for [], (), {}: >
|
||||
|
||||
input: {|} (press <SPACE> at |)
|
||||
output: { | }
|
||||
|
||||
input: {|} (press <SPACE>foo} at |)
|
||||
output: { foo }|
|
||||
|
||||
input: '|' (press <SPACE> at |)
|
||||
output: ' |'
|
||||
|
||||
Skip ' when inside a word: >
|
||||
|
||||
input: foo| (press ' at |)
|
||||
output: foo'
|
||||
|
||||
Skip closed bracket: >
|
||||
|
||||
input: []
|
||||
output: []
|
||||
|
||||
Ignore auto pair when previous character is '\': >
|
||||
|
||||
input: "\'
|
||||
output: "\'"
|
||||
|
||||
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 |)
|
||||
output: ([foo, bar()])
|
||||
|
||||
Quick jump to closed pair: >
|
||||
|
||||
input:
|
||||
{
|
||||
something;|
|
||||
}
|
||||
|
||||
(press } at |)
|
||||
|
||||
output:
|
||||
{
|
||||
|
||||
}|
|
||||
|
||||
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 (|autopairs-flymode|): >
|
||||
|
||||
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
|
||||
|
||||
==============================================================================
|
||||
3. Fly Mode *autopairs-flymode*
|
||||
|
||||
Fly Mode will always force closed-pair jumping instead of inserting. Only for
|
||||
")", "}", "]". If jumps in mistake, you can use |g:AutoPairsBackInsert| (default
|
||||
Key: <M-b>) to jump back and insert closed pair.
|
||||
|
||||
The most situation maybe you want to insert single closed pair in the string,
|
||||
eg: >
|
||||
|
||||
")"
|
||||
|
||||
Fly Mode is DISABLED by default. To enable Fly Mode add following to your
|
||||
'.vimrc': >
|
||||
|
||||
let g:AutoPairsFlyMode = 1
|
||||
|
||||
Default Options: >
|
||||
|
||||
let g:AutoPairsFlyMode = 0
|
||||
let g:AutoPairsShortcutBackInsert = '<M-b>'
|
||||
|
||||
==============================================================================
|
||||
4. Shortcuts *autopairs-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 (|g:AutoPairsShortcutToggle|)
|
||||
<M-e>: Fast Wrap (|g:AutoPairsShortcutFastWrap|)
|
||||
<M-n>: Jump to next closed pair (|g:AutoPairsShortcutJump|)
|
||||
<M-b>: BackInsert (|g:AutoPairsShortcutBackInsert|)
|
||||
|
||||
|
||||
To rebind keys <M-p>, <M-e> or <M-n> or in case of conflicts with
|
||||
another keys:
|
||||
|
||||
let g:AutoPairsShortcutToggle = '<another key>'
|
||||
|
||||
If the key is empty string '', then the shortcut will be disabled.
|
||||
|
||||
==============================================================================
|
||||
5. Options *autopairs-options*
|
||||
|
||||
*g:AutoPairs*
|
||||
|g:AutoPairs| dict
|
||||
|
||||
Default: >
|
||||
{'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
||||
|
||||
Specifies which symbols should be automatically paired.
|
||||
|
||||
To append new pairs without overwriting defaults, add values in your `.vimrc`.:
|
||||
|
||||
let g:AutoPairs['<']='>'
|
||||
|
||||
This example will enable matching of `<` with `>`.
|
||||
|
||||
|
||||
*b:AutoPairs*
|
||||
|b:AutoPairs| dict
|
||||
|
||||
Default: |g:AutoPairs|
|
||||
|
||||
Buffer level pairs set.
|
||||
|
||||
You can set |b:AutoPairs| before |BufEnter|: >
|
||||
|
||||
au Filetype FILETYPE let b:AutoPairs = {"(": ")"}
|
||||
|
||||
This sets |AutoPairs| to only match for parenthesis for 'FILETYPE'.
|
||||
|
||||
|
||||
|
||||
*g:AutoPairsShortcutToggle*
|
||||
|g:AutoPairsShortcutToggle| string
|
||||
|
||||
Default: <M-p>
|
||||
|
||||
The shortcut to toggle autopairs.
|
||||
|
||||
|
||||
|
||||
*g:AutoPairsShortcutFastWrap*
|
||||
|g:AutoPairsShortcutFastWrap| string
|
||||
|
||||
Default: <M-e>
|
||||
|
||||
Fast wrap the word. All pairs will be considered as a block (including <>).
|
||||
|
||||
(|)'hello' after fast wrap at |, the word will be ('hello')
|
||||
(|)<hello> after fast wrap at |, the word will be (<hello>)
|
||||
|
||||
|
||||
|
||||
*g:AutoPairsShortcutJump*
|
||||
|g:AutoPairsShortcutJump| string
|
||||
|
||||
Default: <M-n>
|
||||
|
||||
Jump to the next closed pair.
|
||||
|
||||
|
||||
*g:AutoPairsShortcutBackInsert*
|
||||
|g:AutoPairsShortcutBackInsert| string
|
||||
|
||||
Default: <M-b>
|
||||
|
||||
Work with |autopairs-flymode|, insert the key at the Fly Mode jumped position.
|
||||
|
||||
|
||||
|
||||
*g:AutoPairsMapBS*
|
||||
|g:AutoPairsMapBS| int
|
||||
|
||||
Default: 1
|
||||
|
||||
Map <BS> to delete brackets and quotes in pair, executes:
|
||||
|
||||
inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>
|
||||
|
||||
|
||||
*g:AutoPairsMapCh*
|
||||
|g:AutoPairsMapCh| int
|
||||
|
||||
Default: 1
|
||||
|
||||
Map <C-h> to delete brackets and quotes in pair.
|
||||
|
||||
|
||||
*g:AutoPairsMapCR*
|
||||
|g:AutoPairsMapCR| int
|
||||
|
||||
Default: 1
|
||||
|
||||
Map <CR> to insert a new indented line if cursor in (|), {|} [|], '|', "|".
|
||||
Executes:
|
||||
|
||||
inoremap <buffer> <silent> <CR> <C-R>=AutoPairsReturn()<CR>
|
||||
|
||||
|
||||
*g:AutoPairsCenterLine*
|
||||
|g:AutoPairsCenterLine| int
|
||||
|
||||
Default: 1
|
||||
|
||||
When |g:AutoPairsMapCR| is on, center current line after return if the line
|
||||
is at the bottom 1/3 of the window.
|
||||
|
||||
|
||||
*g:AutoPairsMapSpace*
|
||||
|g:AutoPairsMapSpace| int
|
||||
|
||||
Default: 1
|
||||
|
||||
Map <space> to insert a space after the opening character and before the
|
||||
closing one.
|
||||
|
||||
Executes:
|
||||
|
||||
inoremap <buffer> <silent> <CR> <C-R>=AutoPairsSpace()<CR>
|
||||
|
||||
|
||||
*g:AutoPairsFlyMode*
|
||||
|g:AutoPairsFlyMode| int
|
||||
|
||||
Default: 0
|
||||
|
||||
Set it to 1 to enable |autopairs-flymode|.
|
||||
|
||||
|
||||
*g:AutoPairsMultilineClose*
|
||||
|g:AutoPairsMultilineClose| int
|
||||
|
||||
Default: 1
|
||||
|
||||
When you press the key for the closing pair (e.g. `)`) it jumps past it.
|
||||
If set to 1, then it'll jump to the next line, if there is only 'whitespace'.
|
||||
If set to 0, then it'll only jump to a closing pair on the same line.
|
||||
|
||||
==============================================================================
|
||||
6. Troubleshooting *autopairs-troubleshooting*
|
||||
|
||||
This plugin remaps 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 conflicts with some other plugins. Use command: >
|
||||
|
||||
:call AutoPairsInit() to remap the keys.
|
||||
|
||||
--- How to insert parens purely? ---
|
||||
|
||||
There are 3 ways:
|
||||
|
||||
1. Use Ctrl-V ) to insert paren without trigger the plugin.
|
||||
|
||||
2. Use Alt-P to turn off the plugin.
|
||||
|
||||
3. Use DEL or <C-O>x to delete the character insert by plugin.
|
||||
|
||||
--- Swedish Character Conflict ---
|
||||
|
||||
Because AutoPairs uses Meta(Alt) key as a shortcut, it conflicts with some
|
||||
Swedish character such as å. To fix the issue, you need remap or disable the
|
||||
related shortcut.
|
@ -1,8 +1,8 @@
|
||||
" Insert or delete brackets, parens, quotes in pairs.
|
||||
" Maintainer: JiangMiao <jiangfriend@gmail.com>
|
||||
" Contributor: camthompson
|
||||
" Last Change: 2013-07-13
|
||||
" Version: 1.3.2
|
||||
" Last Change: 2019-02-02
|
||||
" Version: 2.0.0
|
||||
" Homepage: http://www.vim.org/scripts/script.php?script_id=3599
|
||||
" Repository: https://github.com/jiangmiao/auto-pairs
|
||||
" License: MIT
|
||||
@ -13,12 +13,30 @@ end
|
||||
let g:AutoPairsLoaded = 1
|
||||
|
||||
if !exists('g:AutoPairs')
|
||||
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
||||
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '```':'```', '"""':'"""', "'''":"'''", "`":"`"}
|
||||
end
|
||||
|
||||
if !exists('g:AutoPairsParens')
|
||||
let g:AutoPairsParens = {'(':')', '[':']', '{':'}'}
|
||||
end
|
||||
" default pairs base on filetype
|
||||
func! AutoPairsDefaultPairs()
|
||||
if exists('b:autopairs_defaultpairs')
|
||||
return b:autopairs_defaultpairs
|
||||
end
|
||||
let r = copy(g:AutoPairs)
|
||||
let allPairs = {
|
||||
\ 'vim': {'\v^\s*\zs"': ''},
|
||||
\ 'rust': {'\w\zs<': '>', '&\zs''': ''},
|
||||
\ 'php': {'<?': '?>//k]', '<?php': '?>//k]'}
|
||||
\ }
|
||||
for [filetype, pairs] in items(allPairs)
|
||||
if &filetype == filetype
|
||||
for [open, close] in items(pairs)
|
||||
let r[open] = close
|
||||
endfor
|
||||
end
|
||||
endfor
|
||||
let b:autopairs_defaultpairs = r
|
||||
return r
|
||||
endf
|
||||
|
||||
if !exists('g:AutoPairsMapBS')
|
||||
let g:AutoPairsMapBS = 1
|
||||
@ -33,6 +51,10 @@ 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
|
||||
@ -49,6 +71,10 @@ if !exists('g:AutoPairsShortcutFastWrap')
|
||||
let g:AutoPairsShortcutFastWrap = '<M-e>'
|
||||
end
|
||||
|
||||
if !exists('g:AutoPairsMoveCharacter')
|
||||
let g:AutoPairsMoveCharacter = "()[]{}\"'"
|
||||
end
|
||||
|
||||
if !exists('g:AutoPairsShortcutJump')
|
||||
let g:AutoPairsShortcutJump = '<M-n>'
|
||||
endif
|
||||
@ -87,267 +113,336 @@ let s:Left = s:Go."\<LEFT>"
|
||||
let s:Right = s:Go."\<RIGHT>"
|
||||
|
||||
|
||||
" Will auto generated {']' => '[', ..., '}' => '{'}in initialize.
|
||||
let g:AutoPairsClosedPairs = {}
|
||||
|
||||
|
||||
function! AutoPairsInsert(key)
|
||||
if !b:autopairs_enabled
|
||||
return a:key
|
||||
end
|
||||
" 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("\<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 pos = col('.') - 1
|
||||
let before = strpart(line, 0, pos)
|
||||
let after = strpart(line, pos)
|
||||
let next_chars = split(after, '\zs')
|
||||
let current_char = get(next_chars, 0, '')
|
||||
let next_char = get(next_chars, 1, '')
|
||||
let prev_chars = split(before, '\zs')
|
||||
let prev_char = get(prev_chars, -1, '')
|
||||
|
||||
let eol = 0
|
||||
if col('$') - col('.') <= 1
|
||||
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
|
||||
|
||||
if !g:AutoPairsFlyMode
|
||||
" Skip the character if next character is space
|
||||
if current_char == ' ' && next_char == a:key
|
||||
return s:Right.s:Right
|
||||
end
|
||||
|
||||
" 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
|
||||
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 n = n + 1
|
||||
let pos = pos + 1
|
||||
let i = i+1
|
||||
endwhile
|
||||
if n % 2 == 1
|
||||
return a:key
|
||||
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 = AutoPairsDefaultPairs()
|
||||
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 open pairs
|
||||
for [open, close, opt] in b:AutoPairsList
|
||||
let ms = s:matchend(before.a:key, open)
|
||||
let m = matchstr(afterline, '^\v\s*\zs\V'.close)
|
||||
if len(ms) > 0
|
||||
" process the open pair
|
||||
|
||||
" remove inserted pair
|
||||
" eg: if the pairs include < > and <!-- -->
|
||||
" when <!-- is detected the inserted pair < > should be clean up
|
||||
let target = ms[1]
|
||||
let openPair = ms[2]
|
||||
if len(openPair) == 1 && m == openPair
|
||||
break
|
||||
end
|
||||
let bs = ''
|
||||
let del = ''
|
||||
while len(before) > len(target)
|
||||
let found = 0
|
||||
" delete pair
|
||||
for [o, c, opt] in b:AutoPairsList
|
||||
let os = s:matchend(before, o)
|
||||
if len(os) && len(os[1]) < len(target)
|
||||
" any text before openPair should not be deleted
|
||||
continue
|
||||
end
|
||||
let cs = s:matchbegin(afterline, c)
|
||||
if len(os) && len(cs)
|
||||
let found = 1
|
||||
let before = os[1]
|
||||
let afterline = cs[2]
|
||||
let bs = bs.s:backspace(os[2])
|
||||
let del = del.s:delete(cs[1])
|
||||
break
|
||||
end
|
||||
endfor
|
||||
if !found
|
||||
" delete charactor
|
||||
let ms = s:matchend(before, '\v.')
|
||||
if len(ms)
|
||||
let before = ms[1]
|
||||
let bs = bs.s:backspace(ms[2])
|
||||
end
|
||||
end
|
||||
endwhile
|
||||
return bs.del.openPair.close.s:left(close)
|
||||
end
|
||||
endfor
|
||||
|
||||
" check close pairs
|
||||
for [open, close, opt] in b:AutoPairsList
|
||||
if close == ''
|
||||
continue
|
||||
end
|
||||
if a:key == g:AutoPairsWildClosedPair || opt['mapclose'] && opt['key'] == 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
|
||||
let m = matchstr(after, '^\v\s*\zs\V'.close)
|
||||
if m != ''
|
||||
if a:key == g:AutoPairsWildClosedPair || opt['multiline']
|
||||
if b:autopairs_return_pos == line('.') && getline('.') =~ '\v^\s*$'
|
||||
normal! ddk$
|
||||
end
|
||||
call search(m, 'We')
|
||||
return "\<Right>"
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
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
|
||||
|
||||
return open.close.s:Left
|
||||
endfunction
|
||||
return a:key
|
||||
endf
|
||||
|
||||
function! AutoPairsDelete()
|
||||
func! AutoPairsDelete()
|
||||
if !b:autopairs_enabled
|
||||
return "\<BS>"
|
||||
end
|
||||
|
||||
let line = getline('.')
|
||||
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(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
|
||||
let [before, after, ig] = s:getline()
|
||||
for [open, close, opt] in b:AutoPairsList
|
||||
let b = matchstr(before, '\V'.open.'\v\s?$')
|
||||
let a = matchstr(after, '^\v\s*\V'.close)
|
||||
if b != '' && a != ''
|
||||
if b[-1:-1] == ' '
|
||||
if a[0] == ' '
|
||||
return "\<BS>\<DELETE>"
|
||||
else
|
||||
return "\<BS>"
|
||||
end
|
||||
|
||||
let space = matchstr(nline, '^\s*')
|
||||
return "\<BS>\<DEL>". repeat("\<DEL>", len(space)+1)
|
||||
end
|
||||
return s:backspace(b).s:delete(a)
|
||||
end
|
||||
end
|
||||
endfor
|
||||
|
||||
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')
|
||||
" delete the pair foo[]| <BS> to foo
|
||||
for [open, close, opt] in b:AutoPairsList
|
||||
let m = s:matchend(before, '\V'.open.'\v\s*'.'\V'.close.'\v$')
|
||||
if len(m) > 0
|
||||
return s:backspace(m[2])
|
||||
end
|
||||
endfor
|
||||
return "\<BS>"
|
||||
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('.')]
|
||||
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(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
|
||||
func! AutoPairsFastWrap()
|
||||
let c = @"
|
||||
normal! x
|
||||
let [before, after, ig] = s:getline()
|
||||
if after[0] =~ '\v[\{\[\(\<]'
|
||||
normal! %
|
||||
normal! p
|
||||
else
|
||||
normal he
|
||||
return s:Right.current_char.s:Left
|
||||
for [open, close, opt] in b:AutoPairsList
|
||||
if close == ''
|
||||
continue
|
||||
end
|
||||
if after =~ '^\s*\V'.open
|
||||
call search(close, 'We')
|
||||
normal! p
|
||||
let @" = c
|
||||
return ""
|
||||
end
|
||||
endfor
|
||||
if after[1:1] =~ '\v\w'
|
||||
normal! e
|
||||
normal! p
|
||||
else
|
||||
normal! p
|
||||
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()
|
||||
let pair = b:autopairs_saved_pair[0]
|
||||
let pos = b:autopairs_saved_pair[1]
|
||||
call setpos('.', pos)
|
||||
return pair
|
||||
endf
|
||||
|
||||
func! AutoPairsReturn()
|
||||
if b:autopairs_enabled == 0
|
||||
return ''
|
||||
end
|
||||
let b:autopairs_return_pos = 0
|
||||
let before = getline(line('.')-1)
|
||||
let [ig, ig, afterline] = s:getline()
|
||||
let cmd = ''
|
||||
for [open, close, opt] in b:AutoPairsList
|
||||
if close == ''
|
||||
continue
|
||||
end
|
||||
|
||||
if before =~ '\V'.open.'\v\s*$' && afterline =~ '^\s*\V'.close
|
||||
let b:autopairs_return_pos = line('.')
|
||||
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, opt] in b:AutoPairsList
|
||||
if close == ''
|
||||
continue
|
||||
end
|
||||
if before =~ '\V'.open.'\v$' && after =~ '^\V'.close
|
||||
if close =~ '\v^[''"`]$'
|
||||
return "\<SPACE>"
|
||||
else
|
||||
return "\<SPACE>\<SPACE>".s:Left
|
||||
end
|
||||
end
|
||||
endfor
|
||||
return "\<SPACE>"
|
||||
endf
|
||||
|
||||
func! AutoPairsMap(key)
|
||||
" | is special key which separate map command from text
|
||||
let key = a:key
|
||||
if key == '|'
|
||||
@ -356,9 +451,9 @@ function! AutoPairsMap(key)
|
||||
let escaped_key = substitute(key, "'", "''", 'g')
|
||||
" use expr will cause search() doesn't work
|
||||
execute 'inoremap <buffer> <silent> '.key." <C-R>=AutoPairsInsert('".escaped_key."')<CR>"
|
||||
endfunction
|
||||
endf
|
||||
|
||||
function! AutoPairsToggle()
|
||||
func! AutoPairsToggle()
|
||||
if b:autopairs_enabled
|
||||
let b:autopairs_enabled = 0
|
||||
echo 'AutoPairs Disabled.'
|
||||
@ -367,78 +462,81 @@ function! AutoPairsToggle()
|
||||
echo 'AutoPairs Enabled.'
|
||||
end
|
||||
return ''
|
||||
endfunction
|
||||
endf
|
||||
|
||||
function! AutoPairsReturn()
|
||||
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
|
||||
func! s:sortByLength(i1, i2)
|
||||
return len(a:i2[0])-len(a:i1[0])
|
||||
endf
|
||||
|
||||
" 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()
|
||||
func! AutoPairsInit()
|
||||
let b:autopairs_loaded = 1
|
||||
let b:autopairs_enabled = 1
|
||||
let b:AutoPairsClosedPairs = {}
|
||||
if !exists('b:autopairs_enabled')
|
||||
let b:autopairs_enabled = 1
|
||||
end
|
||||
|
||||
if !exists('b:AutoPairs')
|
||||
let b:AutoPairs = g:AutoPairs
|
||||
let b:AutoPairs = AutoPairsDefaultPairs()
|
||||
end
|
||||
|
||||
if !exists('b:AutoPairsMoveCharacter')
|
||||
let b:AutoPairsMoveCharacter = g:AutoPairsMoveCharacter
|
||||
end
|
||||
|
||||
let b:autopairs_return_pos = 0
|
||||
let b:autopairs_saved_pair = [0, 0]
|
||||
let b:AutoPairsList = []
|
||||
|
||||
" buffer level map pairs keys
|
||||
" n - do not map the first charactor of closed pair to close key
|
||||
" m - close key jumps through multi line
|
||||
" s - close key jumps only in the same line
|
||||
for [open, close] in items(b:AutoPairs)
|
||||
call AutoPairsMap(open)
|
||||
if open != close
|
||||
call AutoPairsMap(close)
|
||||
let o = open[-1:-1]
|
||||
let c = close[0]
|
||||
let opt = {'mapclose': 1, 'multiline':1}
|
||||
let opt['key'] = c
|
||||
if o == c
|
||||
let opt['multiline'] = 0
|
||||
end
|
||||
let b:AutoPairsClosedPairs[close] = open
|
||||
let m = matchlist(close, '\v(.*)//(.*)$')
|
||||
if len(m) > 0
|
||||
if m[2] =~ 'n'
|
||||
let opt['mapclose'] = 0
|
||||
end
|
||||
if m[2] =~ 'm'
|
||||
let opt['multiline'] = 1
|
||||
end
|
||||
if m[2] =~ 's'
|
||||
let opt['multiline'] = 0
|
||||
end
|
||||
let ks = matchlist(m[2], '\vk(.)')
|
||||
if len(ks) > 0
|
||||
let opt['key'] = ks[1]
|
||||
let c = opt['key']
|
||||
end
|
||||
let close = m[1]
|
||||
end
|
||||
call AutoPairsMap(o)
|
||||
if o != c && c != '' && opt['mapclose']
|
||||
call AutoPairsMap(c)
|
||||
end
|
||||
let b:AutoPairsList += [[open, close, opt]]
|
||||
endfor
|
||||
|
||||
" sort pairs by length, longer pair should have higher priority
|
||||
let b:AutoPairsList = sort(b:AutoPairsList, "s:sortByLength")
|
||||
|
||||
for item in b:AutoPairsList
|
||||
let [open, close, opt] = item
|
||||
if open == "'" && open == close
|
||||
let item[0] = '\v(^|\W)\zs'''
|
||||
end
|
||||
endfor
|
||||
|
||||
|
||||
for key in split(b:AutoPairsMoveCharacter, '\s*')
|
||||
let escaped_key = substitute(key, "'", "''", 'g')
|
||||
execute 'inoremap <silent> <buffer> <M-'.key."> <C-R>=AutoPairsMoveCharacter('".escaped_key."')<CR>"
|
||||
endfor
|
||||
|
||||
" Still use <buffer> level mapping for <BS> <SPACE>
|
||||
@ -479,15 +577,30 @@ function! AutoPairsInit()
|
||||
execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
|
||||
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 = substitute(map, '\(<Plug>\w\+\)', '\=maparg(submatch(1), "i")', 'g')
|
||||
let map = substitute(map, '\(<Plug>([^)]*)\)', '\=maparg(submatch(1), "i")', 'g')
|
||||
return map
|
||||
endfunction
|
||||
endf
|
||||
|
||||
function! AutoPairsTryInit()
|
||||
func! AutoPairsTryInit()
|
||||
if exists('b:autopairs_loaded')
|
||||
return
|
||||
end
|
||||
@ -500,9 +613,9 @@ function! AutoPairsTryInit()
|
||||
" 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.
|
||||
" 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
|
||||
@ -550,7 +663,7 @@ function! AutoPairsTryInit()
|
||||
end
|
||||
endif
|
||||
call AutoPairsInit()
|
||||
endfunction
|
||||
endf
|
||||
|
||||
" Always silent the command
|
||||
inoremap <silent> <SID>AutoPairsReturn <C-R>=AutoPairsReturn()<CR>
|
||||
|
Loading…
x
Reference in New Issue
Block a user