From 53da3fb4c2338f0b7d3fc22de0af5d8efd4231ce Mon Sep 17 00:00:00 2001 From: Dhruva Sagar Date: Wed, 30 Apr 2014 21:30:44 +0530 Subject: [PATCH] Fixed #28 Altered border generation code to incorporate true display width of characters, hence generate more accurate borders. --- autoload/tablemode/align.vim | 32 +++----------------------------- autoload/tablemode/table.vim | 4 +++- autoload/tablemode/utils.vim | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/autoload/tablemode/align.vim b/autoload/tablemode/align.vim index b54b67e..0b670e6 100644 --- a/autoload/tablemode/align.vim +++ b/autoload/tablemode/align.vim @@ -19,32 +19,6 @@ " Borrowed from Tabular " Private Functions {{{1 -" Return the number of bytes in a string after expanding tabs to spaces. {{{2 -" This expansion is done based on the current value of 'tabstop' -if exists('*strdisplaywidth') - " Needs vim 7.3 - let s:Strlen = function("strdisplaywidth") -else - function! s:Strlen(string) - " Implement the tab handling part of strdisplaywidth for vim 7.2 and - " earlier - not much that can be done about handling doublewidth - " characters. - let rv = 0 - let i = 0 - - for char in split(a:string, '\zs') - if char == "\t" - let rv += &ts - i - let i = 0 - else - let rv += 1 - let i = (i + 1) % &ts - endif - endfor - - return rv - endfunction -endif " function! s:StripTrailingSpaces(string) - Remove all trailing spaces {{{2 " from a string. function! s:StripTrailingSpaces(string) @@ -52,7 +26,7 @@ function! s:StripTrailingSpaces(string) endfunction function! s:Padding(string, length, where) "{{{3 - let gap_length = a:length - s:Strlen(a:string) + let gap_length = a:length - tablemode#utils#StrDisplayWidth(a:string) if a:where =~# 'l' return a:string . repeat(" ", gap_length) elseif a:where =~# 'r' @@ -154,9 +128,9 @@ function! tablemode#align#Align(lines) "{{{2 if len(stext) <= 1 | continue | endif for i in range(len(stext)) if i == len(maxes) - let maxes += [ s:Strlen(stext[i]) ] + let maxes += [ tablemode#utils#StrDisplayWidth(stext[i]) ] else - let maxes[i] = max([ maxes[i], s:Strlen(stext[i]) ]) + let maxes[i] = max([ maxes[i], tablemode#utils#StrDisplayWidth(stext[i]) ]) endif endfor endfor diff --git a/autoload/tablemode/table.vim b/autoload/tablemode/table.vim index 551d072..6de40df 100644 --- a/autoload/tablemode/table.vim +++ b/autoload/tablemode/table.vim @@ -47,7 +47,9 @@ function! s:GenerateHeaderBorder(line) "{{{2 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(border, '[^' . g:table_mode_corner . ']', g:table_mode_fillchar, 'g') + " To accurately deal with unicode double width characters + let fill_columns = map(split(border, g:table_mode_corner), 'repeat(g:table_mode_fillchar, tablemode#utils#StrDisplayWidth(v:val))') + let border = g:table_mode_corner . join(fill_columns, g:table_mode_corner) . g:table_mode_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 diff --git a/autoload/tablemode/utils.vim b/autoload/tablemode/utils.vim index 21bce69..af9495d 100644 --- a/autoload/tablemode/utils.vim +++ b/autoload/tablemode/utils.vim @@ -51,3 +51,30 @@ endfunction function! tablemode#utils#strlen(text) return strlen(substitute(a:text, '.', 'x', 'g')) endfunction + +" Return the number of bytes in a string after expanding tabs to spaces. {{{2 +" This expansion is done based on the current value of 'tabstop' +function! tablemode#utils#StrDisplayWidth(string) + if exists('*strdisplaywidth') + return strdisplaywidth(a:string) + else + " Implement the tab handling part of strdisplaywidth for vim 7.2 and + " earlier - not much that can be done about handling doublewidth + " characters. + let rv = 0 + let i = 0 + + for char in split(a:string, '\zs') + if char == "\t" + let rv += &ts - i + let i = 0 + else + let rv += 1 + let i = (i + 1) % &ts + endif + endfor + + return rv + endif +endfunction +