@@ -106,6 +106,27 @@ function! s:StripLeadingSpaces(string)
106
106
return matchstr (a: string , ' ^\s*\zs.*$' )
107
107
endfunction
108
108
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
+
109
130
" Split a string into fields and delimiters {{{2
110
131
" Like split(), but include the delimiters as elements
111
132
" All odd numbered elements are delimiters
@@ -220,27 +241,30 @@ function! tabular#TabularizeStrings(strings, delim, ...)
220
241
221
242
let format = split (formatstr, s: formatelempat . ' \zs' )
222
243
223
- let lines = map ( a: strings, ' s:SplitDelim(v:val, a:delim) ' )
244
+ let lines = a: strings
224
245
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
229
252
for line in lines
230
253
if len (line ) == 1 && s: do_gtabularize
231
254
continue " Leave non-matching lines unchanged for GTabularize
232
255
endif
233
256
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 )
239
261
let line [i ] = s: StripLeadingSpaces (s: StripTrailingSpaces (line [i ]))
240
262
endfor
241
263
endif
242
264
endfor
243
265
266
+ let common_indent = s: LongestCommonIndent (first_fields)
267
+
244
268
" Find the max length of each field
245
269
let maxes = []
246
270
for line in lines
@@ -257,8 +281,6 @@ function! tabular#TabularizeStrings(strings, delim, ...)
257
281
endfor
258
282
endfor
259
283
260
- let lead_blank = empty (filter (copy (lines ), ' v:val[0] =~ "\\S"' ))
261
-
262
284
" Concatenate the fields, according to the format pattern.
263
285
for idx in range (len (lines ))
264
286
let line = lines [idx]
@@ -280,10 +302,16 @@ function! tabular#TabularizeStrings(strings, delim, ...)
280
302
let field = s: Center (line [i ], maxes[i ])
281
303
endif
282
304
283
- let line [i ] = field . (lead_blank && i == 0 ? ' ' : repeat (" " , pad) )
305
+ let line [i ] = field . repeat (" " , pad)
284
306
endfor
285
307
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 , ' ' ))
287
315
endfor
288
316
endfunction
289
317
0 commit comments