mirror of
https://github.com/dhruvasagar/vim-table-mode.git
synced 2025-11-10 20:13:46 -05:00
* Disabled by default, if enabled directs table mode to ignore aligning based on alignment characters on the header and always left aligns
141 lines
4.1 KiB
VimL
141 lines
4.1 KiB
VimL
" Borrowed from Tabular
|
|
" Private Functions {{{1
|
|
" function! s:StripTrailingSpaces(string) - Remove all trailing spaces {{{2
|
|
" from a string.
|
|
function! s:StripTrailingSpaces(string)
|
|
return matchstr(a:string, '^.\{-}\ze\s*$')
|
|
endfunction
|
|
|
|
function! s:Padding(string, length, where) "{{{3
|
|
let gap_length = a:length - tablemode#utils#StrDisplayWidth(a:string)
|
|
if a:where =~# 'l'
|
|
return a:string . repeat(" ", gap_length)
|
|
elseif a:where =~# 'r'
|
|
return repeat(" ", gap_length) . a:string
|
|
elseif a:where =~# 'c'
|
|
let right = gap_length / 2
|
|
let left = right + (right * 2 != gap_length)
|
|
return repeat(" ", left) . a:string . repeat(" ", right)
|
|
endif
|
|
endfunction
|
|
|
|
" Public Functions {{{1
|
|
" function! tablemode#align#Split() - Split a string into fields and delimiters {{{2
|
|
" Like split(), but include the delimiters as elements
|
|
" All odd numbered elements are delimiters
|
|
" All even numbered elements are non-delimiters (including zero)
|
|
function! tablemode#align#Split(string, delim)
|
|
let rv = []
|
|
let beg = 0
|
|
|
|
let len = len(a:string)
|
|
let searchoff = 0
|
|
|
|
while 1
|
|
let mid = match(a:string, a:delim, beg + searchoff, 1)
|
|
if mid == -1 || mid == len
|
|
break
|
|
endif
|
|
|
|
let matchstr = matchstr(a:string, a:delim, beg + searchoff, 1)
|
|
let length = strlen(matchstr)
|
|
|
|
if length == 0 && beg == mid
|
|
" Zero-length match for a zero-length delimiter - advance past it
|
|
let searchoff += 1
|
|
continue
|
|
endif
|
|
|
|
if beg == mid
|
|
let rv += [ "" ]
|
|
else
|
|
let rv += [ a:string[beg : mid-1] ]
|
|
endif
|
|
|
|
let rv += [ matchstr ]
|
|
|
|
let beg = mid + length
|
|
let searchoff = 0
|
|
endwhile
|
|
|
|
let rv += [ strpart(a:string, beg) ]
|
|
|
|
return rv
|
|
endfunction
|
|
|
|
function! tablemode#align#alignments(lnum, ncols) "{{{2
|
|
let achr = g:table_mode_align_char
|
|
let alignments = []
|
|
if tablemode#table#IsBorder(a:lnum+1)
|
|
let corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner')
|
|
let corner_corner = tablemode#utils#get_buffer_or_global_option('table_mode_corner_corner')
|
|
let hcols = tablemode#align#Split(getline(a:lnum+1), '[' . corner . corner_corner . ']')
|
|
for idx in range(len(hcols))
|
|
" Right align if header
|
|
call add(alignments, 'l')
|
|
if hcols[idx] =~# achr . '[^'.achr.']\+' . achr
|
|
let alignments[idx] = 'c'
|
|
elseif hcols[idx] =~# achr . '$'
|
|
let alignments[idx] = 'r'
|
|
endif
|
|
" if hcols[idx] !~# '[^0-9\.]' | let alignments[idx] = 'r' | endif
|
|
endfor
|
|
end
|
|
return alignments
|
|
endfunction
|
|
|
|
function! tablemode#align#Align(lines) "{{{2
|
|
if empty(a:lines) | return [] | endif
|
|
let lines = map(a:lines, 'map(v:val, "v:key =~# \"text\" ? tablemode#align#Split(v:val, g:table_mode_escaped_separator_regex) : v:val")')
|
|
|
|
for line in lines
|
|
let stext = line.text
|
|
if len(stext) <= 1 | continue | endif
|
|
|
|
if stext[0] !~ tablemode#table#StartExpr()
|
|
let stext[0] = s:StripTrailingSpaces(stext[0])
|
|
endif
|
|
if len(stext) >= 2
|
|
for i in range(1, len(stext)-1)
|
|
let stext[i] = tablemode#utils#strip(stext[i])
|
|
endfor
|
|
endif
|
|
endfor
|
|
|
|
let maxes = []
|
|
for line in lines
|
|
let stext = line.text
|
|
if len(stext) <= 1 | continue | endif
|
|
for i in range(len(stext))
|
|
if i == len(maxes)
|
|
let maxes += [ tablemode#utils#StrDisplayWidth(stext[i]) ]
|
|
else
|
|
let maxes[i] = max([ maxes[i], tablemode#utils#StrDisplayWidth(stext[i]) ])
|
|
endif
|
|
endfor
|
|
endfor
|
|
|
|
if g:table_mode_ignore_align ==# 1
|
|
let alignments = []
|
|
else
|
|
let alignments = tablemode#align#alignments(lines[0].lnum, len(lines[0].text))
|
|
endif
|
|
|
|
for idx in range(len(lines))
|
|
let tlnum = lines[idx].lnum
|
|
let tline = lines[idx].text
|
|
|
|
if len(tline) <= 1 | continue | endif
|
|
for jdx in range(len(tline))
|
|
" Dealing with the header being the first line
|
|
if jdx >= len(alignments) | call add(alignments, 'l') | endif
|
|
let field = s:Padding(tline[jdx], maxes[jdx], alignments[jdx])
|
|
let tline[jdx] = field . (jdx == 0 || jdx == len(tline) ? '' : ' ')
|
|
endfor
|
|
|
|
let lines[idx].text = s:StripTrailingSpaces(join(tline, ''))
|
|
endfor
|
|
|
|
return lines
|
|
endfunction
|