Allow custom regex for smart_quotes. Close #164.

- Use search() to match on the current line and remove most of the old
  code in IsSmartQuote().
- Allow using ! to negate the pattern.
- Add tests.
- s:s() :unlet variables before setting them.
This commit is contained in:
Israel Chauca Fuentes
2014-11-26 15:03:00 -05:00
parent 38487bbec8
commit 66834e7209
4 changed files with 71 additions and 22 deletions

View File

@@ -20,11 +20,12 @@ function! s:s(name, value, ...) "{{{
let s:options[bufnr] = {}
endif
if scope == 's'
let name = 'options.' . bufnr . '.' . a:name
let name = 's:options.' . bufnr . '.' . a:name
else
let name = 'delimitMate_' . a:name
let name = scope . ':delimitMate_' . a:name
endif
exec 'let ' . scope . ':' . name . ' = a:value'
exec 'silent! unlet! ' . name
exec 'let ' . name . ' = a:value'
endfunction "}}}
function! s:g(name, ...) "{{{
@@ -293,19 +294,18 @@ function! delimitMate#BalancedParens(char) "{{{
endfunction "}}}
function! delimitMate#IsSmartQuote(char) "{{{
if !s:g('smart_quotes')
" TODO: Allow using a:char in the pattern.
let tmp = s:g('smart_quotes')
if empty(tmp)
return 0
endif
let char_at = delimitMate#GetCharFromCursor(0)
let char_before = delimitMate#GetCharFromCursor(-1)
let valid_char_re = '\w\|[^[:punct:][:space:]]'
let word_before = char_before =~ valid_char_re
let word_at = char_at =~ valid_char_re
let escaped = delimitMate#CursorIdx() >= 1
\ && delimitMate#GetCharFromCursor(-1) == '\'
let regex = matchstr(tmp, '^!\?\zs.*')
" Flip matched value if regex starts with !
let mod = tmp =~ '^!' ? [1, 0] : [0, 1]
let matched = search(regex, 'ncb', line('.')) > 0
let noescaped = substitute(getline('.'), '\\.', '', 'g')
let odd = (count(split(noescaped, '\zs'), a:char) % 2)
let result = word_before || escaped || word_at || odd
let result = mod[matched] || odd
return result
endfunction "delimitMate#SmartQuote }}}
@@ -391,7 +391,7 @@ function! delimitMate#QuoteDelim(char) "{{{
" Seems like a smart quote, insert a single char.
return a:char
elseif (char_before == a:char && char_at != a:char)
\ && s:g('smart_quotes')
\ && !empty(s:g('smart_quotes'))
" Seems like we have an unbalanced quote, insert one quotation
" mark and jump to the middle.
return a:char . "\<Left>"

View File

@@ -240,14 +240,25 @@ e.g.: >
------------------------------------------------------------------------------
*'delimitMate_smart_quotes'*
*'b:delimitMate_smart_quotes'*
Values: 1 or 0 ~
Default: 1 ~
Values: String with an optional ! at the beginning followed by a regexp ~
Default: '\%(\w\|[^[:punct:][:space:]]\|\%(\\\\\)*\\\)\%#\|\%#\w' ~
A bang (!) at the beginning is removed and used to "negate" the pattern. The
remaining text is used as a regexp to be matched on the current line. A single
quote is inserted when the pattern matches and a bang is not present. The bang
changes that, so a single quote is inserted only if the regexp does not match.
This feature is disabled when the variable is set to an empty string, with the
exception of apostrophes.
Note that you need to use '\%#' to match the position of the cursor. Keep in
mind that '\%#' matches with zero width, so if you need to match the char
under the cursor (which would be the one to the right on insert mode) use
something like '\%#.'.
This option turns on/off the smart quotes feature. Read
|delimitMateSmartQuotes| for details.
e.g.: >
let delimitMate_smart_quotes = 0
au FileType tcl let b:delimitMate_smart_quotes = 1
let delimitMate_smart_quotes = '\w\%#'
au FileType tcl let b:delimitMate_smart_quotes = '!\s\%#\w'
<
------------------------------------------------------------------------------
*'delimitMate_smart_matchpairs'*
@@ -449,8 +460,8 @@ e.g. typing at the "|": >
Only one quote will be inserted following a quote, a "\", following or
preceding a keyword character, or when the number of quotes in the current
line is odd. This should cover closing quotes after a string, opening quotes
before a string, escaped quotes and apostrophes. Except for apostrophes, this
feature can be disabled setting the option |'delimitMate_smart_quotes'| to 0.
before a string, escaped quotes and apostrophes. See more details about
customizing this feature on |'delimitMate_smart_quotes'|.
e.g. typing at the "|": >
@@ -740,6 +751,7 @@ This script was inspired by the auto-completion of delimiters on TextMate.
- Reduce the number of mappings.
- Stop using setline().
- Better handling of nested quotes.
- Allow a custom pattern for smart_quotes.
|---------|------------|-----------------------------------------------------|
2.6 2011-01-14 * - Add smart_matchpairs feature.
- Add mapping to jump over contiguous delimiters.

View File

@@ -107,7 +107,28 @@ function! s:init() "{{{
" smart_matchpairs
call s:option_init("smart_matchpairs", '^\%(\w\|\!\|£\|\$\|_\|["'']\s*\S\)')
" smart_quotes
call s:option_init("smart_quotes", 1)
" XXX: backward compatibility. Ugly, should go the way of the dodo soon.
let default_smart_quotes = '\%(\w\|[^[:punct:][:space:]]\|\%(\\\\\)*\\\)\%#\|\%#\%(\w\|[^[:space:][:punct:]]\)'
if exists('g:delimitMate_smart_quotes') && type(g:delimitMate_smart_quotes) == type(0)
if g:delimitMate_smart_quotes
unlet g:delimitMate_smart_quotes
else
unlet g:delimitMate_smart_quotes
let g:delimitMate_smart_quotes = ''
endif
endif
if exists('b:delimitMate_smart_quotes') && type(b:delimitMate_smart_quotes) == type(0)
if b:delimitMate_smart_quotes
unlet b:delimitMate_smart_quotes
if exists('g:delimitMate_smart_quotes') && type(g:delimitMate_smart_quotes) && g:delimitMate_smart_quotes
let b:delimitMate_smart_quotes = default_smart_quotes
endif
else
unlet b:delimitMate_smart_quotes
let b:delimitMate_smart_quotes = ''
endif
endif
call s:option_init("smart_quotes", default_smart_quotes)
" apostrophes
call s:option_init("apostrophes", "")
call s:option_init("apostrophes_list", split(s:g('apostrophes'), ":\s*"))

View File

@@ -38,6 +38,8 @@ set cpo=ces$
"'x" "'x'"
# Make sure smart quote works beyond first column.
" 'x" " 'x'"
# smart quote, check fo char on the right.
"a\<space>b\<left>'" "a 'b"
# Make sure we jump over a quote on the right. #89.
"('test'x" "('test'x)"
# Duplicate whole line when inserting quote at bol #105
@@ -54,3 +56,17 @@ unlet g:delimitMate_nesting_quotes
# expand iabbreviations
iabb def ghi
"def'" "ghi'"
let g:delimitMate_smart_quotes = '\w\%#\_.'
"xyz'x" "xyz'x"
"xyz 'x" "xyz 'x'"
let g:delimitMate_smart_quotes = '\s\%#\_.'
"abc'x" "abc'x'"
"abc 'x" "abc 'x"
# let's try the negated form
let g:delimitMate_smart_quotes = '!\w\%#\_.'
"cba'x" "cba'x'"
"cba 'x" "cba 'x"
let g:delimitMate_smart_quotes = '!\s\%#\_.'
"zyx'x" "zyx'x"
"zyx 'x" "zyx 'x'"
unlet g:delimitMate_smart_quotes