From 9f74ceaa869ebbe7f073f05f629ed3051dd37a84 Mon Sep 17 00:00:00 2001 From: Yclept Nemo Date: Tue, 10 Mar 2015 04:29:05 -0400 Subject: [PATCH 1/7] Support Tabstop Alignment --- autoload/tabular.vim | 85 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/autoload/tabular.vim b/autoload/tabular.vim index f60a73c..4237fd2 100644 --- a/autoload/tabular.vim +++ b/autoload/tabular.vim @@ -71,6 +71,18 @@ else endfunction endif +function! s:TabOffset(position, string) + let offset = 0 + let sections = split(a:string, "\t", 1) + for index in range(len(sections)) + let offset += s:Strlen(sections[index]) + if index+1 < len(sections) + let offset += &tabstop - ((a:position + offset) % &tabstop) + endif + endfor + return offset +endfunction + " Align a string within a field {{{2 " These functions do not trim leading and trailing spaces. @@ -94,6 +106,53 @@ function! s:Center(string, fieldwidth) return repeat(" ", left) . a:string . repeat(" ", right) endfunction +function! s:TabToString(position, count) + if a:count <= 0 + throw "Invalid tab count!" + endif + + let offset = &tabstop - (a:position % &tabstop) + if &expandtab + let result = repeat(" ", offset) . repeat(" ", &tabstop * (a:count - 1)) + else + let result = repeat("\t", a:count) + endif + let offset += a:count - 1 + return [offset, result] +endfunction + +" Convert padding specification to string: +function! s:PaddingToString(padding, position) + let result = "" + let offset = 0 + let sections = split(a:padding, s:paddingpat . '\zs') + for section in sections + let l:count = matchstr(section, '^\d\+') + let l:count = len(l:count) ? str2nr(l:count) : 1 + let type = matchstr(section, '[st]$') + let type = len(type) ? type : g:tabular_default_padding + if type ==? "s" + let result .= repeat(" ", l:count) + let offset += l:count + else + let [section_offset, section_result] = s:TabToString(a:position + offset, l:count) + let result .= section_result + let offset += section_offset + endif + endfor + return [offset, result] +endfunction + +function! s:FieldToString(field, align, max) + if a:align =~? 'l' + return s:Left(a:field, a:max) + elseif how =~? 'r' + return s:Right(a:field, a:max) + elseif how =~? 'c' + return s:Center(a:field, a:max) + endif +endfunction + " Remove spaces around a string {{{2 " Remove all trailing spaces from a string. @@ -194,7 +253,12 @@ if !exists("g:tabular_default_format") let g:tabular_default_format = "l1" endif -let s:formatelempat = '\%([lrc]\d\+\)' +if !exists("g:tabular_default_padding") + let g:tabular_default_padding = "s" +endif + +let s:paddingpat = '\%(\d\+[st]\?\|[st]\)' +let s:formatelempat = '\%([lrc]' . s:paddingpat . '\+\)' function! tabular#ElementFormatPattern() return s:formatelempat @@ -268,19 +332,14 @@ function! tabular#TabularizeStrings(strings, delim, ...) continue endif + let l:count = 0 for i in range(len(line)) - let how = format[i % len(format)][0] - let pad = format[i % len(format)][1:-1] - - if how =~? 'l' - let field = s:Left(line[i], maxes[i]) - elseif how =~? 'r' - let field = s:Right(line[i], maxes[i]) - elseif how =~? 'c' - let field = s:Center(line[i], maxes[i]) - endif - - let line[i] = field . (lead_blank && i == 0 ? '' : repeat(" ", pad)) + let align = format[i % len(format)][0] + let field = s:FieldToString(line[i], align, maxes[i]) + let l:count += s:TabOffset(l:count, field) + let padding = s:PaddingToString(format[i % len(format)][1:-1], l:count) + let l:count += padding[0] + let line[i] = field . (lead_blank && i == 0 ? '' : padding[1]) endfor let lines[idx] = s:StripTrailingSpaces(join(line, '')) From 9304d3ab42a7b0f6267076ec06f41adb85f34737 Mon Sep 17 00:00:00 2001 From: Yclept Nemo Date: Tue, 10 Mar 2015 13:51:36 -0400 Subject: [PATCH 2/7] Tabstop Alignment: fixes --- autoload/tabular.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autoload/tabular.vim b/autoload/tabular.vim index 4237fd2..edf5994 100644 --- a/autoload/tabular.vim +++ b/autoload/tabular.vim @@ -146,9 +146,9 @@ endfunction function! s:FieldToString(field, align, max) if a:align =~? 'l' return s:Left(a:field, a:max) - elseif how =~? 'r' + elseif a:align =~? 'r' return s:Right(a:field, a:max) - elseif how =~? 'c' + elseif a:align =~? 'c' return s:Center(a:field, a:max) endif endfunction From ea02056bd501ba39abb13cea64d811a2b9285240 Mon Sep 17 00:00:00 2001 From: Yclept Nemo Date: Tue, 10 Mar 2015 14:52:06 -0400 Subject: [PATCH 3/7] Tabstop Alignment: documentation --- doc/Tabular.txt | 67 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/doc/Tabular.txt b/doc/Tabular.txt index a71e032..d2cdb5a 100644 --- a/doc/Tabular.txt +++ b/doc/Tabular.txt @@ -89,11 +89,18 @@ fields, you would provide a different format to the Tabularize command: Some short phrase, some other phrase A much longer phrase here,and another long phrase -< -A format specifier is either l, r, or c, followed by one or more digits. If -the letter is l, the field will be left aligned, similarly for r and right -aligning and c and center aligning. The number following the letter is the -number of spaces padding to insert before the start of the next field. + +A format specifier is composed of an alignment specifier followed by a padding +specifier. The alignment specifier is either l, r, or c. If the letter is l, +the field will be left aligned, similarly for r and right aligning and c and +center aligning. The padding specification is a repeated sequence composed of +one or more digits followed by a whitespace specifier of s or t. Either digit +sequence or whitespace specifier is optional, but not both. Omitted, the +whitespace specifier defaults to |g:tabular_default_padding|. Conversely, the +digit sequence defaults to one. A whitespace specifier of s represents space, +similarly for t and tab. Each represented character is repeated as per the +digit sequence. Tabs respect the |shiftwidth| and |expandtab| settings. + Multiple format specifiers can be added to the same command - each field will be printed with the next format specifier in the list; when they all have been used the first will be used again, and so on. So, the last command right @@ -115,20 +122,44 @@ left, or center aligned. Also notice that the 0 padding spaces specified for the 3rd field are unused - but they would be used if there were enough fields to require looping through the fields again. For instance: > - abc,def,ghi - a,b + +.......+.......+.......+.......+.......+ + abc,def,ghi,jkl,mno a,b,c - - :Tabularize /,/r1c1l0 - - abc , def, ghi - a , b - a , b , c -< -Notice that now, the format pattern has been reused; field 4 (the second comma) -is right aligned, field 5 is center aligned. No spaces were inserted between -the 3rd field (containing "def") and the 4th field (the second comma) because -the format specified 'l0'. + a,b,c,d,e + + abc,defghi,jkl + abcdefghijkl,m + a,b,c + +.......+.......+.......+.......+.......+ + + :echo [&tabstop, &expandtab] + [8, 1] + :exec "Tabularize /,/r1ctl0ct" | exec "norm }j" | Tabularize + + +.......+.......+.......+.......+.......+ + abc , def, ghi , jkl, mno + a , b , c + a , b , c , d , e + + abc , defghi, jkl + abcdefghijkl , m + a , b , c + +.......+.......+.......+.......+.......+ + +Notice that now, the format pattern has been reused: field 5 (containing +"ghi") is right aligned, field 6 (the third comma) is center aligned, and +field 7 (containing "jkl") is left aligned. A tab is inserted between the 4th +field (the second comma) and the 5th field (containing "ghi") because the +format specifier "ct". + +Notice that, without any arguments, the most recent 'Tabularize' pattern will +automatically be reused. + +The "+" characters in the visual guide represent the tabstop locations. Notice +how, irrespective of indent the correct number of spaces are automatically +inserted, so the "ghi" and "defghi" fields are correctly aligned, as well as +both "jkl" entries. Though not demonstrated here, Tabularize correctly handles +any tabs within the original expression. But, what if you only wanted to act on the first comma on the line, rather than all of the commas on the line? Let's say we want everything before the first From a8c315b0507c91e150653584d353cfe20fab450e Mon Sep 17 00:00:00 2001 From: Yclept Nemo Date: Tue, 10 Mar 2015 15:04:57 -0400 Subject: [PATCH 4/7] Allow spaces within the padding specifier Spaces are stripped anyway, but aid in visually discerning fields. --- autoload/tabular.vim | 5 +++-- doc/Tabular.txt | 20 +++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/autoload/tabular.vim b/autoload/tabular.vim index edf5994..e7af6fd 100644 --- a/autoload/tabular.vim +++ b/autoload/tabular.vim @@ -125,7 +125,8 @@ endfunction function! s:PaddingToString(padding, position) let result = "" let offset = 0 - let sections = split(a:padding, s:paddingpat . '\zs') + let padding = substitute(a:padding, " ", "", "g") + let sections = split(padding, s:paddingpat . '\zs') for section in sections let l:count = matchstr(section, '^\d\+') let l:count = len(l:count) ? str2nr(l:count) : 1 @@ -257,7 +258,7 @@ if !exists("g:tabular_default_padding") let g:tabular_default_padding = "s" endif -let s:paddingpat = '\%(\d\+[st]\?\|[st]\)' +let s:paddingpat = '\%(\%(\d\+[st]\?\|[st]\) *\)' let s:formatelempat = '\%([lrc]' . s:paddingpat . '\+\)' function! tabular#ElementFormatPattern() diff --git a/doc/Tabular.txt b/doc/Tabular.txt index d2cdb5a..c95d43d 100644 --- a/doc/Tabular.txt +++ b/doc/Tabular.txt @@ -94,12 +94,13 @@ A format specifier is composed of an alignment specifier followed by a padding specifier. The alignment specifier is either l, r, or c. If the letter is l, the field will be left aligned, similarly for r and right aligning and c and center aligning. The padding specification is a repeated sequence composed of -one or more digits followed by a whitespace specifier of s or t. Either digit -sequence or whitespace specifier is optional, but not both. Omitted, the -whitespace specifier defaults to |g:tabular_default_padding|. Conversely, the -digit sequence defaults to one. A whitespace specifier of s represents space, -similarly for t and tab. Each represented character is repeated as per the -digit sequence. Tabs respect the |shiftwidth| and |expandtab| settings. +one or more digits followed by a whitespace specifier of s or t, terminated by +optional space characters. Either digit sequence or whitespace specifier is +optional, but not both. Omitted, the whitespace specifier defaults to +|g:tabular_default_padding|. Conversely, the digit sequence defaults to one. A +whitespace specifier of s represents space, similarly for t and tab. Each +represented character is repeated as per the digit sequence. Tabs respect the +|shiftwidth| and |expandtab| settings. Multiple format specifiers can be added to the same command - each field will be printed with the next format specifier in the list; when they all have been @@ -127,14 +128,14 @@ to require looping through the fields again. For instance: a,b,c a,b,c,d,e - abc,defghi,jkl + abc,defghi,jk abcdefghijkl,m a,b,c +.......+.......+.......+.......+.......+ :echo [&tabstop, &expandtab] [8, 1] - :exec "Tabularize /,/r1ctl0ct" | exec "norm }j" | Tabularize + :exec "Tabularize /,/r1 ct l0 ct" | exec "norm }j" | Tabularize +.......+.......+.......+.......+.......+ abc , def, ghi , jkl, mno @@ -152,9 +153,6 @@ field 7 (containing "jkl") is left aligned. A tab is inserted between the 4th field (the second comma) and the 5th field (containing "ghi") because the format specifier "ct". -Notice that, without any arguments, the most recent 'Tabularize' pattern will -automatically be reused. - The "+" characters in the visual guide represent the tabstop locations. Notice how, irrespective of indent the correct number of spaces are automatically inserted, so the "ghi" and "defghi" fields are correctly aligned, as well as From e64b27411b60ebcfb491205b28f7870d25177d69 Mon Sep 17 00:00:00 2001 From: Yclept Nemo Date: Tue, 10 Mar 2015 15:04:57 -0400 Subject: [PATCH 5/7] Allow spaces within the padding specifier Spaces are stripped anyway, but aid in visually discerning fields. --- autoload/tabular.vim | 5 +++-- doc/Tabular.txt | 20 +++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/autoload/tabular.vim b/autoload/tabular.vim index edf5994..e7af6fd 100644 --- a/autoload/tabular.vim +++ b/autoload/tabular.vim @@ -125,7 +125,8 @@ endfunction function! s:PaddingToString(padding, position) let result = "" let offset = 0 - let sections = split(a:padding, s:paddingpat . '\zs') + let padding = substitute(a:padding, " ", "", "g") + let sections = split(padding, s:paddingpat . '\zs') for section in sections let l:count = matchstr(section, '^\d\+') let l:count = len(l:count) ? str2nr(l:count) : 1 @@ -257,7 +258,7 @@ if !exists("g:tabular_default_padding") let g:tabular_default_padding = "s" endif -let s:paddingpat = '\%(\d\+[st]\?\|[st]\)' +let s:paddingpat = '\%(\%(\d\+[st]\?\|[st]\) *\)' let s:formatelempat = '\%([lrc]' . s:paddingpat . '\+\)' function! tabular#ElementFormatPattern() diff --git a/doc/Tabular.txt b/doc/Tabular.txt index d2cdb5a..c95d43d 100644 --- a/doc/Tabular.txt +++ b/doc/Tabular.txt @@ -94,12 +94,13 @@ A format specifier is composed of an alignment specifier followed by a padding specifier. The alignment specifier is either l, r, or c. If the letter is l, the field will be left aligned, similarly for r and right aligning and c and center aligning. The padding specification is a repeated sequence composed of -one or more digits followed by a whitespace specifier of s or t. Either digit -sequence or whitespace specifier is optional, but not both. Omitted, the -whitespace specifier defaults to |g:tabular_default_padding|. Conversely, the -digit sequence defaults to one. A whitespace specifier of s represents space, -similarly for t and tab. Each represented character is repeated as per the -digit sequence. Tabs respect the |shiftwidth| and |expandtab| settings. +one or more digits followed by a whitespace specifier of s or t, terminated by +optional space characters. Either digit sequence or whitespace specifier is +optional, but not both. Omitted, the whitespace specifier defaults to +|g:tabular_default_padding|. Conversely, the digit sequence defaults to one. A +whitespace specifier of s represents space, similarly for t and tab. Each +represented character is repeated as per the digit sequence. Tabs respect the +|shiftwidth| and |expandtab| settings. Multiple format specifiers can be added to the same command - each field will be printed with the next format specifier in the list; when they all have been @@ -127,14 +128,14 @@ to require looping through the fields again. For instance: a,b,c a,b,c,d,e - abc,defghi,jkl + abc,defghi,jk abcdefghijkl,m a,b,c +.......+.......+.......+.......+.......+ :echo [&tabstop, &expandtab] [8, 1] - :exec "Tabularize /,/r1ctl0ct" | exec "norm }j" | Tabularize + :exec "Tabularize /,/r1 ct l0 ct" | exec "norm }j" | Tabularize +.......+.......+.......+.......+.......+ abc , def, ghi , jkl, mno @@ -152,9 +153,6 @@ field 7 (containing "jkl") is left aligned. A tab is inserted between the 4th field (the second comma) and the 5th field (containing "ghi") because the format specifier "ct". -Notice that, without any arguments, the most recent 'Tabularize' pattern will -automatically be reused. - The "+" characters in the visual guide represent the tabstop locations. Notice how, irrespective of indent the correct number of spaces are automatically inserted, so the "ghi" and "defghi" fields are correctly aligned, as well as From bf94f610b21def688f0e308301029733f76d39a2 Mon Sep 17 00:00:00 2001 From: Yclept Nemo Date: Tue, 10 Mar 2015 15:04:57 -0400 Subject: [PATCH 6/7] Padding Specifier Spaces: fixes --- doc/Tabular.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Tabular.txt b/doc/Tabular.txt index c95d43d..734b480 100644 --- a/doc/Tabular.txt +++ b/doc/Tabular.txt @@ -128,7 +128,7 @@ to require looping through the fields again. For instance: a,b,c a,b,c,d,e - abc,defghi,jk + abc,defghi,jkl abcdefghijkl,m a,b,c +.......+.......+.......+.......+.......+ From 9e14718df836e30a757659c1fee94dae4d64b6ae Mon Sep 17 00:00:00 2001 From: Yclept Nemo Date: Tue, 10 Mar 2015 15:27:23 -0400 Subject: [PATCH 7/7] Padding Specifier Spaces: fixes --- doc/Tabular.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Tabular.txt b/doc/Tabular.txt index c95d43d..734b480 100644 --- a/doc/Tabular.txt +++ b/doc/Tabular.txt @@ -128,7 +128,7 @@ to require looping through the fields again. For instance: a,b,c a,b,c,d,e - abc,defghi,jk + abc,defghi,jkl abcdefghijkl,m a,b,c +.......+.......+.......+.......+.......+