vimwiki

Personal wiki for vim
git clone https://github.com/vimwiki/vimwiki.git
Log | Files | Refs | README | LICENSE

commit 8e53e53ffec643f48cb3001ec45745dcdde900d2
parent bb1f5b3c469aa08deb94387aa4e40eedcc6b85e5
Author: Maxim Kim <habamax@gmail.com>
Date:   Wed, 12 May 2010 00:00:00 +0000

Version 1.0

* NEW: Issue 41: Table cell and column text objects. See `vimwiki-text-objects`.
* NEW: Issue 42: Commands to move table columns left and right. See `:VimwikiTableMoveColumnLeft` and `:VimwikiTableMoveColumnRight`.
* NEW: Issue 44: `<S-Tab>` should move cursor to the previous table cell.
* NEW: Issue 45: It should be possible to indent tables. Indented tables are centered in html.
* NEW: Issue 46: Do not htmlize some wiki pages (blacklist). New placeholder is added: `%nohtml`. See `vimwiki-nohtml`.
* FIX: Issue 47: Lists aren't HTMLized properly.
* FIX: Issue 48: With autochdir it is impossible to have path_html such as `d:\vimwiki\html\`
* FIX: Issue 49: Table is not HTMLized properly at the end of wiki page.
* FIX: Issue 50: Inline formatting is not performed in table cells.
* FIX: Issue 51: Cannot insert '-' (minus) into table cells of the first column.
* FIX: Issue 52: Table cell width is incorrect when double wide characters are used (ie. Chinese). Check `g:vimwiki_CJK_length`.
* NEW: Issue 53: Wiki markup can not nested. (Use links and inline markup in Headers).
* NEW: Issue 54: Highlight for placeholders.
* NEW: Issue 56: Directory indexes. See `g:vimwiki_dir_link` option and `:VimwikiGenerateLinks` command.
* NEW: Issue 58: Html new lines with `<br />`. Could be inserted with `<S-CR>` in insert mode.
* FIX: Issue 59: List item's text can't be started from `*`.
* NEW: Issue 60: Links inside completed gtd-items.
* NEW: Issue 61: Headers numbering. See `g:vimwiki_html_header_numbering` and `g:vimwiki_html_header_numbering_sym` options.
* FIX: Issue 63: Table cannot have leading empty cells in html.
* FIX: Issue 65: Table separator is not htmlized right if on top of the table.
* FIX: Issue 66: Table empty cells are very small in html.
* FIX: Issue 67: Wrong html conversion of multilined list item with bold text on the start of next line.
* FIX: Issue 68: auto-indent problem with langmap.
* FIX: Issue 73: Link navigation by Tab. "Escaped" wiki-word should be skipped for navigation with `<tab>`.
* FIX: Issue 75: `code` syntax doesn't display correctly in toc.
* FIX: Issue 77: Diary index only showing link to today's diary entry file for extensions other than '.wiki'.
* FIX: Issue 79: Further calendar.vim integration -- add sign to calendar date if it has corresponding diary page.
* FIX: Issue 80: Debian Lenny GUI Vim 7.2 has problems with toggling inner todo list items.
* FIX: Issue 81: Don't convert `WikiWord` as a link in html when `let g:vimwiki_camel_case = 0`


Diffstat:
Mautoload/vimwiki.vim | 356++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mautoload/vimwiki_diary.vim | 16++++++++++++----
Mautoload/vimwiki_html.vim | 494+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mautoload/vimwiki_lst.vim | 5+++--
Mautoload/vimwiki_tbl.vim | 245++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mdoc/vimwiki.txt | 300++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Mftplugin/vimwiki.vim | 48++++++++++++++++++++++++++++++++++++++++++------
Mplugin/vimwiki.vim | 43++++++++++++++++++++++++++-----------------
Msyntax/vimwiki.vim | 40++++++++++++++++++++++++++--------------
Msyntax/vimwiki_default.vim | 10+++++-----
Msyntax/vimwiki_media.vim | 2+-
11 files changed, 1204 insertions(+), 355 deletions(-)

diff --git a/autoload/vimwiki.vim b/autoload/vimwiki.vim @@ -1,3 +1,4 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki autoload plugin file " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ @@ -17,20 +18,14 @@ let s:badsymbols = '['.g:vimwiki_badsyms.g:vimwiki_stripsym.'<>|?*:"]' " MISC helper functions {{{ -" This function is double defined. -" TODO: refactor common functions into new module. -function! s:chomp_slash(str) "{{{ +function! vimwiki#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) + let path = vimwiki#chomp_slash(path) if s:is_windows() && !empty(g:vimwiki_w32_dir_enc) let path = iconv(path, &enc, g:vimwiki_w32_dir_enc) endif @@ -53,7 +48,7 @@ function! vimwiki#subdir(path, filename)"{{{ let path = expand(a:path) let filename = expand(a:filename) let idx = 0 - while path[idx] == filename[idx] + while path[idx] ==? filename[idx] let idx = idx + 1 endwhile @@ -79,7 +74,18 @@ function! vimwiki#open_link(cmd, link, ...) "{{{ let vimwiki_prev_link = [expand('%:p'), getpos('.')] endif - call s:edit_file(a:cmd, VimwikiGet('path').a:link.VimwikiGet('ext')) + if vimwiki#is_link_to_dir(a:link) + if g:vimwiki_dir_link == '' + call s:edit_file(a:cmd, VimwikiGet('path').a:link) + else + call s:edit_file(a:cmd, + \ VimwikiGet('path').a:link. + \ g:vimwiki_dir_link. + \ VimwikiGet('ext')) + endif + else + call s:edit_file(a:cmd, VimwikiGet('path').a:link.VimwikiGet('ext')) + endif if exists('vimwiki_prev_link') let b:vimwiki_prev_link = vimwiki_prev_link @@ -88,6 +94,71 @@ function! vimwiki#open_link(cmd, link, ...) "{{{ endfunction " }}} +function! vimwiki#select(wnum)"{{{ + if a:wnum < 1 || a:wnum > len(g:vimwiki_list) + return + endif + if &ft == 'vimwiki' + let b:vimwiki_idx = g:vimwiki_current_idx + endif + let g:vimwiki_current_idx = a:wnum - 1 +endfunction +" }}} + +function! vimwiki#generate_links()"{{{ + let links = s:get_links('*'.VimwikiGet('ext')) + + " We don't want link to itself. + let cur_link = expand('%:t:r') + call filter(links, 'v:val != cur_link') + + if len(links) + call append(line('$'), '= Generated Links =') + endif + + call sort(links) + + for link in links + if s:is_wiki_word(link) + call append(line('$'), '- '.link) + else + call append(line('$'), '- [['.link.']]') + endif + endfor +endfunction " }}} + +function! s:is_windows() "{{{ + return has("win32") || has("win64") || has("win95") || has("win16") +endfunction "}}} + +function! s:get_links(pat) "{{{ + " search all wiki files in 'path' and its subdirs. + let subdir = vimwiki#current_subdir() + let globlinks = glob(VimwikiGet('path').subdir.'**/'.a:pat) + + " remove .wiki extensions + let globlinks = substitute(globlinks, '\'.VimwikiGet('ext'), "", "g") + let links = split(globlinks, '\n') + + " remove backup files (.wiki~) + call filter(links, 'v:val !~ ''.*\~$''') + + " remove paths + let rem_path = escape(expand(VimwikiGet('path')).subdir, '\') + call map(links, 'substitute(v:val, rem_path, "", "g")') + + " Remove trailing slashes. + call map(links, 'substitute(v:val, "[/\\\\]*$", "", "g")') + + return links +endfunction "}}} + +" Builtin cursor doesn't work right with unicode characters. +function! s:cursor(lnum, cnum) "{{{ + exe a:lnum + exe 'normal! 0'.a:cnum.'|' +endfunction "}}} + function! s:filename(link) "{{{ let result = vimwiki#safe_link(a:link) if a:link =~ '|' @@ -100,7 +171,7 @@ endfunction " }}} function! s:is_wiki_word(str) "{{{ - if a:str =~ g:vimwiki_word1 && a:str !~ '[[:space:]\\/]' + if a:str =~ g:vimwiki_rxWikiWord && a:str !~ '[[:space:]\\/]' return 1 endif return 0 @@ -164,10 +235,20 @@ function! s:strip_word(word) "{{{ endfunction " }}} -function! s:is_link_to_non_wiki_file(word) "{{{ - " Check if word is link to a non-wiki file. +function! s:is_link_to_non_wiki_file(link) "{{{ + " Check if link is to a non-wiki file. " The easiest way is to check if it has extension like .txt or .html - if a:word =~ '\.\w\{1,4}$' + if a:link =~ '\.\w\{1,4}$' + return 1 + endif + return 0 +endfunction +" }}} + +function! vimwiki#is_link_to_dir(link) "{{{ + " Check if link is to a directory. + " It should be ended with \ or /. + if a:link =~ '.\+[/\\]$' return 1 endif return 0 @@ -191,17 +272,6 @@ function! s:print_wiki_list() "{{{ endfunction " }}} -function! vimwiki#select(wnum)"{{{ - if a:wnum < 1 || a:wnum > len(g:vimwiki_list) - return - endif - if &ft == 'vimwiki' - let b:vimwiki_idx = g:vimwiki_current_idx - endif - let g:vimwiki_current_idx = a:wnum - 1 -endfunction -" }}} - function! s:update_wiki_link(fname, old, new) " {{{ echo "Updating links in ".a:fname let has_updates = 0 @@ -309,42 +379,38 @@ endfunction " }}} " SYNTAX highlight {{{ -function! vimwiki#WikiHighlightWords() "{{{ - " search all wiki files in 'path' and its subdirs. - let subdir = vimwiki#current_subdir() - let wikies = glob(VimwikiGet('path').subdir.'**/*'.VimwikiGet('ext')) - - " remove .wiki extensions - let wikies = substitute(wikies, '\'.VimwikiGet('ext'), "", "g") - let g:vimwiki_wikiwords = split(wikies, '\n') - - " remove backup files (.wiki~) - call filter(g:vimwiki_wikiwords, 'v:val !~ ''.*\~$''') - - " remove paths - let rem_path = escape(expand(VimwikiGet('path')).subdir, '\') - call map(g:vimwiki_wikiwords, 'substitute(v:val, rem_path, "", "g")') +function! vimwiki#WikiHighlightLinks() "{{{ + let links = s:get_links('*'.VimwikiGet('ext')) " Links with subdirs should be highlighted for linux and windows separators " Change \ or / to [/\\] let os_p = '[/\\]' let os_p2 = escape(os_p, '\') - call map(g:vimwiki_wikiwords, 'substitute(v:val, os_p, os_p2, "g")') + call map(links, 'substitute(v:val, os_p, os_p2, "g")') - for word in g:vimwiki_wikiwords + for link in links if g:vimwiki_camel_case && - \ word =~ g:vimwiki_word1 && !s:is_link_to_non_wiki_file(word) - execute 'syntax match VimwikiWord /\%(^\|[^!]\)\@<=\<'.word.'\>/' + \ link =~ g:vimwiki_rxWikiWord && !s:is_link_to_non_wiki_file(link) + execute 'syntax match VimwikiLink /!\@<!\<'.link.'\>/' endif - execute 'syntax match VimwikiWord /\[\[\<'. - \ vimwiki#unsafe_link(word). + execute 'syntax match VimwikiLink /\[\[\<'. + \ vimwiki#unsafe_link(link). \ '\>\%(|\+.*\)*\]\]/' - execute 'syntax match VimwikiWord /\[\[\<'. - \ vimwiki#unsafe_link(word). + execute 'syntax match VimwikiLink /\[\[\<'. + \ vimwiki#unsafe_link(link). \ '\>\]\[.\+\]\]/' endfor - execute 'syntax match VimwikiWord /\[\[.\+\.\%(jpg\|png\|gif\)\%(|\+.*\)*\]\]/' - execute 'syntax match VimwikiWord /\[\[.\+\.\%(jpg\|png\|gif\)\]\[.\+\]\]/' + execute 'syntax match VimwikiLink /\[\[.\+\.\%(jpg\|png\|gif\)\%(|\+.*\)*\]\]/' + execute 'syntax match VimwikiLink /\[\[.\+\.\%(jpg\|png\|gif\)\]\[.\+\]\]/' + + " highlight dirs + let dirs = s:get_links('*/') + call map(dirs, 'substitute(v:val, os_p, os_p2, "g")') + for dir in dirs + execute 'syntax match VimwikiLink /\[\[\<'. + \ vimwiki#unsafe_link(dir). + \ '\>[/\\]*\%(|\+.*\)*\]\]/' + endfor endfunction " }}} @@ -398,12 +464,12 @@ endfunction "}}} " WIKI functions {{{ function! vimwiki#WikiNextWord() "{{{ - call s:search_word(g:vimwiki_rxWikiWord.'\|'.g:vimwiki_rxWeblink, '') + call s:search_word(g:vimwiki_rxWikiLink.'\|'.g:vimwiki_rxWeblink, '') endfunction " }}} function! vimwiki#WikiPrevWord() "{{{ - call s:search_word(g:vimwiki_rxWikiWord.'\|'.g:vimwiki_rxWeblink, 'b') + call s:search_word(g:vimwiki_rxWikiLink.'\|'.g:vimwiki_rxWeblink, 'b') endfunction " }}} @@ -416,7 +482,7 @@ function! vimwiki#WikiFollowWord(split) "{{{ let cmd = ":e " endif - let link = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWikiWord)) + let link = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWikiLink)) if link == "" let weblink = s:strip_word(s:get_word_at_cursor(g:vimwiki_rxWeblink)) if weblink != "" @@ -601,7 +667,7 @@ endfunction " TEXT OBJECTS functions {{{ function! vimwiki#TO_header(inner, visual) "{{{ - if !search('^\(=\+\)[^=]\+\1\s*$', 'bcW') + if !search('^\(=\+\).\+\1\s*$', 'bcW') return endif @@ -618,7 +684,7 @@ function! vimwiki#TO_header(inner, visual) "{{{ if a:visual && is_header_selected if level > 1 let level -= 1 - call search('^\(=\{'.level.'\}\)[^=]\+\1\s*$', 'bcW') + call search('^\(=\{'.level.'\}\).\+\1\s*$', 'bcW') else let advance = 1 endif @@ -630,7 +696,7 @@ function! vimwiki#TO_header(inner, visual) "{{{ call cursor(sel_end + advance, 0) endif - if search('^\(=\{1,'.level.'}\)[^=]\+\1\s*$', 'W') + if search('^\(=\{1,'.level.'}\).\+\1\s*$', 'W') call cursor(line('.') - 1, 0) else call cursor(line('$'), 0) @@ -643,6 +709,184 @@ function! vimwiki#TO_header(inner, visual) "{{{ endfunction "}}} +function! vimwiki#TO_table_cell(inner, visual) "{{{ + if col('.') == col('$')-1 + return + endif + + if a:visual + normal! `> + let sel_end = getpos('.') + normal! `< + let sel_start = getpos('.') + + let firsttime = sel_start == sel_end + + if firsttime + if !search('|\|\(-+-\)', 'cb', line('.')) + return + endif + if getline('.')[virtcol('.')] == '+' + normal! l + endif + if a:inner + normal! 2l + endif + let sel_start = getpos('.') + endif + + normal! `> + call search('|\|\(-+-\)', '', line('.')) + if getline('.')[virtcol('.')] == '+' + normal! l + endif + if a:inner + if firsttime || abs(sel_end[2] - getpos('.')[2]) != 2 + normal! 2h + endif + endif + let sel_end = getpos('.') + + call setpos('.', sel_start) + exe "normal! \<C-v>" + call setpos('.', sel_end) + + " XXX: WORKAROUND. + " if blockwise selection is ended at | character then pressing j to extend + " selection furhter fails. But if we shake the cursor left and right then + " it works. + normal! hl + else + if !search('|\|\(-+-\)', 'cb', line('.')) + return + endif + if a:inner + normal! 2l + endif + normal! v + call search('|\|\(-+-\)', '', line('.')) + if !a:inner && getline('.')[virtcol('.')-1] == '|' + normal! h + elseif a:inner + normal! 2h + endif + endif +endfunction "}}} + +function! vimwiki#TO_table_col(inner, visual) "{{{ + let t_rows = vimwiki_tbl#get_rows(line('.')) + if empty(t_rows) + return + endif + + " TODO: refactor it! + if a:visual + normal! `> + let sel_end = getpos('.') + normal! `< + let sel_start = getpos('.') + + let firsttime = sel_start == sel_end + + if firsttime + " place cursor to the top row of the table + call s:cursor(t_rows[0][0], virtcol('.')) + " do not accept the match at cursor position if cursor is next to column + " separator of the table separator (^ is a cursor): + " |-----^-+-------| + " | bla | bla | + " |-------+-------| + " or it will select wrong column. + if strpart(getline('.'), virtcol('.')-1) =~ '^-+' + let s_flag = 'b' + else + let s_flag = 'cb' + endif + " search the column separator backwards + if !search('|\|\(-+-\)', s_flag, line('.')) + return + endif + " -+- column separator is matched --> move cursor to the + sign + if getline('.')[virtcol('.')] == '+' + normal! l + endif + " inner selection --> reduce selection + if a:inner + normal! 2l + endif + let sel_start = getpos('.') + endif + + normal! `> + if !firsttime && getline('.')[virtcol('.')] == '|' + normal! l + elseif a:inner && getline('.')[virtcol('.')+1] =~ '[|+]' + normal! 2l + endif + " search for the next column separator + call search('|\|\(-+-\)', '', line('.')) + " Outer selection selects a column without border on the right. So we move + " our cursor left if the previous search finds | border, not -+-. + if getline('.')[virtcol('.')] != '+' + normal! h + endif + if a:inner + " reduce selection a bit more if inner. + normal! h + endif + " expand selection to the bottom line of the table + call s:cursor(t_rows[-1][0], virtcol('.')) + let sel_end = getpos('.') + + call setpos('.', sel_start) + exe "normal! \<C-v>" + call setpos('.', sel_end) + + else + " place cursor to the top row of the table + call s:cursor(t_rows[0][0], virtcol('.')) + " do not accept the match at cursor position if cursor is next to column + " separator of the table separator (^ is a cursor): + " |-----^-+-------| + " | bla | bla | + " |-------+-------| + " or it will select wrong column. + if strpart(getline('.'), virtcol('.')-1) =~ '^-+' + let s_flag = 'b' + else + let s_flag = 'cb' + endif + " search the column separator backwards + if !search('|\|\(-+-\)', s_flag, line('.')) + return + endif + " -+- column separator is matched --> move cursor to the + sign + if getline('.')[virtcol('.')] == '+' + normal! l + endif + " inner selection --> reduce selection + if a:inner + normal! 2l + endif + + exe "normal! \<C-V>" + + " search for the next column separator + call search('|\|\(-+-\)', '', line('.')) + " Outer selection selects a column without border on the right. So we move + " our cursor left if the previous search finds | border, not -+-. + if getline('.')[virtcol('.')] != '+' + normal! h + endif + " reduce selection a bit more if inner. + if a:inner + normal! h + endif + " expand selection to the bottom line of the table + call s:cursor(t_rows[-1][0], virtcol('.')) + endif +endfunction "}}} + function! vimwiki#count_first_sym(line) "{{{ let first_sym = matchstr(a:line, '\S') return len(matchstr(a:line, first_sym.'\+')) diff --git a/autoload/vimwiki_diary.vim b/autoload/vimwiki_diary.vim @@ -1,3 +1,4 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki autoload plugin file " Desc: Handle diary notes " Author: Maxim Kim <habamax@gmail.com> @@ -85,10 +86,10 @@ 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 = glob(VimwikiGet('path').VimwikiGet('diary_rel_path'). + \ '*'.VimwikiGet('ext')) - "let s_links = substitute(s_links, '\'.VimwikiGet('ext'), "", "g") - let s_links = substitute(s_links, '\.wiki', "", "g") + let s_links = substitute(s_links, '\'.VimwikiGet('ext'), "", "g") let links = split(s_links, '\n') " remove backup files (.wiki~) @@ -191,7 +192,7 @@ function! vimwiki_diary#make_note(index, ...) "{{{ call vimwiki#open_link(':e ', link, s:diary_index()) endfunction "}}} -" Calendar.vim callback. +" Calendar.vim callback and sign functions. function! vimwiki_diary#calendar_action(day, month, year, week, dir) "{{{ let day = s:prefix_zero(a:day) let month = s:prefix_zero(a:month) @@ -214,3 +215,10 @@ function! vimwiki_diary#calendar_action(day, month, year, week, dir) "{{{ call vimwiki_diary#make_note(1, link) endfunction +function vimwiki_diary#calendar_sign(day, month, year) "{{{ + let day = s:prefix_zero(a:day) + let month = s:prefix_zero(a:month) + let sfile = VimwikiGet('path').VimwikiGet('diary_rel_path'). + \ a:year.'-'.month.'-'.day.VimwikiGet('ext') + return filereadable(expand(sfile)) +endfunction "}}} diff --git a/autoload/vimwiki_html.vim b/autoload/vimwiki_html.vim @@ -1,3 +1,4 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki autoload plugin file " Export to HTML " Author: Maxim Kim <habamax@gmail.com> @@ -28,7 +29,7 @@ function! s:syntax_supported() " {{{ endfunction " }}} function! s:remove_blank_lines(lines) " {{{ - while a:lines[-1] =~ '^\s*$' + while !empty(a:lines) && a:lines[-1] =~ '^\s*$' call remove(a:lines, -1) endwhile endfunction "}}} @@ -69,7 +70,7 @@ function! s:create_default_CSS(path) " {{{ call vimwiki#mkdir(fnamemodify(css_full_name, ':p:h')) let lines = [] - call add(lines, 'body {font-family: Arial, sans-serif; margin: 1em 2em 1em 2em; font-size: 100%; line-height: 130%;}') + call add(lines, 'body {font-family: Tahoma, sans-serif; margin: 1em 2em 1em 2em; font-size: 100%; line-height: 130%;}') call add(lines, 'h1, h2, h3, h4, h5, h6 {font-family: Trebuchet MS, serif; margin-top: 1.5em; margin-bottom: 0.5em;}') call add(lines, 'h1 {font-size: 2.0em; color: #a77070;}') call add(lines, 'h2 {font-size: 1.6em; color: #779977;}') @@ -94,6 +95,7 @@ function! s:create_default_CSS(path) " {{{ call add(lines, '.justleft {text-align: left;}') call add(lines, '.justright {text-align: right;}') call add(lines, '.justcenter {text-align: center;}') + call add(lines, '.center {margin-left: auto; margin-right: auto;}') call writefile(lines, css_full_name) echomsg "Default style.css is created." @@ -165,11 +167,15 @@ function! s:get_html_footer() "{{{ endfunction "}}} function! s:safe_html(line) "{{{ - "" change dangerous html symbols: < > & + "" htmlize symbols: < > & let line = substitute(a:line, '&', '\&amp;', 'g') - let line = substitute(line, '<', '\&lt;', 'g') - let line = substitute(line, '>', '\&gt;', 'g') + + " let line = substitute(line, '<', '\&lt;', 'g') + " let line = substitute(line, '>', '\&gt;', 'g') + " XXX: I believe there should be a much nicer way to do it. + let line = substitute(line, '<\(br\|hr\)\@!', '\&lt;', 'g') + let line = substitute(line, '\(\(br\|hr\)\s*/\?\)\@<!>', '\&gt;', 'g') return line endfunction "}}} @@ -257,9 +263,18 @@ function! s:trim(string) "{{{ return res endfunction "}}} -" toc_list is list of [level, header_text, header_id] -" ex: [[1, "Header", "toc1"], [2, "Header2", "toc2"], ...] function! s:get_html_toc(toc_list) "{{{ + " toc_list is list of [level, header_text, header_id] + " ex: [[1, "Header", "toc1"], [2, "Header2", "toc2"], ...] + function! s:close_list(toc, plevel, level) "{{{ + let plevel = a:plevel + while plevel > a:level + call add(a:toc, '</ul>') + let plevel -= 1 + endwhile + return plevel + endfunction "}}} + if empty(a:toc_list) return [] endif @@ -271,15 +286,15 @@ function! s:get_html_toc(toc_list) "{{{ if level > plevel call add(toc, '<ul>') elseif level < plevel - call add(toc, '</ul>') + let plevel = s:close_list(toc, plevel, level) endif - call add(toc, '<li><a href="#'.id.'">'.text.'</a></li>') + + let toc_text = s:process_tags_remove_links(text) + let toc_text = s:process_tags_typefaces(toc_text) + call add(toc, '<li><a href="#'.id.'">'.toc_text.'</a></li>') let plevel = level endfor - while level > 0 - call add(toc, '</ul>') - let level -= 1 - endwhile + call s:close_list(toc, level, 0) call add(toc, '</div>') return toc endfunction "}}} @@ -336,6 +351,70 @@ function! s:tag_pre(value) "{{{ return '<code>'.s:mid(a:value, 3).'</code>' endfunction "}}} +function! s:tag_internal_link(value) "{{{ + " Make <a href="This is a link">This is a link</a> + " from [[This is a link]] + " Make <a href="link">This is a link</a> + " from [[link|This is a link]] + " Make <a href="link">This is a link</a> + " from [[link][This is a link]] + " TODO: rename function -- it makes not only internal links. + " TODO: refactor it. + + function! s:linkify(src, caption, style) "{{{ + if a:style == '' + let style_str = '' + else + let style_str = ' style="'.a:style.'"' + endif + + if s:is_img_link(a:caption) + let link = '<a href="'.a:src.'"><img src="'.a:caption.'"'.style_str.' />'. + \ '</a>' + elseif s:is_non_wiki_link(a:src) + let link = '<a href="'.a:src.'">'.a:caption.'</a>' + elseif s:is_img_link(a:src) + let link = '<img src="'.a:src.'" alt="'.a:caption.'"'. style_str.' />' + elseif vimwiki#is_link_to_dir(a:src) + if g:vimwiki_dir_link == '' + let link = '<a href="'.vimwiki#safe_link(a:src).'">'.a:caption.'</a>' + else + let link = '<a href="'.vimwiki#safe_link(a:src). + \ g:vimwiki_dir_link.'.html">'.a:caption.'</a>' + endif + else + let link = '<a href="'.vimwiki#safe_link(a:src). + \ '.html">'.a:caption.'</a>' + endif + + return link + endfunction "}}} + + let value = s:mid(a:value, 2) + + let line = '' + if value =~ '|' + let link_parts = split(value, "|", 1) + else + let link_parts = split(value, "][", 1) + endif + + + if len(link_parts) > 1 + if len(link_parts) < 3 + let style = "" + else + let style = link_parts[2] + endif + + let line = s:linkify(link_parts[0], link_parts[1], style) + + else + let line = s:linkify(value, value, '') + endif + return line +endfunction "}}} + function! s:tag_external_link(value) "{{{ "" Make <a href="link">link desc</a> "" from [link link desc] @@ -369,16 +448,39 @@ function! s:tag_external_link(value) "{{{ return line endfunction "}}} -function! s:tag_internal_link(value) "{{{ - " Make <a href="This is a link">This is a link</a> - " from [[This is a link]] - " Make <a href="link">This is a link</a> - " from [[link|This is a link]] - " Make <a href="link">This is a link</a> - " from [[link][This is a link]] - " TODO: rename function -- it makes not only internal links. - " TODO: refactor it. +function! s:tag_wikiword_link(value) "{{{ + " Make <a href="WikiWord">WikiWord</a> from WikiWord + if a:value[0] == '!' + return a:value[1:] + elseif g:vimwiki_camel_case + let line = '<a href="'.a:value.'.html">'.a:value.'</a>' + return line + else + return a:value + endif +endfunction "}}} + +function! s:tag_barebone_link(value) "{{{ + "" Make <a href="http://habamax.ru">http://habamax.ru</a> + "" from http://habamax.ru + if s:is_img_link(a:value) + let line = '<img src="'.a:value.'" />' + else + let line = '<a href="'.a:value.'">'.a:value.'</a>' + endif + return line +endfunction "}}} + +function! s:tag_no_wikiword_link(value) "{{{ + if a:value[0] == '!' + return a:value[1:] + else + return a:value + endif +endfunction "}}} + +function! s:tag_remove_internal_link(value) "{{{ let value = s:mid(a:value, 2) let line = '' @@ -394,53 +496,31 @@ function! s:tag_internal_link(value) "{{{ else let style = link_parts[2] endif - - if s:is_img_link(link_parts[1]) - let line = '<a href="'.link_parts[0].'"><img src="'.link_parts[1]. - \ '" style="'.style.'" /></a>' - elseif len(link_parts) < 3 - if s:is_non_wiki_link(link_parts[0]) - let line = '<a href="'.link_parts[0].'">'.link_parts[1].'</a>' - else - let line = '<a href="'.vimwiki#safe_link(link_parts[0]). - \ '.html">'.link_parts[1].'</a>' - endif - elseif s:is_img_link(link_parts[0]) - let line = '<img src="'.link_parts[0].'" alt="'. - \ link_parts[1].'" style="'.style.'" />' - endif + let line = link_parts[1] else - if s:is_img_link(value) - let line = '<img src="'.value.'" />' - elseif s:is_non_wiki_link(link_parts[0]) - let line = '<a href="'.value.'">'.value.'</a>' - else - let line = '<a href="'.vimwiki#safe_link(value). - \ '.html">'.value.'</a>' - endif + let line = value endif return line endfunction "}}} -function! s:tag_wikiword_link(value) "{{{ - " Make <a href="WikiWord">WikiWord</a> from WikiWord - " if first symbol is ! then remove it and make no link. - if a:value[0] == '!' - return a:value[1:] - else - let line = '<a href="'.a:value.'.html">'.a:value.'</a>' - return line - endif -endfunction "}}} - -function! s:tag_barebone_link(value) "{{{ - "" Make <a href="http://habamax.ru">http://habamax.ru</a> - "" from http://habamax.ru +function! s:tag_remove_external_link(value) "{{{ + let value = s:mid(a:value, 1) - if s:is_img_link(a:value) - let line = '<img src="'.a:value.'" />' + let line = '' + if s:is_web_link(value) + let lnkElements = split(value) + let head = lnkElements[0] + let rest = join(lnkElements[1:]) + if rest=="" + let rest=head + endif + let line = rest + elseif s:is_img_link(value) + let line = '<img src="'.value.'" />' else - let line = '<a href="'.a:value.'">'.a:value.'</a>' + " [alskfj sfsf] shouldn't be a link. So return it as it was -- + " enclosed in [...] + let line = '['.value.']' endif return line endfunction "}}} @@ -472,13 +552,16 @@ function! s:make_tag(line, regexp, func) "{{{ return res_line endfunction "}}} -function! s:process_inline_tags(line) "{{{ +function! s:process_tags_remove_links(line) " {{{ let line = a:line - let line = s:make_tag(line, '\[\[.\{-}\]\]', 's:tag_internal_link') - let line = s:make_tag(line, '\[.\{-}\]', 's:tag_external_link') - let line = s:make_tag(line, g:vimwiki_rxWeblink, 's:tag_barebone_link') - let line = s:make_tag(line, '!\?'.g:vimwiki_rxWikiWord, - \ 's:tag_wikiword_link') + let line = s:make_tag(line, '\[\[.\{-}\]\]', 's:tag_remove_internal_link') + let line = s:make_tag(line, '\[.\{-}\]', 's:tag_remove_external_link') + return line +endfunction " }}} + +function! s:process_tags_typefaces(line) "{{{ + let line = a:line + let line = s:make_tag(line, g:vimwiki_rxNoWikiWord, 's:tag_no_wikiword_link') let line = s:make_tag(line, g:vimwiki_rxItalic, 's:tag_em') let line = s:make_tag(line, g:vimwiki_rxBold, 's:tag_strong') let line = s:make_tag(line, g:vimwiki_rxTodo, 's:tag_todo') @@ -490,6 +573,21 @@ function! s:process_inline_tags(line) "{{{ \ 's:tag_pre') return line endfunction " }}} + +function! s:process_tags_links(line) " {{{ + let line = a:line + let line = s:make_tag(line, '\[\[.\{-}\]\]', 's:tag_internal_link') + let line = s:make_tag(line, '\[.\{-}\]', 's:tag_external_link') + let line = s:make_tag(line, g:vimwiki_rxWeblink, 's:tag_barebone_link') + let line = s:make_tag(line, g:vimwiki_rxWikiWord, 's:tag_wikiword_link') + return line +endfunction " }}} + +function! s:process_inline_tags(line) "{{{ + let line = s:process_tags_links(a:line) + let line = s:process_tags_typefaces(line) + return line +endfunction " }}} "}}} " BLOCK TAGS {{{ @@ -518,17 +616,63 @@ function! s:close_tag_para(para, ldest) "{{{ endfunction "}}} function! s:close_tag_table(table, ldest) "{{{ - if len(a:table) - call insert(a:ldest, "</table>") - return [] + " The first element of table list is a string which tells us if table should be centered. + " The rest elements are rows which are lists of columns: + " ['center', + " ['col1', 'col2', 'col3'], + " ['col1', 'col2', 'col3'], + " ['col1', 'col2', 'col3'] + " ] + let table = a:table + let ldest = a:ldest + if len(table) + if table[0] == 'center' + call add(ldest, "<table class='center'>") + else + call add(ldest, "<table>") + endif + + " Empty lists are table separators. + " Search for the last empty list. All the above rows would be a table header. + " We should exclude the first element of the table list as it is a text tag + " that shows if table should be centered or not. + let head = 0 + for idx in range(len(table)-1, 1, -1) + if empty(table[idx]) + let head = idx + break + endif + endfor + if head > 0 + for row in table[1 : head-1] + if !empty(filter(row, '!empty(v:val)')) + call add(ldest, '<tr>') + call extend(ldest, map(row, '"<th>".s:process_inline_tags(v:val)."</th>"')) + call add(ldest, '</tr>') + endif + endfor + for row in table[head+1 :] + call add(ldest, '<tr>') + call extend(ldest, map(row, '"<td>".s:process_inline_tags(v:val)."</td>"')) + call add(ldest, '</tr>') + endfor + else + for row in table[1 :] + call add(ldest, '<tr>') + call extend(ldest, map(row, '"<td>".s:process_inline_tags(v:val)."</td>"')) + call add(ldest, '</tr>') + endfor + endif + call add(ldest, "</table>") + let table = [] endif - return a:table + return table endfunction "}}} function! s:close_tag_list(lists, ldest) "{{{ while len(a:lists) let item = remove(a:lists, -1) - call insert(a:ldest, item[0]) + call add(a:ldest, item[0]) endwhile endfunction! "}}} @@ -605,10 +749,15 @@ function! s:process_tag_list(line, lists) "{{{ return [st_tag, en_tag] endfunction "}}} - " Do not process line that starts from *bold* text as list item. - let pos = match(a:line, g:vimwiki_rxBold) - if pos != -1 && strpart(a:line, 0, pos) =~ '^\s*$' - return [0, []] + let in_list = (len(a:lists) > 0) + + " If it is not list yet then do not process line that starts from *bold* + " text. + if !in_list + let pos = match(a:line, g:vimwiki_rxBold) + if pos != -1 && strpart(a:line, 0, pos) =~ '^\s*$' + return [0, []] + endif endif let lines = [] @@ -631,7 +780,6 @@ function! s:process_tag_list(line, lists) "{{{ let lstRegExp = '' endif - let in_list = (len(a:lists) > 0) if lstSym != '' " To get proper indent level 'retab' the line -- change all tabs " to spaces*tabstop @@ -674,10 +822,7 @@ function! s:process_tag_list(line, lists) "{{{ endif let processed = 1 else - while len(a:lists) - let item = remove(a:lists, -1) - call add(lines, item[0]) - endwhile + call s:close_tag_list(a:lists, lines) endif return [processed, lines] endfunction "}}} @@ -744,6 +889,12 @@ function! s:process_tag_h(line, id) "{{{ let h_level = 1 endif if h_level > 0 + let a:id[h_level] += 1 + " reset higher level ids + for level in range(h_level+1, 6) + let a:id[level] = 0 + endfor + let centered = 0 if a:line =~ '^\s\+' let centered = 1 @@ -751,8 +902,14 @@ function! s:process_tag_h(line, id) "{{{ let line = s:trim(line) - let h_text = s:trim(strpart(line, h_level, len(line) - h_level * 2)) - let h_id = 'toc'.a:id + let h_number = '' + for l in range(1, h_level-1) + let h_number .= a:id[l].'.' + endfor + let h_number .= a:id[h_level] + + let h_id = 'toc_'.h_number + let h_part = '<h'.h_level.' id="'.h_id.'"' if centered @@ -760,6 +917,17 @@ function! s:process_tag_h(line, id) "{{{ else let h_part .= '>' endif + + let h_text = s:trim(strpart(line, h_level, len(line) - h_level * 2)) + if g:vimwiki_html_header_numbering + let num = matchstr(h_number, + \ '^\(\d.\)\{'.(g:vimwiki_html_header_numbering-1).'}\zs.*') + if !empty(num) + let num .= g:vimwiki_html_header_numbering_sym + endif + let h_text = num.' '.h_text + endif + let line = h_part.h_text.'</h'.h_level.'>' let processed = 1 endif @@ -777,54 +945,42 @@ function! s:process_tag_hr(line) "{{{ endfunction "}}} function! s:process_tag_table(line, table) "{{{ - " XXX: This should be refactored!!! + function! s:table_empty_cell(value) "{{{ + if a:value =~ '^\s*$' + return '&nbsp;' + endif + return a:value + endfunction "}}} + + function! s:table_add_row(table, line) "{{{ + if empty(a:table) + if a:line =~ '^\s\+' + let row = ['center', []] + else + let row = ['normal', []] + endif + else + let row = [[]] + endif + return row + endfunction "}}} + let table = a:table let lines = [] let processed = 0 - if a:line =~ '^\s*|[-+]\+|\s*$' && len(table) - call add(table, []) + if a:line =~ '^\s*|[-+]\+|\s*$' + call extend(table, s:table_add_row(a:table, a:line)) let processed = 1 elseif a:line =~ '^\s*|.\+|\s*$' - if empty(table) - let table = [[]] - else - call add(table, []) - endif - let processed = 1 - - call extend(table[-1], split(a:line, '\s*|\s*')) + call extend(table, s:table_add_row(a:table, a:line)) - 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 = [] + let processed = 1 + let cells = split(a:line, '\s*|\s*', 1)[1: -2] + call map(cells, 's:table_empty_cell(v:val)') + call extend(table[-1], cells) + else + let table = s:close_tag_table(table, lines) endif return [processed, lines, table] endfunction "}}} @@ -850,6 +1006,14 @@ function! s:parse_line(line, state) " {{{ let processed = 0 + " nohtml -- placeholder + if !processed + if line =~ '^\s*%nohtml' + let processed = 1 + let state.placeholder = ['nohtml'] + endif + endif + " toc -- placeholder "{{{ if !processed if line =~ '^\s*%toc' @@ -916,17 +1080,23 @@ function! s:parse_line(line, state) " {{{ 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') + let line = s:process_inline_tags(line) call add(res_lines, line) " gather information for table of contents call add(state.toc, [h_level, h_text, h_id]) - let state.toc_id += 1 endif endif "}}} + " tables "{{{ + if !processed + let [processed, lines, state.table] = s:process_tag_table(line, state.table) + call extend(res_lines, lines) + endif + "}}} + " quotes "{{{ if !processed let [processed, lines, state.quote] = s:process_tag_quote(line, state.quote) @@ -952,16 +1122,6 @@ function! s:parse_line(line, state) " {{{ endif "}}} - " tables "{{{ - if !processed - let [processed, lines, state.table] = s:process_tag_table(line, state.table) - - call map(lines, 's:process_inline_tags(v:val)') - - call extend(res_lines, lines) - endif - "}}} - " horizontal rules "{{{ if !processed let [processed, line] = s:process_tag_hr(line) @@ -1025,11 +1185,14 @@ function! vimwiki_html#Wiki2HTML(path, wikifile) "{{{ let wikifile = fnamemodify(a:wikifile, ":p") let subdir = vimwiki#subdir(VimwikiGet('path'), wikifile) + let lsource = s:remove_comments(readfile(wikifile)) + let ldest = s:get_html_header(wikifile, subdir, &fileencoding) + let path = expand(a:path).subdir call vimwiki#mkdir(path) - let lsource = s:remove_comments(readfile(wikifile)) - let ldest = s:get_html_header(wikifile, subdir, &fileencoding) + " nohtml placeholder -- to skip html generation. + let nohtml = 0 " for table of contents placeholders. let placeholders = [] @@ -1044,7 +1207,7 @@ function! vimwiki_html#Wiki2HTML(path, wikifile) "{{{ let state.lists = [] let state.placeholder = [] let state.toc = [] - let state.toc_id = 1 + let state.toc_id = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 } for line in lsource let oldquote = state.quote @@ -1053,40 +1216,47 @@ function! vimwiki_html#Wiki2HTML(path, wikifile) "{{{ " 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 " to refactor it out. - if (oldquote != state.quote) && ldest[-1] =~ '^\s*$' + if oldquote != state.quote call s:remove_blank_lines(ldest) endif if !empty(state.placeholder) - call add(placeholders, [state.placeholder, len(ldest), len(placeholders)]) - let state.placeholder = [] + if state.placeholder[0] == 'nohtml' + let nohtml = 1 + break + else + call add(placeholders, [state.placeholder, len(ldest), len(placeholders)]) + let state.placeholder = [] + endif endif call extend(ldest, lines) endfor - let toc = s:get_html_toc(state.toc) - call s:process_placeholders(ldest, placeholders, 'toc', toc) + if !nohtml + let toc = s:get_html_toc(state.toc) + call s:process_placeholders(ldest, placeholders, 'toc', toc) - call s:remove_blank_lines(ldest) + call s:remove_blank_lines(ldest) - "" process end of file - "" close opened tags if any - let lines = [] - call s:close_tag_quote(state.quote, lines) - call s:close_tag_para(state.para, lines) - call s:close_tag_pre(state.pre, lines) - call s:close_tag_list(state.lists, lines) - call s:close_tag_def_list(state.deflist, lines) - call s:close_tag_table(state.table, lines) - call extend(ldest, lines) - - call extend(ldest, s:get_html_footer()) - - "" make html file. - let wwFileNameOnly = fnamemodify(wikifile, ":t:r") - call writefile(ldest, path.wwFileNameOnly.'.html') + "" process end of file + "" close opened tags if any + let lines = [] + call s:close_tag_quote(state.quote, lines) + call s:close_tag_para(state.para, lines) + call s:close_tag_pre(state.pre, lines) + call s:close_tag_list(state.lists, lines) + call s:close_tag_def_list(state.deflist, lines) + call s:close_tag_table(state.table, lines) + call extend(ldest, lines) + + call extend(ldest, s:get_html_footer()) + + "" make html file. + let wwFileNameOnly = fnamemodify(wikifile, ":t:r") + call writefile(ldest, path.wwFileNameOnly.'.html') + endif endfunction "}}} function! vimwiki_html#WikiAll2HTML(path) "{{{ diff --git a/autoload/vimwiki_lst.vim b/autoload/vimwiki_lst.vim @@ -1,3 +1,4 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki autoload plugin file " Todo lists related stuff here. " Author: Maxim Kim <habamax@gmail.com> @@ -237,9 +238,9 @@ function! s:all_siblings_checked(lnum) "{{{ let cnt = 0 let siblings = s:get_sibling_items(a:lnum) for lnum in siblings - let cnt += s:get_state(lnum)/100.0 + let cnt += s:get_state(lnum) endfor - let result = (cnt*100.0)/len(siblings) + let result = cnt/len(siblings) return result endfunction "}}} diff --git a/autoload/vimwiki_tbl.vim b/autoload/vimwiki_tbl.vim @@ -1,3 +1,4 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki autoload plugin file " Desc: Tables " | Easily | manageable | text | tables | ! | @@ -18,7 +19,19 @@ let s:textwidth = &tw " Misc functions {{{ function! s:wide_len(str) "{{{ - return strlen(substitute(a:str, '.', 'x', 'g')) + if !g:vimwiki_CJK_length + let ret = strlen(substitute(a:str, '.', 'x', 'g')) + else + let savemodified = &modified + let save_cursor = getpos('.') + exe "norm! o\<esc>" + call setline(line("."), a:str) + let ret = virtcol("$") - 1 + d + call setpos('.', save_cursor) + let &modified = savemodified + endif + return ret endfunction "}}} function! s:is_table(line) "{{{ @@ -26,14 +39,31 @@ function! s:is_table(line) "{{{ endfunction "}}} function! s:is_separator(line) "{{{ - return a:line =~ '^\s*|\s*-\+' + 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) "{{{ +function! s:is_first_column(lnum, cnum) "{{{ + let line = strpart(getline(a:lnum), 0, a:cnum - 1) + return line =~ '^\s*|[^|]*$' || line =~ '^\s*$' +endfunction "}}} + +function! s:count_separators_up(lnum) "{{{ + let lnum = a:lnum - 1 + while lnum > 1 + if !s:is_separator(getline(lnum)) + break + endif + let lnum -= 1 + endwhile + + return (a:lnum-lnum) +endfunction "}}} + +function! s:count_separators_down(lnum) "{{{ let lnum = a:lnum + 1 while lnum < line('$') if !s:is_separator(getline(lnum)) @@ -78,19 +108,38 @@ function! s:create_row_sep(cols) "{{{ 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 + return split(a:line, '\s*|\s*', 1)[1:-2] +endfunction "}}} + +function! s:col_count(lnum) "{{{ + let line = getline(a:lnum) + if !s:is_separator(line) + return len(split(line, '\s*|\s*', 1)[1:-2]) + else + return len(split(line, '-+-', 1)) + endif endfunction "}}} +function! s:get_indent(lnum) "{{{ + if !s:is_table(getline(a:lnum)) + return + endif + + let indent = 0 + + let lnum = a:lnum - 1 + while lnum > 1 + let line = getline(lnum) + if !s:is_table(line) + let indent = indent(lnum+1) + break + endif + let lnum -= 1 + endwhile + + return indent +endfunction " }}} + function! s:get_rows(lnum) "{{{ if !s:is_table(getline(a:lnum)) return @@ -131,29 +180,57 @@ function! s:get_cell_max_lens(lnum) "{{{ if s:is_separator(row) continue endif - for [idx, cell] in s:get_values(row) + let cells = s:get_values(row) + for idx in range(len(cells)) + let value = cells[idx] if has_key(max_lens, idx) - let max_lens[idx] = max([s:wide_len(cell), max_lens[idx]]) + let max_lens[idx] = max([s:wide_len(value), max_lens[idx]]) else - let max_lens[idx] = s:wide_len(cell) + let max_lens[idx] = s:wide_len(value) endif endfor endfor return max_lens endfunction "}}} -function! s:get_aligned_rows(lnum, max_lens) "{{{ +function! s:get_aligned_rows(lnum, col1, col2) "{{{ + let max_lens = s:get_cell_max_lens(a:lnum) 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) + let new_row = s:fmt_sep(max_lens, a:col1, a:col2) else - let new_row = s:fmt_row(row, a:max_lens) + let new_row = s:fmt_row(row, max_lens, a:col1, a:col2) endif call add(rows, [lnum, new_row]) endfor return rows endfunction "}}} + +" Number of the current column. Starts from 0. +function! s:cur_column() "{{{ + let line = getline('.') + if !s:is_table(line) + return -1 + endif + if s:is_separator(line) + let sep = '[+|]' + else + let sep = '|' + endif + + let curs_pos = col('.') + let mpos = match(line, '|', 0) + let col = -1 + while mpos < curs_pos && mpos != -1 + let mpos = match(line, sep, mpos+1) + if mpos != -1 + let col += 1 + endif + endwhile + return col +endfunction "}}} + " }}} " Format functions {{{ @@ -169,14 +246,20 @@ function! s:fmt_cell(cell, max_len) "{{{ return cell endfunction "}}} -function! s:fmt_row(line, max_lens) "{{{ +function! s:fmt_row(line, max_lens, col1, col2) "{{{ 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]).'|' + let cells = s:get_values(a:line) + for idx in range(len(cells)) + if idx == a:col1 + let idx = a:col2 + elseif idx == a:col2 + let idx = a:col1 + endif + let value = cells[idx] + let new_line .= s:fmt_cell(value, a:max_lens[idx]).'|' endfor - let idx = len(values) + let idx = len(cells) while idx < len(a:max_lens) let new_line .= s:fmt_cell('', a:max_lens[idx]).'|' let idx += 1 @@ -192,9 +275,14 @@ function! s:fmt_cell_sep(max_len) "{{{ endif endfunction "}}} -function! s:fmt_sep(max_lens) "{{{ +function! s:fmt_sep(max_lens, col1, col2) "{{{ let sep = '|' for idx in range(len(a:max_lens)) + if idx == a:col1 + let idx = a:col2 + elseif idx == a:col2 + let idx = a:col1 + endif let sep .= s:fmt_cell_sep(a:max_lens[idx]).'+' endfor let sep = substitute(sep, '+$', '|', '') @@ -207,7 +295,7 @@ 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" + let cmd .= "\<ESC>0:call search('|', 'c', line('.'))\<CR>la" else let cmd .= "0".(col('.')-1)."lT|a" endif @@ -219,16 +307,27 @@ function! s:kbd_goto_next_row() "{{{ return cmd endfunction "}}} +function! s:kbd_goto_prev_row() "{{{ + let cmd = "\<ESC>jt|T|a" + return cmd +endfunction "}}} + function! s:kbd_goto_next_col(last) "{{{ - if col('.') == 1 - let cmd = "\<ESC>la" + if a:last + let seps = s:count_separators_down(line('.')) + let cmd = "\<ESC>".seps."j0:call search('|', 'c', line('.'))\<CR>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 + let cmd = "\<ESC>:call search('|', 'c', line('.'))\<CR>la" + endif + return cmd +endfunction "}}} + +function! s:kbd_goto_prev_col(first) "{{{ + if a:first + let seps = s:count_separators_up(line('.')) + let cmd = "\<ESC>".seps."k$:call search('|', 'b', line('.'))\<CR>la" + else + let cmd = "\<ESC>2F|la" endif return cmd endfunction "}}} @@ -264,15 +363,37 @@ function! vimwiki_tbl#kbd_tab() "{{{ return s:kbd_goto_next_col(last) endfunction "}}} -function! vimwiki_tbl#format(lnum) "{{{ +function! vimwiki_tbl#kbd_shift_tab() "{{{ + let lnum = line('.') + if !s:is_table(getline(lnum)) + return "\<S-Tab>" + endif + + let first = s:is_first_column(lnum, col('.')) + if first && !s:is_table(getline(lnum-1)) + return "" + endif + return s:kbd_goto_prev_col(first) +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) + if a:0 == 2 + let col1 = a:1 + let col2 = a:2 + else + let col1 = 0 + let col2 = 0 + endif - for [lnum, row] in s:get_aligned_rows(a:lnum, max_lens) + let indent = s:get_indent(a:lnum) + + for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2) + let row = repeat(' ', indent).row call setline(lnum, row) endfor @@ -332,4 +453,52 @@ function! vimwiki_tbl#reset_tw(lnum) "{{{ let &tw = 0 endfunction "}}} +" TODO: move_column_left and move_column_right are good candidates to be +" refactored. +function! vimwiki_tbl#move_column_left() "{{{ + if !s:is_table(getline('.')) + return + endif + + let cur_col = s:cur_column() + if cur_col == -1 + return + endif + + if cur_col > 0 + call vimwiki_tbl#format(line('.'), cur_col-1, cur_col) + call cursor(line('.'), 1) + if !s:is_separator(getline('.')) + call search('\%(|[^|]\+\)\{'.(cur_col-1).'}| .', 'eW') + else + call search('|\%([^+]\++\)\{'.(cur_col-1).'}--', 'eW') + endif + endif +endfunction "}}} + +function! vimwiki_tbl#move_column_right() "{{{ + if !s:is_table(getline('.')) + return + endif + + let cur_col = s:cur_column() + if cur_col == -1 + return + endif + + if cur_col < s:col_count(line('.'))-1 + call vimwiki_tbl#format(line('.'), cur_col, cur_col+1) + call cursor(line('.'), 1) + if !s:is_separator(getline('.')) + call search('\%(|[^|]\+\)\{'.(cur_col+1).'}| .', 'eW') + else + call search('|\%([^+]\++\)\{'.(cur_col+1).'}--', 'eW') + endif + endif +endfunction "}}} + +function! vimwiki_tbl#get_rows(lnum) "{{{ + return s:get_rows(a:lnum) +endfunction "}}} + "}}} diff --git a/doc/vimwiki.txt b/doc/vimwiki.txt @@ -1,14 +1,15 @@ *vimwiki.txt* A Personal Wiki for Vim - __ __ ______ __ __ ______ __ __ ______ ~ - /\ \/\ \/\__ _\ /'\_/`\/\ \ __/\ \/\__ _\ /\ \/\ \ /\__ _\ ~ - \ \ \ \ \/_/\ \/ /\ \ \ \/\ \ \ \/_/\ \/ \ \ \/'/'\/_/\ \/ ~ - \ \ \ \ \ \ \ \ \ \ \__\ \ \ \ \ \ \ \ \ \ \ \ \ , < \ \ \ ~ - \ \ \_/ \ \_\ \__\ \ \_/\ \ \ \_/ \_\ \ \_\ \__\ \ \\`\ \_\ \__ ~ - \ `\___/ /\_____\\ \_\\ \_\ `\___x___/ /\_____\\ \_\ \_\ /\_____\~ - `\/__/ \/_____/ \/_/ \/_/'\/__//__/ \/_____/ \/_/\/_/ \/_____/~ + __ __ ___ __ __ _ _ ___ ___ _ ___ ~ + | | | || | | |_| || | _ | || | | | | || | ~ + | |_| || | | || || || || | | |_| || | ~ + | || | | || || | | _|| | ~ + | || | | || || | | |_ | | ~ + | | | | | ||_|| || _ || | | _ || | ~ + |___| |___| |_| |_||__| |__||___| |___| |_||___| ~ - Version: 0.9.9 + + Version: 1.0 ============================================================================== CONTENTS *vimwiki-contents* @@ -34,13 +35,12 @@ CONTENTS *vimwiki-contents* 5.9. Comments |vimwiki-syntax-comments| 6. Folding/Outline |vimwiki-folding| 7. Placeholders |vimwiki-placeholders| - 7.1 Table of Contents |vimwiki-table-of-contents| 8. Todo lists |vimwiki-todo-lists| 9. Tables |vimwiki-tables| 10. Diary |vimwiki-diary| 11. Options |vimwiki-options| 12. Help |vimwiki-help| - 13. Author |vimwiki-author| + 13. Developers |vimwiki-developers| 14. Changelog |vimwiki-changelog| 15. License |vimwiki-license| @@ -242,6 +242,13 @@ gqq Format table. If you did some changes to a table or without swapping insert/normal modes this command gww reformat it. + *vimwiki_<A-Left>* +<A-Left> Move current table column to the left. + See |:VimwikiTableMoveColumnLeft| + + *vimwiki_<A-Right>* +<A-Right> Move current table column to the right. + See |:VimwikiTableMoveColumnRight| @@ -267,6 +274,8 @@ INSERT MODE *vimwiki-table-mappings* <Tab> Goto next table cell, create new row if on the last cell. + *vimwiki_i_<S-CR>* +<S-CR> Insert <br /> and a newline. ------------------------------------------------------------------------------ @@ -278,6 +287,10 @@ ih Inner Header without leading empty lines. You can 'vah' to select a header with its contents or 'dah' to delete it or 'yah' to yank it or 'cah' to change it. +a\ A cell in a table. +i\ Inner cell in a table. +ac A column in a table. +ic Inner column in a table. ============================================================================== 4. Commands *vimwiki-commands* @@ -362,6 +375,37 @@ You can 'vah' to select a header with its contents or 'dah' to delete it or :VimwikiTable cols Create a table with a given cols and 2 rows +*:VimwikiTableMoveColumnLeft* , *:VimwikiTableMoveColumnRight* + Move current column to the left or to the right: + Example: > + + | head1 | head2 | head3 | head4 | head5 | + |--------+--------+--------+--------+--------| + | value1 | value2 | value3 | value4 | value5 | + + + Cursor is on 'head1'. + :VimwikiTableMoveColumnRight + + | head2 | head1 | head3 | head4 | head5 | + |--------+--------+--------+--------+--------| + | value2 | value1 | value3 | value4 | value5 | + + Cursor is on 'head3'. + :VimwikiTableMoveColumnLeft + + | head2 | head3 | head1 | head4 | head5 | + |--------+--------+--------+--------+--------| + | value2 | value3 | value1 | value4 | value5 | +< + + Commands are mapped to <A-Left> and <A-Right> respectively. + + +*:VimwikiGenerateLinks* + Insert all available links into current buffer. + + ============================================================================== 5. Wiki syntax *vimwiki-syntax* @@ -370,13 +414,8 @@ There are a lot of different wikies out there. Most of them have their own syntax and vimwiki is not an exception here. Default vimwiki's syntax is a subset of google's wiki syntax markup. -As for MediaWiki's syntax -- it is not that convenient for non English -(Russian in my case :)) keyboard layouts to emphasize text as it uses a lot -of '''''' to do it. You have to switch layouts every time you want some bold -non English text. This is the answer to "Why not MediaWiki?" - -Nevertheless, there is MediaWiki syntax file included in the distribution (it -doesn't have all the fancy stuff original MediaWiki syntax has though). +There is MediaWiki syntax file included in the distribution (it doesn't have +all the fancy stuff original MediaWiki syntax has though). See |vimwiki-option-syntax|. @@ -500,18 +539,6 @@ You can center your headers in html by placing spaces before the first '=': -Note: before vimwiki 0.8.2, header's markup syntax used exclamation marks: -! Header level 1 -!! Header level 2 -etc... - -If you upgrade from pre 0.8.2 you might find the next commands useful. -To change headers from !Header to =Header= in your wiki files do: > - :args .wiki - :argdo %s/^\(!\+\)\([^!].*$\)/\=substitute(submatch(1),'!','=','g').submatch(2).substitute(submatch(1),'!','=','g') - -Note: BACKUP FIRST! - ------------------------------------------------------------------------------ 5.4. Paragraphs *vimwiki-syntax-paragraphs* @@ -619,6 +646,7 @@ In html the following part > > is higlighted as a table header. +If you indent table then it would be centered in html. See |vimwiki-tables| for more details on how to manage tables. @@ -723,7 +751,7 @@ To turn folding on/off check |g:vimwiki_folding|. 7. Placeholders *vimwiki-placeholders* ------------------------------------------------------------------------------ -7.1. Table of Contents *vimwiki-toc* *vimwiki-table-of-contents* +%toc Table of Contents *vimwiki-toc* *vimwiki-table-of-contents* You can add 'table of contents' to your html page generated from wiki one. Just place > @@ -740,6 +768,16 @@ or > %toc Whatever +------------------------------------------------------------------------------ +%nohtml *vimwiki-nohtml* + +If you do not want a wiki page to be converted to html, place: + +%nohtml + +into it. + + ============================================================================== 8. Todo lists *vimwiki-todo-lists* @@ -825,6 +863,8 @@ values: > | James | Esfandiary | 27 | Istanbul | esfandiary@tmail.com | < +To indent table indent the first row. Then format it with 'gqq'. + ============================================================================== @@ -870,6 +910,8 @@ be created in default wiki's diary. Get it from http://www.vim.org/scripts/script.php?script_id=52 +See |g:vimwiki_use_calendar| option to turn it off/on. + ============================================================================== @@ -907,6 +949,20 @@ Empty |Dictionary| in the g:vimwiki_list is the wiki with default options: > < +You can also create wikis as a separate |Dictionary|s. > + + let wiki_1 = {} + let wiki_1.path = '~/my_docs/' + let wiki_1.html_header = '~/public_html/header.tpl' + let wiki_1.nested_syntaxes = {'python': 'python', 'c++': 'cpp'} + + let wiki_2 = {} + let wiki_2.path = '~/project_docs/' + let wiki_2.index = 'main' + + let g:vimwiki_list = [wiki_1, wiki_2] + +< PER WIKI OPTIONS *viwmiki-local-options* @@ -1079,11 +1135,11 @@ nested_syntaxes {} pairs of highlight keyword and vim filetype Description~ You can make preformatted text to be highlighted with a different syntaxes available for vim. -For example the following setup: > +For example the following setup in your vimrc: > let wiki = {} - let wiki.path = '~/my_site/' + let wiki.path = '~/my_wiki/' let wiki.nested_syntaxes = {'python': 'python', 'c++': 'cpp'} - let vimwiki_list = [wiki] + let g:vimwiki_list = [wiki] would give you python and c++ highlighting in: > {{{class="brush: python" @@ -1152,8 +1208,8 @@ Description~ Number of maximum dated links placed on one line. Ex: = Diary = -|| [[2010-01-30]] || [[2010-01-29]] || [[2010-01-28]] || [[2010-01-27]] || -|| [[2010-01-26]] || [[2010-01-25]] || +| [[2010-01-30]] | [[2010-01-29]] | [[2010-01-28]] | [[2010-01-27]] | +| [[2010-01-26]] | [[2010-01-25]] | @@ -1399,7 +1455,7 @@ Default: 1 Convert directory name from current |encoding| into 'g:vimwiki_w32_dir_enc' before it is created. -If have 'enc=utf-8' and you set up > +If you have 'enc=utf-8' and set up > let g:vimwiki_w32_dir_enc = 'cp1251' < then following the next link with <CR>: > @@ -1407,40 +1463,184 @@ then following the next link with <CR>: > > would convert utf-8 'привет' to cp1251 and create directory with that name. -Default value: '' +Default: '' + + +------------------------------------------------------------------------------ +*g:vimwiki_CJK_length* + +Use special method to calculate correct length of the strings with double wide +characters. (To align table cells properly) + +Value Description~ +0 Do not use it. +1 Use it. + +Default: 0 + + +------------------------------------------------------------------------------ +*g:vimwiki_dir_link* + +This option is about what to do with links to directories -- [[directory/]], +[[papers/]], etc. + +Value Description~ +'' Open 'directory/' using standard netrw plugin. +'index' Open 'directory/index.wiki', create if needed. +'main' Open 'directory/main.wiki', create if needed. +etc. + +Default: '' (empty string) + + +------------------------------------------------------------------------------ +*g:vimwiki_html_header_numbering* + +Set this option if you want headers to be auto numbered in html. + +ex: > + 1 Header1 + 1.1 Header2 + 1.2 Header2 + 1.2.1 Header3 + 1.2.2 Header3 + 1.3 Header2 + 2 Header1 + 3 Header1 +etc. + +Value Description~ +0 Header numbering is off. +1 Header numbering is on. Headers are numbered starting from + header level 1. +2 Header numbering is on. Headers are numbered starting from + header level 2. +etc. +Example when g:vimwiki_html_header_numbering = 2: > + Header1 + 1 Header2 + 2 Header2 + 2.1 Header3 + 2.1.1 Header4 + 2.1.2 Header4 + 2.2 Header3 + 3 Header2 + 4 Header2 +etc. + +Default: 0 + + +------------------------------------------------------------------------------ +*g:vimwiki_html_header_numbering_sym* + +Ending symbol for |g:vimwiki_html_header_numbering|. + +Value Description~ +'.' Dot would be added to the end of header's number. +')' Closing bracket would be added to the end of header's number. +etc. + +With + let g:vimwiki_html_header_numbering = '.' +headers would look like: > + 1. Header1 + 1.1. Header2 + 1.2. Header2 + 1.2.1. Header3 + 1.2.2. Header3 + 1.3. Header2 + 2. Header1 + 3. Header1 + + +Default: '' (empty) ============================================================================== 12. Help *vimwiki-help* -As you could see I am not native English speaker (not a writer as well). -Please send me correct phrases instead of that incorrect stuff I have used -here. +Your help in making vimwiki better is really appreciated! +Any help. Would it be spell correction or code snippet to patch -- everything +is welcomed. + +Issues could be filled in at http://code.google.com/p/vimwiki/issues . -Any help is really appreciated! ============================================================================== -13. Author *vimwiki-author* +13. Developers *vimwiki-developers* -I live in Moscow and you may believe me -- there are no polar bears (no brown -too) here in the streets. + - Maxim Kim <habamax@gmail.com> + Original author. + - Mikhail Trishchenkov <kriomant(at)gmail.com> + Joined in at Dec 2009. -I do not do programming for a living. So don't blame me for an ugly -ineffective code. Improvements are welcome. +Vimwiki's website: http://code.google.com/p/vimwiki/ +Vim plugins website: http://www.vim.org/scripts/script.php?script_id=2226 + +... afterword Many thanks to all of you for voting vimwiki up on www.vim.org. I do vimwiki in my spare time I could use to dance argentine tango with beautiful women. Your votes are kind of a good replacement. ;) Sincerely yours, -Maxim Kim <habamax@gmail.com>. +Maxim Kim. -Vimwiki's website: http://code.google.com/p/vimwiki/ -Vim plugins website: http://www.vim.org/scripts/script.php?script_id=2226 ============================================================================== 14. Changelog *vimwiki-changelog* +1.0~ + * NEW: Issue 41: Table cell and column text objects. See + |vimwiki-text-objects|. + * NEW: Issue 42: Commands to move table columns left and right. See + |:VimwikiTableMoveColumnLeft| and |:VimwikiTableMoveColumnRight|. + * NEW: Issue 44: <S-Tab> should move cursor to the previous table cell. + * NEW: Issue 45: It should be possible to indent tables. Indented tables + are centered in html. + * NEW: Issue 46: Do not htmlize some wiki pages (blacklist). New + placeholder is added: %nohtml. See |vimwiki-nohtml|. + * FIX: Issue 47: Lists aren't HTMLized properly. + * FIX: Issue 48: With autochdir it is impossible to have path_html such as + 'd:\vimwiki\html\' + * FIX: Issue 49: Table is not HTMLized properly at the end of wiki page. + * FIX: Issue 50: Inline formatting is not performed in table cells. + * FIX: Issue 51: Cannot insert '-' (minus) into table cells of the first + column. + * FIX: Issue 52: Table cell width is incorrect when double wide characters + are used (ie. Chinese). Check |g:vimwiki_CJK_length|. + * NEW: Issue 53: Wiki markup can not nested. (Use links and inline markup + in Headers). + * NEW: Issue 54: Highlight for placeholders. + * NEW: Issue 56: Directory indexes. See |g:vimwiki_dir_link| option and + |:VimwikiGenerateLinks| command. + * NEW: Issue 58: Html new lines with <br />. Could be inserted with <S-CR> + in insert mode. + * FIX: Issue 59: List item's text can't be started from *. + * NEW: Issue 60: Links inside completed gtd-items. + * NEW: Issue 61: Headers numbering. See |g:vimwiki_html_header_numbering| + and |g:vimwiki_html_header_numbering_sym| options. + * FIX: Issue 63: Table cannot have leading empty cells in html. + * FIX: Issue 65: Table separator is not htmlized right if on top of the + table. + * FIX: Issue 66: Table empty cells are very small in html. + * FIX: Issue 67: Wrong html conversion of multilined list item with bold + text on the start of next line. + * FIX: Issue 68: auto-indent problem with langmap. + * FIX: Issue 73: Link navigation by Tab. "Escaped" wiki-word should be + skipped for navigation with <tab>. + * FIX: Issue 75: `code` syntax doesn't display correctly in toc. + * FIX: Issue 77: Diary index only showing link to today's diary entry + file for extensions other than '.wiki'. + * FIX: Issue 79: Further calendar.vim integration -- add sign to calendar + date if it has corresponding diary page. + * FIX: Issue 80: Debian Lenny GUI Vim 7.2 has problems with toggling inner + todo list items. + * FIX: Issue 81: Don't convert WikiWord as a link in html when + `let g:vimwiki_camel_case = 0` + 0.9.9~ * NEW: Diary. Help in making daily notes. See |vimwiki-diary|. Now you can really easy add information into vimwiki that should be sorted out @@ -1819,7 +2019,7 @@ Vim plugins website: http://www.vim.org/scripts/script.php?script_id=2226 The MIT Licence http://www.opensource.org/licenses/mit-license.php -Copyright (c) 2010 Maxim Kim +Copyright (c) 2008-2010 Maxim Kim Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim @@ -1,3 +1,4 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki filetype plugin file " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ @@ -41,6 +42,19 @@ inoremap <buffer> <expr> <CR> vimwiki_lst#insertCR() nnoremap <buffer> o :call vimwiki_lst#insertOo('o')<CR>a nnoremap <buffer> O :call vimwiki_lst#insertOo('O')<CR>a +if !empty(&langmap) + " Valid only if langmap is a comma separated pairs of chars + let l_o = matchstr(&langmap, '\C,\zs.\zeo,') + if l_o + exe 'nnoremap <buffer> '.l_o.' :call vimwiki_lst#insertOo("o")<CR>a' + endif + + let l_O = matchstr(&langmap, '\C,\zs.\zeO,') + if l_O + exe 'nnoremap <buffer> '.l_O.' :call vimwiki_lst#insertOo("O")<CR>a' + endif +endif + " COMMENTS }}} " FOLDING for headers and list items using expr fold method. {{{ @@ -205,6 +219,8 @@ command! -buffer VimwikiVSplitWord call vimwiki#WikiFollowWord('vsplit') command! -buffer -range VimwikiToggleListItem call vimwiki_lst#ToggleListItem(<line1>, <line2>) +command! -buffer VimwikiGenerateLinks call vimwiki#generate_links() + exe 'command! -buffer -nargs=* VimwikiSearch vimgrep <args> '. \ escape(VimwikiGet('path').'**/*'.VimwikiGet('ext'), ' ') @@ -215,6 +231,8 @@ exe 'command! -buffer -nargs=* VWS vimgrep <args> '. command! -buffer -nargs=* VimwikiTable call vimwiki_tbl#create(<f-args>) command! -buffer VimwikiTableAlignQ call vimwiki_tbl#align_or_cmd('gqq') command! -buffer VimwikiTableAlignW call vimwiki_tbl#align_or_cmd('gww') +command! -buffer VimwikiTableMoveColumnLeft call vimwiki_tbl#move_column_left() +command! -buffer VimwikiTableMoveColumnRight call vimwiki_tbl#move_column_right() " COMMANDS }}} @@ -291,21 +309,39 @@ noremap <silent><script><buffer> if g:vimwiki_table_auto_fmt inoremap <expr> <buffer> <CR> vimwiki_tbl#kbd_cr() inoremap <expr> <buffer> <Tab> vimwiki_tbl#kbd_tab() + inoremap <expr> <buffer> <S-Tab> vimwiki_tbl#kbd_shift_tab() endif nnoremap <buffer> gqq :VimwikiTableAlignQ<CR> nnoremap <buffer> gww :VimwikiTableAlignW<CR> +nnoremap <buffer> <A-Left> :VimwikiTableMoveColumnLeft<CR> +nnoremap <buffer> <A-Right> :VimwikiTableMoveColumnRight<CR> + +" Misc mappings +inoremap <buffer> <S-CR> <br /><CR> " Text objects {{{ -omap <silent><buffer> ah :<C-U>call vimwiki#TO_header(0, 0)<CR> -vmap <silent><buffer> ah :<C-U>call vimwiki#TO_header(0, 1)<CR> +onoremap <silent><buffer> ah :<C-U>call vimwiki#TO_header(0, 0)<CR> +vnoremap <silent><buffer> ah :<C-U>call vimwiki#TO_header(0, 1)<CR> + +onoremap <silent><buffer> ih :<C-U>call vimwiki#TO_header(1, 0)<CR> +vnoremap <silent><buffer> ih :<C-U>call vimwiki#TO_header(1, 1)<CR> + +onoremap <silent><buffer> a\ :<C-U>call vimwiki#TO_table_cell(0, 0)<CR> +vnoremap <silent><buffer> a\ :<C-U>call vimwiki#TO_table_cell(0, 1)<CR> + +onoremap <silent><buffer> i\ :<C-U>call vimwiki#TO_table_cell(1, 0)<CR> +vnoremap <silent><buffer> i\ :<C-U>call vimwiki#TO_table_cell(1, 1)<CR> + +onoremap <silent><buffer> ac :<C-U>call vimwiki#TO_table_col(0, 0)<CR> +vnoremap <silent><buffer> ac :<C-U>call vimwiki#TO_table_col(0, 1)<CR> -omap <silent><buffer> ih :<C-U>call vimwiki#TO_header(1, 0)<CR> -vmap <silent><buffer> ih :<C-U>call vimwiki#TO_header(1, 1)<CR> +onoremap <silent><buffer> ic :<C-U>call vimwiki#TO_table_col(1, 0)<CR> +vnoremap <silent><buffer> ic :<C-U>call vimwiki#TO_table_col(1, 1)<CR> -nmap <silent><buffer> = :call vimwiki#AddHeaderLevel()<CR> -nmap <silent><buffer> - :call vimwiki#RemoveHeaderLevel()<CR> +noremap <silent><buffer> = :call vimwiki#AddHeaderLevel()<CR> +noremap <silent><buffer> - :call vimwiki#RemoveHeaderLevel()<CR> " }}} diff --git a/plugin/vimwiki.vim b/plugin/vimwiki.vim @@ -1,3 +1,4 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki plugin file " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ @@ -18,25 +19,22 @@ function! s:default(varname, value) "{{{ endif endfunction "}}} -function! Str_common_part(str1, str2)"{{{ +" return longest common prefix of 2 given strings. +" 'Hello world', 'Hello worm' => 'Hello wor' +function! s:str_common_pfx(str1, str2) "{{{ let idx = 0 let minlen = min([len(a:str1), len(a:str2)]) - while (idx < minlen) && (a:str1[idx] == a:str2[idx]) + while (idx < minlen) && (a:str1[idx] ==? a:str2[idx]) let idx = idx + 1 endwhile - return strpart(a:str1, 0, idx) -endfunction"}}} - -function! s:chomp_slash(str)"{{{ - return substitute(a:str, '[/\\]\+$', '', '') -endfunction"}}} +endfunction "}}} function! s:find_wiki(path) "{{{ let idx = 0 while idx < len(g:vimwiki_list) - let path = s:chomp_slash(expand(VimwikiGet('path', idx))) - if Str_common_part(path, a:path) == path + let path = vimwiki#chomp_slash(expand(VimwikiGet('path', idx))) + if s:str_common_pfx(path, a:path) == path return idx endif let idx += 1 @@ -214,7 +212,7 @@ let s:vimwiki_defaults.diary_rel_path = 'diary/' let s:vimwiki_defaults.diary_index = 'diary' let s:vimwiki_defaults.diary_header = 'Diary' -" Do not change this! Will wait till vim would be more datetime awareable. +" Do not change this! Will wait till vim become more datetime awareable. let s:vimwiki_defaults.diary_link_fmt = '%Y-%m-%d' let s:vimwiki_defaults.diary_link_count = 4 @@ -265,6 +263,11 @@ endif call s:default('use_calendar', 1) call s:default('table_auto_fmt', 1) call s:default('w32_dir_enc', '') +call s:default('CJK_length', 0) +call s:default('dir_link', '') + +call s:default('html_header_numbering', 0) +call s:default('html_header_numbering_sym', '') call s:default('current_idx', 0) @@ -275,14 +278,17 @@ let nup = low.oth let nlo = upp.oth let any = upp.nup -let g:vimwiki_word1 = '\C\<['.upp.']['.nlo.']*['. - \ low.']['.nup.']*['.upp.']['.any.']*\>' -let g:vimwiki_word2 = '\[\[[^\]]\+\]\]' -let g:vimwiki_word3 = '\[\[[^\]]\+\]\[[^\]]\+\]\]' +let wword = '\C\<['.upp.']['.nlo.']*['.low.']['.nup.']*['.upp.']['.any.']*\>' +let g:vimwiki_rxWikiWord = '!\@<!'.wword +let g:vimwiki_rxNoWikiWord = '!'.wword + +let g:vimwiki_rxWikiLink1 = '\[\[[^\]]\+\]\]' +let g:vimwiki_rxWikiLink2 = '\[\[[^\]]\+\]\[[^\]]\+\]\]' if g:vimwiki_camel_case - let g:vimwiki_rxWikiWord = g:vimwiki_word1.'\|'.g:vimwiki_word2.'\|'.g:vimwiki_word3 + let g:vimwiki_rxWikiLink = g:vimwiki_rxWikiWord.'\|'. + \ g:vimwiki_rxWikiLink1.'\|'.g:vimwiki_rxWikiLink2 else - let g:vimwiki_rxWikiWord = g:vimwiki_word2.'\|'.g:vimwiki_word3 + let g:vimwiki_rxWikiLink = g:vimwiki_rxWikiLink1.'\|'.g:vimwiki_rxWikiLink2 endif let g:vimwiki_rxWeblink = '\%("[^"(]\+\((\([^)]\+\))\)\?":\)\?'. \'\%(https\?\|ftp\|gopher\|telnet\|file\|notes\|ms-help\):'. @@ -387,6 +393,8 @@ function! s:build_table_menu(topmenu) exe 'menu '.a:topmenu.'.-Sep- :' exe 'menu '.a:topmenu.'.Table.Create\ (enter\ cols\ rows) :VimwikiTable ' exe 'nmenu '.a:topmenu.'.Table.Format<tab>gqq gqq' + exe 'nmenu '.a:topmenu.'.Table.Move\ column\ left<tab><A-Left> :VimwikiTableMoveColumnLeft<CR>' + exe 'nmenu '.a:topmenu.'.Table.Move\ column\ right<tab><A-Right> :VimwikiTableMoveColumnRight<CR>' exe 'nmenu disable '.a:topmenu.'.Table' endfunction @@ -399,6 +407,7 @@ endif " CALENDAR Hook "{{{ if g:vimwiki_use_calendar let g:calendar_action = 'vimwiki_diary#calendar_action' + let g:calendar_sign = 'vimwiki_diary#calendar_sign' endif "}}} diff --git a/syntax/vimwiki.vim b/syntax/vimwiki.vim @@ -1,7 +1,7 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki syntax file " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ -" vim:tw=79: " Quit if syntax file is already loaded if version < 600 @@ -14,17 +14,18 @@ endif if VimwikiGet('maxhi') " Every WikiWord is nonexistent if g:vimwiki_camel_case - execute 'syntax match VimwikiNoExistsWord /\%(^\|[^!]\)\@<='.g:vimwiki_word1.'/' + execute 'syntax match VimwikiNoExistsLink /'.g:vimwiki_rxWikiWord.'/' endif - execute 'syntax match VimwikiNoExistsWord /'.g:vimwiki_word2.'/' - execute 'syntax match VimwikiNoExistsWord /'.g:vimwiki_word3.'/' + execute 'syntax match VimwikiNoExistsLink /'.g:vimwiki_rxWikiLink1.'/' + execute 'syntax match VimwikiNoExistsLink /'.g:vimwiki_rxWikiLink2.'/' " till we find them in vimwiki's path - call vimwiki#WikiHighlightWords() + call vimwiki#WikiHighlightLinks() else " A WikiWord (unqualifiedWikiName) - execute 'syntax match VimwikiWord /\%(^\|[^!]\)\@<=\<'.g:vimwiki_word1.'\>/' + execute 'syntax match VimwikiLink /\<'.g:vimwiki_rxWikiWord.'\>/' " A [[bracketed wiki word]] - execute 'syntax match VimwikiWord /'.g:vimwiki_word2.'/' + execute 'syntax match VimwikiLink /'.g:vimwiki_rxWikiLink1.'/' + execute 'syntax match VimwikiLink /'.g:vimwiki_rxWikiLink2.'/' endif execute 'syntax match VimwikiLink `'.g:vimwiki_rxWeblink.'`' @@ -41,8 +42,8 @@ execute 'runtime! syntax/vimwiki_'.VimwikiGet('syntax').'.vim' " Tables " execute 'syntax match VimwikiTable /'.g:vimwiki_rxTable.'/' syntax match VimwikiTableRow /\s*|.\+|\s*/ - \ transparent contains=VimwikiCellSeparator,VimwikiWord, - \ VimwikiNoExistsWord,VimwikiEmoticons,VimwikiTodo, + \ transparent contains=VimwikiCellSeparator,VimwikiLink, + \ VimwikiNoExistsLink,VimwikiEmoticons,VimwikiTodo, \ VimwikiBold,VimwikiItalic,VimwikiBoldItalic,VimwikiItalicBold, \ VimwikiDelText,VimwikiSuperScript,VimwikiSubScript,VimwikiCode syntax match VimwikiCellSeparator @@ -79,11 +80,21 @@ execute 'syntax region VimwikiPre start=/'.g:vimwiki_rxPreStart. syntax match VimwikiCheckBox /\[.\?\]/ if g:vimwiki_hl_cb_checked execute 'syntax match VimwikiCheckBoxDone /'. - \ g:vimwiki_rxListBullet.'\s*\['.g:vimwiki_listsyms[4].'\].*$/' + \ g:vimwiki_rxListBullet.'\s*\['.g:vimwiki_listsyms[4].'\].*$/'. + \ ' contains=VimwikiNoExistsLink,VimwikiLink' execute 'syntax match VimwikiCheckBoxDone /'. - \ g:vimwiki_rxListNumber.'\s*\['.g:vimwiki_listsyms[4].'\].*$/' + \ g:vimwiki_rxListNumber.'\s*\['.g:vimwiki_listsyms[4].'\].*$/'. + \ ' contains=VimwikiNoExistsLink,VimwikiLink' endif +" placeholders +syntax match VimwikiPlaceholder /^\s*%toc\%(\s.*\)\?$/ +syntax match VimwikiPlaceholder /^\s*%nohtml\s*$/ + +" html tags +syntax match VimwikiHTMLtag '<br\s*/\?>' +syntax match VimwikiHTMLtag '<hr\s*/\?>' + syntax region VimwikiComment start='<!--' end='-->' if !vimwiki#hl_exists("VimwikiHeader1") @@ -116,10 +127,9 @@ hi def VimwikiBoldItalic term=bold cterm=bold gui=bold,italic hi def link VimwikiItalicBold VimwikiBoldItalic hi def link VimwikiCode PreProc -hi def link VimwikiWord Underlined -hi def link VimwikiNoExistsWord Error +hi def link VimwikiNoExistsLink Error -hi def link VimwikiPre SpecialComment +hi def link VimwikiPre PreProc hi def link VimwikiLink Underlined hi def link VimwikiList Function hi def link VimwikiCheckBox VimwikiList @@ -132,6 +142,8 @@ hi def link VimwikiTodo Todo hi def link VimwikiComment Comment hi def link VimwikiCellSeparator SpecialKey +hi def link VimwikiPlaceholder SpecialKey +hi def link VimwikiHTMLtag SpecialKey "}}} let b:current_syntax="vimwiki" diff --git a/syntax/vimwiki_default.vim b/syntax/vimwiki_default.vim @@ -1,14 +1,14 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki syntax file " Default syntax " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ -" vim:tw=78: " text: *strong* " let g:vimwiki_rxBold = '\*[^*]\+\*' let g:vimwiki_rxBold = '\%(^\|\s\|[[:punct:]]\)\@<='. \'\*'. - \'\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`]\)'. + \'\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)'. \'\*'. \'\%([[:punct:]]\|\s\|$\)\@=' @@ -16,20 +16,20 @@ let g:vimwiki_rxBold = '\%(^\|\s\|[[:punct:]]\)\@<='. " let g:vimwiki_rxItalic = '_[^_]\+_' let g:vimwiki_rxItalic = '\%(^\|\s\|[[:punct:]]\)\@<='. \'_'. - \'\%([^_`[:space:]][^_`]*[^_`[:space:]]\|[^_`]\)'. + \'\%([^_`[:space:]][^_`]*[^_`[:space:]]\|[^_`[:space:]]\)'. \'_'. \'\%([[:punct:]]\|\s\|$\)\@=' " text: *_bold italic_* or _*italic bold*_ let g:vimwiki_rxBoldItalic = '\%(^\|\s\|[[:punct:]]\)\@<='. \'\*_'. - \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`]\)'. + \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'. \'_\*'. \'\%([[:punct:]]\|\s\|$\)\@=' let g:vimwiki_rxItalicBold = '\%(^\|\s\|[[:punct:]]\)\@<='. \'_\*'. - \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`]\)'. + \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'. \'\*_'. \'\%([[:punct:]]\|\s\|$\)\@=' diff --git a/syntax/vimwiki_media.vim b/syntax/vimwiki_media.vim @@ -1,8 +1,8 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 " Vimwiki syntax file " MediaWiki syntax " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ -" vim:tw=78: " text: '''strong''' let g:vimwiki_rxBold = "'''[^']\\+'''"