" Private Functions {{{1 function! s:SetBufferOptDefault(opt, val) "{{{2 if !exists('b:' . a:opt) let b:{a:opt} = a:val endif endfunction function! s:Map(map, to, mode) "{{{2 if !empty(a:to) && !hasmapto(a:map, a:mode) for l:mode in split(a:mode, '.\zs') execute l:mode . 'map ' a:to a:map endfor endif endfunction function! s:UnMap(map, mode) "{{{2 if !empty(maparg(a:map, a:mode)) for mode in split(a:mode, '.\zs') execute l:mode . 'unmap ' a:map endfor endif endfunction function! s:ToggleMapping() "{{{2 if !g:table_mode_disable_mappings if tablemode#IsActive() call s:Map('(table-mode-tableize)', g:table_mode_separator_map, 'i') call s:Map('(table-mode-motion-up)', g:table_mode_motion_up_map, 'n') call s:Map('(table-mode-motion-down)', g:table_mode_motion_down_map, 'n') call s:Map('(table-mode-motion-left)', g:table_mode_motion_left_map, 'n') call s:Map('(table-mode-motion-right)', g:table_mode_motion_right_map, 'n') call s:Map('(table-mode-cell-text-object-a)', g:table_mode_cell_text_object_a_map, 'ox') call s:Map('(table-mode-cell-text-object-i)', g:table_mode_cell_text_object_i_map, 'ox') call s:Map('(table-mode-realign)', g:table_mode_realign_map, 'n') call s:Map('(table-mode-delete-row)', g:table_mode_delete_row_map, 'n') call s:Map('(table-mode-delete-column)', g:table_mode_delete_column_map, 'n') call s:Map('(table-mode-insert-column-before)', g:table_mode_insert_column_before_map, 'n') call s:Map('(table-mode-insert-column-after)', g:table_mode_insert_column_after_map, 'n') call s:Map('(table-mode-add-formula)', g:table_mode_add_formula_map, 'n') call s:Map('(table-mode-eval-formula)', g:table_mode_eval_formula_map, 'n') call s:Map('(table-mode-echo-cell)', g:table_mode_echo_cell_map, 'n') call s:Map('(table-mode-sort)', g:table_mode_sort_map, 'n') else call s:UnMap(g:table_mode_separator_map, 'i') call s:UnMap(g:table_mode_motion_up_map, 'n') call s:UnMap(g:table_mode_motion_down_map, 'n') call s:UnMap(g:table_mode_motion_left_map, 'n') call s:UnMap(g:table_mode_motion_right_map, 'n') call s:UnMap(g:table_mode_cell_text_object_a_map, 'ox') call s:UnMap(g:table_mode_cell_text_object_i_map, 'ox') call s:UnMap(g:table_mode_realign_map, 'n') call s:UnMap(g:table_mode_delete_row_map, 'n') call s:UnMap(g:table_mode_delete_column_map, 'n') call s:UnMap(g:table_mode_insert_column_before_map, 'n') call s:UnMap(g:table_mode_insert_column_after_map, 'n') call s:UnMap(g:table_mode_add_formula_map, 'n') call s:UnMap(g:table_mode_eval_formula_map, 'n') call s:UnMap(g:table_mode_echo_cell_map, 'n') call s:UnMap(g:table_mode_sort_map, 'n') endif endif endfunction function! s:ToggleSyntax() "{{{2 if !g:table_mode_syntax | return | endif if tablemode#IsActive() exec 'syntax match Table' \ '/' . tablemode#table#StartExpr() . '\zs|.\+|\ze' . tablemode#table#EndExpr() . '/' \ 'contains=TableBorder,TableSeparator,TableColumnAlign,yesCell,noCell,maybeCell' \ 'containedin=ALL' syntax match TableSeparator /|/ contained syntax match TableColumnAlign /:/ contained syntax match TableBorder /[\-+]\+/ contained hi! link TableBorder Delimiter hi! link TableSeparator Delimiter hi! link TableColumnAlign Type if exists("g:table_mode_color_cells") && g:table_mode_color_cells syntax match yesCell '[^|]*yes[^|]*' syntax match noCell ' *no[^|]*' syntax match maybeCell ' *?[^|]*' endif else syntax clear Table syntax clear TableBorder syntax clear TableSeparator syntax clear TableColumnAlign hi! link TableBorder NONE hi! link TableSeparator NONE hi! link TableColumnAlign NONE endif endfunction function! s:ToggleAutoAlign() "{{{2 if !g:table_mode_auto_align | return | endif if tablemode#IsActive() augroup TableModeAutoAlign au! autocmd CursorHold nested silent! if &modified | call tablemode#table#Realign('.') | endif " autocmd InsertLeave nested silent! if &modified | call tablemode#table#Realign('.') | endif augroup END else autocmd! TableModeAutoAlign endif endfunction function! s:ToggleOptions() "{{{2 if tablemode#IsActive() let b:old_update_time = &updatetime exec 'set updatetime='.g:table_mode_update_time else exec 'set updatetime='.get(b:, 'old_update_time', 4000) endif endfunction function! s:SetActive(bool) "{{{2 let b:table_mode_active = a:bool call s:ToggleSyntax() call s:ToggleMapping() call s:ToggleAutoAlign() call s:ToggleOptions() if tablemode#IsActive() doautocmd User TableModeEnabled else doautocmd User TableModeDisabled endif endfunction function! s:ConvertDelimiterToSeparator(line, ...) "{{{2 let old_gdefault = &gdefault set nogdefault let delim = g:table_mode_delimiter if a:0 | let delim = a:1 | endif if delim ==# ',' silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs,\\ze[^\'\"]*[\'\"]/__COMMA__/g" endif let [cstart, cend] = [tablemode#table#GetCommentStart(), tablemode#table#GetCommentEnd()] let [match_char_start, match_char_end] = ['.', '.'] if tablemode#utils#strlen(cend) > 0 | let match_char_end = '[^' . cend . ']' | endif if tablemode#utils#strlen(cstart) > 0 | let match_char_start = '[^' . cstart . ']' | endif silent! execute a:line . 's/' . tablemode#table#StartExpr() . '\zs\ze' . match_char_start . \ '\|' . delim . '\|' . match_char_end . '\zs\ze' . tablemode#table#EndExpr() . '/' . \ g:table_mode_separator . '/g' if delim ==# ',' silent! execute a:line . 's/' . "[\'\"][^\'\"]*\\zs__COMMA__\\ze[^\'\"]*[\'\"]/,/g" endif let &gdefault=old_gdefault endfunction function! s:Tableizeline(line, ...) "{{{2 let delim = g:table_mode_delimiter if a:0 && type(a:1) == type('') && !empty(a:1) | let delim = a:1[1:-1] | endif call s:ConvertDelimiterToSeparator(a:line, delim) endfunction " Public API {{{1 function! tablemode#IsActive() "{{{2 if g:table_mode_always_active | return 1 | endif call s:SetBufferOptDefault('table_mode_active', 0) return b:table_mode_active endfunction function! tablemode#TableizeInsertMode() "{{{2 if tablemode#IsActive() if getline('.') =~# (tablemode#table#StartExpr() . g:table_mode_separator . g:table_mode_separator . tablemode#table#EndExpr()) call tablemode#table#AddBorder('.') normal! A elseif getline('.') =~# (tablemode#table#StartExpr() . g:table_mode_separator) let column = tablemode#utils#strlen(substitute(getline('.')[0:col('.')], '[^' . g:table_mode_separator . ']', '', 'g')) let position = tablemode#utils#strlen(matchstr(getline('.')[0:col('.')], '.*' . g:table_mode_separator . '\s*\zs.*')) call tablemode#table#Realign('.') normal! 0 call search(repeat('[^' . g:table_mode_separator . ']*' . g:table_mode_separator, column) . '\s\{-\}' . repeat('.', position), 'ce', line('.')) endif endif endfunction function! tablemode#Enable() "{{{2 call s:SetActive(1) endfunction function! tablemode#Disable() "{{{2 call s:SetActive(0) endfunction function! tablemode#Toggle() "{{{2 if g:table_mode_always_active return 1 endif call s:SetBufferOptDefault('table_mode_active', 0) call s:SetActive(!b:table_mode_active) endfunction function! tablemode#TableizeRange(...) range "{{{2 let lnum = a:firstline let total = (a:lastline - a:firstline + 1) " echom total let cntr = 1 while cntr <= total call s:Tableizeline(lnum, a:1) undojoin if g:table_mode_tableize_auto_border if cntr == 1 normal! O call tablemode#table#AddBorder('.') normal! j let lnum += 1 endif normal! o call tablemode#table#AddBorder('.') let lnum += 1 endif let cntr += 1 let lnum += 1 endwhile call tablemode#table#Realign(lnum - 1) endfunction function! tablemode#TableizeByDelimiter() "{{{2 let delim = input('/') if delim =~# "\" || delim =~# "\" | return | endif let vm = visualmode() if vm ==? 'line' || vm ==? 'V' exec line("'<") . ',' . line("'>") . "call tablemode#TableizeRange('/' . delim)" endif endfunction if !hlexists('yesCell') | hi yesCell cterm=bold ctermfg=10 ctermbg=2 | endif | if !hlexists('noCell') | hi noCell cterm=bold ctermfg=9 ctermbg=1 | endif | if !hlexists('maybeCell') | hi maybeCell cterm=bold ctermfg=11 ctermbg=3 | endif |