Version 0.9.9

* NEW: Diary. Help in making daily notes. See ':h vimwiki-diary'. Now you
  can really easy add information into vimwiki that should be sorted out
  later.
* NEW: Tables are redesigned. Syntax is changed. Now they are
  auto-formattable. You can navigate them with <tab> and <cr> in insert
  mode. See 'vimwiki-syntax-tables' and 'vimwiki-tables' for more details.
* NEW: Keyword STARTED: is added.
* NEW: Words TODO:, DONE:, STARTED:, XXX:, FIXME:, FIXED: are highlighed
  inside headers.
* FIX: Export to html external links with 'file://' protocol. Ex:
  '[file:///home/user1/book.pdf my book]'.
* FIX: Menu is corrupted if wiki's path contains spaces.
* FIX: Settings 'wrap' and 'linebreak' are removed from ftplugin. Add them
  into your personal settings file '.vim/after/ftplugin/vimwiki.vim' if
  needed.
* NEW: Headers are highlighted in different colors by default.  See ':h
  g:vimwiki_hl_headers' to turn it off.
* FIX: Issue 40: Links with russian subdirs don't work.
* NEW: It is now possible to generate HTML files automatically on page
  save. See ':h vimwiki-option-auto_export'.
This commit is contained in:
Maxim Kim
2010-02-23 00:00:00 +00:00
committed by Able Scraper
parent 74160d8e3e
commit bb1f5b3c46
8 changed files with 1179 additions and 184 deletions

View File

@ -23,10 +23,17 @@ function! s:chomp_slash(str) "{{{
return substitute(a:str, '[/\\]\+$', '', '')
endfunction "}}}
function! s:is_windows()
return has("win32") || has("win64") || has("win95") || has("win16")
endfunction
function! vimwiki#mkdir(path) "{{{
let path = expand(a:path)
if !isdirectory(path) && exists("*mkdir")
let path = s:chomp_slash(path)
if s:is_windows() && !empty(g:vimwiki_w32_dir_enc)
let path = iconv(path, &enc, g:vimwiki_w32_dir_enc)
endif
call mkdir(path, "p")
endif
endfunction
@ -62,6 +69,25 @@ function! vimwiki#current_subdir()"{{{
return vimwiki#subdir(VimwikiGet('path'), expand('%:p'))
endfunction"}}}
function! vimwiki#open_link(cmd, link, ...) "{{{
if s:is_link_to_non_wiki_file(a:link)
call s:edit_file(a:cmd, a:link)
else
if a:0
let vimwiki_prev_link = [a:1, []]
elseif &ft == 'vimwiki'
let vimwiki_prev_link = [expand('%:p'), getpos('.')]
endif
call s:edit_file(a:cmd, VimwikiGet('path').a:link.VimwikiGet('ext'))
if exists('vimwiki_prev_link')
let b:vimwiki_prev_link = vimwiki_prev_link
endif
endif
endfunction
" }}}
function! s:filename(link) "{{{
let result = vimwiki#safe_link(a:link)
if a:link =~ '|'
@ -165,11 +191,13 @@ function! s:print_wiki_list() "{{{
endfunction
" }}}
function! s:wiki_select(wnum)"{{{
function! vimwiki#select(wnum)"{{{
if a:wnum < 1 || a:wnum > len(g:vimwiki_list)
return
endif
let b:vimwiki_idx = g:vimwiki_current_idx
if &ft == 'vimwiki'
let b:vimwiki_idx = g:vimwiki_current_idx
endif
let g:vimwiki_current_idx = a:wnum - 1
endfunction
" }}}
@ -260,7 +288,7 @@ function! s:get_wiki_buffers() "{{{
if bufexists(bcount)
let bname = fnamemodify(bufname(bcount), ":p")
if bname =~ VimwikiGet('ext')."$"
let bitem = [bname, getbufvar(bname, "vimwiki_prev_word")]
let bitem = [bname, getbufvar(bname, "vimwiki_prev_link")]
call add(blist, bitem)
endif
endif
@ -273,7 +301,7 @@ endfunction
function! s:open_wiki_buffer(item) "{{{
call s:edit_file('e', a:item[0])
if !empty(a:item[1])
call setbufvar(a:item[0], "vimwiki_prev_word", a:item[1])
call setbufvar(a:item[0], "vimwiki_prev_link", a:item[1])
endif
endfunction
" }}}
@ -388,8 +416,8 @@ function! vimwiki#WikiFollowWord(split) "{{{
let cmd = ":e "
endif
let word = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWikiWord))
if word == ""
let link = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWikiWord))
if link == ""
let weblink = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWeblink))
if weblink != ""
call VimwikiWeblinkHandler(weblink)
@ -399,21 +427,16 @@ function! vimwiki#WikiFollowWord(split) "{{{
return
endif
if s:is_link_to_non_wiki_file(word)
call s:edit_file(cmd, word)
else
let vimwiki_prev_word = [expand('%:p'), getpos('.')]
let subdir = vimwiki#current_subdir()
call s:edit_file(cmd, VimwikiGet('path').subdir.word.VimwikiGet('ext'))
let b:vimwiki_prev_word = vimwiki_prev_word
endif
let subdir = vimwiki#current_subdir()
call vimwiki#open_link(cmd, subdir.link)
endfunction
" }}}
function! vimwiki#WikiGoBackWord() "{{{
if exists("b:vimwiki_prev_word")
if exists("b:vimwiki_prev_link")
" go back to saved WikiWord
let prev_word = b:vimwiki_prev_word
let prev_word = b:vimwiki_prev_link
execute ":e ".substitute(prev_word[0], '\s', '\\\0', 'g')
call setpos('.', prev_word[1])
endif
@ -421,7 +444,7 @@ endfunction
" }}}
function! vimwiki#WikiGoHome(index) "{{{
call s:wiki_select(a:index)
call vimwiki#select(a:index)
call vimwiki#mkdir(VimwikiGet('path'))
try
@ -523,7 +546,7 @@ function! vimwiki#WikiRenameWord() "{{{
let &buftype="nofile"
let cur_buffer = [expand('%:p'),
\getbufvar(expand('%:p'), "vimwiki_prev_word")]
\getbufvar(expand('%:p'), "vimwiki_prev_link")]
let blist = s:get_wiki_buffers()

216
autoload/vimwiki_diary.vim Normal file
View File

@ -0,0 +1,216 @@
" Vimwiki autoload plugin file
" Desc: Handle diary notes
" Author: Maxim Kim <habamax@gmail.com>
" Home: http://code.google.com/p/vimwiki/
" Load only once {{{
if exists("g:loaded_vimwiki_diary_auto") || &cp
finish
endif
let g:loaded_vimwiki_diary_auto = 1
"}}}
function! s:prefix_zero(num) "{{{
if a:num < 10
return '0'.a:num
endif
return a:num
endfunction "}}}
function! s:desc(d1, d2) "{{{
return a:d1 == a:d2 ? 0 : a:d1 < a:d2 ? 1 : -1
endfunction "}}}
function! s:get_date_link(fmt) "{{{
return strftime(a:fmt)
endfunction "}}}
function! s:link_exists(lines, link) "{{{
let link_exists = 0
for line in a:lines
if line =~ escape(a:link, '[]\')
let link_exists = 1
break
endif
endfor
return link_exists
endfunction "}}}
function! s:diary_path() "{{{
return VimwikiGet('path').VimwikiGet('diary_rel_path')
endfunction "}}}
function! s:diary_index() "{{{
return s:diary_path().VimwikiGet('diary_index').VimwikiGet('ext')
endfunction "}}}
function! s:get_diary_range(lines, header) "{{{
let rx = '\[\[\d\{4}-\d\d-\d\d\]\]'
let idx = 0
let ln_start = -1
let ln_end = -1
for line in a:lines
if ln_start != -1
if line =~ '^\s*\(=\)\+.*\1\s*$' || (line !~ rx && line !~ '^\s*$')
break
endif
endif
if line =~ '^\s*\(=\)\+\s*'.a:header.'\s*\1\s*$'
let ln_start = idx + 1
endif
let idx += 1
endfor
let ln_end = idx - 1
return [ln_start, ln_end]
endfunction "}}}
function! s:diary_date_link() "{{{
return s:get_date_link(VimwikiGet('diary_link_fmt'))
endfunction "}}}
function! s:get_file_contents(file_name) "{{{
let lines = []
let bufnr = bufnr(expand(a:file_name))
if bufnr != -1
let lines = getbufline(bufnr, 1, '$')
else
try
let lines = readfile(expand(a:file_name))
catch
endtry
endif
return [lines, bufnr]
endfunction "}}}
function! s:get_links() "{{{
let rx = '\d\{4}-\d\d-\d\d'
let s_links = glob(VimwikiGet('path').VimwikiGet('diary_rel_path').'*.wiki')
"let s_links = substitute(s_links, '\'.VimwikiGet('ext'), "", "g")
let s_links = substitute(s_links, '\.wiki', "", "g")
let links = split(s_links, '\n')
" remove backup files (.wiki~)
call filter(links, 'v:val !~ ''.*\~$''')
" remove paths
call map(links, 'fnamemodify(v:val, ":t")')
call filter(links, 'v:val =~ "'.escape(rx, '\').'"')
call map(links, '"[[".v:val."]]"')
return links
endfunction "}}}
function! s:format_links(links) "{{{
let lines = []
let line = '| '
let idx = 0
let trigger = 0
while idx < len(a:links)
if idx/VimwikiGet('diary_link_count') > trigger
let trigger = idx/VimwikiGet('diary_link_count')
call add(lines, substitute(line, '\s\+$', '', ''))
let line = '| '
endif
let line .= a:links[idx].' | '
let idx += 1
endwhile
call add(lines, substitute(line, '\s\+$', '', ''))
call extend(lines, [''])
return lines
endfunction "}}}
function! s:add_link(page, header, link) "{{{
let [lines, bufnr] = s:get_file_contents(a:page)
let [ln_start, ln_end] = s:get_diary_range(lines, a:header)
let link = '[['.a:link.']]'
let link_exists = s:link_exists(lines[ln_start : ln_end], link)
if !link_exists
if ln_start == -1
call insert(lines, '= '.a:header.' =')
let ln_start = 1
endif
" removing 'old' links
let idx = ln_end - ln_start
while idx > 0
call remove(lines, ln_start)
let idx -= 1
endwhile
" get all diary links from filesystem
let links = s:get_links()
" add current link
if index(links, link) == -1
call add(links, link)
endif
let links = sort(links, 's:desc')
call extend(lines, s:format_links(links), ln_start)
if bufnr != -1
exe 'buffer '.bufnr
if !&readonly
1,$delete _
call append(1, lines)
1,1delete _
endif
else
call writefile(lines, expand(a:page))
endif
endif
endfunction "}}}
function! s:make_date_link(...) "{{{
if a:0
let link = a:1
else
let link = s:diary_date_link()
endif
let header = VimwikiGet('diary_header')
call s:add_link(s:diary_index(), header, link)
return VimwikiGet('diary_rel_path').link
endfunction "}}}
function! vimwiki_diary#make_note(index, ...) "{{{
call vimwiki#select(a:index)
call vimwiki#mkdir(VimwikiGet('path').VimwikiGet('diary_rel_path'))
if a:0
let link = s:make_date_link(a:1)
else
let link = s:make_date_link()
endif
call vimwiki#open_link(':e ', link, s:diary_index())
endfunction "}}}
" Calendar.vim callback.
function! vimwiki_diary#calendar_action(day, month, year, week, dir) "{{{
let day = s:prefix_zero(a:day)
let month = s:prefix_zero(a:month)
let link = a:year.'-'.month.'-'.day
if winnr('#') == 0
if a:dir == 'V'
vsplit
else
split
endif
else
wincmd p
if !&hidden && &modified
new
endif
endif
" Create diary note for a selected date in default wiki.
call vimwiki_diary#make_note(1, link)
endfunction

View File

@ -3,6 +3,8 @@
" Author: Maxim Kim <habamax@gmail.com>
" Home: http://code.google.com/p/vimwiki/
" XXX: This file should be refactored!
" Load only once {{{
if exists("g:loaded_vimwiki_html_auto") || &cp
finish
@ -32,7 +34,7 @@ function! s:remove_blank_lines(lines) " {{{
endfunction "}}}
function! s:is_web_link(lnk) "{{{
if a:lnk =~ '^\%(https://\|http://\|www.\|ftp://\)'
if a:lnk =~ '^\%(https://\|http://\|www.\|ftp://\|file://\)'
return 1
endif
return 0
@ -83,7 +85,8 @@ function! s:create_default_CSS(path) " {{{
call add(lines, 'img {border: none;}')
call add(lines, 'pre {border-left: 1px solid #ccc; margin-left: 2em; padding-left: 0.5em;}')
call add(lines, 'blockquote {padding: 0.4em; background-color: #f6f5eb;}')
call add(lines, 'td {border: 1px solid #ccc; padding: 0.3em;}')
call add(lines, 'th, td {border: 1px solid #ccc; padding: 0.3em;}')
call add(lines, 'th {background-color: #f0f0f0;}')
call add(lines, 'hr {border: none; border-top: 1px solid #ccc; width: 100%;}')
call add(lines, 'del {text-decoration: line-through; color: #777777;}')
call add(lines, '.toc li {list-style-type: none;}')
@ -515,9 +518,9 @@ function! s:close_tag_para(para, ldest) "{{{
endfunction "}}}
function! s:close_tag_table(table, ldest) "{{{
if a:table
if len(a:table)
call insert(a:ldest, "</table>")
return 0
return []
endif
return a:table
endfunction "}}}
@ -774,45 +777,54 @@ function! s:process_tag_hr(line) "{{{
endfunction "}}}
function! s:process_tag_table(line, table) "{{{
" XXX: This should be refactored!!!
let table = a:table
let lines = []
let processed = 0
if a:line =~ '^||.\+||.*'
if !table
call add(lines, "<table>")
let table = 1
if a:line =~ '^\s*|[-+]\+|\s*$' && len(table)
call add(table, [])
let processed = 1
elseif a:line =~ '^\s*|.\+|\s*$'
if empty(table)
let table = [[]]
else
call add(table, [])
endif
let processed = 1
call add(lines, "<tr>")
let pos1 = 0
let pos2 = 0
let done = 0
while !done
let pos1 = stridx(a:line, '||', pos2)
let pos2 = stridx(a:line, '||', pos1+2)
if pos1==-1 || pos2==-1
let done = 1
let pos2 = len(a:line)
endif
let line = strpart(a:line, pos1+2, pos2-pos1-2)
if line == ''
continue
endif
if strpart(line, 0, 1) == ' ' &&
\ strpart(line, len(line) - 1, 1) == ' '
call add(lines, '<td class="justcenter">'.line.'</td>')
elseif strpart(line, 0, 1) == ' '
call add(lines, '<td class="justright">'.line.'</td>')
else
call add(lines, '<td class="justleft">'.line.'</td>')
endif
endwhile
call add(lines, "</tr>")
call extend(table[-1], split(a:line, '\s*|\s*'))
elseif table
elseif len(table)
call add(lines, "<table>")
let head = 0
for idx in range(len(table))
if empty(table[idx])
let head = idx
break
endif
endfor
if head > 0
for row in table[: head-1]
call add(lines, '<tr>')
call extend(lines, map(row, '"<th>".v:val."</th>"'))
call add(lines, '</tr>')
endfor
for row in table[head+1 :]
call add(lines, '<tr>')
call extend(lines, map(row, '"<td>".v:val."</td>"'))
call add(lines, '</tr>')
endfor
else
for row in table
call add(lines, '<tr>')
call extend(lines, map(row, '"<td>".v:val."</td>"'))
call add(lines, '</tr>')
endfor
endif
call add(lines, "</table>")
let table = 0
let table = []
endif
return [processed, lines, table]
endfunction "}}}
@ -820,12 +832,12 @@ endfunction "}}}
"}}}
" WIKI2HTML "{{{
function! s:wiki2html(line, state) " {{{
function! s:parse_line(line, state) " {{{
let state = {}
let state.para = a:state.para
let state.quote = a:state.quote
let state.pre = a:state.pre
let state.table = a:state.table
let state.table = a:state.table[:]
let state.lists = a:state.lists[:]
let state.deflist = a:state.deflist
let state.placeholder = a:state.placeholder
@ -838,7 +850,7 @@ function! s:wiki2html(line, state) " {{{
let processed = 0
" toc -- placeholder
" toc -- placeholder "{{{
if !processed
if line =~ '^\s*%toc'
let processed = 1
@ -846,14 +858,15 @@ function! s:wiki2html(line, state) " {{{
let state.placeholder = ['toc', param]
endif
endif
"}}}
" pres
" pres "{{{
if !processed
let [processed, lines, state.pre] = s:process_tag_pre(line, state.pre)
if processed && len(state.lists)
call s:close_tag_list(state.lists, lines)
endif
if processed && state.table
if processed && len(state.table)
let state.table = s:close_tag_table(state.table, lines)
endif
if processed && state.deflist
@ -867,8 +880,9 @@ function! s:wiki2html(line, state) " {{{
endif
call extend(res_lines, lines)
endif
"}}}
" lists
" lists "{{{
if !processed
let [processed, lines] = s:process_tag_list(line, state.lists)
if processed && state.quote
@ -877,7 +891,7 @@ function! s:wiki2html(line, state) " {{{
if processed && state.pre
let state.pre = s:close_tag_pre(state.pre, lines)
endif
if processed && state.table
if processed && len(state.table)
let state.table = s:close_tag_table(state.table, lines)
endif
if processed && state.deflist
@ -891,8 +905,9 @@ function! s:wiki2html(line, state) " {{{
call extend(res_lines, lines)
endif
"}}}
" headers
" headers "{{{
if !processed
let [processed, line, h_level, h_text, h_id] = s:process_tag_h(line, state.toc_id)
if processed
@ -900,6 +915,9 @@ function! s:wiki2html(line, state) " {{{
let state.table = s:close_tag_table(state.table, res_lines)
let state.pre = s:close_tag_pre(state.pre, res_lines)
let state.quote = s:close_tag_quote(state.quote, res_lines)
let line = s:make_tag(line, g:vimwiki_rxTodo, 's:tag_todo')
call add(res_lines, line)
" gather information for table of contents
@ -907,8 +925,9 @@ function! s:wiki2html(line, state) " {{{
let state.toc_id += 1
endif
endif
"}}}
" quotes
" quotes "{{{
if !processed
let [processed, lines, state.quote] = s:process_tag_quote(line, state.quote)
if processed && len(state.lists)
@ -917,7 +936,7 @@ function! s:wiki2html(line, state) " {{{
if processed && state.deflist
let state.deflist = s:close_tag_def_list(state.deflist, lines)
endif
if processed && state.table
if processed && len(state.table)
let state.table = s:close_tag_table(state.table, lines)
endif
if processed && state.pre
@ -931,17 +950,9 @@ function! s:wiki2html(line, state) " {{{
call extend(res_lines, lines)
endif
"}}}
" definition lists
if !processed
let [processed, lines, state.deflist] = s:process_tag_def_list(line, state.deflist)
call map(lines, 's:process_inline_tags(v:val)')
call extend(res_lines, lines)
endif
" tables
" tables "{{{
if !processed
let [processed, lines, state.table] = s:process_tag_table(line, state.table)
@ -949,8 +960,9 @@ function! s:wiki2html(line, state) " {{{
call extend(res_lines, lines)
endif
"}}}
" horizontal lines
" horizontal rules "{{{
if !processed
let [processed, line] = s:process_tag_hr(line)
if processed
@ -960,8 +972,19 @@ function! s:wiki2html(line, state) " {{{
call add(res_lines, line)
endif
endif
"}}}
"" P
" definition lists "{{{
if !processed
let [processed, lines, state.deflist] = s:process_tag_def_list(line, state.deflist)
call map(lines, 's:process_inline_tags(v:val)')
call extend(res_lines, lines)
endif
"}}}
"" P "{{{
if !processed
let [processed, lines, state.para] = s:process_tag_para(line, state.para)
if processed && len(state.lists)
@ -973,7 +996,7 @@ function! s:wiki2html(line, state) " {{{
if processed && state.pre
let state.pre = s:close_tag_pre(state.pre, res_lines)
endif
if processed && state.table
if processed && len(state.table)
let state.table = s:close_tag_table(state.table, res_lines)
endif
@ -981,6 +1004,7 @@ function! s:wiki2html(line, state) " {{{
call extend(res_lines, lines)
endif
"}}}
"" add the rest
if !processed
@ -1015,7 +1039,7 @@ function! vimwiki_html#Wiki2HTML(path, wikifile) "{{{
let state.para = 0
let state.quote = 0
let state.pre = 0
let state.table = 0
let state.table = []
let state.deflist = 0
let state.lists = []
let state.placeholder = []
@ -1024,7 +1048,7 @@ function! vimwiki_html#Wiki2HTML(path, wikifile) "{{{
for line in lsource
let oldquote = state.quote
let [lines, state] = s:wiki2html(line, state)
let [lines, state] = s:parse_line(line, state)
" Hack: There could be a lot of empty strings before s:process_tag_quote
" find out `quote` is over. So we should delete them all. Think of the way

335
autoload/vimwiki_tbl.vim Normal file
View File

@ -0,0 +1,335 @@
" Vimwiki autoload plugin file
" Desc: Tables
" | Easily | manageable | text | tables | ! |
" |--------+------------+-------+--------+---------|
" | Have | fun! | Drink | tea | Period. |
"
" Author: Maxim Kim <habamax@gmail.com>
" Home: http://code.google.com/p/vimwiki/
" Load only once {{{
if exists("g:loaded_vimwiki_tbl_auto") || &cp
finish
endif
let g:loaded_vimwiki_tbl_auto = 1
"}}}
let s:textwidth = &tw
" Misc functions {{{
function! s:wide_len(str) "{{{
return strlen(substitute(a:str, '.', 'x', 'g'))
endfunction "}}}
function! s:is_table(line) "{{{
return a:line =~ '^\s*\%(|[^|]\+\)\+|\s*$' || s:is_separator(a:line)
endfunction "}}}
function! s:is_separator(line) "{{{
return a:line =~ '^\s*|\s*-\+'
endfunction "}}}
function! s:is_last_column(lnum, cnum) "{{{
return strpart(getline(a:lnum), a:cnum - 1) =~ '^[^|]*|\s*$'
endfunction "}}}
function! s:count_separators(lnum) "{{{
let lnum = a:lnum + 1
while lnum < line('$')
if !s:is_separator(getline(lnum))
break
endif
let lnum += 1
endwhile
return (lnum-a:lnum)
endfunction "}}}
function! s:create_empty_row(cols) "{{{
let first_cell = "| |"
let cell = " |"
let row = first_cell
for c in range(a:cols - 1)
let row .= cell
endfor
return row
endfunction "}}}
function! s:create_row_sep(cols) "{{{
let first_cell = "|---+"
let cell = "---+"
let last_cell = "---|"
if a:cols < 2
return "|---|"
endif
let row = first_cell
for c in range(a:cols - 2)
let row .= cell
endfor
let row .= last_cell
return row
endfunction "}}}
function! s:get_values(line) "{{{
let cells = []
let cnt = 0
let idx = 0
while idx != -1 && idx < strlen(a:line) - 1
let cell = matchstr(a:line, '|\zs[^|]\+\ze|', idx)
let cell = substitute(cell, '^\s*\(.\{-}\)\s*$', '\1', 'g')
call add(cells, [cnt, cell])
let cnt += 1
let idx = matchend(a:line, '|\zs[^|]\+\ze|', idx)
endwhile
return cells
endfunction "}}}
function! s:get_rows(lnum) "{{{
if !s:is_table(getline(a:lnum))
return
endif
let upper_rows = []
let lower_rows = []
let lnum = a:lnum - 1
while lnum > 1
let line = getline(lnum)
if s:is_table(line)
call add(upper_rows, [lnum, line])
else
break
endif
let lnum -= 1
endwhile
call reverse(upper_rows)
let lnum = a:lnum
while lnum <= line('$')
let line = getline(lnum)
if s:is_table(line)
call add(lower_rows, [lnum, line])
else
break
endif
let lnum += 1
endwhile
return upper_rows + lower_rows
endfunction "}}}
function! s:get_cell_max_lens(lnum) "{{{
let max_lens = {}
for [lnum, row] in s:get_rows(a:lnum)
if s:is_separator(row)
continue
endif
for [idx, cell] in s:get_values(row)
if has_key(max_lens, idx)
let max_lens[idx] = max([s:wide_len(cell), max_lens[idx]])
else
let max_lens[idx] = s:wide_len(cell)
endif
endfor
endfor
return max_lens
endfunction "}}}
function! s:get_aligned_rows(lnum, max_lens) "{{{
let rows = []
for [lnum, row] in s:get_rows(a:lnum)
if s:is_separator(row)
let new_row = s:fmt_sep(a:max_lens)
else
let new_row = s:fmt_row(row, a:max_lens)
endif
call add(rows, [lnum, new_row])
endfor
return rows
endfunction "}}}
" }}}
" Format functions {{{
function! s:fmt_cell(cell, max_len) "{{{
let cell = ' '.a:cell.' '
let diff = a:max_len - s:wide_len(a:cell)
if diff == 0 && empty(a:cell)
let diff = 1
endif
let cell .= repeat(' ', diff)
return cell
endfunction "}}}
function! s:fmt_row(line, max_lens) "{{{
let new_line = '|'
let values = s:get_values(a:line)
for [idx, cell] in values
let new_line .= s:fmt_cell(cell, a:max_lens[idx]).'|'
endfor
let idx = len(values)
while idx < len(a:max_lens)
let new_line .= s:fmt_cell('', a:max_lens[idx]).'|'
let idx += 1
endwhile
return new_line
endfunction "}}}
function! s:fmt_cell_sep(max_len) "{{{
if a:max_len == 0
return repeat('-', 3)
else
return repeat('-', a:max_len+2)
endif
endfunction "}}}
function! s:fmt_sep(max_lens) "{{{
let sep = '|'
for idx in range(len(a:max_lens))
let sep .= s:fmt_cell_sep(a:max_lens[idx]).'+'
endfor
let sep = substitute(sep, '+$', '|', '')
return sep
endfunction "}}}
"}}}
" Keyboard functions "{{{
function! s:kbd_create_new_row(cols, goto_first) "{{{
let cmd = "\<ESC>o".s:create_empty_row(a:cols)
let cmd .= "\<ESC>:call vimwiki_tbl#format(line('.'))\<CR>"
if a:goto_first
let cmd .= "0f|T|a"
else
let cmd .= "0".(col('.')-1)."lT|a"
endif
return cmd
endfunction "}}}
function! s:kbd_goto_next_row() "{{{
let cmd = "\<ESC>jt|T|a"
return cmd
endfunction "}}}
function! s:kbd_goto_next_col(last) "{{{
if col('.') == 1
let cmd = "\<ESC>la"
else
if a:last
let seps = s:count_separators(line('.'))
let cmd = "\<ESC>".seps."j0f|F|la"
else
let cmd = "\<ESC>f|la"
endif
endif
return cmd
endfunction "}}}
"}}}
" Global functions {{{
function! vimwiki_tbl#kbd_cr() "{{{
let lnum = line('.')
if !s:is_table(getline(lnum))
return "\<CR>"
endif
if s:is_separator(getline(lnum+1)) || !s:is_table(getline(lnum+1))
let cols = len(s:get_values(getline(lnum)))
return s:kbd_create_new_row(cols, 0)
else
return s:kbd_goto_next_row()
endif
endfunction "}}}
function! vimwiki_tbl#kbd_tab() "{{{
let lnum = line('.')
if !s:is_table(getline(lnum))
return "\<Tab>"
endif
let last = s:is_last_column(lnum, col('.'))
if last && !s:is_table(getline(lnum+1))
let cols = len(s:get_values(getline(lnum)))
return s:kbd_create_new_row(cols, 1)
endif
return s:kbd_goto_next_col(last)
endfunction "}}}
function! vimwiki_tbl#format(lnum) "{{{
let line = getline(a:lnum)
if !s:is_table(line)
return
endif
let max_lens = s:get_cell_max_lens(a:lnum)
for [lnum, row] in s:get_aligned_rows(a:lnum, max_lens)
call setline(lnum, row)
endfor
let &tw = s:textwidth
endfunction "}}}
function! vimwiki_tbl#create(...) "{{{
if a:0 > 1
let cols = a:1
let rows = a:2
elseif a:0 == 1
let cols = a:1
let rows = 2
elseif a:0 == 0
let cols = 5
let rows = 2
endif
if cols < 1
let cols = 5
endif
if rows < 1
let rows = 2
endif
let lines = []
let row = s:create_empty_row(cols)
call add(lines, row)
if rows > 1
call add(lines, s:create_row_sep(cols))
endif
for r in range(rows - 1)
call add(lines, row)
endfor
call append(line('.'), lines)
endfunction "}}}
function! vimwiki_tbl#align_or_cmd(cmd) "{{{
if s:is_table(getline('.'))
call vimwiki_tbl#format(line('.'))
else
exe 'normal! '.a:cmd
endif
endfunction "}}}
function! vimwiki_tbl#reset_tw(lnum) "{{{
let line = getline(a:lnum)
if !s:is_table(line)
return
endif
let s:textwidth = &tw
let &tw = 0
endfunction "}}}
"}}}