Improve right-justification mode

With this commit you can right-align the last token with * or ** field number.
For example, the following lines
    a = 1
    bb = 22
    ccc = 333
are aligned as follows on `:EasyAlign**=`
    a   =   1
    bb  =  22
    ccc = 333
And even if we don't have the second =, we can do `:EasyAlign!2=` to get
    a =     1
    bb =   22
    ccc = 333
This commit is contained in:
Junegunn Choi
2013-08-16 13:58:28 +09:00
parent b6625f6d2b
commit 5c6558bd1b
6 changed files with 286 additions and 28 deletions

View File

@@ -139,8 +139,10 @@ function! s:validate_options(opts)
return a:opts return a:opts
endfunction endfunction
function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, ignores) function! s:split_line(line, nth, just, recur, fc, lc, pattern, stick_to_left, ignore_unmatched, ignores)
let left = a:lc ? 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, a:lc - a:fc + 1) :
\ strpart(getline(a:line), a:fc - 1) \ strpart(getline(a:line), a:fc - 1)
let idx = 0 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 ignorable = 0
let token = '' let token = ''
while 1 while 1
let matches = matchlist(left, pattern, idx) let matches = matchlist(string, pattern, idx)
" No match
if empty(matches) | break | endif if empty(matches) | break | endif
" Match, but empty delimiter
if empty(matches[1]) if empty(matches[1])
let char = strpart(left, idx, 1) let char = strpart(string, idx, 1)
if empty(char) | break | endif if empty(char) | break | endif
let [match, part, delim] = [char, char, ''] let [match, part, delim] = [char, char, '']
" Match
else else
let [match, part, delim] = matches[1 : 3] let [match, part, delim] = matches[1 : 3]
endif endif
@@ -172,16 +178,27 @@ function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, i
else else
call add(tokens, token . match) call add(tokens, token . match)
call add(delims, delim) call add(delims, delim)
let [pjust, just] = [just, a:recur == 2 ? !just : just]
let token = '' let token = ''
endif endif
let idx += len(match) 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 endwhile
let leftover = token . strpart(left, idx) let leftover = token . strpart(string, idx)
if !empty(leftover) if !empty(leftover)
let ignorable = s:highlighted_as(a:line, len(string) + a:fc - 1, a:ignores)
call add(tokens, leftover) call add(tokens, leftover)
call add(delims, '') call add(delims, '')
let [pjust, just] = [just, a:recur == 2 ? !just : just]
endif endif
" Preserve indentation - merge first two tokens " 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 if ignorable && len(tokens) == 1 && a:ignore_unmatched
let tokens = [] let tokens = []
let delims = [] 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 endif
return [tokens, delims] 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) for line in range(a:fl, a:ll)
if !has_key(a:all_tokens, line) if !has_key(a:all_tokens, line)
" Split line into the tokens by the delimiters " 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 " Remember tokens for subsequent recursive calls
let a:all_tokens[line] = tokens 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 continue
endif endif
let nth = a:nth - 1 " make it 0-based let nth = a:nth - 1 " make it 0-based
else " Negative field number 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 let nth = len(tokens) + a:nth
endif
if empty(delims[len(delims) - 1]) if empty(delims[len(delims) - 1])
let nth -= 1 let nth -= 1
endif 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( tokens[nth] )
let token = s:rtrim( strpart(token, 0, len(token) - len(s:rtrim(delim))) ) let token = s:rtrim( strpart(token, 0, len(token) - len(s:rtrim(delim))) )
if empty(delim) && !exists('tokens[nth + 1]') && a:ignore_unmatched if empty(delim) && !exists('tokens[nth + 1]') && a:ignore_unmatched
if a:just == 0
continue 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
endif endif
let indent = len(matchstr(tokens[0], '^\s\+')) let indent = len(matchstr(tokens[0], '^\s\+'))

View File

@@ -109,10 +109,10 @@ j, , k
bbbb = 2 bbbb = 2
ccccccc = 3 ccccccc = 3
ccccccccccccccc ccccccccccccccc
ddd = 4 ddd = #
eeee === eee = eee = eee=f eeee === eee = eee = eee=f
fff = ggg += gg &&= gg fff = ggg += gg &&= gg
g != hhhhhhhh == 888 g != hhhhhhhh == # 8
i := 5 i := 5
i %= 5 i %= 5
i *= 5 i *= 5
@@ -134,10 +134,10 @@ a = 1
bbbb = 2 bbbb = 2
ccccccc = 3 ccccccc = 3
ccccccccccccccc ccccccccccccccc
ddd = 4 ddd = #
eeee === eee = eee = eee = f eeee === eee = eee = eee = f
fff = ggg += gg &&= gg fff = ggg += gg &&= gg
g != hhhhhhhh == 888 g != hhhhhhhh == # 8
i := 5 i := 5
i %= 5 i %= 5
i *= 5 i *= 5
@@ -159,10 +159,10 @@ a = 1
bbbb = 2 bbbb = 2
ccccccc = 3 ccccccc = 3
ccccccccccccccc ccccccccccccccc
ddd = 4 ddd = #
eeee === eee = eee = eee = f eeee === eee = eee = eee = f
fff = ggg += gg &&= gg fff = ggg += gg &&= gg
g != hhhhhhhh == 888 g != hhhhhhhh == # 8
i := 5 i := 5
i %= 5 i %= 5
i *= 5 i *= 5
@@ -184,10 +184,10 @@ a = 1
bbbb = 2 bbbb = 2
ccccccc = 3 ccccccc = 3
ccccccccccccccc ccccccccccccccc
ddd = 4 ddd = #
eeee === eee = eee = eee=f eeee === eee = eee = eee=f
fff = ggg += gg &&= gg fff = ggg += gg &&= gg
g != hhhhhhhh == 888 g != hhhhhhhh == # 8
i := 5 i := 5
i %= 5 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"
```

View File

@@ -29,10 +29,10 @@ a = 1
bbbb = 2 bbbb = 2
ccccccc = 3 ccccccc = 3
ccccccccccccccc ccccccccccccccc
ddd = 4 ddd = #
eeee === eee = eee = eee=f eeee === eee = eee = eee=f
fff = ggg += gg &&= gg fff = ggg += gg &&= gg
g != hhhhhhhh == 888 g != hhhhhhhh == # 8
i := 5 i := 5
i %= 5 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"
```

View File

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

View File

@@ -37,6 +37,7 @@ vnoremap <silent> <C-l> <nop>
set nolazyredraw set nolazyredraw
set buftype=nofile set buftype=nofile
set colorcolumn=
silent! ScrollPositionHide silent! ScrollPositionHide

View File

@@ -91,6 +91,6 @@ apricot = 'DAD' + 'F#AD'
banana = 'Gros Michel' # comment 2 banana = 'Gros Michel' # comment 2
``` ```
a()p()p()l()e();():()b()a()n()a()n()a():():()c()a()k()e 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 d()a()t()a();();()e()x()c()h()a()n()g()e():();()f()o()r()m()a()t(