Forgiving interactive mode: Do not terminate on invalid input

This commit is contained in:
Junegunn Choi
2013-09-22 21:17:02 +09:00
parent 1d2c58c06a
commit afc95b5ed7
3 changed files with 51 additions and 22 deletions

View File

@@ -143,7 +143,9 @@ function! s:echon(l, n, r, d, o, warn)
\ [['Identifier', a:d == ' ' ? '\ ' : (a:d == '\' ? '\\' : a:d)]])
if a:r == -1 | call add(tokens, ['Comment', ')']) | endif
call add(tokens, ['Statement', empty(a:o) ? '' : ' '.string(a:o)])
call add(tokens, ['WarningMsg', a:warn])
if !empty(a:warn)
call add(tokens, ['WarningMsg', ' ('.a:warn.')'])
endif
call s:echon_(tokens)
endfunction
@@ -561,7 +563,7 @@ function! s:atoi(str)
return (a:str =~ '^[0-9]\+$') ? str2nr(a:str) : a:str
endfunction
function! s:interactive(modes, vis, opts)
function! s:interactive(modes, vis, opts, delims)
let mode = s:shift(a:modes, 1)
let n = ''
let ch = ''
@@ -607,9 +609,21 @@ function! s:interactive(modes, vis, opts)
elseif ch == "\<C-I>"
let opts['idt'] = s:shift(vals['indentation'], 1)
elseif ch == "\<C-L>"
let opts['lm'] = s:atoi(s:input("Left margin: ", get(opts, 'lm', ''), a:vis))
let lm = s:input("Left margin: ", get(opts, 'lm', ''), a:vis)
if empty(lm)
let warn = 'Set to default. Input 0 to remove it'
silent! call remove(opts, 'lm')
else
let opts['lm'] = s:atoi(lm)
endif
elseif ch == "\<C-R>"
let opts['rm'] = s:atoi(s:input("Right margin: ", get(opts, 'rm', ''), a:vis))
let rm = s:input("Right margin: ", get(opts, 'rm', ''), a:vis)
if empty(rm)
let warn = 'Set to default. Input 0 to remove it'
silent! call remove(opts, 'rm')
else
let opts['rm'] = s:atoi(rm)
endif
elseif ch == "\<C-U>"
let opts['iu'] = s:shift(vals['ignore_unmatched'], 1)
elseif ch == "\<C-G>"
@@ -636,24 +650,40 @@ function! s:interactive(modes, vis, opts)
elseif ch == "\<C-_>" || ch == "\<C-X>"
let prompt = 'Regular expression: '
let ch = s:input(prompt, '', a:vis)
if !empty(ch)
let regx = 1
let s:prev_echon_len = len(prompt . ch)
break
endif
elseif ch =~ '[[:print:]]'
if !empty(ch) && s:valid_regexp(ch)
let regx = 1
break
else
let warn = ' - Invalid character'
let warn = 'Invalid regular expression: '.ch
endif
elseif ch =~ '[[:print:]]'
if has_key(a:delims, ch)
break
else
let warn = 'Unknown delimiter key: '.ch
endif
else
let warn = 'Invalid character'
endif
endwhile
return [mode, n, ch, s:normalize_options(opts), regx]
endfunction
function! s:test_regexp(regexp)
try | call matchlist('', a:regexp)
catch | call s:exit("Invalid regular expression: ". a:regexp)
function! s:valid_regexp(regexp)
try
call matchlist('', a:regexp)
catch
return 0
endtry
return 1
endfunction
function! s:test_regexp(regexp)
if !s:valid_regexp(a:regexp)
call s:exit('Invalid regular expression: '. a:regexp)
endif
return a:regexp
endfunction
function! s:parse_args(args)
@@ -700,7 +730,7 @@ function! s:parse_args(args)
" Found regexp
if !empty(matches)
return [matches[1], matches[2], opts, 1]
return [matches[1], s:test_regexp(matches[2]), opts, 1]
else
let tokens = matchlist(args, '^\([1-9][0-9]*\|-[0-9]*\|\*\*\?\)\?\s*\(.\{-}\)\?$')
return [tokens[1], tokens[2], opts, 0]
@@ -735,12 +765,17 @@ function! s:align(bang, first_line, last_line, expr)
" Heuristically determine if the user was in visual mode
let vis = a:first_line == line("'<") && a:last_line == line("'>")
let delimiters = s:easy_align_delimiters_default
if exists('g:easy_align_delimiters')
let delimiters = extend(copy(delimiters), g:easy_align_delimiters)
endif
if empty(a:expr)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts, delimiters)
else
let [n, ch, opts, regexp] = s:parse_args(a:expr)
if empty(n) && empty(ch)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts, delimiters)
elseif empty(ch)
" Try swapping n and ch
let [n, ch] = ['', n]
@@ -757,13 +792,7 @@ function! s:align(bang, first_line, last_line, expr)
let nth = n
endif
let delimiters = s:easy_align_delimiters_default
if exists('g:easy_align_delimiters')
let delimiters = extend(copy(delimiters), g:easy_align_delimiters)
endif
if regexp
call s:test_regexp(ch)
let dict = { 'pattern': ch }
else
" Resolving command-line ambiguity

View File

@@ -1 +1 @@
4Gvipjyvip
4Gvipjyvip

View File

@@ -1 +1 @@
4Gvipjyvip:EasyAlign:
4Gvipjyvip:EasyAlign: