mirror of
https://github.com/dhruvasagar/vim-table-mode.git
synced 2025-11-08 11:03:47 -05:00
Merge branch 'feature/gfm_column_alignment'
This commit is contained in:
@@ -64,11 +64,21 @@ function! s:Padding(string, length, where) "{{{3
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" function! s:Split() - Split a string into fields and delimiters {{{2
|
" Public Functions {{{1
|
||||||
|
function! tablemode#align#sid() "{{{2
|
||||||
|
return maparg('<sid>', 'n')
|
||||||
|
endfunction
|
||||||
|
nnoremap <sid> <sid>
|
||||||
|
|
||||||
|
function! tablemode#align#scope() "{{{2
|
||||||
|
return s:
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" function! tablemode#align#Split() - Split a string into fields and delimiters {{{2
|
||||||
" Like split(), but include the delimiters as elements
|
" Like split(), but include the delimiters as elements
|
||||||
" All odd numbered elements are delimiters
|
" All odd numbered elements are delimiters
|
||||||
" All even numbered elements are non-delimiters (including zero)
|
" All even numbered elements are non-delimiters (including zero)
|
||||||
function! s:Split(string, delim)
|
function! tablemode#align#Split(string, delim)
|
||||||
let rv = []
|
let rv = []
|
||||||
let beg = 0
|
let beg = 0
|
||||||
|
|
||||||
@@ -107,59 +117,61 @@ function! s:Split(string, delim)
|
|||||||
return rv
|
return rv
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Public Functions {{{1
|
function! tablemode#align#alignments(lnum, ncols) "{{{2
|
||||||
function! tablemode#align#sid() "{{{2
|
let alignments = repeat(['l'], a:ncols) " For each column
|
||||||
return maparg('<sid>', 'n')
|
if tablemode#table#IsHeader(a:lnum+1)
|
||||||
endfunction
|
let hcols = tablemode#align#Split(getline(a:lnum+1), '[' . g:table_mode_corner . g:table_mode_corner_corner . ']')
|
||||||
nnoremap <sid> <sid>
|
for idx in range(len(hcols))
|
||||||
|
" Right align if header
|
||||||
function! tablemode#align#scope() "{{{2
|
if hcols[idx] =~# g:table_mode_align_char . '$' | let alignments[idx] = 'r' | endif
|
||||||
return s:
|
endfor
|
||||||
|
end
|
||||||
|
return alignments
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! tablemode#align#Align(lines) "{{{2
|
function! tablemode#align#Align(lines) "{{{2
|
||||||
let lines = map(a:lines, 's:Split(v:val, g:table_mode_separator)')
|
let lines = map(a:lines, 'map(v:val, "v:key =~# \"text\" ? tablemode#align#Split(v:val, g:table_mode_separator) : v:val")')
|
||||||
|
|
||||||
for line in lines
|
for line in lines
|
||||||
if len(line) <= 1 | continue | endif
|
let stext = line.text
|
||||||
|
if len(stext) <= 1 | continue | endif
|
||||||
|
|
||||||
if line[0] !~ tablemode#table#StartExpr()
|
if stext[0] !~ tablemode#table#StartExpr()
|
||||||
let line[0] = s:StripTrailingSpaces(line[0])
|
let stext[0] = s:StripTrailingSpaces(stext[0])
|
||||||
endif
|
endif
|
||||||
if len(line) >= 2
|
if len(stext) >= 2
|
||||||
for i in range(1, len(line)-1)
|
for i in range(1, len(stext)-1)
|
||||||
let line[i] = tablemode#utils#strip(line[i])
|
let stext[i] = tablemode#utils#strip(stext[i])
|
||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
let maxes = []
|
let maxes = []
|
||||||
for line in lines
|
for line in lines
|
||||||
if len(line) <= 1 | continue | endif
|
let stext = line.text
|
||||||
for i in range(len(line))
|
if len(stext) <= 1 | continue | endif
|
||||||
|
for i in range(len(stext))
|
||||||
if i == len(maxes)
|
if i == len(maxes)
|
||||||
let maxes += [ s:Strlen(line[i]) ]
|
let maxes += [ s:Strlen(stext[i]) ]
|
||||||
else
|
else
|
||||||
let maxes[i] = max([ maxes[i], s:Strlen(line[i]) ])
|
let maxes[i] = max([ maxes[i], s:Strlen(stext[i]) ])
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
let alignments = tablemode#align#alignments(lines[0].lnum, len(lines[0].text))
|
||||||
|
|
||||||
for idx in range(len(lines))
|
for idx in range(len(lines))
|
||||||
let line = lines[idx]
|
let tlnum = lines[idx].lnum
|
||||||
|
let tline = lines[idx].text
|
||||||
|
|
||||||
if len(line) <= 1 | continue | endif
|
if len(tline) <= 1 | continue | endif
|
||||||
for i in range(len(line))
|
for i in range(len(tline))
|
||||||
if line[i] !~# '[^0-9\.]'
|
let field = s:Padding(tline[i], maxes[i], alignments[i])
|
||||||
let field = s:Padding(line[i], maxes[i], 'r')
|
let tline[i] = field . (i == 0 || i == len(tline) ? '' : ' ')
|
||||||
else
|
|
||||||
let field = s:Padding(line[i], maxes[i], 'l')
|
|
||||||
endif
|
|
||||||
|
|
||||||
let line[i] = field . (i == 0 || i == len(line) ? '' : ' ')
|
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
let lines[idx] = s:StripTrailingSpaces(join(line, ''))
|
let lines[idx].text = s:StripTrailingSpaces(join(tline, ''))
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
function! s:HeaderBorderExpr() "{{{2
|
function! s:HeaderBorderExpr() "{{{2
|
||||||
return tablemode#table#StartExpr() .
|
return tablemode#table#StartExpr() .
|
||||||
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
|
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
|
||||||
\ '[' . g:table_mode_fillchar . g:table_mode_corner . ']*' .
|
\ '[' . g:table_mode_fillchar . g:table_mode_corner . g:table_mode_align_char . ']*' .
|
||||||
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
|
\ '[' . g:table_mode_corner . g:table_mode_corner_corner . ']' .
|
||||||
\ tablemode#table#EndExpr()
|
\ tablemode#table#EndExpr()
|
||||||
endfunction
|
endfunction
|
||||||
@@ -45,10 +45,29 @@ function! s:GenerateHeaderBorder(line) "{{{2
|
|||||||
let line_val = getline(line - 1)
|
let line_val = getline(line - 1)
|
||||||
endif
|
endif
|
||||||
if tablemode#utils#strlen(line_val) <= 1 | return s:DefaultHeaderBorder() | endif
|
if tablemode#utils#strlen(line_val) <= 1 | return s:DefaultHeaderBorder() | endif
|
||||||
|
|
||||||
let border = substitute(line_val[stridx(line_val, g:table_mode_separator):strridx(line_val, g:table_mode_separator)], g:table_mode_separator, g:table_mode_corner, 'g')
|
let border = substitute(line_val[stridx(line_val, g:table_mode_separator):strridx(line_val, g:table_mode_separator)], g:table_mode_separator, g:table_mode_corner, 'g')
|
||||||
let border = substitute(border, '[^' . g:table_mode_corner . ']', g:table_mode_fillchar, 'g')
|
let border = substitute(border, '[^' . g:table_mode_corner . ']', g:table_mode_fillchar, 'g')
|
||||||
let border = substitute(border, '^' . g:table_mode_corner . '\(.*\)' . g:table_mode_corner . '$', g:table_mode_corner_corner . '\1' . g:table_mode_corner_corner, '')
|
let border = substitute(border, '^' . g:table_mode_corner . '\(.*\)' . g:table_mode_corner . '$', g:table_mode_corner_corner . '\1' . g:table_mode_corner_corner, '')
|
||||||
|
|
||||||
|
" Incorporate header alignment chars
|
||||||
|
if getline(line) =~# g:table_mode_align_char
|
||||||
|
let pat = '[' . g:table_mode_corner_corner . g:table_mode_corner . ']'
|
||||||
|
let hcols = tablemode#align#Split(getline(line), pat)
|
||||||
|
let gcols = tablemode#align#Split(border, pat)
|
||||||
|
|
||||||
|
for idx in range(len(hcols))
|
||||||
|
if hcols[idx] =~# g:table_mode_align_char
|
||||||
|
if hcols[idx] =~# g:table_mode_align_char . '$'
|
||||||
|
let gcols[idx] = gcols[idx][:-2] . g:table_mode_align_char
|
||||||
|
else
|
||||||
|
let gcols[idx] = g:table_mode_align_char . gcols[idx][1:]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
let border = join(gcols, '')
|
||||||
|
endif
|
||||||
|
|
||||||
let cstartexpr = tablemode#table#StartCommentExpr()
|
let cstartexpr = tablemode#table#StartCommentExpr()
|
||||||
if tablemode#utils#strlen(cstartexpr) > 0 && getline(line) =~# cstartexpr
|
if tablemode#utils#strlen(cstartexpr) > 0 && getline(line) =~# cstartexpr
|
||||||
let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
|
let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
|
||||||
@@ -134,15 +153,14 @@ function! tablemode#table#EndExpr() "{{{2
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! tablemode#table#IsRow(line) "{{{2
|
|
||||||
return getline(a:line) =~# (tablemode#table#StartExpr() . g:table_mode_separator . '[^' .
|
|
||||||
\ g:table_mode_fillchar . ']*[^' . g:table_mode_corner . ']*$')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! tablemode#table#IsHeader(line) "{{{2
|
function! tablemode#table#IsHeader(line) "{{{2
|
||||||
return getline(a:line) =~# s:HeaderBorderExpr()
|
return getline(a:line) =~# s:HeaderBorderExpr()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! tablemode#table#IsRow(line) "{{{2
|
||||||
|
return !tablemode#table#IsHeader(a:line) && getline(a:line) =~# (tablemode#table#StartExpr() . g:table_mode_separator)
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! tablemode#table#AddHeaderBorder(line) "{{{2
|
function! tablemode#table#AddHeaderBorder(line) "{{{2
|
||||||
call setline(a:line, s:GenerateHeaderBorder(a:line))
|
call setline(a:line, s:GenerateHeaderBorder(a:line))
|
||||||
endfunction
|
endfunction
|
||||||
@@ -150,41 +168,36 @@ endfunction
|
|||||||
function! tablemode#table#Realign(line) "{{{2
|
function! tablemode#table#Realign(line) "{{{2
|
||||||
let line = tablemode#utils#line(a:line)
|
let line = tablemode#utils#line(a:line)
|
||||||
|
|
||||||
let [lnums, lines] = [[], []]
|
let lines = []
|
||||||
let [tline, blines] = [line, []]
|
let [lnum, blines] = [line, []]
|
||||||
while tablemode#table#IsRow(tline) || tablemode#table#IsHeader(tline)
|
while tablemode#table#IsRow(lnum) || tablemode#table#IsHeader(lnum)
|
||||||
if tablemode#table#IsHeader(tline)
|
if tablemode#table#IsHeader(lnum)
|
||||||
call insert(blines, tline)
|
call insert(blines, lnum)
|
||||||
let tline -= 1
|
let lnum -= 1
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
call insert(lnums, tline)
|
call insert(lines, {'lnum': lnum, 'text': getline(lnum)})
|
||||||
call insert(lines, getline(tline))
|
let lnum -= 1
|
||||||
let tline -= 1
|
|
||||||
endwhile
|
endwhile
|
||||||
|
|
||||||
let tline = line + 1
|
let lnum = line + 1
|
||||||
|
while tablemode#table#IsRow(lnum) || tablemode#table#IsHeader(lnum)
|
||||||
while tablemode#table#IsRow(tline) || tablemode#table#IsHeader(tline)
|
if tablemode#table#IsHeader(lnum)
|
||||||
if tablemode#table#IsHeader(tline)
|
call add(blines, lnum)
|
||||||
call insert(blines, tline)
|
let lnum += 1
|
||||||
let tline += 1
|
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
call add(lnums, tline)
|
call add(lines, {'lnum': lnum, 'text': getline(lnum)})
|
||||||
call add(lines, getline(tline))
|
let lnum += 1
|
||||||
let tline += 1
|
|
||||||
endwhile
|
endwhile
|
||||||
|
|
||||||
let lines = tablemode#align#Align(lines)
|
let lines = tablemode#align#Align(lines)
|
||||||
|
|
||||||
for lnum in lnums
|
for aline in lines
|
||||||
let index = index(lnums, lnum)
|
call setline(aline.lnum, aline.text)
|
||||||
call setline(lnum, lines[index])
|
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
for bline in blines
|
for bline in blines
|
||||||
call tablemode#table#AddHeaderBorder(bline)
|
call tablemode#table#AddHeaderBorder(bline)
|
||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ call s:SetGlobalOptDefault('table_mode_toggle_map', 'm')
|
|||||||
call s:SetGlobalOptDefault('table_mode_always_active', 0)
|
call s:SetGlobalOptDefault('table_mode_always_active', 0)
|
||||||
call s:SetGlobalOptDefault('table_mode_delimiter', ',')
|
call s:SetGlobalOptDefault('table_mode_delimiter', ',')
|
||||||
call s:SetGlobalOptDefault('table_mode_corner_corner', '|')
|
call s:SetGlobalOptDefault('table_mode_corner_corner', '|')
|
||||||
|
call s:SetGlobalOptDefault('table_mode_align_char', ':')
|
||||||
|
|
||||||
function! s:TableEchoCell() "{{{1
|
function! s:TableEchoCell() "{{{1
|
||||||
if tablemode#table#IsRow('.')
|
if tablemode#table#IsRow('.')
|
||||||
|
|||||||
12
t/align.vim
12
t/align.vim
@@ -3,12 +3,20 @@ source t/config/options.vim
|
|||||||
|
|
||||||
call vspec#hint({'scope': 'tablemode#align#scope()', 'sid': 'tablemode#align#sid()'})
|
call vspec#hint({'scope': 'tablemode#align#scope()', 'sid': 'tablemode#align#sid()'})
|
||||||
|
|
||||||
|
function! ConvertLines2Dict(lines)
|
||||||
|
let lines = []
|
||||||
|
for idx in range(len(a:lines))
|
||||||
|
call insert(lines, {"lnum": idx+1, "text": a:lines[idx]})
|
||||||
|
endfor
|
||||||
|
return lines
|
||||||
|
endfunction
|
||||||
|
|
||||||
describe 'Align'
|
describe 'Align'
|
||||||
it 'should align table content correctly'
|
it 'should align table content correctly'
|
||||||
Expect tablemode#align#Align(readfile('t/fixtures/align/simple_before.txt')) == readfile('t/fixtures/align/simple_after.txt')
|
Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/simple_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/simple_after.txt'))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should align table content with unicode characters correctly'
|
it 'should align table content with unicode characters correctly'
|
||||||
Expect tablemode#align#Align(readfile('t/fixtures/align/unicode_before.txt')) == readfile('t/fixtures/align/unicode_after.txt')
|
Expect tablemode#align#Align(ConvertLines2Dict(readfile('t/fixtures/align/unicode_before.txt'))) == ConvertLines2Dict(readfile('t/fixtures/align/unicode_after.txt'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ let g:table_mode_toggle_map = 'm'
|
|||||||
let g:table_mode_always_active = 0
|
let g:table_mode_always_active = 0
|
||||||
let g:table_mode_delimiter = ','
|
let g:table_mode_delimiter = ','
|
||||||
let g:table_mode_corner_corner = '|'
|
let g:table_mode_corner_corner = '|'
|
||||||
|
let g:table_mode_align_char = ':'
|
||||||
|
|||||||
Reference in New Issue
Block a user