Skip to content

Commit cdac1a6

Browse files
committed
Change the methodology for handling indentation
Indentation is left alone until after lines have been split into fields. We then find the common indent remaining in the 1st field of each line that will be affected by the align operation (for GTabularize, non-matching lines don't factor in here). Also, blank lines don't affect the calculation of longest common indent. Before calculation of field widths, leading indent is stripped from all fields, and after the fields have been joined back together we re-add the common indent that was stripped earlier.
1 parent 8405725 commit cdac1a6

File tree

1 file changed

+42
-14
lines changed

1 file changed

+42
-14
lines changed

autoload/tabular.vim

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,27 @@ function! s:StripLeadingSpaces(string)
106106
return matchstr(a:string, '^\s*\zs.*$')
107107
endfunction
108108

109+
" Find the longest common indent for a list of strings {{{2
110+
" If a string is shorter than the others but contains no non-whitespace
111+
" characters, it does not end the match. This provides consistency with
112+
" vim's behavior that blank lines don't have trailing spaces.
113+
function! s:LongestCommonIndent(strings)
114+
if empty(a:strings)
115+
return ''
116+
endif
117+
118+
let n = 0
119+
while 1
120+
let ns = join(map(copy(a:strings), 'v:val[n]'), '')
121+
if ns !~ '^ \+$\|^\t\+$'
122+
break
123+
endif
124+
let n += 1
125+
endwhile
126+
127+
return strpart(a:strings[0], 0, n)
128+
endfunction
129+
109130
" Split a string into fields and delimiters {{{2
110131
" Like split(), but include the delimiters as elements
111132
" All odd numbered elements are delimiters
@@ -220,27 +241,30 @@ function! tabular#TabularizeStrings(strings, delim, ...)
220241

221242
let format = split(formatstr, s:formatelempat . '\zs')
222243

223-
let lines = map(a:strings, 's:SplitDelim(v:val, a:delim)')
244+
let lines = a:strings
224245

225-
" Strip spaces
226-
" - Only from non-delimiters; spaces in delimiters must have been matched
227-
" intentionally
228-
" - Don't strip leading spaces from the first element; we like indenting.
246+
call map(lines, 's:SplitDelim(v:val, a:delim)')
247+
248+
let first_fields = []
249+
250+
" Strip spaces from non-delimiters; spaces in delimiters must have been
251+
" matched intentionally
229252
for line in lines
230253
if len(line) == 1 && s:do_gtabularize
231254
continue " Leave non-matching lines unchanged for GTabularize
232255
endif
233256

234-
if line[0] !~ '^\s*$'
235-
let line[0] = s:StripTrailingSpaces(line[0])
236-
endif
237-
if len(line) >= 3
238-
for i in range(2, len(line)-1, 2)
257+
call add(first_fields, line[0])
258+
259+
if len(line) >= 1
260+
for i in range(0, len(line)-1, 2)
239261
let line[i] = s:StripLeadingSpaces(s:StripTrailingSpaces(line[i]))
240262
endfor
241263
endif
242264
endfor
243265

266+
let common_indent = s:LongestCommonIndent(first_fields)
267+
244268
" Find the max length of each field
245269
let maxes = []
246270
for line in lines
@@ -257,8 +281,6 @@ function! tabular#TabularizeStrings(strings, delim, ...)
257281
endfor
258282
endfor
259283

260-
let lead_blank = empty(filter(copy(lines), 'v:val[0] =~ "\\S"'))
261-
262284
" Concatenate the fields, according to the format pattern.
263285
for idx in range(len(lines))
264286
let line = lines[idx]
@@ -280,10 +302,16 @@ function! tabular#TabularizeStrings(strings, delim, ...)
280302
let field = s:Center(line[i], maxes[i])
281303
endif
282304

283-
let line[i] = field . (lead_blank && i == 0 ? '' : repeat(" ", pad))
305+
let line[i] = field . repeat(" ", pad)
284306
endfor
285307

286-
let lines[idx] = s:StripTrailingSpaces(join(line, ''))
308+
let prefix = common_indent
309+
if len(line) == 1 && s:do_gtabularize
310+
" We didn't strip the indent in this case; nothing to put back.
311+
let prefix = ''
312+
endif
313+
314+
let lines[idx] = s:StripTrailingSpaces(prefix . join(line, ''))
287315
endfor
288316
endfunction
289317

0 commit comments

Comments
 (0)