mirror of
https://github.com/Raimondi/delimitMate.git
synced 2025-12-06 12:44:27 +08:00
Add support for quotes and a couple of other things.
This commit is contained in:
@@ -7,6 +7,10 @@ let s:defaults.delimitMate_expand_space = 0
|
||||
let s:defaults.delimitMate_smart_pairs = 1
|
||||
let s:defaults.delimitMate_smart_pairs_extra = []
|
||||
let s:defaults.delimitMate_balance_pairs = 0
|
||||
let s:defaults.delimitMate_nesting_quotes = []
|
||||
let s:defaults.delimitMate_smart_quotes = 1
|
||||
let s:defaults.delimitMate_smart_quotes_extra = []
|
||||
let s:defaults.delimitMate_excluded_regions = ['String', 'Comment']
|
||||
|
||||
" Set smart_pairs expressions:
|
||||
let s:exprs = []
|
||||
@@ -15,6 +19,19 @@ call add(s:exprs, 'next_char =~# "[".escape(v:char,"\\^]")."€£$]"')
|
||||
call add(s:exprs, 'ahead =~# "^[^[:space:][:punct:]]"')
|
||||
let s:defaults.delimitMate_smart_pairs_base = s:exprs
|
||||
|
||||
" Set smart_quotes expressions:
|
||||
let s:exprs = []
|
||||
call add(s:exprs, 'prev_char =~# "\\w"')
|
||||
call add(s:exprs, 'prev_char =~# "[^[:space:][:punct]".escape(join(options.quotes, ""), "\\^[]")."]"')
|
||||
call add(s:exprs, 'next_char =~# "\\w"')
|
||||
call add(s:exprs, 'next_char =~# "[^[:space:][:punct]".escape(join(options.quotes, ""), "\\^[]")."]"')
|
||||
" Balance quotes
|
||||
call add(s:exprs, 'strchars(substitute(substitute(a:info.cur.text, "\\\\.", "", "g"), "[^".escape(char, "\\^[]")."]", "", "g")) % 2')
|
||||
|
||||
let s:defaults.delimitMate_smart_quotes_base = s:exprs
|
||||
|
||||
unlet s:exprs
|
||||
|
||||
function! s:defaults.consolidate()
|
||||
let g = filter(copy(g:), 'v:key =~# "^delimitMate_"')
|
||||
let b = filter(copy(b:), 'v:key =~# "^delimitMate_"')
|
||||
@@ -70,6 +87,14 @@ function! s:option(name, ...)
|
||||
return opt
|
||||
endfunction
|
||||
|
||||
function! delimitMate#option(name)
|
||||
return s:option(a:name)
|
||||
endfunction
|
||||
|
||||
function! s:synstack(lnum, col)
|
||||
return map(synstack(a:lnum, a:col), 'synIDattr(v:val, "name")') + [synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name')]
|
||||
endfunction
|
||||
|
||||
function! delimitMate#ex_cmd(global, action)
|
||||
let scope = a:global ? g: : b:
|
||||
if a:action ==# 'enable'
|
||||
@@ -83,6 +108,7 @@ endfunction
|
||||
|
||||
function! delimitMate#InsertCharPre(str)
|
||||
if s:info.skip_icp
|
||||
" iabbrev fires this event for every char and the trigger
|
||||
echom 11
|
||||
return 0
|
||||
endif
|
||||
@@ -91,6 +117,10 @@ function! delimitMate#InsertCharPre(str)
|
||||
echom 12
|
||||
return 0
|
||||
endif
|
||||
if !empty(filter(s:option('excluded_regions'), 'index(s:synstack(line("."), col(".")), v:val) >= 0'))
|
||||
echom 13
|
||||
return 0
|
||||
endif
|
||||
return map(split(a:str, '\zs'), 's:handle_vchar(v:val)')
|
||||
endfunction
|
||||
|
||||
@@ -109,7 +139,7 @@ function! s:handle_vchar(str)
|
||||
return 0
|
||||
elseif !empty(filter(copy(opts.quotes), 'v:val ==# a:str'))
|
||||
echom 15
|
||||
return 0
|
||||
let keys = s:keys4quote(a:str, s:info, opts)
|
||||
elseif !empty(filter(copy(opts.pairs), 'strcharpart(v:val, 0, 1) ==# a:str'))
|
||||
echom 16
|
||||
let pair = get(filter(copy(opts.pairs), 'strcharpart(v:val, 0, 1) ==# a:str'), 0, '')
|
||||
@@ -169,6 +199,40 @@ function! s:keys4right(char, pair, info, opts)
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:keys4quote(char, info, opts)
|
||||
let quotes_behind = strchars(matchstr(a:info.cur.behind, '['.escape(a:char, '\^[]').']*$'))
|
||||
let quotes_ahead = strchars(matchstr(a:info.cur.ahead, '^['.escape(a:char, '\^[]').']*'))
|
||||
echom 'k4q: ' quotes_behind . ' - ' . quotes_ahead
|
||||
echom string(a:opts.nesting_quotes)
|
||||
if a:opts.autoclose && index(a:opts.nesting_quotes, a:char) >= 0
|
||||
\&& quotes_behind > 1
|
||||
let add2right = quotes_ahead > quotes_behind + 1 ? 0 : quotes_behind - quotes_ahead + 1
|
||||
echom 51
|
||||
echom add2right
|
||||
return repeat(a:char, add2right) . repeat("\<C-G>U\<Left>", add2right)
|
||||
endif
|
||||
if a:info.cur.n_char ==# a:char
|
||||
echom 53
|
||||
return "\<Del>"
|
||||
endif
|
||||
let exprs = a:opts.smart_quotes_base + a:opts.smart_quotes_extra
|
||||
if a:opts.autoclose && a:opts.smart_quotes
|
||||
\&& s:any_is_true(exprs, a:info, a:opts)
|
||||
echom 52
|
||||
return ''
|
||||
endif
|
||||
if !a:opts.autoclose && quotes_behind
|
||||
echom 54
|
||||
return "\<Left>"
|
||||
endif
|
||||
if !a:opts.autoclose
|
||||
echom 55
|
||||
return ''
|
||||
endif
|
||||
echom 59
|
||||
return a:char . "\<C-G>U\<Left>"
|
||||
endfunction
|
||||
|
||||
function! s:get_info(...)
|
||||
if a:0
|
||||
let d = a:1
|
||||
@@ -189,6 +253,7 @@ function! s:get_info(...)
|
||||
endfunction
|
||||
|
||||
function! s:any_is_true(expressions, info, options)
|
||||
let char = a:info.char
|
||||
let info = deepcopy(a:info)
|
||||
let options = deepcopy(a:options)
|
||||
let line = info.cur.text
|
||||
@@ -248,7 +313,8 @@ function! s:is_bs()
|
||||
return feedkeys("\<Del>", 'tni')
|
||||
endif
|
||||
let pair = filter(s:option('pairs'), 'v:val ==# s:info.prev.around')
|
||||
if empty(pair)
|
||||
let quote = filter(s:option('quotes'), 'v:val . v:val ==# s:info.prev.around')
|
||||
if empty(pair) && empty(quote)
|
||||
echom 26
|
||||
return
|
||||
endif
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
if exists("g:loaded_delimitMate") || &cp
|
||||
if exists("g:loaded_delimitMate") || &cp || v:version < 800
|
||||
finish
|
||||
endif
|
||||
let g:loaded_delimitMate = 1
|
||||
let save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if v:version < 800
|
||||
echohl ErrorMsg
|
||||
echom "delimitMate: this plugin requires vim 8.0 or later!"
|
||||
echohl None
|
||||
finish
|
||||
endif
|
||||
|
||||
command! -bar -bang DelimitMateSwitch call delimitMate#ex_cmd(<bang>0,'switch')
|
||||
command! -bar -bang DelimitMateOn call delimitMate#ex_cmd(<bang>0,'enable')
|
||||
command! -bar -bang DelimitMateOff call delimitMate#ex_cmd(<bang>0,'disable')
|
||||
|
||||
@@ -37,6 +37,9 @@ endfunction
|
||||
"function! DMTest_single(setup, typed, expected[, skip_expr[, todo_expr]])
|
||||
" Runs a single test (add 1 to vimtap#Plan())
|
||||
function! DMTest_single(setup, typed, expected, ...)
|
||||
if type(a:typed) != v:t_list
|
||||
return vimtap#Fail('Second argument should be a list: ' . a:typed)
|
||||
end
|
||||
if type(a:setup) == v:t_list
|
||||
let setup = copy(a:setup)
|
||||
else
|
||||
@@ -67,6 +70,9 @@ function! DMTest_single(setup, typed, expected, ...)
|
||||
endfunction
|
||||
|
||||
function! s:do_set(pat, sub, set, setup, typed, expected, ...)
|
||||
if type(a:typed) != v:t_list
|
||||
return vimtap#Fail('Second argument should be a list: ' . string(a:typed))
|
||||
end
|
||||
let skip_expr = get(a:, '1', '')
|
||||
let todo_expr = get(a:, '2', '')
|
||||
let escaped = '\.*^$'
|
||||
@@ -102,7 +108,7 @@ endfunction
|
||||
function! DMTest_pairs(setup, typed, expected, ...)
|
||||
let skip_expr = get(a:, '1', '')
|
||||
let todo_expr = get(a:, '2', '')
|
||||
let pairs = ['()','{}','[]','<>','¿?','¡!',',:'] "delimitMate#options('pairs')
|
||||
let pairs = delimitMate#option('pairs')
|
||||
let pat = '[()]'
|
||||
let sub = '\=submatch(0) == "(" ? left : right'
|
||||
return s:do_set(pat, sub, pairs, a:setup, a:typed, a:expected, skip_expr, todo_expr)
|
||||
@@ -113,7 +119,7 @@ endfunction
|
||||
function! DMTest_quotes(setup, typed, expected, ...)
|
||||
let skip_expr = get(a:, '1', '')
|
||||
let todo_expr = get(a:, '2', '')
|
||||
let quotes = ['"', "'", '`', '«', '|'] "delimitMate#options('quotes')
|
||||
let quotes = delimitMate#option('quotes')
|
||||
let pat = "'"
|
||||
let sub = 'quote'
|
||||
return s:do_set(pat, sub, quotes, a:setup, a:typed, a:expected, skip_expr, todo_expr)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
" - Add 5 to vimtap#Plan().
|
||||
|
||||
call vimtest#StartTap()
|
||||
call vimtap#Plan(224)
|
||||
call vimtap#Plan(210)
|
||||
|
||||
let g:delimitMate_matchpairs = '(:),{:},[:],<:>,¿:?,¡:!,,::'
|
||||
let g:delimitMate_autoclose = 1
|
||||
|
||||
@@ -11,94 +11,67 @@
|
||||
" - Add 5 to vimtap#Plan().
|
||||
|
||||
call vimtest#StartTap()
|
||||
call vimtap#Plan(230)
|
||||
call vimtap#Plan(140)
|
||||
|
||||
let g:delimitMate_quotes = '" '' ` « |'
|
||||
let g:delimitMate_autoclose = 1
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "'x", "'x'")
|
||||
call DMTest_quotes('', "'x\<Esc>u", "")
|
||||
call DMTest_quotes('', "''x", "''x")
|
||||
call DMTest_quotes('', "'\<BS>x", "x")
|
||||
call DMTest_quotes('', "'\<C-G>gx", "''x")
|
||||
call DMTest_quotes('', ["i'", "ax"], "'x'")
|
||||
call DMTest_quotes('', ["i'x", "u"], "")
|
||||
call DMTest_quotes('', ["i'", "a'", "ax"], "''x", 'a:typed[0] == "i«"')
|
||||
call DMTest_quotes('', ["a'", "a\<BS>", "ax"], "x")
|
||||
"call DMTest_quotes('', "'\<C-G>gx", "''x")
|
||||
" This will fail for double quote.
|
||||
call DMTest_quotes('', "'\"x", "'\"x\"'", "a:typed == '\"\"x'")
|
||||
call DMTest_quotes('', "@'x", "@'x'")
|
||||
call DMTest_quotes('', "@#\<Left>'x", "@'x'#")
|
||||
call DMTest_quotes('', "'\<S-Tab>x", "''x")
|
||||
call DMTest_quotes('', "abc'", "abc'")
|
||||
call DMTest_quotes('', "abc\\'x", "abc\\'x")
|
||||
call DMTest_quotes('', "u'Привет'", "u'Привет'")
|
||||
call DMTest_quotes('', "u'string'", "u'string'")
|
||||
call DMTest_quotes('', ["i'", "a\"", "ax"], "'\"x\"'", 'a:typed[0] =~ "i[\"«]"')
|
||||
call DMTest_quotes('', ["i@", "a'", "ax"], "@'x'")
|
||||
call DMTest_quotes('', ["i@#", "i'", "ax"], "@'x'#")
|
||||
"call DMTest_quotes('', "'\<S-Tab>x", "''x")
|
||||
call DMTest_quotes('', ["iabc", "a'"], "abc'")
|
||||
call DMTest_quotes('abc\', ["A'", "ax"], "abc\\'x")
|
||||
" TODO find out why this test doesn't work when it does interactively.
|
||||
call DMTest_quotes('', ["au", "a'", "aПривет", "a'"], "u'Привет'", '', 1)
|
||||
call DMTest_quotes('', ["au", "a'", "astring", "a'"], "u'string'")
|
||||
let g:delimitMate_autoclose = 0
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "'x", "'x")
|
||||
call DMTest_quotes('', "''x", "'x'")
|
||||
call DMTest_quotes('', "'''x", "''x")
|
||||
call DMTest_quotes('', "''\<BS>x", "x")
|
||||
call DMTest_quotes('', "@''x", "@'x'")
|
||||
call DMTest_quotes('', "@#\<Left>''x", "@'x'#")
|
||||
let g:delimitMate_expand_space = 1
|
||||
call DMTest_quotes('', ["a'", "ax"], "'x")
|
||||
call DMTest_quotes('', ["a'", "a'", "ax"], "'x'")
|
||||
call DMTest_quotes('', ["a'", "a'", "a'", "ax"], "''x")
|
||||
call DMTest_quotes('', ["a'", "a'", "a\<BS>", "ax"], "x")
|
||||
call DMTest_quotes('', ["a@", "a'", "a'", "ax"], "@'x'")
|
||||
call DMTest_quotes('', ["a@#", "i'", "a'", "ax"], "@'x'#")
|
||||
let g:delimitMate_autoclose = 1
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "'\<Space>x", "' x'")
|
||||
let g:delimitMate_expand_inside_quotes = 1
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "'\<Space>x", "' x '")
|
||||
call DMTest_quotes('', "'\<Space>\<BS>x", "'x'")
|
||||
call DMTest_quotes('', "abc\\''\<Space>x", "abc\\' x'")
|
||||
let g:delimitMate_autoclose = 0
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "''\<Space>\<BS>x", "'x'")
|
||||
let g:delimitMate_autoclose = 1
|
||||
DelimitMateReload
|
||||
"let g:delimitMate_expand_space = 1
|
||||
"call DMTest_quotes('', "'\<Space>x", "' x'")
|
||||
"let g:delimitMate_expand_inside_quotes = 1
|
||||
"call DMTest_quotes('', "'\<Space>x", "' x '")
|
||||
"call DMTest_quotes('', "'\<Space>\<BS>x", "'x'")
|
||||
"call DMTest_quotes('', "abc\\''\<Space>x", "abc\\' x'")
|
||||
"let g:delimitMate_autoclose = 0
|
||||
"call DMTest_quotes('', "''\<Space>\<BS>x", "'x'")
|
||||
"let g:delimitMate_autoclose = 1
|
||||
" Handle backspace gracefully.
|
||||
set backspace=
|
||||
call DMTest_quotes('', "'\<Esc>a\<BS>x", "'x'")
|
||||
call DMTest_quotes('', ["a'", "a\<BS>", "ax"], "'x'")
|
||||
set backspace=2
|
||||
set cpo=ces$
|
||||
call DMTest_quotes('', "'x", "'x'")
|
||||
"set cpo=ces$
|
||||
"call DMTest_quotes('', "'x", "'x'")
|
||||
" Make sure smart quote works beyond first column.
|
||||
call DMTest_quotes('', " 'x", " 'x'")
|
||||
call DMTest_quotes(' ', ["a'", "ax"], " 'x'")
|
||||
" smart quote, check fo char on the right.
|
||||
call DMTest_quotes('', "a\<space>b\<left>'", "a 'b")
|
||||
call DMTest_quotes('a b', ["la'"], "a 'b")
|
||||
" Make sure we jump over a quote on the right. #89.
|
||||
call DMTest_quotes('', "('test'x", "('test'x)")
|
||||
call DMTest_quotes('', ["a(", "a'", "atest", "a'", "ax"], "('test'x)")
|
||||
" Duplicate whole line when inserting quote at bol #105
|
||||
call DMTest_quotes('', "}\<Home>'", "''}")
|
||||
call DMTest_quotes('', "'\<Del>abc '", "'abc '")
|
||||
call DMTest_quotes('', "''abc '", "''abc ''")
|
||||
" Nesting quotes:
|
||||
let g:delimitMate_nesting_quotes = split(g:delimitMate_quotes, '\s\+')
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "'''x", "'''x'''")
|
||||
call DMTest_quotes('', "''''x", "''''x''''")
|
||||
call DMTest_quotes('', "''x", "''x")
|
||||
call DMTest_quotes('', "'x", "'x'")
|
||||
call DMTest_quotes('}', ["i'"], "''}")
|
||||
call DMTest_quotes("'abc ", ["A'"], "'abc '")
|
||||
call DMTest_quotes("''abc ", ["A'"], "''abc ''")
|
||||
"" Nesting quotes:
|
||||
let g:delimitMate_nesting_quotes = delimitMate#option('quotes')
|
||||
call DMTest_quotes("'' ", ["la'\<Right>", "ix"], "'''x''' ")
|
||||
call DMTest_quotes("''' ", ["lla'\<Right>", "ix"], "''''x'''' ")
|
||||
call DMTest_quotes(' ', ["i'", "a'\<Right>", "ix"], "''x ")
|
||||
call DMTest_quotes('', ["i'", "ax"], "'x'")
|
||||
unlet g:delimitMate_nesting_quotes
|
||||
DelimitMateReload
|
||||
" expand iabbreviations
|
||||
iabb def ghi
|
||||
call DMTest_quotes('', "def'", "ghi'")
|
||||
let g:delimitMate_smart_quotes = '\w\%#\_.'
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "xyz'x", "xyz'x")
|
||||
call DMTest_quotes('', "xyz 'x", "xyz 'x'")
|
||||
let g:delimitMate_smart_quotes = '\s\%#\_.'
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "abc'x", "abc'x'")
|
||||
call DMTest_quotes('', "abc 'x", "abc 'x")
|
||||
" let's try the negated form
|
||||
let g:delimitMate_smart_quotes = '!\w\%#\_.'
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "cba'x", "cba'x'")
|
||||
call DMTest_quotes('', "cba 'x", "cba 'x")
|
||||
let g:delimitMate_smart_quotes = '!\s\%#\_.'
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "zyx'x", "zyx'x")
|
||||
call DMTest_quotes('', "zyx 'x", "zyx 'x'")
|
||||
unlet g:delimitMate_smart_quotes
|
||||
DelimitMateReload
|
||||
call DMTest_quotes('', "'\<CR>\<BS>", "''")
|
||||
"" expand iabbreviations
|
||||
"iabb def ghi
|
||||
"call DMTest_quotes('', "def'", "ghi'")
|
||||
"call DMTest_quotes('', "'\<CR>\<BS>", "''")
|
||||
|
||||
call vimtest#Quit()
|
||||
|
||||
Reference in New Issue
Block a user