diff --git a/autoload/easy_align.vim b/autoload/easy_align.vim index 3dcabd2..0414224 100644 --- a/autoload/easy_align.vim +++ b/autoload/easy_align.vim @@ -139,8 +139,10 @@ function! s:validate_options(opts) return a:opts endfunction -function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, ignores) - let left = a:lc ? +function! s:split_line(line, nth, just, recur, fc, lc, pattern, stick_to_left, ignore_unmatched, ignores) + let pjust = a:just + let just = a:just + let string = a:lc ? \ strpart(getline(a:line), a:fc - 1, a:lc - a:fc + 1) : \ strpart(getline(a:line), a:fc - 1) let idx = 0 @@ -156,12 +158,16 @@ function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, i let ignorable = 0 let token = '' while 1 - let matches = matchlist(left, pattern, idx) + let matches = matchlist(string, pattern, idx) + " No match if empty(matches) | break | endif + + " Match, but empty delimiter if empty(matches[1]) - let char = strpart(left, idx, 1) + let char = strpart(string, idx, 1) if empty(char) | break | endif let [match, part, delim] = [char, char, ''] + " Match else let [match, part, delim] = matches[1 : 3] endif @@ -172,16 +178,27 @@ function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, i else call add(tokens, token . match) call add(delims, delim) + let [pjust, just] = [just, a:recur == 2 ? !just : just] let token = '' endif let idx += len(match) + + " If the string is non-empty and ends with the delimiter, + " append an empty token to the list + if idx == len(string) + call add(tokens, '') + call add(delims, '') + break + endif endwhile - let leftover = token . strpart(left, idx) + let leftover = token . strpart(string, idx) if !empty(leftover) + let ignorable = s:highlighted_as(a:line, len(string) + a:fc - 1, a:ignores) call add(tokens, leftover) call add(delims, '') + let [pjust, just] = [just, a:recur == 2 ? !just : just] endif " Preserve indentation - merge first two tokens @@ -195,6 +212,11 @@ function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, i if ignorable && len(tokens) == 1 && a:ignore_unmatched let tokens = [] let delims = [] + " Append an empty item to enable right justification of the last token + " - if the last token is not ignorable or ignorable but not the only token + elseif pjust == 1 && (!ignorable || len(tokens) > 1) && a:nth >= 0 " includes -0 + call add(tokens, '') + call add(delims, '') endif return [tokens, delims] @@ -213,7 +235,7 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth, for line in range(a:fl, a:ll) if !has_key(a:all_tokens, line) " Split line into the tokens by the delimiters - let [tokens, delims] = s:split_line(line, a:fc, a:lc, a:pattern, a:stick_to_left, a:ignore_unmatched, a:ignores) + let [tokens, delims] = s:split_line(line, a:nth, a:just, a:recursive, a:fc, a:lc, a:pattern, a:stick_to_left, a:ignore_unmatched, a:ignores) " Remember tokens for subsequent recursive calls let a:all_tokens[line] = tokens @@ -236,8 +258,12 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth, continue endif let nth = a:nth - 1 " make it 0-based - else " Negative field number - let nth = len(tokens) + a:nth + else " -0 or Negative field number + if a:nth == 0 && a:just == 1 + let nth = len(tokens) - 1 + else + let nth = len(tokens) + a:nth + endif if empty(delims[len(delims) - 1]) let nth -= 1 endif @@ -252,13 +278,7 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth, let token = s:rtrim( tokens[nth] ) let token = s:rtrim( strpart(token, 0, len(token) - len(s:rtrim(delim))) ) if empty(delim) && !exists('tokens[nth + 1]') && a:ignore_unmatched - if a:just == 0 - continue - " Do not ignore on right-justification mode, except when the end of the - " line is highlighted as ignored syntax (e.g. comments or strings). - elseif s:highlighted_as(line, a:fc + len(prefix.token) - 1, a:ignores) - continue - endif + continue endif let indent = len(matchstr(tokens[0], '^\s\+')) diff --git a/test/basic.expected b/test/basic.expected index 7a50062..e5a2740 100644 --- a/test/basic.expected +++ b/test/basic.expected @@ -109,10 +109,10 @@ j, , k bbbb = 2 ccccccc = 3 ccccccccccccccc - ddd = 4 + ddd = # eeee === eee = eee = eee=f fff = ggg += gg &&= gg - g != hhhhhhhh == 888 + g != hhhhhhhh == # 8 i := 5 i %= 5 i *= 5 @@ -134,10 +134,10 @@ a = 1 bbbb = 2 ccccccc = 3 ccccccccccccccc -ddd = 4 +ddd = # eeee === eee = eee = eee = f fff = ggg += gg &&= gg -g != hhhhhhhh == 888 +g != hhhhhhhh == # 8 i := 5 i %= 5 i *= 5 @@ -159,10 +159,10 @@ a = 1 bbbb = 2 ccccccc = 3 ccccccccccccccc -ddd = 4 +ddd = # eeee === eee = eee = eee = f fff = ggg += gg &&= gg -g != hhhhhhhh == 888 +g != hhhhhhhh == # 8 i := 5 i %= 5 i *= 5 @@ -184,10 +184,10 @@ a = 1 bbbb = 2 ccccccc = 3 ccccccccccccccc -ddd = 4 +ddd = # eeee === eee = eee = eee=f fff = ggg += gg &&= gg -g != hhhhhhhh == 888 +g != hhhhhhhh == # 8 i := 5 i %= 5 i *= 5 @@ -651,3 +651,204 @@ string i = "asdf"; ``` +```ruby + +a = +a = 1 +bbbb = 2 +ccccccc = 3 + ccccccccccccccc +# eeeeeeeeeeeeeeee +e # asdf +ddd = # +eeee === eee = eee = eee=f +fff = ggg += gg &&= gg +g != hhhhhhhh == # 8 +i := 5 +i %= 5 +i *= 5 +j =~ 5 +j >= 5 +aa => 123 +aa <<= 123 +aa >>= 123 +bbb => 123 +c => 1233123 +d => 123 +dddddd &&= 123 +dddddd ||= 123 +dddddd /= 123 +gg <=> ee + +a = +a = 1 +bbbb = 2 +ccccccc = 3 +ccccccccccccccc +# eeeeeeeeeeeeeeee +e # asdf +ddd = # +eeee === eee = eee = eee = f +fff = ggg += gg &&= gg +g != hhhhhhhh == # 8 +i := 5 +i %= 5 +i *= 5 +j =~ 5 +j >= 5 +aa => 123 +aa <<= 123 +aa >>= 123 +bbb => 123 +c => 1233123 +d => 123 +dddddd &&= 123 +dddddd ||= 123 +dddddd /= 123 +gg <=> ee + + a = + a = 1 + bbbb = 2 + ccccccc = 3 +ccccccccccccccc +# eeeeeeeeeeeeeeee +e # asdf + ddd = # + eeee === eee = eee = eee = f + fff = ggg += gg &&= gg + g != hhhhhhhh == # 8 + i := 5 + i %= 5 + i *= 5 + j =~ 5 + j >= 5 + aa => 123 + aa <<= 123 + aa >>= 123 + bbb => 123 + c => 1233123 + d => 123 + dddddd &&= 123 + dddddd ||= 123 + dddddd /= 123 + gg <=> ee + +a = +a = 1 +bbbb = 2 +ccccccc = 3 +ccccccccccccccc +# eeeeeeeeeeeeeeee +e # asdf +ddd = # +eeee === eee = eee = eee = f +fff = ggg += gg &&= gg +g != hhhhhhhh == # 8 +i := 5 +i %= 5 +i *= 5 +j =~ 5 +j >= 5 +aa => 123 +aa <<= 123 +aa >>= 123 +bbb => 123 +c => 1233123 +d => 123 +dddddd &&= 123 +dddddd ||= 123 +dddddd /= 123 +gg <=> ee + + a = + a = 1 + bbbb = 2 + ccccccc = 3 +ccccccccccccccc +# eeeeeeeeeeeeeeee +e # asdf + ddd = # + eeee === eee = eee = eee = f + fff = ggg += gg &&= gg + g != hhhhhhhh == # 8 + i := 5 + i %= 5 + i *= 5 + j =~ 5 + j >= 5 + aa => 123 + aa <<= 123 + aa >>= 123 + bbb => 123 + c => 1233123 + d => 123 + dddddd &&= 123 + dddddd ||= 123 + dddddd /= 123 + gg <=> ee + + a = + a = 1 + bbbb = 2 + ccccccc = 3 +ccccccccccccccc +# eeeeeeeeeeeeeeee +e # asdf + ddd = # + eeee === eee = eee = eee=f + fff = ggg += gg &&= gg + g != hhhhhhhh == # 8 + i := 5 + i %= 5 + i *= 5 + j =~ 5 + j >= 5 + aa => 123 + aa <<= 123 + aa >>= 123 + bbb => 123 + c => 1233123 + d => 123 + dddddd &&= 123 + dddddd ||= 123 + dddddd /= 123 + gg <=> ee + +a = 1 +bb = 22 +ccc = 333 +dddd = "asdf" + +a = 1 +bb = 22 +ccc = 333 +dddd = "asdf" + + a = 1 + bb = 22 + ccc = 333 +dddd = "asdf" + +a = 1 +bb = 22 +ccc = 333 +dddd = "asdf" + + a = 1 + bb = 22 + ccc = 333 +dddd = "asdf" + +a = 1 +bb = 22 +ccc = 333 +dddd = "asdf" + + a = 1 + bb = 22 + ccc = 333 +dddd = "asdf" + +``` + diff --git a/test/basic.md b/test/basic.md index 919d210..8074ac6 100644 --- a/test/basic.md +++ b/test/basic.md @@ -29,10 +29,10 @@ a = 1 bbbb = 2 ccccccc = 3 ccccccccccccccc -ddd = 4 +ddd = # eeee === eee = eee = eee=f fff = ggg += gg &&= gg -g != hhhhhhhh == 888 +g != hhhhhhhh == # 8 i := 5 i %= 5 i *= 5 @@ -152,3 +152,39 @@ string i = "asdf"; ``` +```ruby + +a = +a = 1 +bbbb = 2 +ccccccc = 3 +ccccccccccccccc +# eeeeeeeeeeeeeeee +e # asdf +ddd = # +eeee === eee = eee = eee=f +fff = ggg += gg &&= gg +g != hhhhhhhh == # 8 +i := 5 +i %= 5 +i *= 5 +j =~ 5 +j >= 5 +aa => 123 +aa <<= 123 +aa >>= 123 +bbb => 123 +c => 1233123 +d => 123 +dddddd &&= 123 +dddddd ||= 123 +dddddd /= 123 +gg <=> ee + +a = 1 +bb = 22 +ccc = 333 +dddd = "asdf" + +``` + diff --git a/test/basic.script b/test/basic.script index 3cf14b4..d97ffc3 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': '#\+', 'ignores': ['String'] } } vip #227zzvip :239zzvip *=vipjyP:let g:easy_align_ignores = [] vip *=:unlet g:easy_align_delimiters :unlet g:easy_align_ignores 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 = +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': '#\+', 'ignores': ['String'] } } vip #227zzvip :239zzvip *=vipjyP:let g:easy_align_ignores = [] vip *=:unlet g:easy_align_delimiters :unlet g:easy_align_ignores 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= diff --git a/test/include.vim b/test/include.vim index 2114fd0..cacb75e 100644 --- a/test/include.vim +++ b/test/include.vim @@ -37,6 +37,7 @@ vnoremap set nolazyredraw set buftype=nofile +set colorcolumn= silent! ScrollPositionHide diff --git a/test/regexp.expected b/test/regexp.expected index 2a2fd20..0d4ac9f 100644 --- a/test/regexp.expected +++ b/test/regexp.expected @@ -91,6 +91,6 @@ apricot = 'DAD' + 'F#AD' banana = 'Gros Michel' # comment 2 ``` -a()p()p()l()e();():()b()a()n()a()n()a():():()c()a()k()e -d()a()t()a();();()e()x()c()h()a()n()g()e():();()f()o()r()m()a()t +a()p()p()l()e();():()b()a()n()a()n()a():():()c()a()k()e( +d()a()t()a();();()e()x()c()h()a()n()g()e():();()f()o()r()m()a()t(