diff --git a/autoload/easy_align.vim b/autoload/easy_align.vim index c0a5a66..0a618ad 100644 --- a/autoload/easy_align.vim +++ b/autoload/easy_align.vim @@ -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 == "\" let opts['idt'] = s:shift(vals['indentation'], 1) elseif ch == "\" - 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 == "\" - 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 == "\" let opts['iu'] = s:shift(vals['ignore_unmatched'], 1) elseif ch == "\" @@ -636,24 +650,40 @@ function! s:interactive(modes, vis, opts) elseif ch == "\" || ch == "\" let prompt = 'Regular expression: ' let ch = s:input(prompt, '', a:vis) - if !empty(ch) + let s:prev_echon_len = len(prompt . ch) + if !empty(ch) && s:valid_regexp(ch) let regx = 1 - let s:prev_echon_len = len(prompt . ch) break + else + let warn = 'Invalid regular expression: '.ch endif elseif ch =~ '[[:print:]]' - break + if has_key(a:delims, ch) + break + else + let warn = 'Unknown delimiter key: '.ch + endif else - let warn = ' - Invalid character' + 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 diff --git a/test/basic.script b/test/basic.script index 946899c..3057f2d 100644 --- a/test/basic.script +++ b/test/basic.script @@ -1 +1 @@ -4Gvipjyvip Pvip 2 Pvip * Pvip Pvip 2 Pvip * Pvip ** Pvip - Pvip -2 Pvip -1 Pvip ** 60zzvipjyvip *|Pvip *|Pvip **|80zzvip **|gv 3|vip *|90zzvip *,100zzvipjyvip =Pvip *=Pvip **=Pvip =vip 2=198Gvipjyvip =Pvip -=Pf:jj3E =209Gvip - 214zzvipjyvip #P:let g:easy_align_delimiters = { '#': {'pattern': '#\+', 'ignore_groups': ['String'] } } vip #227zzvip :239zzvip *=vipjyP:let g:easy_align_ignore_groups = [] vip *=:unlet g:easy_align_delimiters :unlet g:easy_align_ignore_groups 4Gvipy4GP7Gojkkvip:EasyAlign /1/{'ml':'{{', 'mr-r':'}}'} vipjyPvip:EasyAlign */../ 263zzvipjygv .Pvip *.Pvip * .Pvip .vip 2.Pvip **.Pvip **.Pvip -.G303zzvip .310zzvipjygv *|Pvip *|Pvip |gv -|gv **|gv *|gv **|jji jjjhi vip ** |339Gpvip:EasyAlign*|{'ml': 5, 'mrr': 0 } 349Gpvip:EasyAlign*/|/{'ml':'~', 'mrr': 4} 362G:let g:easy_align_delimiters = { 'd': { 'pattern': '\s\+\(\S\+\s*[;=]\)\@=', 'left_margin': 0, 'right_margin': 0 } } vip dgv =236GvipjyPvip :377Gvip gv 2 382Gvipjyvip:EasyAlign/-\+/ Pvip:EasyAlign2/-\+/ Pvip:EasyAlign*/-\+/ Pvip:EasyAlign*/-\+/{'da': L} Pvip:EasyAlign/-\+/{'da': c} Pvip:EasyAlign*/-\+/{'delimiter_align':'C'} Pvip:EasyAlign*/-\+/{'da': 'x'} 381Gpvip:EasyAlign/-\+/{'da':r} :let g:easy_align_delimiter_align = 'l' Pvip:EasyAlign/-\+/ Pvip:EasyAlign*/-\+/ :unlet g:easy_align_delimiter_align :let g:easy_align_delimiters['\'] = { 'pattern': '-\+', 'delimiter_align': 'c' } Pvip \Pvip *-vip *\Pvip:EasyAlign *\\ {'da':l} Pvip:EasyAlign*\\ Pvip:EasyAlign*\\{'da': 'R'} 377GvipjyPvip:EasyAlign\ {'l': '@@@'} gv:EasyAlign 2 \ {'l': '{{{'} 507Gvipjygv:EasyAlign= Pvip:EasyAlign = {'idt': s} Pvip:EasyAlign= {'idt': d} Pvip:EasyAlign**={'indentation': 'd'} Pvip:EasyAlign!= Pvip:EasyAlign! **= {'indent': s} Pvip:EasyAlign!* = {'idt': D} Pvip:EasyAlign! ={'idt':'S'} 507GPvip:EasyAlign-={'idt':d} PA = 2j.j.j.j.vip:EasyAlign2={'idt': s} 507GPljjjj$:EasyAlign = {'idt': s} Pljjjj$:EasyAlign={'indent':d} Phhxxvip:EasyAlign={'idt':'s'} 525Gvipjy507GPPvip:EasyAlign*={'idt':s} Pvip:EasyAlign!**={'idt':s} Pvip:EasyAlign = {'idt': D} 525G^hhr1jr1jr1jr1jr1llkkkk$:EasyAlign = { 'idt': s } 513GvipjyPvip:EasyAlign*={'idt':n} Pvip:EasyAlign = { 'idt': N } Pvip:EasyAlign!*= {'idt': 'n'} 630Gvipjygv =Pvip =656Gvipjygv =Pvip *=Pvip **=Pvip **=Pvip:EasyAlign**= {'iu':0} Pvip =vip 2=vip -0 =818Gvipjygv =Pvip 2=Pvip *=Pvip **=Pvip **=Pvip -0=Pvip -0=855Gvip ** 860Gvip 2=}863Gvip 2=866Gvip 2=869Gvip 2=872Gvip *=875Gvip 2 878Gvip 2 881Gvip:EasyAlign**={'m': 'c','idt':s} ggjjj70Gvipjy883Gpvip *|vipjy893Gpvip:EasyAlign*|{'m': 'lcr'} 903Gpvip:EasyAlign**|{'m':'llc'} 913Gpvip:s/^|// vip:EasyAlign*|{'idt':n} vip:EasyAlign**|{'m':'cl'} 107GvipjyPvip  *=Pvip  *=975GVj 2=978Gvipjygv =Pvip =Pvip =Pvip =Pvip 2=993Gvip =996Gvip =999Gvip =1002Gvip =vipjyPvip =Pvip =1023Gvip =1026Gvip =1030Gvip =1033Gvip =1036Gvip 3=vipjyPvip 2=1044Gvip *,1052Gvipjygv:EasyAlign{'m':'lrc*'} 3 Pvip:EasyAlign{'mode_seq':'lrc**'} 2 Pvip:EasyAlign{'ms':'lccr**'} +4Gvipjyvip Pvip 2 Pvip * Pvip Pvip 2 Pvip * Pvip ** Pvip - Pvip -2 Pvip -1 Pvip ** 60zzvipjyvip *|Pvip *|Pvip **|80zzvip **|gv 3|vip *|90zzvip *,100zzvipjyvip =Pvip *=Pvip **=Pvip =vip 2=198Gvipjyvip =Pvip -=Pf:jj3E =209Gvip - 214zzvipjyvip #P:let g:easy_align_delimiters = { '#': {'pattern': '#\+', 'ignore_groups': ['String'] } } vip #227zzvip :239zzvip *=vipjyP:let g:easy_align_ignore_groups = [] vip *=:unlet g:easy_align_delimiters :unlet g:easy_align_ignore_groups 4Gvipy4GP7Gojkkvip:EasyAlign /1/{'ml':'{{', 'mr-r':'}}'} vipjyPvip:EasyAlign */../ 263zzvipjygv .Pvip *.Pvip * .Pvip .vip 2.Pvip **.Pvip **.Pvip -.G303zzvip .310zzvipjygv *|Pvip *|Pvip |gv -|gv **|gv *|gv **|jji jjjhi vip ** |339Gpvip:EasyAlign*|{'ml': 5, 'mrr': 0 } 349Gpvip:EasyAlign*/|/{'ml':'~', 'mrr': 4} 362G:let g:easy_align_delimiters = { 'd': { 'pattern': '\s\+\(\S\+\s*[;=]\)\@=', 'left_margin': 0, 'right_margin': 0 } } vip dgv =236GvipjyPvip :377Gvip gv 2 382Gvipjyvip:EasyAlign/-\+/ Pvip:EasyAlign2/-\+/ Pvip:EasyAlign*/-\+/ Pvip:EasyAlign*/-\+/{'da': L} Pvip:EasyAlign/-\+/{'da': c} Pvip:EasyAlign*/-\+/{'delimiter_align':'C'} Pvip:EasyAlign*/-\+/{'da': 'x'} 381Gpvip:EasyAlign/-\+/{'da':r} :let g:easy_align_delimiter_align = 'l' Pvip:EasyAlign/-\+/ Pvip:EasyAlign*/-\+/ :unlet g:easy_align_delimiter_align :let g:easy_align_delimiters['\'] = { 'pattern': '-\+', 'delimiter_align': 'c' } Pvip \Pvip *-vip *\Pvip:EasyAlign *\\ {'da':l} Pvip:EasyAlign*\\ Pvip:EasyAlign*\\{'da': 'R'} 377GvipjyPvip:EasyAlign\ {'l': '@@@'} gv:EasyAlign 2 \ {'l': '{{{'} 507Gvipjygv:EasyAlign= Pvip:EasyAlign = {'idt': s} Pvip:EasyAlign= {'idt': d} Pvip:EasyAlign**={'indentation': 'd'} Pvip:EasyAlign!= Pvip:EasyAlign! **= {'indent': s} Pvip:EasyAlign!* = {'idt': D} Pvip:EasyAlign! ={'idt':'S'} 507GPvip:EasyAlign-={'idt':d} PA = 2j.j.j.j.vip:EasyAlign2={'idt': s} 507GPljjjj$:EasyAlign = {'idt': s} Pljjjj$:EasyAlign={'indent':d} Phhxxvip:EasyAlign={'idt':'s'} 525Gvipjy507GPPvip:EasyAlign*={'idt':s} Pvip:EasyAlign!**={'idt':s} Pvip:EasyAlign = {'idt': D} 525G^hhr1jr1jr1jr1jr1llkkkk$:EasyAlign = { 'idt': s } 513GvipjyPvip:EasyAlign*={'idt':n} Pvip:EasyAlign = { 'idt': N } Pvip:EasyAlign!*= {'idt': 'n'} 630Gvipjygv =Pvip =656Gvipjygv =Pvip *=Pvip **=Pvip **=Pvip:EasyAlign**= {'iu':0} Pvip =vip 2=vip -0 =818Gvipjygv =Pvip 2=Pvip *=Pvip **=Pvip **=Pvip -0=Pvip -0=855Gvip ** 860Gvip 2=}863Gvip 2=866Gvip 2=869Gvip 2=872Gvip *=875Gvip 2 878Gvip 2 881Gvip:EasyAlign**={'m': 'c','idt':s} ggjjj70Gvipjy883Gpvip *|vipjy893Gpvip:EasyAlign*|{'m': 'lcr'} 903Gpvip:EasyAlign**|{'m':'llc'} 913Gpvip:s/^|// vip:EasyAlign*|{'idt':n} vip:EasyAlign**|{'m':'cl'} 107GvipjyPvip  *=Pvip  *=975GVj 2=978Gvipjygv =Pvip =Pvip =Pvip =Pvip 2=993Gvip =996Gvip =999Gvip =1002Gvip =vipjyPvip =Pvip =1023Gvip =1026Gvip =1030Gvip =1033Gvip =1036Gvip 3=vipjyPvip 2=1044Gvip *,1052Gvipjygv:EasyAlign{'m':'lrc*'} 3 Pvip:EasyAlign{'mode_seq':'lrc**'} 2 Pvip:EasyAlign{'ms':'lccr**'} diff --git a/test/regexp.script b/test/regexp.script index ca8b777..85508ee 100644 --- a/test/regexp.script +++ b/test/regexp.script @@ -1 +1 @@ -4Gvipjyvip:EasyAlign: Pvip:EasyAlign*: Pvip:EasyAlign-: Pvip:EasyAlign * : Pvip:EasyAlign -2 : Pvip:EasyAlign -2: Pvip:easyA€kb€kb€kb€kb€kbEasAli€kb€kb€kbyAlign *: Pvip:EasyAlign; Pvip:EasyAlign /;/ Pvip:EasyAlign/;/ Pvip:EasyAlign*/;/ Pvip:e€kbEasyAlign/[:;]\+/ Pvip:EasyAlign*/[:;]\+/ Pvip:EasyAlign* /[:;]\+/ Pvip:EasyAlign */[:;]\+/ Pvip:EasyAlign * [:€kb€kb/[:;]\+/ Pvip:EasyAlign*[:;]\+€kb€kb€kb€kb€kb€kb€kb=/[€kb€kb€kb-/[:;]\+/ Pvip:EasyAlign-2/[:;\€kb\€kb]\+/ Pvip:EasyAlign/[:;]\+/{ 'l': '<<<', 'r': '>>>'} Pvip:EasyAlign/[:;]\+/{'l':''m€kb, 's': 1} Pvip:EasyAlign * /€kb /[:;]€kb\€kb]\+/ {'stick_to': 1, 'le': '???', 'marr': '~~~'} Pvip:EasyAlign /../ Pvip:EasyAlign*/../ Pvip:EasyAlign ** €kb/[:;]/€kb€kb\+]/ Pvip:EasyAlign/[:;\€kb\€kb]\+/'€kb{'rm':'____'} Pvip:EasyAlign**[€kb/[:;]\+/ Pvip:EasyAlign!**/[:;]\+/ Pfbjfm:EasyAlign/[:;]\+/ 90Gvip:EasyAlign/#/{'is':['String'],'iu':0} 93Gpvip:EasyAlign*/\s*/{'l':'(', 'r': ')'} +4Gvipjyvip:EasyAlign: Pvip:EasyAlign*: Pvip:EasyAlign-: Pvip:EasyAlign * : Pvip:EasyAlign -2 : Pvip:EasyAlign -2: Pvip:EasyAlign *: Pvip:EasyAlign; Pvip:EasyAlign /;/ Pvip:EasyAlign/;/ Pvip:EasyAlign*/;/ Pvip:EasyAlign/[:;]\+/ Pvip:EasyAlign*/[:;]\+/ Pvip:EasyAlign* /[:;]\+/ Pvip:EasyAlign */[:;]\+/ Pvip:EasyAlign * /[:;]\+/ Pvip:EasyAlign-/[:;]\+/ Pvip:EasyAlign-2/[:;]\+/ Pvip:EasyAlign/[:;]\+/{ 'l': '<<<', 'r': '>>>'} Pvip:EasyAlign/[:;]\+/{'l':'', 's': 1} Pvip:EasyAlign * /[:;]\+/ {'stick_to': 1, 'le': '???', 'marr': '~~~'} Pvip:EasyAlign /../ Pvip:EasyAlign*/../ Pvip:EasyAlign **/[:;\+]/ Pvip:EasyAlign/[:;]\+/{'rm':'____'} Pvip:EasyAlign**/[:;]\+/ Pvip:EasyAlign!**/[:;]\+/ Pfbjfm:EasyAlign/[:;]\+/ 90Gvip:EasyAlign/#/{'is':['String'],'iu':0} 93Gpvip:EasyAlign*/\s*/{'l':'(', 'r': ')'}