vimwiki

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

commit d5a6d097da1c67e07b3fb073f22217c7462f5088
parent 84297c90516c40df5c6e224930c3bd92a8046efd
Author: Maxim Kim <habamax@gmail.com>
Date:   Thu,  7 Jun 2012 00:00:00 +0000

Version 2.0.stu

This release is partly incompatible with 1.2.

You should delete previous version of vimwiki before install.

= Summary =

    * Quick page-link creation.
    * Redesign of link syntaxes (!)
        * No more CamelCase links. Check the ways to convert them http://goo.gl/15ctX
        * No more [[link][desc]] links.
        * No more [http://link description] links.
        * No more plain image links. Use transclusions.
        * No more image links identified by extension. Use transclusions.
    * Interwiki links.
    * Link schemes.
    * Transclusions.
    * Normalize link command.
    * Improved diary organization and generation.
    * List manipulation.
    * Markdown support.
    * Mathjax support.
    * Improved handling of special characters and punctuation in filenames and urls.
    * Back links command: list links referring to the current page.
    * Highlighting nonexisted links are off by default.
    * Table syntax change. Row separator uses | instead of +.
    * Fold multilined list items.
    * Custom wiki to HTML converters.
    * Conceal long weblinks.
    * Option to disable table mappings.

For detailed information see issues list on
http://code.google.com/p/vimwiki/issues/list


Diffstat:
MREADME | 39++++++++++++++++++++-------------------
Mautoload/vimwiki/base.vim | 1178++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mautoload/vimwiki/diary.vim | 400+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mautoload/vimwiki/html.vim | 684+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mautoload/vimwiki/lst.vim | 206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Aautoload/vimwiki/markdown_base.vim | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mautoload/vimwiki/style.css | 64++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mautoload/vimwiki/tbl.vim | 302++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Aautoload/vimwiki/u.vim | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/vimwiki.txt | 1470+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mftplugin/vimwiki.vim | 137++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mplugin/vimwiki.vim | 453+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msyntax/vimwiki.vim | 491++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msyntax/vimwiki_default.vim | 38+++++++++++++++++++++-----------------
Asyntax/vimwiki_markdown.vim | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asyntax/vimwiki_markdown_custom.vim | 367+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msyntax/vimwiki_media.vim | 40+++++++++++++++++++++-------------------
17 files changed, 4148 insertions(+), 1998 deletions(-)

diff --git a/README b/README @@ -5,8 +5,6 @@ A Personal Wiki For Vim Plugin Screenshots are available on http://code.google.com/p/vimwiki/ There are also zipped vimwiki files there in case you do not like vimball archives. -Vimwiki quick reference card http://vimwiki.googlecode.com/hg/misc/Vimwiki1.1.1QR.pdf. - Prerequisites ============================================================================== @@ -24,31 +22,35 @@ Intro Vimwiki is a personal wiki for Vim -- a number of linked text files that have their own syntax highlighting. -With vimwiki you can - - organize notes and ideas - - manage todo-lists - - write documentation +With vimwiki you can: + - organize notes and ideas; + - manage todo-lists; + - write documentation. To do a quick start press <Leader>ww (this is usually \ww) to go to your index -wiki file. By default it is located in: +wiki file. By default it is located in: ~/vimwiki/index.wiki Feed it with the following example: = My knowledge base = - * MyUrgentTasks -- things to be done _yesterday_!!! - * ProjectGutenberg -- good books are power. - * ScratchPad -- various temporary stuff. + * Tasks -- things to be done _yesterday_!!! + * Project Gutenberg -- good books are power. + * Scratchpad -- various temporary stuff. +Place your cursor on 'Tasks' and press Enter to create a link. Once pressed, +'Tasks' will become '[[Tasks]]' -- a vimwiki link. Press Enter again to +open it. Edit the file, save it, and then press Backspace to jump back to your +index. -Notice that !ProjectGutenberg, !MyUrgentTasks and !ScratchPad curly underlined. -These are links in CamelCase form that do not exists yet. (CamelCase -form -- capitalized word connected with other capitalized words) +A vimwiki link can be constructed from more than one word. Just visually +select the words to be linked and press Enter. Try it with 'Project +Gutenberg'. The result should look something like: -Place cursor on ProjectGutenberg and press <Enter>. Now you are in -ProjectGutenberg. Edit and save it, then press Backspace to return to parent -wiki page. You should see the difference now -- ProjectGutenberg is -highlighted as a link. += My knowledge base = + * [[Tasks]] -- things to be done _yesterday_!!! + * [[Project Gutenberg]] -- good books are power. + * Scratchpad -- various temporary stuff. For the various options see :h vimwiki-options. @@ -60,9 +62,8 @@ see :h vimwiki-syntax *bold* -- bold _italic_ -- italic -WikiWord -- link to WikiWord + [[wiki link]] -- link with spaces -[[wiki link][description]] -- link with description [[wiki link|description]] -- link with description Lists: diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim @@ -8,143 +8,492 @@ if exists("g:loaded_vimwiki_auto") || &cp endif let g:loaded_vimwiki_auto = 1 -if has("win32") - let s:os_sep = '\' -else - let s:os_sep = '/' -endif - -let s:badsymbols = '['.g:vimwiki_badsyms.g:vimwiki_stripsym.'<>|?*:"]' +" ------------------------------------------------------------------------- +" Load syntax-specific Wiki functionality +execute 'runtime! autoload/vimwiki/'.VimwikiGet('syntax').'_base.vim' +" ------------------------------------------------------------------------- " MISC helper functions {{{ -function! vimwiki#base#chomp_slash(str) "{{{ - return substitute(a:str, '[/\\]\+$', '', '') +function! s:normalize_path(path) "{{{ + let g:VimwikiLog.normalize_path += 1 "XXX + " resolve doesn't work quite right with symlinks ended with / or \ + return resolve(expand(substitute(a:path, '[/\\]\+$', '', ''))).'/' +endfunction "}}} + +function! s:path_html(idx) "{{{ + let path_html = VimwikiGet('path_html', a:idx) + if !empty(path_html) + return path_html + else + let g:VimwikiLog.path_html += 1 "XXX + let path = VimwikiGet('path', a:idx) + return substitute(path, '[/\\]\+$', '', '').'_html/' + endif endfunction "}}} -function! vimwiki#base#path_norm(path) "{{{ - return substitute(a:path, '\', '/', 'g') +" }}} + +function! vimwiki#base#apply_wiki_options(options) " {{{ Update the current + " wiki using the options dictionary + for kk in keys(a:options) + let g:vimwiki_list[g:vimwiki_current_idx][kk] = a:options[kk] + endfor + call vimwiki#base#validate_wiki_options(g:vimwiki_current_idx) + call vimwiki#base#setup_buffer_state(g:vimwiki_current_idx) +endfunction " }}} + +function! vimwiki#base#read_wiki_options(check) " {{{ Attempt to read wiki + " options from the current page's directory, or its ancesters. If a file + " named vimwiki.vimrc is found, which declares a wiki-options dictionary + " named g:local_wiki, a message alerts the user that an update has been + " found and may be applied. If the argument check=1, the user is queried + " before applying the update to the current wiki's option. + + " Save global vimwiki options ... after all, the global list is often + " initialized for the first time in vimrc files, and we don't want to + " overwrite !! (not to mention all the other globals ...) + let l:vimwiki_list = deepcopy(g:vimwiki_list, 1) + " + if a:check + call vimwiki#base#print_wiki_state() + echo " \n" + endif + " + let g:local_wiki = {} + let done = 0 + " ... start the wild-goose chase! + for invsubdir in ['.', '..', '../..', '../../..'] + " other names are possible, but most vimrc files will cause grief! + for nm in ['vimwiki.vimrc'] + " TODO: use an alternate strategy, instead of source, to read options + if done | + continue + endif + " + let local_wiki_options_filename = expand('%:p:h').'/'.invsubdir.'/'.nm + if !filereadable(local_wiki_options_filename) + continue + endif + " + echo "\nFound file : ".local_wiki_options_filename + let query = "Vimwiki: Check for options in this file [Y]es/[n]o? " + if a:check && (tolower(input(query)) !~ "y") + continue + endif + " + try + execute 'source '.local_wiki_options_filename + catch + endtry + if empty(g:local_wiki) + continue + endif + " + if a:check + echo "\n\nFound wiki options\n g:local_wiki = ".string(g:local_wiki) + let query = "Vimwiki: Apply these options [Y]es/[n]o? " + if tolower(input(query)) !~ "y" + let g:local_wiki = {} + continue + endif + endif + " + " restore global list + " - this prevents corruption by g:vimwiki_list in options_file + let g:vimwiki_list = deepcopy(l:vimwiki_list, 1) + " + call vimwiki#base#apply_wiki_options(g:local_wiki) + let done = 1 + endfor + endfor + if !done + " + " restore global list, if no local options were found + " - this prevents corruption by g:vimwiki_list in options_file + let g:vimwiki_list = deepcopy(l:vimwiki_list, 1) + " + endif + if a:check + echo " \n " + if done + call vimwiki#base#print_wiki_state() + else + echo "Vimwiki: No options were applied." + endif + endif +endfunction " }}} + +function! vimwiki#base#validate_wiki_options(idx) " {{{ Validate wiki options + " Only call this function *before* opening a wiki page. + " + " XXX: It's too early to update global / buffer variables, because they are + " still needed in their existing state for s:setup_buffer_leave() + "" let g:vimwiki_current_idx = a:idx + + " update normalized path & path_html + call VimwikiSet('path', s:normalize_path(VimwikiGet('path', a:idx)), a:idx) + call VimwikiSet('path_html', s:normalize_path(s:path_html(a:idx)), a:idx) + call VimwikiSet('template_path', + \ s:normalize_path(VimwikiGet('template_path', a:idx)), a:idx) + call VimwikiSet('diary_rel_path', + \ s:normalize_path(VimwikiGet('diary_rel_path', a:idx)), a:idx) + + " XXX: It's too early to update global / buffer variables, because they are + " still needed in their existing state for s:setup_buffer_leave() + "" call vimwiki#base#cache_buffer_state() +endfunction " }}} + +function! vimwiki#base#setup_buffer_state(idx) " {{{ Init page-specific variables + " Only call this function *after* opening a wiki page. + if a:idx < 0 + return + endif + + let g:vimwiki_current_idx = a:idx + + " The following state depends on the current active wiki page + let subdir = vimwiki#base#current_subdir(a:idx) + call VimwikiSet('subdir', subdir, a:idx) + call VimwikiSet('invsubdir', vimwiki#base#invsubdir(subdir), a:idx) + call VimwikiSet('url', vimwiki#html#get_wikifile_url(expand('%:p')), a:idx) + + " update cache + call vimwiki#base#cache_buffer_state() +endfunction " }}} + +function! vimwiki#base#cache_buffer_state() "{{{ + if !exists('g:vimwiki_current_idx') && g:vimwiki_debug + echo "[Vimwiki Internal Error]: Missing global state variable: 'g:vimwiki_current_idx'" + endif + let b:vimwiki_idx = g:vimwiki_current_idx endfunction "}}} -function! vimwiki#base#mkdir(path) "{{{ +function! vimwiki#base#recall_buffer_state() "{{{ + if !exists('b:vimwiki_idx') + if g:vimwiki_debug + echo "[Vimwiki Internal Error]: Missing buffer state variable: 'b:vimwiki_idx'" + endif + return 0 + else + let g:vimwiki_current_idx = b:vimwiki_idx + return 1 + endif +endfunction " }}} + +function! vimwiki#base#print_wiki_state() "{{{ print wiki options + " and buffer state variables + let g_width = 18 + let b_width = 18 + echo "- Wiki Options (idx=".g:vimwiki_current_idx.") -" + for kk in VimwikiGetOptionNames() + echo " '".kk."': ".repeat(' ', g_width-len(kk)).string(VimwikiGet(kk)) + endfor + if !exists('b:vimwiki_list') + return + endif + echo "- Cached Variables -" + for kk in keys(b:vimwiki_list) + echo " '".kk."': ".repeat(' ', b_width-len(kk)).string(b:vimwiki_list[kk]) + endfor +endfunction "}}} + +" If the optional argument 'confirm' == 1 is provided, +" vimwiki#base#mkdir will ask before creating a directory +function! vimwiki#base#mkdir(path, ...) "{{{ let path = expand(a:path) if !isdirectory(path) && exists("*mkdir") - let path = vimwiki#base#chomp_slash(path) - if s:is_windows() && !empty(g:vimwiki_w32_dir_enc) + let path = vimwiki#u#chomp_slash(path) + if vimwiki#u#is_windows() && !empty(g:vimwiki_w32_dir_enc) let path = iconv(path, &enc, g:vimwiki_w32_dir_enc) endif + if a:0 && a:1 && tolower(input("Vimwiki: Make new directory: ".path."\n [Y]es/[n]o? ")) !~ "y" + return 0 + endif call mkdir(path, "p") endif + return 1 endfunction " }}} -function! vimwiki#base#safe_link(link) "{{{ - " handling Windows absolute paths - if a:link =~ '^[[:alpha:]]:[/\\].*' - let link_start = a:link[0 : 2] - let link = a:link[3 : ] - else - let link_start = '' - let link = a:link - endif - let link = substitute(link, s:badsymbols, g:vimwiki_stripsym, 'g') - return link_start.link +function! vimwiki#base#file_pattern(files) "{{{ Get search regex from glob() + " string. Aim to support *all* special characters, forcing the user to choose + " names that are compatible with any external restrictions that they + " encounter (e.g. filesystem, wiki conventions, other syntaxes, ...). + " See: http://code.google.com/p/vimwiki/issues/detail?id=316 + " Change / to [/\\] to allow "Windows paths" + " TODO: boundary cases ... + " e.g. "File$", "^File", "Fi]le", "Fi[le", "Fi\le", "Fi/le" + " XXX: (remove my comment if agreed) Maxim: with \V (very nomagic) boundary + " cases works for 1 and 2. + " 3, 4, 5 is not highlighted as links thus wouldn't be highlighted. + " 6 is a regular vimwiki link with subdirectory... + " + let pattern = vimwiki#base#branched_pattern(a:files,"\n") + return '\V'.pattern.'\m' endfunction "}}} -function! vimwiki#base#unsafe_link(string) "{{{ - if len(g:vimwiki_stripsym) > 0 - return substitute(a:string, g:vimwiki_stripsym, s:badsymbols, 'g') - else - return a:string - endif +function! vimwiki#base#branched_pattern(string,separator) "{{{ get search regex +" from a string-list; separators assumed at start and end as well + let pattern = substitute(a:string, a:separator, '\\|','g') + let pattern = substitute(pattern, '\%^\\|', '\\%(','') + let pattern = substitute(pattern,'\\|\%$', '\\)','') + return pattern endfunction "}}} +"FIXME TODO slow and faulty function! vimwiki#base#subdir(path, filename)"{{{ - let path = expand(a:path) - let filename = expand(a:filename) + let g:VimwikiLog.subdir += 1 "XXX + let path = a:path + " ensure that we are not fooled by a symbolic link + "FIXME if we are not "fooled", we end up in a completely different wiki? + let filename = resolve(a:filename) let idx = 0 + "FIXME this can terminate in the middle of a path component! while path[idx] ==? filename[idx] let idx = idx + 1 endwhile let p = split(strpart(filename, idx), '[/\\]') - let res = join(p[:-2], s:os_sep) + let res = join(p[:-2], '/') if len(res) > 0 - let res = res.s:os_sep + let res = res.'/' endif return res -endfunction"}}} +endfunction "}}} -function! vimwiki#base#current_subdir()"{{{ - return vimwiki#base#subdir(VimwikiGet('path'), expand('%:p')) +function! vimwiki#base#current_subdir(idx)"{{{ + return vimwiki#base#subdir(VimwikiGet('path', a:idx), expand('%:p')) endfunction"}}} -function! vimwiki#base#open_link(cmd, link, ...) "{{{ - if vimwiki#base#is_non_wiki_link(a:link) - if s:is_path_absolute(a:link) - call vimwiki#base#edit_file(a:cmd, a:link) +function! vimwiki#base#invsubdir(subdir) " {{{ + return substitute(a:subdir, '[^/\.]\+/', '../', 'g') +endfunction " }}} + +function! vimwiki#base#resolve_scheme(lnk, as_html) " {{{ Resolve scheme + " - Only return non-negative index when valid wiki link found + " + " if link is schemeless add wikiN: scheme + let lnk = a:lnk + let is_schemeless = lnk !~ g:vimwiki_rxSchemeUrl + let lnk = (is_schemeless ? 'wiki'.g:vimwiki_current_idx.':'.lnk : lnk) + + " Get scheme + let scheme = matchstr(lnk, g:vimwiki_rxSchemeUrlMatchScheme) + " Get link (without scheme) + let lnk = matchstr(lnk, g:vimwiki_rxSchemeUrlMatchUrl) + let path = '' + let subdir = '' + let ext = '' + let idx = -1 + + " do nothing if scheme is unknown to vimwiki + if !(scheme =~ 'wiki.*' || scheme =~ 'diary' || scheme =~ 'local' + \ || scheme =~ 'file') + return [idx, scheme, path, subdir, lnk, ext, scheme.':'.lnk] + endif + + " scheme behaviors + if scheme =~ 'wiki\d\+' + let idx = eval(matchstr(scheme, '\D\+\zs\d\+\ze')) + if idx < 0 || idx >= len(g:vimwiki_list) + echom 'Vimwiki Error: Numbered scheme refers to a non-existent wiki!' + return [idx,'','','','','',''] else - call vimwiki#base#edit_file(a:cmd, VimwikiGet('path').a:link) - endif - else - if a:0 - let vimwiki_prev_link = [a:1, []] - elseif &ft == 'vimwiki' - let vimwiki_prev_link = [expand('%:p'), getpos('.')] + if idx != g:vimwiki_current_idx + call vimwiki#base#validate_wiki_options(idx) + endif endif - if vimwiki#base#is_link_to_dir(a:link) - if g:vimwiki_dir_link == '' - call vimwiki#base#edit_file(a:cmd, VimwikiGet('path').a:link) + if a:as_html + if idx == g:vimwiki_current_idx + let path = VimwikiGet('path_html') else - call vimwiki#base#edit_file(a:cmd, - \ VimwikiGet('path').a:link. - \ g:vimwiki_dir_link. - \ VimwikiGet('ext')) + let path = VimwikiGet('path_html', idx) endif else - call vimwiki#base#edit_file(a:cmd, VimwikiGet('path').a:link.VimwikiGet('ext')) + if idx == g:vimwiki_current_idx + let path = VimwikiGet('path') + else + let path = VimwikiGet('path', idx) + endif + endif + + " For Issue 310. Otherwise current subdir is used for another wiki. + if idx == g:vimwiki_current_idx + let subdir = VimwikiGet('subdir') + else + let subdir = "" + endif + + if a:as_html + let ext = '.html' + else + if idx == g:vimwiki_current_idx + let ext = VimwikiGet('ext') + else + let ext = VimwikiGet('ext', idx) + endif endif - if exists('vimwiki_prev_link') - let b:vimwiki_prev_link = vimwiki_prev_link + " default link for directories + if vimwiki#u#is_link_to_dir(lnk) + let ext = (g:vimwiki_dir_link != '' ? g:vimwiki_dir_link. ext : '') + endif + elseif scheme =~ 'diary' + if a:as_html + " use cached value (save time when converting diary index!) + let path = VimwikiGet('invsubdir') + let ext = '.html' + else + let path = VimwikiGet('path') + let ext = VimwikiGet('ext') endif + let subdir = VimwikiGet('diary_rel_path') + elseif scheme =~ 'local' + " revisiting the 'lcd'-bug ... + let path = VimwikiGet('path') + let subdir = VimwikiGet('subdir') + if a:as_html + " prepend browser-specific file: scheme + let path = 'file://'.fnamemodify(path, ":p") + endif + elseif scheme =~ 'file' + " RM repeated leading "/"'s within a link + let lnk = substitute(lnk, '^/*', '/', '') + " convert "/~..." into "~..." for fnamemodify + let lnk = substitute(lnk, '^/\~', '\~', '') + " convert /C: to C: (or fnamemodify(...":p:h") interpret it as C:\C: + if vimwiki#u#is_windows() + let lnk = substitute(lnk, '^/\ze[[:alpha:]]:', '', '') + endif + if a:as_html + " prepend browser-specific file: scheme + let path = 'file://'.fnamemodify(lnk, ":p:h").'/' + else + let path = fnamemodify(lnk, ":p:h").'/' + endif + let lnk = fnamemodify(lnk, ":p:t") + let subdir = '' endif -endfunction -" }}} -function! vimwiki#base#select(wnum)"{{{ - if a:wnum < 1 || a:wnum > len(g:vimwiki_list) - return + + " construct url from parts + if is_schemeless && a:as_html + let scheme = '' + let url = lnk.ext + else + let url = path.subdir.lnk.ext endif - if &ft == 'vimwiki' - let b:vimwiki_idx = g:vimwiki_current_idx + + " result + return [idx, scheme, path, subdir, lnk, ext, url] +endfunction "}}} + +function! vimwiki#base#system_open_link(url) "{{{ + " handlers + function! s:win32_handler(url) + "http://vim.wikia.com/wiki/Opening_current_Vim_file_in_your_Windows_browser + execute 'silent ! start "Title" /B ' . shellescape(a:url, 1) + endfunction + function! s:macunix_handler(url) + execute '!open ' . shellescape(a:url, 1) + endfunction + function! s:linux_handler(url) + execute 'silent !xdg-open ' . shellescape(a:url, 1) + endfunction + let success = 0 + try + if vimwiki#u#is_windows() + call s:win32_handler(a:url) + return + elseif has("macunix") + call s:macunix_handler(a:url) + return + else + call s:linux_handler(a:url) + return + endif + endtry + echomsg 'Default Vimwiki link handler was unable to open the HTML file!' +endfunction "}}} + +function! vimwiki#base#open_link(cmd, link, ...) "{{{ + let [idx, scheme, path, subdir, lnk, ext, url] = + \ vimwiki#base#resolve_scheme(a:link, 0) + + if url == '' + if g:vimwiki_debug + echom 'open_link: idx='.idx.', scheme='.scheme.', path='.path.', subdir='.subdir.', lnk='.lnk.', ext='.ext.', url='.url + endif + echom 'Vimwiki Error: Unable to resolve link!' + return endif - let g:vimwiki_current_idx = a:wnum - 1 -endfunction -" }}} -function! vimwiki#base#generate_links()"{{{ - let links = s:get_links('*'.VimwikiGet('ext')) + let update_prev_link = ( + \ scheme == '' || + \ scheme =~ 'wiki' || + \ scheme =~ 'diary' ? 1 : 0) - " We don't want link to itself. - let cur_link = expand('%:t:r') - call filter(links, 'v:val != cur_link') + let use_system_open = ( + \ scheme == '' || + \ scheme =~ 'wiki' || + \ scheme =~ 'diary' ? 0 : 1) - if len(links) - call append(line('$'), '= Generated Links =') + let vimwiki_prev_link = [] + " update previous link for wiki pages + if update_prev_link + if a:0 + let vimwiki_prev_link = [a:1, []] + elseif &ft == 'vimwiki' + let vimwiki_prev_link = [expand('%:p'), getpos('.')] + endif endif + " open/edit + if g:vimwiki_debug + echom 'open_link: idx='.idx.', scheme='.scheme.', path='.path.', subdir='.subdir.', lnk='.lnk.', ext='.ext.', url='.url + endif + + if use_system_open + call vimwiki#base#system_open_link(url) + else + call vimwiki#base#edit_file(a:cmd, url, + \ vimwiki_prev_link, update_prev_link) + if idx != g:vimwiki_current_idx + " this call to setup_buffer_state may not be necessary + call vimwiki#base#setup_buffer_state(idx) + endif + endif +endfunction +" }}} + +function! vimwiki#base#generate_links() "{{{only get links from the current dir + " change to the directory of the current file + let orig_pwd = getcwd() + lcd! %:h + " all path are relative to the current file's location + let globlinks = glob('*'.VimwikiGet('ext'),1)."\n" + " remove extensions + let globlinks = substitute(globlinks, '\'.VimwikiGet('ext').'\ze\n', '', 'g') + " restore the original working directory + exe 'lcd! '.orig_pwd + + " We don't want link to itself. XXX Why ??? + " let cur_link = expand('%:t:r') + " call filter(links, 'v:val != cur_link') + let links = split(globlinks,"\n") + call append(line('$'), substitute(g:vimwiki_rxH1_Template, '__Header__', 'Generated Links', '')) + call sort(links) + let bullet = repeat(' ', vimwiki#lst#get_list_margin()). + \ vimwiki#lst#default_symbol().' ' for link in links - if s:is_wiki_word(link) - call append(line('$'), '- '.link) - else - call append(line('$'), '- [['.link.']]') - endif + call append(line('$'), bullet. + \ substitute(g:vimwiki_WikiLinkTemplate1, '__LinkUrl__', '\='."'".link."'", '')) endfor endfunction " }}} @@ -155,17 +504,30 @@ function! vimwiki#base#goto(key) "{{{ \ VimwikiGet('ext')) endfunction "}}} -function! s:is_windows() "{{{ - return has("win32") || has("win64") || has("win95") || has("win16") +function! vimwiki#base#backlinks() "{{{ + execute 'lvimgrep "\%(^\|[[:blank:][:punct:]]\)'. + \ expand("%:t:r"). + \ '\([[:blank:][:punct:]]\|$\)" '. + \ escape(VimwikiGet('path').'**/*'.VimwikiGet('ext'), ' ') endfunction "}}} -function! s:is_path_absolute(path) "{{{ - return a:path =~ '^/.*' || a:path =~ '^[[:alpha:]]:[/\\].*' -endfunction "}}} +function! vimwiki#base#get_links(pat) "{{{ return string-list for files + " in the current wiki matching the pattern "pat" + " search all wiki files (or directories) in wiki 'path' and its subdirs. + + let time1 = reltime() " start the clock XXX -function! s:get_links(pat) "{{{ - " search all wiki files in 'path' and its subdirs. - let subdir = vimwiki#base#current_subdir() + " XXX: + " if maxhi = 1 and <leader>w<leader>w before loading any vimwiki file + " cached 'subdir' is not set up + try + let subdir = VimwikiGet('subdir') + " FIXED: was previously converting './' to '../' + let invsubdir = VimwikiGet('invsubdir') + catch + let subdir = '' + let invsubdir = '' + endtry " if current wiki is temporary -- was added by an arbitrary wiki file then do " not search wiki files in subdirectories. Or it would hang the system if @@ -175,68 +537,92 @@ function! s:get_links(pat) "{{{ else let search_dirs = '**/' endif - let globlinks = glob(VimwikiGet('path').subdir.search_dirs.a:pat) + " let globlinks = "\n".glob(VimwikiGet('path').search_dirs.a:pat,1)."\n" - " remove extensions (and backup extensions too: .wiki~) - let globlinks = substitute(globlinks, '\'.VimwikiGet('ext').'\~\?', "", "g") - let links = split(globlinks, '\n') + "save pwd, do lcd %:h, restore old pwd; getcwd() + " change to the directory of the current file + let orig_pwd = getcwd() - " remove paths - let rem_path = escape(expand(VimwikiGet('path')).subdir, '\') - call map(links, 'substitute(v:val, rem_path, "", "g")') + " calling from other than vimwiki file + let path_base = vimwiki#u#path_norm(vimwiki#u#chomp_slash(VimwikiGet('path'))) + let path_file = vimwiki#u#path_norm(vimwiki#u#chomp_slash(expand('%:p:h'))) - " Remove trailing slashes. - call map(links, 'substitute(v:val, "[/\\\\]*$", "", "g")') + if vimwiki#u#path_common_pfx(path_file, path_base) != path_base + exe 'lcd! '.path_base + else + lcd! %:p:h + endif - return links -endfunction "}}} + " all path are relative to the current file's location + let globlinks = "\n".glob(invsubdir.search_dirs.a:pat,1)."\n" + " remove extensions + let globlinks = substitute(globlinks,'\'.VimwikiGet('ext').'\ze\n', '', 'g') + " standardize path separators on Windows + let globlinks = substitute(globlinks,'\\', '/', 'g') + + " shortening those paths ../../dir1/dir2/ that can be shortened + " first for the current directory, then for parent etc. + let sp_rx = '\n\zs' . invsubdir . subdir . '\ze' + for i in range(len(invsubdir)/3) "XXX multibyte? + let globlinks = substitute(globlinks, sp_rx, '', 'g') + let sp_rx = substitute(sp_rx,'\\zs../','../\\zs','') + let sp_rx = substitute(sp_rx,'[^/]\+/\\ze','\\ze','') + endfor + " for directories: add ./ (instead of now empty) and invsubdir (if distinct) + if a:pat == '*/' + let globlinks = substitute(globlinks, "\n\n", "\n./\n",'') + if invsubdir != '' + let globlinks .= invsubdir."\n" + else + let globlinks .= "./\n" + endif + endif -" Builtin cursor doesn't work right with unicode characters. -function! s:cursor(lnum, cnum) "{{{ - exe a:lnum - exe 'normal! 0'.a:cnum.'|' + " restore the original working directory + exe 'lcd! '.orig_pwd + + let time2 = vimwiki#u#time(time1) + call VimwikiLog_extend('timing',['base:afterglob('.len(split(globlinks, '\n')).')',time2]) + return globlinks endfunction "}}} -function! s:filename(link) "{{{ - let result = vimwiki#base#safe_link(a:link) - if a:link =~ '|' - let result = vimwiki#base#safe_link(split(a:link, '|')[0]) - elseif a:link =~ '][' - let result = vimwiki#base#safe_link(split(a:link, '][')[0]) +function! vimwiki#base#edit_file(command, filename, ...) "{{{ + " XXX: Should we allow * in filenames!? + " Maxim: It is allowed, escaping here is for vim to be able to open files + " which have that symbols. + " Try to remove * from escaping and open&save : + " [[testBLAfile]]... + " then + " [[test*file]]... + " you'll have E77: Too many file names + let fname = escape(a:filename, '% *|') + let dir = fnamemodify(a:filename, ":p:h") + if vimwiki#base#mkdir(dir, 1) + execute a:command.' '.fname + else + echom ' ' + echom 'Vimwiki: Unable to edit file in non-existent directory: '.dir endif - return result -endfunction -" }}} -function! s:is_wiki_word(str) "{{{ - if a:str =~ g:vimwiki_rxWikiWord && a:str !~ '[[:space:]\\/]' - return 1 + " save previous link + " a:1 -- previous vimwiki link to save + " a:2 -- should we update previous link + if a:0 && a:2 && len(a:1) > 0 + let b:vimwiki_prev_link = a:1 endif - return 0 endfunction " }}} -function! vimwiki#base#edit_file(command, filename) "{{{ - let fname = escape(a:filename, '% ') - call vimwiki#base#mkdir(fnamemodify(a:filename, ":p:h")) - try - execute a:command.' '.fname - catch /E37/ " catch 'No write since last change' error - execute ':split '.fname - catch /E325/ " catch 'ATTENTION' error (:h E325) - endtry -endfunction -" }}} - -function! s:search_word(wikiRx, cmd) "{{{ +function! vimwiki#base#search_word(wikiRx, cmd) "{{{ let match_line = search(a:wikiRx, 's'.a:cmd) if match_line == 0 - echomsg "vimwiki: Wiki link not found." + echomsg 'vimwiki: Wiki link not found.' endif endfunction " }}} -function! s:get_word_at_cursor(wikiRX) "{{{ +" Returns part of the line that matches wikiRX at cursor +function! vimwiki#base#matchstr_at_cursor(wikiRX) "{{{ let col = col('.') - 1 let line = getline('.') let ebeg = -1 @@ -258,44 +644,27 @@ function! s:get_word_at_cursor(wikiRX) "{{{ endif endf "}}} -function! s:strip_word(word) "{{{ - let result = a:word - if strpart(a:word, 0, 2) == "[[" - " get rid of [[ and ]] - let w = strpart(a:word, 2, strlen(a:word)-4) - - if w =~ '|' - " we want "link" from [[link|link desc]] - let w = split(w, "|")[0] - elseif w =~ '][' - " we want "link" from [[link][link desc]] - let w = split(w, "][")[0] +function! vimwiki#base#replacestr_at_cursor(wikiRX, sub) "{{{ + let col = col('.') - 1 + let line = getline('.') + let ebeg = -1 + let cont = match(line, a:wikiRX, 0) + while (ebeg >= 0 || (0 <= cont) && (cont <= col)) + let contn = matchend(line, a:wikiRX, cont) + if (cont <= col) && (col < contn) + let ebeg = match(line, a:wikiRX, cont) + let elen = contn - ebeg + break + else + let cont = match(line, a:wikiRX, contn) endif - - let result = vimwiki#base#safe_link(w) - endif - return result -endfunction -" }}} - -function! vimwiki#base#is_non_wiki_link(lnk) "{{{ - let exts = '.\+\.\%('. - \ join(split(g:vimwiki_file_exts, '\s*,\s*'), '\|'). - \ '\)$' - if a:lnk =~ exts - return 1 - endif - return 0 -endfunction "}}} - -function! vimwiki#base#is_link_to_dir(link) "{{{ - " Check if link is to a directory. - " It should be ended with \ or /. - if a:link =~ '.\+[/\\]$' - return 1 + endwh + if ebeg >= 0 + " TODO: There might be problems with Unicode chars... + let newline = strpart(line, 0, ebeg).a:sub.strpart(line, ebeg+elen) + call setline(line('.'), newline) endif - return 0 -endfunction " }}} +endf "}}} function! s:print_wiki_list() "{{{ let idx = 0 @@ -322,6 +691,7 @@ function! s:update_wiki_link(fname, old, new) " {{{ if !has_updates && match(line, a:old) != -1 let has_updates = 1 endif + " XXX: any other characters to escape!? call add(dest, substitute(line, a:old, escape(a:new, "&"), "g")) endfor " add exception handling... @@ -339,16 +709,10 @@ function! s:update_wiki_links_dir(dir, old_fname, new_fname) " {{{ let old_fname_r = old_fname let new_fname_r = new_fname - if !s:is_wiki_word(new_fname) && s:is_wiki_word(old_fname) - let new_fname_r = '[['.new_fname.']]' - endif - - if !s:is_wiki_word(old_fname) - let old_fname_r = '\[\[\zs'.vimwiki#base#unsafe_link(old_fname). - \ '\ze\%(|.*\)\?\%(\]\[.*\)\?\]\]' - else - let old_fname_r = '!\@<!\<'.old_fname.'\>' - endif + let old_fname_r = vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate1, + \ '\zs'.old_fname.'\ze', '.*', ''). + \ '\|'. vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate2, + \ '\zs'.old_fname.'\ze', '.*', '') let files = split(glob(VimwikiGet('path').a:dir.'*'.VimwikiGet('ext')), '\n') for fname in files @@ -419,128 +783,6 @@ function! s:open_wiki_buffer(item) "{{{ endif endfunction " }}} -" }}} - -" SYNTAX highlight {{{ -function! vimwiki#base#highlight_links() "{{{ - try - syntax clear VimwikiNoExistsLink - syntax clear VimwikiNoExistsLinkT - syntax clear VimwikiLink - syntax clear VimwikiLinkT - catch - endtry - - "" use max highlighting - could be quite slow if there are too many wikifiles - if VimwikiGet('maxhi') - " Every WikiWord is nonexistent - if g:vimwiki_camel_case - execute 'syntax match VimwikiNoExistsLink /'.g:vimwiki_rxWikiWord.'/ display' - execute 'syntax match VimwikiNoExistsLinkT /'.g:vimwiki_rxWikiWord.'/ display contained' - endif - execute 'syntax match VimwikiNoExistsLink /'.g:vimwiki_rxWikiLink1.'/ display contains=VimwikiNoLinkChar' - execute 'syntax match VimwikiNoExistsLink /'.g:vimwiki_rxWikiLink2.'/ display contains=VimwikiNoLinkChar' - - execute 'syntax match VimwikiNoExistsLinkT /'.g:vimwiki_rxWikiLink1.'/ display contained' - execute 'syntax match VimwikiNoExistsLinkT /'.g:vimwiki_rxWikiLink2.'/ display contained' - - " till we find them in vimwiki's path - call s:highlight_existed_links() - else - " A WikiWord (unqualifiedWikiName) - execute 'syntax match VimwikiLink /\<'.g:vimwiki_rxWikiWord.'\>/' - " A [[bracketed wiki word]] - execute 'syntax match VimwikiLink /'.g:vimwiki_rxWikiLink1.'/ display contains=VimwikiLinkChar' - execute 'syntax match VimwikiLink /'.g:vimwiki_rxWikiLink2.'/ display contains=VimwikiLinkChar' - - execute 'syntax match VimwikiLinkT /\<'.g:vimwiki_rxWikiWord.'\>/ display contained' - execute 'syntax match VimwikiLinkT /'.g:vimwiki_rxWikiLink1.'/ display contained' - execute 'syntax match VimwikiLinkT /'.g:vimwiki_rxWikiLink2.'/ display contained' - endif - - execute 'syntax match VimwikiLink `'.g:vimwiki_rxWeblink.'` display contains=@NoSpell' -endfunction "}}} - -function! s:highlight_existed_links() "{{{ - 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(links, 'substitute(v:val, os_p, os_p2, "g")') - - for link in links - if g:vimwiki_camel_case && - \ link =~ g:vimwiki_rxWikiWord && !vimwiki#base#is_non_wiki_link(link) - execute 'syntax match VimwikiLink /!\@<!\<'.link.'\>/ display' - endif - execute 'syntax match VimwikiLink /\[\['. - \ escape(vimwiki#base#unsafe_link(link), '~&$.*'). - \ '\%(|\+.\{-}\)\{-}\]\]/ display contains=VimwikiLinkChar' - execute 'syntax match VimwikiLink /\[\['. - \ escape(vimwiki#base#unsafe_link(link), '~&$.*'). - \ '\]\[.\{-1,}\]\]/ display contains=VimwikiLinkChar' - - execute 'syntax match VimwikiLinkT /\[\['. - \ escape(vimwiki#base#unsafe_link(link), '~&$.*'). - \ '\%(|\+.\{-}\)\{-}\]\]/ display contained' - execute 'syntax match VimwikiLinkT /\[\['. - \ escape(vimwiki#base#unsafe_link(link), '~&$.*'). - \ '\]\[.\{-1,}\]\]/ display contained' - endfor - execute 'syntax match VimwikiLink /\[\[.\+\.\%(jpg\|png\|gif\)\%(|\+.*\)*\]\]/ display contains=VimwikiLinkChar' - execute 'syntax match VimwikiLink /\[\[.\+\.\%(jpg\|png\|gif\)\]\[.\+\]\]/ display contains=VimwikiLinkChar' - - execute 'syntax match VimwikiLinkT /\[\[.\+\.\%(jpg\|png\|gif\)\%(|\+.*\)*\]\]/ display contained' - execute 'syntax match VimwikiLinkT /\[\[.\+\.\%(jpg\|png\|gif\)\]\[.\+\]\]/ display contained' - - " Issue 103: Always highlight links to non-wiki files as existed. - execute 'syntax match VimwikiLink /\[\[.\+\.\%('. - \join(split(g:vimwiki_file_exts, '\s*,\s*'), '\|'). - \'\)\%(|\+.*\)*\]\]/ display contains=VimwikiLinkChar' - execute 'syntax match VimwikiLink /\[\[.\+\.\%('. - \join(split(g:vimwiki_file_exts, '\s*,\s*'), '\|'). - \'\)\]\[.\+\]\]/ display contains=VimwikiLinkChar' - - execute 'syntax match VimwikiLinkT /\[\[.\+\.\%('. - \join(split(g:vimwiki_file_exts, '\s*,\s*'), '\|'). - \'\)\%(|\+.*\)*\]\]/ display contained' - execute 'syntax match VimwikiLinkT /\[\[.\+\.\%('. - \join(split(g:vimwiki_file_exts, '\s*,\s*'), '\|'). - \'\)\]\[.\+\]\]/ display contained' - - " 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 /\[\['. - \ escape(vimwiki#base#unsafe_link(dir), '~&$.*'). - \ '[/\\]*\%(|\+.*\)*\]\]/ display contains=VimwikiLinkChar' - execute 'syntax match VimwikiLink /\[\['. - \ escape(vimwiki#base#unsafe_link(dir), '~&$.*'). - \ '[/\\]*\%(\]\[\+.*\)*\]\]/ display contains=VimwikiLinkChar' - - execute 'syntax match VimwikiLinkT /\[\['. - \ escape(vimwiki#base#unsafe_link(dir), '~&$.*'). - \ '[/\\]*\%(|\+.*\)*\]\]/ display contained' - execute 'syntax match VimwikiLinkT /\[\['. - \ escape(vimwiki#base#unsafe_link(dir), '~&$.*'). - \ '[/\\]*\%(\]\[\+.*\)*\]\]/ display contained' - endfor -endfunction "}}} - -function! vimwiki#base#hl_exists(hl) "{{{ - if !hlexists(a:hl) - return 0 - endif - redir => hlstatus - exe "silent hi" a:hl - redir END - return (hlstatus !~ "cleared") -endfunction -"}}} - function! vimwiki#base#nested_syntax(filetype, start, end, textSnipHl) abort "{{{ " From http://vim.wikia.com/wiki/VimTip857 let ft=toupper(a:filetype) @@ -588,64 +830,116 @@ function! vimwiki#base#nested_syntax(filetype, start, end, textSnipHl) abort "{{ endif endfunction "}}} -"}}} +" }}} -" WIKI functions {{{ +" WIKI link following functions {{{ function! vimwiki#base#find_next_link() "{{{ - call s:search_word(g:vimwiki_rxWikiLink.'\|'.g:vimwiki_rxWeblink, '') + call vimwiki#base#search_word(g:vimwiki_rxAnyLink, '') endfunction " }}} function! vimwiki#base#find_prev_link() "{{{ - call s:search_word(g:vimwiki_rxWikiLink.'\|'.g:vimwiki_rxWeblink, 'b') + call vimwiki#base#search_word(g:vimwiki_rxAnyLink, 'b') endfunction " }}} -function! vimwiki#base#follow_link(split) "{{{ - if a:split == "split" - let cmd = ":split " - elseif a:split == "vsplit" - let cmd = ":vsplit " - elseif a:split == "tabnew" - let cmd = ":tabnew " +" follow_link +function! vimwiki#base#follow_link(split, ...) "{{{ Parse link at cursor and pass + " to VimwikiLinkHandler, or failing that, the default open_link handler + if exists('*vimwiki#base_'.VimwikiGet('syntax').'#follow_link') + " Syntax-specific links + " XXX: @Stuart: do we still need it? + " XXX: @Maxim: most likely! I am still working on a seemless way to + " integrate regexp's without complicating syntax/vimwiki.vim + if a:0 + call vimwiki#base_{VimwikiGet('syntax')}#follow_link(a:split, a:1) + else + call vimwiki#base_{VimwikiGet('syntax')}#follow_link(a:split) + endif else - let cmd = ":e " - endif + if a:split == "split" + let cmd = ":split " + elseif a:split == "vsplit" + let cmd = ":vsplit " + elseif a:split == "tabnew" + let cmd = ":tabnew " + else + let cmd = ":e " + endif + + " try WikiLink + let lnk = matchstr(vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWikiLink), + \ g:vimwiki_rxWikiLinkMatchUrl) + " try WikiIncl + if lnk == "" + let lnk = matchstr(vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWikiIncl), + \ g:vimwiki_rxWikiInclMatchUrl) + endif + " try Weblink + if lnk == "" + let lnk = matchstr(vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWeblink), + \ g:vimwiki_rxWeblinkMatchUrl) + endif - 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 != "" - call VimwikiWeblinkHandler(escape(weblink, '#')) + if lnk != "" + if !VimwikiLinkHandler(lnk) + call vimwiki#base#open_link(cmd, lnk) + endif + return + endif + + if a:0 > 0 + execute "normal! ".a:1 else - execute "normal! \n" + call vimwiki#base#normalize_link(0) endif - return endif - let subdir = vimwiki#base#current_subdir() - call vimwiki#base#open_link(cmd, subdir.link) - endfunction " }}} function! vimwiki#base#go_back_link() "{{{ if exists("b:vimwiki_prev_link") - " go back to saved WikiWord + " go back to saved wiki link let prev_word = b:vimwiki_prev_link execute ":e ".substitute(prev_word[0], '\s', '\\\0', 'g') call setpos('.', prev_word[1]) endif endfunction " }}} -function! vimwiki#base#goto_index(index) "{{{ - call vimwiki#base#select(a:index) - call vimwiki#base#edit_file('e', - \ VimwikiGet('path').VimwikiGet('index').VimwikiGet('ext')) +function! vimwiki#base#goto_index(wnum, ...) "{{{ + if a:wnum > len(g:vimwiki_list) + echom "vimwiki: Wiki ".a:wnum." is not registered in g:vimwiki_list!" + return + endif + + " usually a:wnum is greater then 0 but with the following command it is == 0: + " vim -n -c "exe 'VimwikiIndex' | echo g:vimwiki_current_idx" + if a:wnum > 0 + let idx = a:wnum - 1 + else + let idx = 0 + endif + + if a:0 + let cmd = 'tabedit' + else + let cmd = 'edit' + endif + + if g:vimwiki_debug == 3 + echom "--- Goto_index g:curr_idx=".g:vimwiki_current_idx." ww_idx=".idx."" + endif + + call vimwiki#base#validate_wiki_options(idx) + call vimwiki#base#edit_file(cmd, + \ VimwikiGet('path', idx).VimwikiGet('index', idx). + \ VimwikiGet('ext', idx)) + call vimwiki#base#setup_buffer_state(idx) endfunction "}}} function! vimwiki#base#delete_link() "{{{ "" file system funcs - "" Delete WikiWord you are in from filesystem + "" Delete wiki link you are in from filesystem let val = input('Delete ['.expand('%').'] (y/n)? ', "") if val != 'y' return @@ -657,17 +951,19 @@ function! vimwiki#base#delete_link() "{{{ echomsg 'vimwiki: Cannot delete "'.expand('%:t:r').'"!' return endtry + + call vimwiki#base#go_back_link() execute "bdelete! ".escape(fname, " ") - " reread buffer => deleted WikiWord should appear as non-existent + " reread buffer => deleted wiki link should appear as non-existent if expand('%:p') != "" execute "e" endif endfunction "}}} function! vimwiki#base#rename_link() "{{{ - "" Rename WikiWord, update all links to renamed WikiWord - let subdir = vimwiki#base#current_subdir() + "" Rename wiki link, update all links to renamed WikiWord + let subdir = VimwikiGet('subdir') let old_fname = subdir.expand('%:t') " there is no file (new one maybe) @@ -695,23 +991,23 @@ function! vimwiki#base#rename_link() "{{{ echomsg 'vimwiki: Cannot rename to an empty filename!' return endif - if vimwiki#base#is_non_wiki_link(new_link) - echomsg 'vimwiki: Cannot rename to a filename with extension (ie .txt .html)!' - return + + let url = matchstr(new_link, g:vimwiki_rxWikiLinkMatchUrl) + if url != '' + let new_link = url endif let new_link = subdir.new_link - let new_link = s:strip_word(new_link) - let new_fname = VimwikiGet('path').s:filename(new_link).VimwikiGet('ext') + let new_fname = VimwikiGet('path').new_link.VimwikiGet('ext') - " do not rename if word with such name exists + " do not rename if file with such name exists let fname = glob(new_fname) if fname != '' echomsg 'vimwiki: Cannot rename to "'.new_fname. \ '". File with that name exist!' return endif - " rename WikiWord file + " rename wiki link file try echomsg "Renaming ".VimwikiGet('path').old_fname." to ".new_fname let res = rename(expand('%:p'), expand(new_fname)) @@ -765,7 +1061,7 @@ function! vimwiki#base#rename_link() "{{{ let &more = setting_more endfunction " }}} -function! vimwiki#base#ui_select()"{{{ +function! vimwiki#base#ui_select() "{{{ call s:print_wiki_list() let idx = input("Select Wiki (specify number): ") if idx == "" @@ -774,7 +1070,6 @@ function! vimwiki#base#ui_select()"{{{ call vimwiki#base#goto_index(idx) endfunction "}}} - " }}} " TEXT OBJECTS functions {{{ @@ -789,7 +1084,7 @@ function! vimwiki#base#TO_header(inner, visual) "{{{ let block_start = line(".") let advance = 0 - let level = vimwiki#base#count_first_sym(getline('.')) + let level = vimwiki#u#count_first_sym(getline('.')) let is_header_selected = sel_start == block_start \ && sel_start != sel_end @@ -887,7 +1182,7 @@ function! vimwiki#base#TO_table_cell(inner, visual) "{{{ endfunction "}}} function! vimwiki#base#TO_table_col(inner, visual) "{{{ - let t_rows = vimwiki_tbl#get_rows(line('.')) + let t_rows = vimwiki#tbl#get_rows(line('.')) if empty(t_rows) return endif @@ -903,7 +1198,7 @@ function! vimwiki#base#TO_table_col(inner, visual) "{{{ if firsttime " place cursor to the top row of the table - call s:cursor(t_rows[0][0], virtcol('.')) + call vimwiki#u#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): " |-----^-+-------| @@ -948,7 +1243,7 @@ function! vimwiki#base#TO_table_col(inner, visual) "{{{ normal! h endif " expand selection to the bottom line of the table - call s:cursor(t_rows[-1][0], virtcol('.')) + call vimwiki#u#cursor(t_rows[-1][0], virtcol('.')) let sel_end = getpos('.') call setpos('.', sel_start) @@ -957,7 +1252,7 @@ function! vimwiki#base#TO_table_col(inner, visual) "{{{ else " place cursor to the top row of the table - call s:cursor(t_rows[0][0], virtcol('.')) + call vimwiki#u#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): " |-----^-+-------| @@ -996,33 +1291,36 @@ function! vimwiki#base#TO_table_col(inner, visual) "{{{ normal! h endif " expand selection to the bottom line of the table - call s:cursor(t_rows[-1][0], virtcol('.')) + call vimwiki#u#cursor(t_rows[-1][0], virtcol('.')) endif endfunction "}}} +" }}} -function! vimwiki#base#count_first_sym(line) "{{{ - let first_sym = matchstr(a:line, '\S') - return len(matchstr(a:line, first_sym.'\+')) -endfunction "}}} - +" HEADER functions {{{ function! vimwiki#base#AddHeaderLevel() "{{{ let lnum = line('.') let line = getline(lnum) - + let rxHdr = g:vimwiki_rxH if line =~ '^\s*$' return endif - if line =~ '^\s*\(=\+\).\+\1\s*$' - let level = vimwiki#base#count_first_sym(line) + if line =~ g:vimwiki_rxHeader + let level = vimwiki#u#count_first_sym(line) if level < 6 - let line = substitute(line, '\(=\+\).\+\1', '=&=', '') + if g:vimwiki_symH + let line = substitute(line, '\('.rxHdr.'\+\).\+\1', rxHdr.'&'.rxHdr, '') + else + let line = substitute(line, '\('.rxHdr.'\+\).\+', rxHdr.'&', '') + endif call setline(lnum, line) endif else - let line = substitute(line, '^\s*', '&= ', '') - let line = substitute(line, '\s*$', ' =&', '') - call setline(lnum, line) + let line = substitute(line, '^\s*', '&'.rxHdr.' ', '') + if g:vimwiki_symH + let line = substitute(line, '\s*$', ' '.rxHdr.'&', '') + endif + call setline(lnum, line) endif endfunction "}}} @@ -1030,27 +1328,175 @@ endfunction function! vimwiki#base#RemoveHeaderLevel() "{{{ let lnum = line('.') let line = getline(lnum) - + let rxHdr = g:vimwiki_rxH if line =~ '^\s*$' return endif - if line =~ '^\s*\(=\+\).\+\1\s*$' - let level = vimwiki#base#count_first_sym(line) - let old = repeat('=', level) - let new = repeat('=', level - 1) + if line =~ g:vimwiki_rxHeader + let level = vimwiki#u#count_first_sym(line) + let old = repeat(rxHdr, level) + let new = repeat(rxHdr, level - 1) - let chomp = line =~ '=\s' + let chomp = line =~ rxHdr.'\s' - let line = substitute(line, old, new, 'g') + if g:vimwiki_symH + let line = substitute(line, old, new, 'g') + else + let line = substitute(line, old, new, '') + endif if level == 1 && chomp let line = substitute(line, '^\s', '', 'g') let line = substitute(line, '\s$', '', 'g') endif + + let line = substitute(line, '\s*$', '', '') + call setline(lnum, line) endif endfunction " }}} +"}}} + +" LINK functions {{{ +" Construct a regular expression matching from template (with special +" characters properly escaped), by substituting rxUrl for __LinkUrl__, rxDesc +" for __LinkDescription__, and rxStyle for __LinkStyle__. The three +" arguments rxUrl, rxDesc, and rxStyle are copied verbatim, without any +" special character escapes or substitutions. +function! vimwiki#base#apply_template(template, rxUrl, rxDesc, rxStyle) "{{{ + let magic_chars = '.*[\^$' + let lnk = escape(a:template, magic_chars) + if a:rxUrl != "" + let lnk = substitute(lnk, '__LinkUrl__', '\='."'".a:rxUrl."'", '') + endif + if a:rxDesc != "" + let lnk = substitute(lnk, '__LinkDescription__', '\='."'".a:rxDesc."'", '') + endif + if a:rxStyle != "" + let lnk = substitute(lnk, '__LinkStyle__', '\='."'".a:rxStyle."'", '') + endif + return lnk +endfunction +" }}} + +function! s:clean_url(url) " {{{ + let url = split(a:url, '/\|=\|-\|&\|?\|\.') + let url = filter(url, 'v:val != ""') + let url = filter(url, 'v:val != "www"') + let url = filter(url, 'v:val != "com"') + let url = filter(url, 'v:val != "org"') + let url = filter(url, 'v:val != "net"') + let url = filter(url, 'v:val != "edu"') + let url = filter(url, 'v:val != "http\:"') + let url = filter(url, 'v:val != "https\:"') + let url = filter(url, 'v:val != "file\:"') + let url = filter(url, 'v:val != "xml\:"') + return join(url, " ") +endfunction " }}} + +function! vimwiki#base#normalize_link_helper(str, rxUrl, rxDesc, template) " {{{ + let str = a:str + let url = matchstr(str, a:rxUrl) + let descr = matchstr(str, a:rxDesc) + let template = a:template + if descr == "" + let descr = s:clean_url(url) + endif + let lnk = substitute(template, '__LinkDescription__', '\="'.descr.'"', '') + let lnk = substitute(lnk, '__LinkUrl__', '\="'.url.'"', '') + return lnk +endfunction " }}} + +function! vimwiki#base#normalize_imagelink_helper(str, rxUrl, rxDesc, rxStyle, template) "{{{ + let lnk = vimwiki#base#normalize_link_helper(a:str, a:rxUrl, a:rxDesc, a:template) + let style = matchstr(str, a:rxStyle) + let lnk = substitute(lnk, '__LinkStyle__', '\="'.style.'"', '') + return lnk +endfunction " }}} + +function! s:normalize_link_syntax_n() " {{{ + let lnum = line('.') + + " try WikiLink + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWikiLink) + if !empty(lnk) + let sub = vimwiki#base#normalize_link_helper(lnk, + \ g:vimwiki_rxWikiLinkMatchUrl, g:vimwiki_rxWikiLinkMatchDescr, + \ g:vimwiki_WikiLinkTemplate2) + call vimwiki#base#replacestr_at_cursor(g:vimwiki_rxWikiLink, sub) + if g:vimwiki_debug > 1 + echomsg "WikiLink: ".lnk." Sub: ".sub + endif + return + endif + + " try WikiIncl + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWikiIncl) + if !empty(lnk) + " NO-OP !! + if g:vimwiki_debug > 1 + echomsg "WikiIncl: ".lnk." Sub: ".lnk + endif + return + endif + + " try Word (any characters except separators) + " rxWord is less permissive than rxWikiLinkUrl which is used in + " normalize_link_syntax_v + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWord) + if !empty(lnk) + let sub = vimwiki#base#normalize_link_helper(lnk, + \ g:vimwiki_rxWord, '', + \ g:vimwiki_WikiLinkTemplate1) + call vimwiki#base#replacestr_at_cursor('\V'.lnk, sub) + if g:vimwiki_debug > 1 + echomsg "Word: ".lnk." Sub: ".sub + endif + return + endif + +endfunction " }}} + +function! s:normalize_link_syntax_v() " {{{ + let lnum = line('.') + let sel_save = &selection + let &selection = "old" + let rv = @" + let rt = getregtype('"') + let done = 0 + + try + norm! gvy + let visual_selection = @" + let visual_selection = substitute(g:vimwiki_WikiLinkTemplate1, '__LinkUrl__', '\='."'".visual_selection."'", '') + + call setreg('"', visual_selection, 'v') + + " paste result + norm! `>pgvd + + finally + call setreg('"', rv, rt) + let &selection = sel_save + endtry + +endfunction " }}} + +" normalize_link +function! vimwiki#base#normalize_link(is_visual_mode) "{{{ + if exists('*vimwiki#'.VimwikiGet('syntax').'_base#normalize_link') + " Syntax-specific links + call vimwiki#{VimwikiGet('syntax')}_base#normalize_link(a:is_visual_mode) + else + if !a:is_visual_mode + call s:normalize_link_syntax_n() + elseif visualmode() ==# 'v' && line("'<") == line("'>") + " action undefined for 'line-wise' or 'multi-line' visual mode selections + call s:normalize_link_syntax_v() + endif + endif +endfunction "}}} " }}} diff --git a/autoload/vimwiki/diary.vim b/autoload/vimwiki/diary.vim @@ -11,6 +11,9 @@ endif let g:loaded_vimwiki_diary_auto = 1 "}}} +let s:vimwiki_max_scan_for_caption = 5 + +" Helpers {{{ function! s:prefix_zero(num) "{{{ if a:num < 10 return '0'.a:num @@ -18,10 +21,6 @@ function! s:prefix_zero(num) "{{{ 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 "}}} @@ -37,76 +36,26 @@ function! s:link_exists(lines, link) "{{{ 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 - return [ln_start, ln_end] +function! s:diary_path(...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + return VimwikiGet('path', idx).VimwikiGet('diary_rel_path', idx) endfunction "}}} -function! s:diary_date_link() "{{{ - return s:get_date_link(VimwikiGet('diary_link_fmt')) +function! s:diary_index(...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + return s:diary_path(idx).VimwikiGet('diary_index', idx).VimwikiGet('ext', idx) 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'). - \ '*'.VimwikiGet('ext')) - - let s_links = substitute(s_links, '\'.VimwikiGet('ext'), "", "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, '\').'"') - return links +function! s:diary_date_link(...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + return s:get_date_link(VimwikiGet('diary_link_fmt', idx)) endfunction "}}} function! s:get_position_links(link) "{{{ let idx = -1 let links = [] - if a:link =~ '\d\{4}-\d\d-\d\d' - let links = s:get_links() + if a:link =~ '^\d\{4}-\d\d-\d\d' + let links = keys(s:get_diary_links()) " include 'today' into links if index(links, s:diary_date_link()) == -1 call add(links, s:diary_date_link()) @@ -117,132 +66,208 @@ function! s:get_position_links(link) "{{{ return [idx, 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 = '| ' +fun! s:get_month_name(month) "{{{ + return g:vimwiki_diary_months[str2nr(a:month)] +endfun "}}} + +" Helpers }}} + +" Diary index stuff {{{ +fun! s:read_captions(files) "{{{ + let result = {} + for fl in a:files + " remove paths and extensions + let fl_key = fnamemodify(fl, ':t:r') + + if filereadable(fl) + for line in readfile(fl, '', s:vimwiki_max_scan_for_caption) + if line =~ g:vimwiki_rxHeader && !has_key(result, fl_key) + let result[fl_key] = vimwiki#u#trim(matchstr(line, g:vimwiki_rxHeader)) + endif + endfor endif - let line .= a:links[idx].' | ' - let idx += 1 - endwhile - call add(lines, substitute(line, '\s\+$', '', '')) - call extend(lines, ['']) - return lines -endfunction "}}} + if !has_key(result, fl_key) + let result[fl_key] = '' + endif -function! s:add_link(page, header, link) "{{{ - let [lines, bufnr] = s:get_file_contents(a:page) + endfor + return result +endfun "}}} - let [ln_start, ln_end] = s:get_diary_range(lines, a:header) +fun! s:get_diary_links(...) "{{{ + let rx = '^\d\{4}-\d\d-\d\d' + let s_files = glob(VimwikiGet('path').VimwikiGet('diary_rel_path').'*'.VimwikiGet('ext')) + let files = split(s_files, '\n') + call filter(files, 'fnamemodify(v:val, ":t") =~ "'.escape(rx, '\').'"') - let link = '[['.a:link.']]' + " remove backup files (.wiki~) + call filter(files, 'v:val !~ ''.*\~$''') - let link_exists = s:link_exists(lines[ln_start : ln_end], link) + if a:0 + call add(files, a:1) + endif + let links_with_captions = s:read_captions(files) + + return links_with_captions +endfun "}}} + +fun! s:group_links(links) "{{{ + let result = {} + let p_year = 0 + let p_month = 0 + for fl in sort(keys(a:links)) + let year = strpart(fl, 0, 4) + let month = strpart(fl, 5, 2) + if p_year != year + let result[year] = {} + let p_month = 0 + endif + if p_month != month + let result[year][month] = {} + endif + let result[year][month][fl] = a:links[fl] + let p_year = year + let p_month = month + endfor + return result +endfun "}}} - if !link_exists +fun! s:sort(lst) "{{{ + if VimwikiGet("diary_sort") == 'desc' + return reverse(sort(a:lst)) + else + return sort(a:lst) + endif +endfun "}}} - if ln_start == -1 - call insert(lines, '= '.a:header.' =') - let ln_start = 1 - let ln_end = 1 - endif +fun! s:format_diary(...) "{{{ + let result = [] - " removing 'old' links - let idx = ln_end - ln_start - while idx > 0 - call remove(lines, ln_start) - let idx -= 1 - endwhile + call add(result, substitute(g:vimwiki_rxH1_Template, '__Header__', VimwikiGet('diary_header'), '')) - " get all diary links from filesystem - let links = s:get_links() - call map(links, '"[[".v:val."]]"') + if a:0 + let g_files = s:group_links(s:get_diary_links(a:1)) + else + let g_files = s:group_links(s:get_diary_links()) + endif - " add current link - if index(links, link) == -1 - call add(links, link) - endif + " for year in s:rev(sort(keys(g_files))) + for year in s:sort(keys(g_files)) + call add(result, '') + call add(result, substitute(g:vimwiki_rxH2_Template, '__Header__', year , '')) + + " for month in s:rev(sort(keys(g_files[year]))) + for month in s:sort(keys(g_files[year])) + call add(result, '') + call add(result, substitute(g:vimwiki_rxH3_Template, '__Header__', s:get_month_name(month), '')) + + " for [fl, cap] in s:rev(sort(items(g_files[year][month]))) + for [fl, cap] in s:sort(items(g_files[year][month])) + if empty(cap) + let entry = substitute(g:vimwiki_WikiLinkTemplate1, '__LinkUrl__', fl, '') + let entry = substitute(entry, '__LinkDescription__', cap, '') + call add(result, repeat(' ', &sw).'* '.entry) + else + let entry = substitute(g:vimwiki_WikiLinkTemplate2, '__LinkUrl__', fl, '') + let entry = substitute(entry, '__LinkDescription__', cap, '') + call add(result, repeat(' ', &sw).'* '.entry) + endif + endfor + + endfor + endfor + call add(result, '') - let links = sort(links, 's:desc') - call extend(lines, s:format_links(links), ln_start) + return result +endfun "}}} - if bufnr != -1 - exe 'buffer '.bufnr - if !&readonly - 1,$delete _ - call append(1, lines) - 1,1delete _ - endif +function! s:delete_diary_section() "{{{ + " remove diary section + let old_pos = getpos('.') + let ln_start = -1 + let ln_end = -1 + call cursor(1, 1) + if search(substitute(g:vimwiki_rxH1_Template, '__Header__', VimwikiGet('diary_header'), ''), 'Wc') + let ln_start = line('.') + if search(g:vimwiki_rxH1, 'W') + let ln_end = line('.') - 1 else - call writefile(lines, expand(a:page)) + let ln_end = line('$') + endif + endif + + if ln_start < 0 || ln_end < 0 + call setpos('.', old_pos) + return + endif + + if !&readonly + exe ln_start.",".ln_end."delete _" + endif + + call setpos('.', old_pos) +endfunction "}}} + +function! s:insert_diary_section() "{{{ + if !&readonly + let ln = line('.') + call append(ln, s:format_diary()) + if ln == 1 && getline(ln) == '' + 1,1delete endif endif endfunction "}}} -function! s:make_date_link(...) "{{{ - if a:0 - let link = a:1 +" Diary index stuff }}} + +function! vimwiki#diary#make_note(wnum, ...) "{{{ + if a:wnum > len(g:vimwiki_list) + echom "vimwiki: Wiki ".a:wnum." is not registered in g:vimwiki_list!" + return + endif + + " TODO: refactor it. base#goto_index uses the same + if a:wnum > 0 + let idx = a:wnum - 1 else - let link = s:diary_date_link() + let idx = 0 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#base#select(a:index) - call vimwiki#base#mkdir(VimwikiGet('path').VimwikiGet('diary_rel_path')) + call vimwiki#base#validate_wiki_options(idx) + call vimwiki#base#mkdir(VimwikiGet('path', idx).VimwikiGet('diary_rel_path', idx)) + if a:0 - let link = s:make_date_link(a:1) + let cmd = 'tabedit' else - let link = s:make_date_link() + let cmd = 'edit' + endif + if len(a:0)>1 + let link = 'diary:'.a:2 + else + let link = 'diary:'.s:diary_date_link(idx) endif - call vimwiki#base#open_link(':e ', link, s:diary_index()) -endfunction "}}} -function! vimwiki#diary#goto_index(index) "{{{ - call vimwiki#base#select(a:index) - call vimwiki#base#edit_file(':e', s:diary_index()) + call vimwiki#base#open_link(cmd, link, s:diary_index(idx)) + call vimwiki#base#setup_buffer_state(idx) endfunction "}}} -" Calendar.vim callback function. -function! vimwiki#diary#calendar_action(day, month, year, week, dir) "{{{ - let day = s:prefix_zero(a:day) - let month = s:prefix_zero(a:month) +function! vimwiki#diary#goto_diary_index(wnum) "{{{ + if a:wnum > len(g:vimwiki_list) + echom "vimwiki: Wiki ".a:wnum." is not registered in g:vimwiki_list!" + return + endif - let link = a:year.'-'.month.'-'.day - if winnr('#') == 0 - if a:dir == 'V' - vsplit - else - split - endif + " TODO: refactor it. base#goto_index uses the same + if a:wnum > 0 + let idx = a:wnum - 1 else - wincmd p - if !&hidden && &modified - new - endif + let idx = 0 endif - " Create diary note for a selected date in default wiki. - call vimwiki#diary#make_note(1, link) -endfunction "}}} - -" Calendar.vim sign function. -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)) + call vimwiki#base#validate_wiki_options(idx) + call vimwiki#base#edit_file('e', s:diary_index(idx)) + call vimwiki#base#setup_buffer_state(idx) endfunction "}}} function! vimwiki#diary#goto_next_day() "{{{ @@ -254,10 +279,10 @@ function! vimwiki#diary#goto_next_day() "{{{ endif if idx != -1 && idx < len(links) - 1 - let link = VimwikiGet('diary_rel_path').links[idx+1] + let link = 'diary:'.links[idx+1] else " goto today - let link = VimwikiGet('diary_rel_path').s:diary_date_link() + let link = 'diary:'.s:diary_date_link() endif if len(link) @@ -274,13 +299,60 @@ function! vimwiki#diary#goto_prev_day() "{{{ endif if idx > 0 - let link = VimwikiGet('diary_rel_path').links[idx-1] + let link = 'diary:'.links[idx-1] else " goto today - let link = VimwikiGet('diary_rel_path').s:diary_date_link() + let link = 'diary:'.s:diary_date_link() endif if len(link) call vimwiki#base#open_link(':e ', link) endif endfunction "}}} + +function! vimwiki#diary#generate_diary_section() "{{{ + let current_file = vimwiki#u#path_norm(expand("%:p")) + let diary_file = vimwiki#u#path_norm(s:diary_index()) + if current_file == diary_file + call s:delete_diary_section() + call s:insert_diary_section() + else + echom "vimwiki: You can generate diary links only in a diary index page!" + endif +endfunction "}}} + +" Calendar.vim {{{ +" Callback function. +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, 0, link) +endfunction "}}} + +" Sign function. +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 "}}} + +" Calendar.vim }}} + diff --git a/autoload/vimwiki/html.vim b/autoload/vimwiki/html.vim @@ -14,6 +14,15 @@ let g:loaded_vimwiki_html_auto = 1 "}}} " UTILITY "{{{ +function s:get_completion_index(sym) "{{{ + for idx in range(1, 5) + if match(g:vimwiki_listsyms, '\C\%'.idx.'v'.a:sym) != -1 + return (idx-1) + endif + endfor + return 0 +endfunction "}}} + function! s:root_path(subdir) "{{{ return repeat('../', len(split(a:subdir, '[/\\]'))) endfunction "}}} @@ -36,7 +45,7 @@ function! s:is_web_link(lnk) "{{{ endfunction "}}} function! s:is_img_link(lnk) "{{{ - if a:lnk =~ '\.\%(png\|jpg\|gif\|jpeg\)$' + if tolower(a:lnk) =~ '\.\%(png\|jpg\|gif\|jpeg\)$' return 1 endif return 0 @@ -59,9 +68,14 @@ function! s:find_autoload_file(name) " {{{ return '' endfunction " }}} -function! s:create_default_CSS(path) " {{{ +function! s:default_CSS_full_name(path) " {{{ let path = expand(a:path) let css_full_name = path.VimwikiGet('css_name') + return css_full_name +endfunction "}}} + +function! s:create_default_CSS(path) " {{{ + let css_full_name = s:default_CSS_full_name(a:path) if glob(css_full_name) == "" call vimwiki#base#mkdir(fnamemodify(css_full_name, ':p:h')) let default_css = s:find_autoload_file('style.css') @@ -81,8 +95,7 @@ function! s:template_full_name(name) "{{{ endif let fname = expand(VimwikiGet('template_path'). - \name. - \VimwikiGet('template_ext')) + \ name.VimwikiGet('template_ext')) if filereadable(fname) return fname @@ -95,8 +108,8 @@ function! s:get_html_template(wikifile, template) "{{{ " TODO: refactor it!!! let lines=[] - let template_name = s:template_full_name(a:template) - if template_name != '' + if a:template != '' + let template_name = s:template_full_name(a:template) try let lines = readfile(template_name) return lines @@ -106,27 +119,40 @@ function! s:get_html_template(wikifile, template) "{{{ endtry endif - " if no VimwikiGet('html_template') set up or error while reading template - " file -- use default one. - let default_tpl = s:find_autoload_file('default.tpl') - if default_tpl != '' - let lines = readfile(default_tpl) + let default_tpl = s:template_full_name('') + + if default_tpl == '' + let default_tpl = s:find_autoload_file('default.tpl') endif + + let lines = readfile(default_tpl) return lines endfunction "}}} +function! s:safe_html_tags(line) "{{{ + let line = substitute(a:line,'<','\&lt;', 'g') + let line = substitute(line,'>','\&gt;', 'g') + return line +endfunction "}}} + function! s:safe_html(line) "{{{ + " escape & < > when producing HTML text + " uses variables s:lt_pattern, s:gt_pattern that are + " set in vimwiki#html#Wiki2HTML() according to g:vimwiki_valid_html_tags "" htmlize symbols: < > & let line = substitute(a:line, '&', '\&amp;', 'g') - - let tags = join(split(g:vimwiki_valid_html_tags, '\s*,\s*'), '\|') - let line = substitute(line,'<\%(/\?\%(' - \.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?>\)\@!', - \'\&lt;', 'g') - let line = substitute(line,'\%(</\?\%(' - \.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?\)\@<!>', - \'\&gt;', 'g') + " the following depends on g:vimwiki_valid_html_tags + let line = substitute(line,s:lt_pattern,'\&lt;', 'g') + let line = substitute(line,s:gt_pattern,'\&gt;', 'g') + + "let tags = join(split(g:vimwiki_valid_html_tags, '\s*,\s*'), '\|') + "let line = substitute(line,'<\%(/\?\%(' + " \.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?>\)\@!', + " \'\&lt;', 'g') + "let line = substitute(line,'\%(</\?\%(' + " \.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?\)\@<!>', + " \'\&gt;', 'g') return line endfunction "}}} @@ -140,8 +166,8 @@ function! s:delete_html_files(path) "{{{ " delete if there is no corresponding wiki file let subdir = vimwiki#base#subdir(VimwikiGet('path_html'), fname) - let wikifile = VimwikiGet("path").subdir. - \fnamemodify(fname, ":t:r").VimwikiGet("ext") + let wikifile = VimwikiGet('path').subdir. + \fnamemodify(fname, ":t:r").VimwikiGet('ext') if filereadable(wikifile) continue endif @@ -182,12 +208,6 @@ function! s:save_vimwiki_buffer() "{{{ endif endfunction "}}} -function! s:trim(string) "{{{ - let res = substitute(a:string, '^\s\+', '', '') - let res = substitute(res, '\s\+$', '', '') - return res -endfunction "}}} - function! s:get_html_toc(toc_list) "{{{ " toc_list is list of [level, header_text, header_id] " ex: [[1, "Header", "toc1"], [2, "Header2", "toc2"], ...] @@ -265,8 +285,7 @@ function! s:is_html_uptodate(wikifile) "{{{ endif let wikifile = fnamemodify(a:wikifile, ":p") - let subdir = vimwiki#base#subdir(VimwikiGet('path'), wikifile) - let htmlfile = expand(VimwikiGet('path_html').subdir. + let htmlfile = expand(VimwikiGet('path_html').VimwikiGet('subdir'). \fnamemodify(wikifile, ":t:r").".html") if getftime(wikifile) <= getftime(htmlfile) && tpl_time <= getftime(htmlfile) @@ -299,6 +318,11 @@ endfunction "}}} "}}} " INLINE TAGS "{{{ +function! s:tag_eqin(value) "{{{ + " mathJAX wants \( \) for inline maths + return '\('.s:mid(a:value, 1).'\)' +endfunction "}}} + function! s:tag_em(value) "{{{ return '<em>'.s:mid(a:value, 1).'</em>' endfunction "}}} @@ -324,141 +348,113 @@ function! s:tag_sub(value) "{{{ endfunction "}}} function! s:tag_code(value) "{{{ - return '<code>'.s:mid(a:value, 1).'</code>' + return '<code>'.s:safe_html_tags(s:mid(a:value, 1)).'</code>' endfunction "}}} -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 vimwiki#base#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#base#is_link_to_dir(a:src) - if g:vimwiki_dir_link == '' - let link = '<a href="'.vimwiki#base#safe_link(a:src).'">'.a:caption.'</a>' - else - let link = '<a href="'.vimwiki#base#safe_link(a:src). - \ g:vimwiki_dir_link.'.html">'.a:caption.'</a>' - endif - else - let link = '<a href="'.vimwiki#base#safe_link(a:src). - \ '.html">'.a:caption.'</a>' - endif +"function! s:tag_pre(value) "{{{ +" return '<code>'.s:mid(a:value, 3).'</code>' +"endfunction "}}} - return link - endfunction "}}} +"FIXME dead code? +"function! s:tag_math(value) "{{{ +" return '\['.s:mid(a:value, 3).'\]' +"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) +"{{{ v2.0 links +" match n-th ARG within {{URL[|ARG1|ARG2|...]}} " {{{ +" *c,d,e),... +function! vimwiki#html#incl_match_arg(nn_index) + let rx = g:vimwiki_rxWikiInclPrefix. g:vimwiki_rxWikiInclUrl + let rx = rx. repeat(g:vimwiki_rxWikiInclSeparator. g:vimwiki_rxWikiInclArg, a:nn_index-1) + if a:nn_index > 0 + let rx = rx. g:vimwiki_rxWikiInclSeparator. '\zs'. g:vimwiki_rxWikiInclArg. '\ze' endif + let rx = rx. g:vimwiki_rxWikiInclArgs. g:vimwiki_rxWikiInclSuffix + return rx +endfunction +"}}} +function! vimwiki#html#linkify_link(src, descr) "{{{ + let src_str = ' href="'.a:src.'"' + let descr = substitute(a:descr,'^\s*\(.*\)\s*$','\1','') + let descr = (descr == "" ? a:src : descr) + let descr_str = (descr =~ g:vimwiki_rxWikiIncl + \ ? s:tag_wikiincl(descr) + \ : descr) + return '<a'.src_str.'>'.descr_str.'</a>' +endfunction "}}} - 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) +function! vimwiki#html#linkify_image(src, descr, verbatim_str) "{{{ + let src_str = ' src="'.a:src.'"' + let descr_str = (a:descr != '' ? ' alt="'.a:descr.'"' : '') + let verbatim_str = (a:verbatim_str != '' ? ' '.a:verbatim_str : '') + return '<img'.src_str.descr_str.verbatim_str.' />' +endfunction "}}} - else - let line = s:linkify(value, value, '') - endif +function! s:tag_weblink(value) "{{{ + " Weblink Template -> <a href="url">descr</a> + let str = a:value + let url = matchstr(str, g:vimwiki_rxWeblinkMatchUrl) + let descr = matchstr(str, g:vimwiki_rxWeblinkMatchDescr) + let line = vimwiki#html#linkify_link(url, descr) return line endfunction "}}} -function! s:tag_external_link(value) "{{{ - "" Make <a href="link">link desc</a> - "" from [link link desc] - - let value = s:mid(a:value, 1) - - 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 - if s:is_img_link(rest) - if rest!=head - let line = '<a href="'.head.'"><img src="'.rest.'" /></a>' - else - let line = '<img src="'.rest.'" />' - endif - else - let line = '<a href="'.head.'">'.rest.'</a>' +function! s:tag_wikiincl(value) "{{{ + " {{imgurl|arg1|arg2}} -> ??? + " {{imgurl}} -> <img src="imgurl"/> + " {{imgurl|descr|style="A"}} -> <img src="imgurl" alt="descr" style="A" /> + " {{imgurl|descr|class="B"}} -> <img src="imgurl" alt="descr" class="B" /> + let str = a:value + " custom transclusions + let line = VimwikiWikiIncludeHandler(str) + " otherwise, assume image transclusion + if line == '' + let url_0 = matchstr(str, g:vimwiki_rxWikiInclMatchUrl) + let descr = matchstr(str, vimwiki#html#incl_match_arg(1)) + let verbatim_str = matchstr(str, vimwiki#html#incl_match_arg(2)) + " resolve url + let [idx, scheme, path, subdir, lnk, ext, url] = + \ vimwiki#base#resolve_scheme(url_0, 1) + " generate html output + " TODO: migrate non-essential debugging messages into g:VimwikiLog + if g:vimwiki_debug > 1 + echom '{{idx='.idx.', scheme='.scheme.', path='.path.', subdir='.subdir.', lnk='.lnk.', ext='.ext.'}}' endif - elseif s:is_img_link(value) - let line = '<img src="'.value.'" />' - else - " [alskfj sfsf] shouldn't be a link. So return it as it was -- - " enclosed in [...] - let line = '['.value.']' + let url = escape(url, '#') + let line = vimwiki#html#linkify_image(url, descr, verbatim_str) + return line endif return line endfunction "}}} -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>' +function! s:tag_wikilink(value) "{{{ + " [[url]] -> <a href="url.html">url</a> + " [[url|descr]] -> <a href="url.html">descr</a> + " [[url|{{...}}]] -> <a href="url.html"> ... </a> + " [[fileurl.ext|descr]] -> <a href="fileurl.ext">descr</a> + " [[dirurl/|descr]] -> <a href="dirurl/index.html">descr</a> + let str = a:value + let url = matchstr(str, g:vimwiki_rxWikiLinkMatchUrl) + let descr = matchstr(str, g:vimwiki_rxWikiLinkMatchDescr) + let descr = (substitute(descr,'^\s*\(.*\)\s*$','\1','') != '' ? descr : url) + + " resolve url + let [idx, scheme, path, subdir, lnk, ext, url] = + \ vimwiki#base#resolve_scheme(url, 1) + + " generate html output + " TODO: migrate non-essential debugging messages into g:VimwikiLog + if g:vimwiki_debug > 1 + echom '[[idx='.idx.', scheme='.scheme.', path='.path.', subdir='.subdir.', lnk='.lnk.', ext='.ext.']]' endif + let url = escape(url, '#') + let line = vimwiki#html#linkify_link(url, descr) return line endfunction "}}} +"}}} v1.3 links -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) @@ -508,10 +504,16 @@ endfunction "}}} function! s:make_tag(line, regexp, func) "{{{ " Make tags for a given matched regexp. " Exclude preformatted text and href links. - - let patt_splitter = '\(`[^`]\+`\)\|\({{{.\+}}}\)\|'. - \ '\(<a href.\{-}</a>\)\|\(<img src.\{-}/>\)' - if '`[^`]\+`' == a:regexp || '{{{.\+}}}' == a:regexp + " FIXME + let patt_splitter = '\(`[^`]\+`\)\|'. + \ '\('.g:vimwiki_rxPreStart.'.\+'.g:vimwiki_rxPreEnd.'\)\|'. + \ '\(<a href.\{-}</a>\)\|'. + \ '\(<img src.\{-}/>\)\|'. + \ '\('.g:vimwiki_rxEqIn.'\)' + + "FIXME FIXME !!! these can easily occur on the same line! + "XXX {{{ }}} ??? obsolete + if '`[^`]\+`' == a:regexp || '{{{.\+}}}' == a:regexp || g:vimwiki_rxEqIn == a:regexp let res_line = s:subst_func(a:line, a:regexp, a:func) else let pos = 0 @@ -541,7 +543,6 @@ 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') @@ -549,15 +550,15 @@ function! s:process_tags_typefaces(line) "{{{ let line = s:make_tag(line, g:vimwiki_rxSuperScript, 's:tag_super') let line = s:make_tag(line, g:vimwiki_rxSubScript, 's:tag_sub') let line = s:make_tag(line, g:vimwiki_rxCode, 's:tag_code') + let line = s:make_tag(line, g:vimwiki_rxEqIn, 's:tag_eqin') 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') + let line = s:make_tag(line, g:vimwiki_rxWikiLink, 's:tag_wikilink') + let line = s:make_tag(line, g:vimwiki_rxWikiIncl, 's:tag_wikiincl') + let line = s:make_tag(line, g:vimwiki_rxWeblink, 's:tag_weblink') return line endfunction " }}} @@ -577,6 +578,14 @@ function! s:close_tag_pre(pre, ldest) "{{{ return a:pre endfunction "}}} +function! s:close_tag_math(math, ldest) "{{{ + if a:math[0] + call insert(a:ldest, "\\\]") + return 0 + endif + return a:math +endfunction "}}} + function! s:close_tag_quote(quote, ldest) "{{{ if a:quote call insert(a:ldest, "</blockquote>") @@ -745,11 +754,15 @@ endfunction! "}}} function! s:process_tag_pre(line, pre) "{{{ " pre is the list of [is_in_pre, indent_of_pre] + "XXX always outputs a single line or empty list! let lines = [] let pre = a:pre let processed = 0 - if !pre[0] && a:line =~ '^\s*{{{[^\(}}}\)]*\s*$' + "XXX huh? + "if !pre[0] && a:line =~ '^\s*{{{[^\(}}}\)]*\s*$' + if !pre[0] && a:line =~ '^\s*{{{' let class = matchstr(a:line, '{{{\zs.*$') + "FIXME class cannot contain arbitrary strings let class = substitute(class, '\s\+$', '', 'g') if class != "" call add(lines, "<pre ".class.">") @@ -764,11 +777,48 @@ function! s:process_tag_pre(line, pre) "{{{ let processed = 1 elseif pre[0] let processed = 1 - call add(lines, substitute(a:line, '^\s\{'.pre[1].'}', '', '')) + "XXX destroys indent in general! + "call add(lines, substitute(a:line, '^\s\{'.pre[1].'}', '', '')) + call add(lines, s:safe_html_tags(a:line)) endif return [processed, lines, pre] endfunction "}}} +function! s:process_tag_math(line, math) "{{{ + " math is the list of [is_in_math, indent_of_math] + let lines = [] + let math = a:math + let processed = 0 + if !math[0] && a:line =~ '^\s*{{\$[^\(}}$\)]*\s*$' + let class = matchstr(a:line, '{{$\zs.*$') + "FIXME class cannot be any string! + let class = substitute(class, '\s\+$', '', 'g') + " Check the math placeholder (default: displaymath) + let b:vimwiki_mathEnv = matchstr(class, '^%\zs\S\+\ze%') + if b:vimwiki_mathEnv != "" + call add(lines, substitute(class, '^%\(\S\+\)%','\\begin{\1}', '')) + elseif class != "" + call add(lines, "\\\[".class) + else + call add(lines, "\\\[") + endif + let math = [1, len(matchstr(a:line, '^\s*\ze{{\$'))] + let processed = 1 + elseif math[0] && a:line =~ '^\s*}}\$\s*$' + let math = [0, 0] + if b:vimwiki_mathEnv != "" + call add(lines, "\\end{".b:vimwiki_mathEnv."}") + else + call add(lines, "\\\]") + endif + let processed = 1 + elseif math[0] + let processed = 1 + call add(lines, substitute(a:line, '^\s\{'.math[1].'}', '', '')) + endif + return [processed, lines, math] +endfunction "}}} + function! s:process_tag_quote(line, quote) "{{{ let lines = [] let quote = a:quote @@ -800,7 +850,8 @@ function! s:process_tag_list(line, lists) "{{{ if chk[1] =~ '[.*\\^$~]' let chk[1] ='\'.chk[1] endif - let completion = match(g:vimwiki_listsyms, '\C' . chk[1]) + " let completion = match(g:vimwiki_listsyms, '\C' . chk[1]) + let completion = s:get_completion_index(chk[1]) if completion >= 0 && completion <=4 let st_tag = '<li class="done'.completion.'">' endif @@ -935,18 +986,9 @@ function! s:process_tag_h(line, id) "{{{ let h_level = 0 let h_text = '' let h_id = '' - if a:line =~ g:vimwiki_rxH6 - let h_level = 6 - elseif a:line =~ g:vimwiki_rxH5 - let h_level = 5 - elseif a:line =~ g:vimwiki_rxH4 - let h_level = 4 - elseif a:line =~ g:vimwiki_rxH3 - let h_level = 3 - elseif a:line =~ g:vimwiki_rxH2 - let h_level = 2 - elseif a:line =~ g:vimwiki_rxH1 - let h_level = 1 + + if a:line =~ g:vimwiki_rxHeader + let h_level = vimwiki#u#count_first_sym(a:line) endif if h_level > 0 let a:id[h_level] += 1 @@ -960,8 +1002,6 @@ function! s:process_tag_h(line, id) "{{{ let centered = 1 endif - let line = s:trim(line) - let h_number = '' for l in range(1, h_level-1) let h_number .= a:id[l].'.' @@ -978,7 +1018,8 @@ function! s:process_tag_h(line, id) "{{{ let h_part .= '>' endif - let h_text = s:trim(strpart(line, h_level, len(line) - h_level * 2)) + let h_text = vimwiki#u#trim(matchstr(line, g:vimwiki_rxHeader)) + if g:vimwiki_html_header_numbering let num = matchstr(h_number, \ '^\(\d.\)\{'.(g:vimwiki_html_header_numbering-1).'}\zs.*') @@ -1046,14 +1087,15 @@ function! s:process_tag_table(line, table) "{{{ let lines = [] let processed = 0 - if a:line =~ '^\s*|[-+]\+|\s*$' + if vimwiki#tbl#is_separator(a:line) call extend(table, s:table_add_row(a:table, a:line)) let processed = 1 - elseif a:line =~ '^\s*|.\+|\s*$' + elseif vimwiki#tbl#is_table(a:line) call extend(table, s:table_add_row(a:table, a:line)) let processed = 1 - let cells = split(a:line, '\s*|\s*', 1)[1: -2] + " let cells = split(a:line, vimwiki#tbl#cell_splitter(), 1)[1: -2] + let cells = vimwiki#tbl#get_cells(a:line) call map(cells, 's:table_empty_cell(v:val)') call extend(table[-1], cells) else @@ -1072,6 +1114,7 @@ function! s:parse_line(line, state) " {{{ let state.para = a:state.para let state.quote = a:state.quote let state.pre = a:state.pre[:] + let state.math = a:state.math[:] let state.table = a:state.table[:] let state.lists = a:state.lists[:] let state.deflist = a:state.deflist @@ -1135,6 +1178,9 @@ function! s:parse_line(line, state) " {{{ " if processed && len(state.lists) " call s:close_tag_list(state.lists, lines) " endif + if !processed + let [processed, lines, state.math] = s:process_tag_math(line, state.math) + endif if processed && len(state.table) let state.table = s:close_tag_table(state.table, lines) endif @@ -1160,6 +1206,9 @@ function! s:parse_line(line, state) " {{{ if processed && state.pre[0] let state.pre = s:close_tag_pre(state.pre, lines) endif + if processed && state.math[0] + let state.math = s:close_tag_math(state.math, lines) + endif if processed && len(state.table) let state.table = s:close_tag_table(state.table, lines) endif @@ -1183,6 +1232,7 @@ function! s:parse_line(line, state) " {{{ call s:close_tag_list(state.lists, res_lines) let state.table = s:close_tag_table(state.table, res_lines) let state.pre = s:close_tag_pre(state.pre, res_lines) + let state.math = s:close_tag_math(state.math, res_lines) let state.quote = s:close_tag_quote(state.quote, res_lines) let state.para = s:close_tag_para(state.para, res_lines) @@ -1218,6 +1268,9 @@ function! s:parse_line(line, state) " {{{ if processed && state.pre[0] let state.pre = s:close_tag_pre(state.pre, lines) endif + if processed && state.math[0] + let state.math = s:close_tag_math(state.math, lines) + endif if processed && state.para let state.para = s:close_tag_para(state.para, lines) endif @@ -1235,6 +1288,7 @@ function! s:parse_line(line, state) " {{{ call s:close_tag_list(state.lists, res_lines) let state.table = s:close_tag_table(state.table, res_lines) let state.pre = s:close_tag_pre(state.pre, res_lines) + let state.math = s:close_tag_math(state.math, res_lines) call add(res_lines, line) endif endif @@ -1262,6 +1316,9 @@ function! s:parse_line(line, state) " {{{ if processed && state.pre[0] let state.pre = s:close_tag_pre(state.pre, res_lines) endif + if processed && state.math[0] + let state.math = s:close_tag_math(state.math, res_lines) + endif if processed && len(state.table) let state.table = s:close_tag_table(state.table, res_lines) endif @@ -1281,128 +1338,174 @@ function! s:parse_line(line, state) " {{{ endfunction " }}} -function! vimwiki#html#Wiki2HTML(path, wikifile) "{{{ +function! s:use_custom_wiki2html() "{{{ + let custom_wiki2html = VimwikiGet('custom_wiki2html') + return !empty(custom_wiki2html) && s:file_exists(custom_wiki2html) +endfunction " }}} + +function! vimwiki#html#CustomWiki2HTML(path, wikifile, force) "{{{ + call vimwiki#base#mkdir(a:path) + execute '!'.VimwikiGet('custom_wiki2html'). ' ' + \ a:force. ' '. + \ VimwikiGet('syntax'). ' '. + \ strpart(VimwikiGet('ext'), 1). ' '. + \ a:path. ' '. + \ a:wikifile. ' '. + \ s:default_CSS_full_name(a:path) +endfunction " }}} + +function! vimwiki#html#Wiki2HTML(path_html, wikifile) "{{{ let starttime = reltime() " start the clock - echo 'Generating HTML ... ' - if !s:syntax_supported() - echomsg 'vimwiki: Only vimwiki_default syntax supported!!!' - return - endif + + let done = 0 let wikifile = fnamemodify(a:wikifile, ":p") - let subdir = vimwiki#base#subdir(VimwikiGet('path'), wikifile) - let path = expand(a:path).subdir + let path_html = expand(a:path_html).VimwikiGet('subdir') let htmlfile = fnamemodify(wikifile, ":t:r").'.html' - let lsource = readfile(wikifile) - let ldest = [] + if s:use_custom_wiki2html() + let force = 1 + call vimwiki#html#CustomWiki2HTML(path_html, wikifile, force) + let done = 1 + endif - call vimwiki#base#mkdir(path) + if s:syntax_supported() && done == 0 + let lsource = readfile(wikifile) + let ldest = [] + + "if g:vimwiki_debug + " echo 'Generating HTML ... ' + "endif + + call vimwiki#base#mkdir(path_html) + + " nohtml placeholder -- to skip html generation. + let nohtml = 0 + + " template placeholder + let template_name = '' + + " for table of contents placeholders. + let placeholders = [] + + " current state of converter + let state = {} + let state.para = 0 + let state.quote = 0 + let state.pre = [0, 0] " [in_pre, indent_pre] + let state.math = [0, 0] " [in_math, indent_math] + let state.table = [] + let state.deflist = 0 + let state.lists = [] + let state.placeholder = [] + let state.toc = [] + let state.toc_id = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 } + + " prepare constants for s:safe_html() + let s:lt_pattern = '<' + let s:gt_pattern = '>' + if g:vimwiki_valid_html_tags != '' + let tags = join(split(g:vimwiki_valid_html_tags, '\s*,\s*'), '\|') + let s:lt_pattern = '<\%(/\?\%('.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?>\)\@!' + let s:gt_pattern = '\%(</\?\%('.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?\)\@<!>' + endif - " nohtml placeholder -- to skip html generation. - let nohtml = 0 + for line in lsource + let oldquote = state.quote + let [lines, state] = s:parse_line(line, state) - " template placeholder - let template_name = '' + " 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 + call s:remove_blank_lines(ldest) + endif - " for table of contents placeholders. - let placeholders = [] + if !empty(state.placeholder) + if state.placeholder[0] == 'nohtml' + let nohtml = 1 + break + elseif state.placeholder[0] == 'template' + let template_name = state.placeholder[1] + else + call add(placeholders, [state.placeholder, len(ldest), len(placeholders)]) + endif + let state.placeholder = [] + endif - " current state of converter - let state = {} - let state.para = 0 - let state.quote = 0 - let state.pre = [0, 0] " [in_pre, indent_pre] - let state.table = [] - let state.deflist = 0 - let state.lists = [] - let state.placeholder = [] - let state.toc = [] - let state.toc_id = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 } - - for line in lsource - let oldquote = state.quote - 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 - " to refactor it out. - if oldquote != state.quote - call s:remove_blank_lines(ldest) - endif + call extend(ldest, lines) + endfor - if !empty(state.placeholder) - if state.placeholder[0] == 'nohtml' - let nohtml = 1 - break - elseif state.placeholder[0] == 'template' - let template_name = state.placeholder[1] - else - call add(placeholders, [state.placeholder, len(ldest), len(placeholders)]) - endif - let state.placeholder = [] + + if nohtml + echon "\r"."%nohtml placeholder found" + return endif + let toc = s:get_html_toc(state.toc) + call s:process_toc(ldest, placeholders, toc) + 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_math(state.math, 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) - endfor + let title = s:process_title(placeholders, fnamemodify(a:wikifile, ":t:r")) - if nohtml - echon "\r"."%nohtml placeholder found" - return - endif + let html_lines = s:get_html_template(a:wikifile, template_name) - let toc = s:get_html_toc(state.toc) - call s:process_toc(ldest, placeholders, toc) - call s:remove_blank_lines(ldest) + " processing template variables (refactor to a function) + call map(html_lines, 'substitute(v:val, "%title%", "'. title .'", "g")') + call map(html_lines, 'substitute(v:val, "%root_path%", "'. + \ s:root_path(VimwikiGet('subdir')) .'", "g")') + + let css_name = expand(VimwikiGet('css_name')) + let css_name = substitute(css_name, '\', '/', 'g') + call map(html_lines, 'substitute(v:val, "%css%", "'. css_name .'", "g")') + + let enc = &fileencoding + if enc == '' + let enc = &encoding + endif + call map(html_lines, 'substitute(v:val, "%encoding%", "'. enc .'", "g")') + + let html_lines = s:html_insert_contents(html_lines, ldest) " %contents% + + "" make html file. + call writefile(html_lines, path_html.htmlfile) + let done = 1 - "" 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) - - let title = s:process_title(placeholders, fnamemodify(a:wikifile, ":t:r")) - - let html_lines = s:get_html_template(a:wikifile, template_name) - - " processing template variables (refactor to a function) - call map(html_lines, 'substitute(v:val, "%title%", "'. title .'", "g")') - call map(html_lines, 'substitute(v:val, "%root_path%", "'. - \ s:root_path(subdir) .'", "g")') - - let css_name = expand(VimwikiGet('css_name')) - let css_name = substitute(css_name, '\', '/', 'g') - call map(html_lines, 'substitute(v:val, "%css%", "'. css_name .'", "g")') - - let enc = &fileencoding - if enc == '' - let enc = &encoding endif - call map(html_lines, 'substitute(v:val, "%encoding%", "'. enc .'", "g")') - let html_lines = s:html_insert_contents(html_lines, ldest) " %contents% + if done == 0 + echomsg 'vimwiki: conversion to HTML is not supported for this syntax!!!' + return + endif - "" make html file. - call writefile(html_lines, path.htmlfile) + " measure the elapsed time + let time1 = vimwiki#u#time(starttime) "XXX + call VimwikiLog_extend('html',[htmlfile,time1]) + "if g:vimwiki_debug + " echon "\r".htmlfile.' written (time: '.time1.'s)' + "endif - " measure the elapsed time and cut away miliseconds and smaller - let elapsedtimestr = matchstr(reltimestr(reltime(starttime)),'\d\+\(\.\d\d\)\=') - echon "\r".htmlfile.' written (time: '.elapsedtimestr.'s)' - return path.htmlfile + return path_html.htmlfile endfunction "}}} -function! vimwiki#html#WikiAll2HTML(path) "{{{ - if !s:syntax_supported() - echomsg 'vimwiki: Only vimwiki_default syntax supported!!!' +function! vimwiki#html#WikiAll2HTML(path_html) "{{{ + if !s:syntax_supported() && !s:use_custom_wiki2html() + echomsg 'vimwiki: conversion to HTML is not supported for this syntax!!!' return endif @@ -1414,28 +1517,63 @@ function! vimwiki#html#WikiAll2HTML(path) "{{{ exe 'buffer '.cur_buf let &eventignore = save_eventignore - let path = expand(a:path) - call vimwiki#base#mkdir(path) + let path_html = expand(a:path_html) + call vimwiki#base#mkdir(path_html) echomsg 'Deleting non-wiki html files...' - call s:delete_html_files(path) + call s:delete_html_files(path_html) echomsg 'Converting wiki to html files...' let setting_more = &more setlocal nomore + " temporarily adjust current_subdir global state variable + let current_subdir = VimwikiGet('subdir') + let current_invsubdir = VimwikiGet('invsubdir') + let wikifiles = split(glob(VimwikiGet('path').'**/*'.VimwikiGet('ext')), '\n') for wikifile in wikifiles + let wikifile = fnamemodify(wikifile, ":p") + + " temporarily adjust 'subdir' and 'invsubdir' state variables + let subdir = vimwiki#base#subdir(VimwikiGet('path'), wikifile) + call VimwikiSet('subdir', subdir) + call VimwikiSet('invsubdir', vimwiki#base#invsubdir(subdir)) + if !s:is_html_uptodate(wikifile) echomsg 'Processing '.wikifile - call vimwiki#html#Wiki2HTML(path, wikifile) + + call vimwiki#html#Wiki2HTML(path_html, wikifile) else echomsg 'Skipping '.wikifile endif endfor - call s:create_default_CSS(path) + " reset 'subdir' state variable + call VimwikiSet('subdir', current_subdir) + call VimwikiSet('invsubdir', current_invsubdir) + + call s:create_default_CSS(path_html) echomsg 'Done!' let &more = setting_more endfunction "}}} + +function! s:file_exists(fname) "{{{ + return !empty(getftype(a:fname)) +endfunction "}}} + +" uses VimwikiGet('path') +function! vimwiki#html#get_wikifile_url(wikifile) "{{{ + return VimwikiGet('path_html'). + \ vimwiki#base#subdir(VimwikiGet('path'), a:wikifile). + \ fnamemodify(a:wikifile, ":t:r").'.html' +endfunction "}}} + +function! vimwiki#html#PasteUrl(wikifile) "{{{ + execute 'r !echo file://'.vimwiki#html#get_wikifile_url(a:wikifile) +endfunction "}}} + +function! vimwiki#html#CatUrl(wikifile) "{{{ + execute '!echo file://'.vimwiki#html#get_wikifile_url(a:wikifile) +endfunction "}}} "}}} diff --git a/autoload/vimwiki/lst.vim b/autoload/vimwiki/lst.vim @@ -15,24 +15,36 @@ let s:rx_li_box = '\[.\?\]' " Script functions {{{ +" Get unicode string symbol at index +function! s:str_idx(str, idx) "{{{ + " Unfortunatly vimscript cannot get symbol at index in unicode string such as + " '✗○◐●✓' + return matchstr(a:str, '\%'.a:idx.'v.') +endfunction "}}} + " Get checkbox regexp function! s:rx_li_symbol(rate) "{{{ let result = '' if a:rate == 100 - let result = g:vimwiki_listsyms[4] + let result = s:str_idx(g:vimwiki_listsyms, 5) elseif a:rate == 0 - let result = g:vimwiki_listsyms[0] + let result = s:str_idx(g:vimwiki_listsyms, 1) elseif a:rate >= 67 - let result = g:vimwiki_listsyms[3] + let result = s:str_idx(g:vimwiki_listsyms, 4) elseif a:rate >= 34 - let result = g:vimwiki_listsyms[2] + let result = s:str_idx(g:vimwiki_listsyms, 3) else - let result = g:vimwiki_listsyms[1] + let result = s:str_idx(g:vimwiki_listsyms, 2) endif return '\['.result.'\]' endfunction "}}} +" Get blank checkbox +function! s:blank_checkbox() "{{{ + return '['.s:str_idx(g:vimwiki_listsyms, 1).'] ' +endfunction "}}} + " Get regexp of the list item. function! s:rx_list_item() "{{{ return '\('.g:vimwiki_rxListBullet.'\|'.g:vimwiki_rxListNumber.'\)' @@ -46,7 +58,7 @@ endfunction "}}} " Get level of the list item. function! s:get_level(lnum) "{{{ if VimwikiGet('syntax') == 'media' - let level = vimwiki#base#count_first_sym(getline(a:lnum)) + let level = vimwiki#u#count_first_sym(getline(a:lnum)) else let level = indent(a:lnum) endif @@ -222,7 +234,7 @@ function! s:create_cb_list_item(lnum) "{{{ let m = matchstr(line, s:rx_list_item()) if m != '' let li_content = substitute(strpart(line, len(m)), '^\s*', '', '') - let line = substitute(m, '\s*$', ' ', '').'[ ] '.li_content + let line = substitute(m, '\s*$', ' ', '').s:blank_checkbox().li_content call setline(a:lnum, line) endif endfunction "}}} @@ -320,7 +332,7 @@ function! vimwiki#lst#kbd_cr() "{{{ " This function is heavily relies on proper 'set comments' option. let cr = "\<CR>" if getline('.') =~ s:rx_cb_list_item() - let cr .= '[ ] ' + let cr .= s:blank_checkbox() endif return cr endfunction "}}} @@ -341,11 +353,10 @@ function! vimwiki#lst#kbd_oO(cmd) "{{{ let lnum = line('.') endif - " let line = substitute(m, '\s*$', ' ', '').'[ ] '.li_content let m = matchstr(line, s:rx_list_item()) let res = '' if line =~ s:rx_cb_list_item() - let res = substitute(m, '\s*$', ' ', '').'[ ] ' + let res = substitute(m, '\s*$', ' ', '').s:blank_checkbox() elseif line =~ s:rx_list_item() let res = substitute(m, '\s*$', ' ', '') elseif &autoindent || &smartindent @@ -367,3 +378,178 @@ function! vimwiki#lst#kbd_oO(cmd) "{{{ endfunction "}}} +function! vimwiki#lst#default_symbol() "{{{ + " TODO: initialize default symbol from syntax/vimwiki_xxx.vim + if VimwikiGet('syntax') == 'default' + return '-' + else + return '*' + endif +endfunction "}}} + +function vimwiki#lst#get_list_margin() "{{{ + if VimwikiGet('list_margin') < 0 + return &sw + else + return VimwikiGet('list_margin') + endif +endfunction "}}} + +function s:get_list_sw() "{{{ + if VimwikiGet('syntax') == 'media' + return 1 + else + return &sw + endif +endfunction "}}} + +function s:get_list_nesting_level(lnum) "{{{ + if VimwikiGet('syntax') == 'media' + if getline(a:lnum) !~ s:rx_list_item() + let level = 0 + else + let level = vimwiki#u#count_first_sym(getline(a:lnum)) - 1 + let level = level < 0 ? 0 : level + endif + else + let level = indent(a:lnum) + endif + return level +endfunction "}}} + +function s:get_list_indent(lnum) "{{{ + if VimwikiGet('syntax') == 'media' + return indent(a:lnum) + else + return 0 + endif +endfunction "}}} + +function! s:compose_list_item(n_indent, n_nesting, sym_nest, sym_bullet, li_content, ...) "{{{ + if a:0 + let sep = a:1 + else + let sep = '' + endif + let li_indent = repeat(' ', max([0,a:n_indent])).sep + let li_nesting = repeat(a:sym_nest, max([0,a:n_nesting])).sep + if len(a:sym_bullet) > 0 + let li_bullet = a:sym_bullet.' '.sep + else + let li_bullet = ''.sep + endif + return li_indent.li_nesting.li_bullet.a:li_content +endfunction "}}} + +function s:compose_cb_bullet(prev_cb_bullet, sym) "{{{ + return a:sym.matchstr(a:prev_cb_bullet, '\S*\zs\s\+.*') +endfunction "}}} + +function! vimwiki#lst#change_level(...) "{{{ + let default_sym = vimwiki#lst#default_symbol() + let cmd = '>>' + let sym = default_sym + + " parse argument + if a:0 + if a:1 != '<<' && a:1 != '>>' + let cmd = '--' + let sym = a:1 + else + let cmd = a:1 + endif + endif + " is symbol valid + if sym.' ' !~ s:rx_cb_list_item() && sym.' ' !~ s:rx_list_item() + return + endif + + " parsing setup + let lnum = line('.') + let line = getline('.') + + let list_margin = vimwiki#lst#get_list_margin() + let list_sw = s:get_list_sw() + let n_nesting = s:get_list_nesting_level(lnum) + let n_indent = s:get_list_indent(lnum) + + " remove indent and nesting + let li_bullet_and_content = strpart(line, n_nesting + n_indent) + + " list bullet and checkbox + let cb_bullet = matchstr(li_bullet_and_content, s:rx_list_item()). + \ matchstr(li_bullet_and_content, s:rx_cb_list_item()) + + " XXX: it could be not unicode proof --> if checkboxes are set up with unicode syms + " content + let li_content = strpart(li_bullet_and_content, len(cb_bullet)) + + " trim + let cb_bullet = vimwiki#u#trim(cb_bullet) + let li_content = vimwiki#u#trim(li_content) + + " nesting symbol + if VimwikiGet('syntax') == 'media' + if len(cb_bullet) > 0 + let sym_nest = cb_bullet[0] + else + let sym_nest = sym + endif + else + let sym_nest = ' ' + endif + + if g:vimwiki_debug + echomsg "PARSE: Sw [".list_sw."]" + echomsg s:compose_list_item(n_indent, n_nesting, sym_nest, cb_bullet, li_content, '|') + endif + + " change level + if cmd == '--' + let cb_bullet = s:compose_cb_bullet(cb_bullet, sym) + if VimwikiGet('syntax') == 'media' + let sym_nest = sym + endif + elseif cmd == '>>' + if cb_bullet == '' + let cb_bullet = sym + else + let n_nesting = n_nesting + list_sw + endif + elseif cmd == '<<' + let n_nesting = n_nesting - list_sw + if VimwikiGet('syntax') == 'media' + if n_nesting < 0 + let cb_bullet = '' + endif + else + if n_nesting < list_margin + let cb_bullet = '' + endif + endif + endif + + let n_nesting = max([0, n_nesting]) + + if g:vimwiki_debug + echomsg "SHIFT:" + echomsg s:compose_list_item(n_indent, n_nesting, sym_nest, cb_bullet, li_content, '|') + endif + + " XXX: this is the code that adds the initial indent + let add_nesting = VimwikiGet('syntax') != 'media' + if n_indent + n_nesting*(add_nesting) < list_margin + let n_indent = list_margin - n_nesting*(add_nesting) + endif + + if g:vimwiki_debug + echomsg "INDENT:" + echomsg s:compose_list_item(n_indent, n_nesting, sym_nest, cb_bullet, li_content, '|') + endif + + let line = s:compose_list_item(n_indent, n_nesting, sym_nest, cb_bullet, li_content) + + " replace + call setline(lnum, line) + call cursor(lnum, match(line, '\S') + 1) +endfunction "}}} diff --git a/autoload/vimwiki/markdown_base.vim b/autoload/vimwiki/markdown_base.vim @@ -0,0 +1,111 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" Vimwiki autoload plugin file +" Desc: Link functions for markdown syntax +" Author: Maxim Kim <habamax@gmail.com> +" Home: http://code.google.com/p/vimwiki/ + + +function! s:normalize_link_syntax_n() " {{{ + let lnum = line('.') + + " try WikiIncl + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWikiIncl) + if !empty(lnk) + " NO-OP !! + if g:vimwiki_debug > 1 + echomsg "WikiIncl: ".lnk." Sub: ".lnk + endif + return + endif + + " try WikiLink0: replace with WikiLink1 + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWikiLink0) + if !empty(lnk) + let sub = vimwiki#base#normalize_link_helper(lnk, + \ g:vimwiki_rxWikiLinkMatchUrl, g:vimwiki_rxWikiLinkMatchDescr, + \ g:vimwiki_WikiLink1Template2) + call vimwiki#base#replacestr_at_cursor(g:vimwiki_rxWikiLink0, sub) + if g:vimwiki_debug > 1 + echomsg "WikiLink: ".lnk." Sub: ".sub + endif + return + endif + + " try WikiLink1: replace with WikiLink0 + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWikiLink1) + if !empty(lnk) + let sub = vimwiki#base#normalize_link_helper(lnk, + \ g:vimwiki_rxWikiLinkMatchUrl, g:vimwiki_rxWikiLinkMatchDescr, + \ g:vimwiki_WikiLinkTemplate2) + call vimwiki#base#replacestr_at_cursor(g:vimwiki_rxWikiLink1, sub) + if g:vimwiki_debug > 1 + echomsg "WikiLink: ".lnk." Sub: ".sub + endif + return + endif + + " try Weblink + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWeblink) + if !empty(lnk) + let sub = vimwiki#base#normalize_link_helper(lnk, + \ g:vimwiki_rxWeblinkMatchUrl, g:vimwiki_rxWeblinkMatchDescr, + \ g:vimwiki_Weblink1Template) + call vimwiki#base#replacestr_at_cursor(g:vimwiki_rxWeblink, sub) + if g:vimwiki_debug > 1 + echomsg "WebLink: ".lnk." Sub: ".sub + endif + return + endif + + " try Word (any characters except separators) + " rxWord is less permissive than rxWikiLinkUrl which is used in + " normalize_link_syntax_v + let lnk = vimwiki#base#matchstr_at_cursor(g:vimwiki_rxWord) + if !empty(lnk) + let sub = vimwiki#base#normalize_link_helper(lnk, + \ g:vimwiki_rxWord, '', + \ g:vimwiki_WikiLinkTemplate1) + call vimwiki#base#replacestr_at_cursor('\V'.lnk, sub) + if g:vimwiki_debug > 1 + echomsg "Word: ".lnk." Sub: ".sub + endif + return + endif + +endfunction " }}} + +function! s:normalize_link_syntax_v() " {{{ + let lnum = line('.') + let sel_save = &selection + let &selection = "old" + let rv = @" + let rt = getregtype('"') + let done = 0 + + try + norm! gvy + let visual_selection = @" + let visual_selection = substitute(g:vimwiki_WikiLinkTemplate1, '__LinkUrl__', '\='."'".visual_selection."'", '') + + call setreg('"', visual_selection, 'v') + + " paste result + norm! `>pgvd + + finally + call setreg('"', rv, rt) + let &selection = sel_save + endtry + +endfunction " }}} + +" normalize_link +function! vimwiki#markdown_base#normalize_link(is_visual_mode) "{{{ + if !a:is_visual_mode + call s:normalize_link_syntax_n() + elseif visualmode() ==# 'v' && line("'<") == line("'>") + " action undefined for 'line-wise' or 'multi-line' visual mode selections + call s:normalize_link_syntax_v() + endif +endfunction "}}} + diff --git a/autoload/vimwiki/style.css b/autoload/vimwiki/style.css @@ -24,16 +24,56 @@ del {text-decoration: line-through; color: #777777;} .justright {text-align: right;} .justcenter {text-align: center;} .center {margin-left: auto; margin-right: auto;} + /* classes for items of todo lists */ -.done0:before {content: "\2592\2592\2592\2592"; color: SkyBlue;} -.done1:before {content: "\2588\2592\2592\2592"; color: SkyBlue;} -.done2:before {content: "\2588\2588\2592\2592"; color: SkyBlue;} -.done3:before {content: "\2588\2588\2588\2592"; color: SkyBlue;} -.done4:before {content: "\2588\2588\2588\2588"; color: SkyBlue;} -/* comment the next four or five lines out * - * if you do not want color-coded todo lists */ -.done0 {color: #c00000;} -.done1 {color: #c08000;} -.done2 {color: #80a000;} -.done3 {color: #00c000;} -.done4 {color: #7f7f7f; text-decoration: line-through;} +.done0 { + /* list-style: none; */ + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAA7SURBVCiR7dMxEgAgCANBI3yVRzF5KxNbW6wsuH7LQ2YKQK1mkswBVERYF5Os3UV3gwd/jF2SkXy66gAZkxS6BniubAAAAABJRU5ErkJggg==); + background-repeat: no-repeat; + background-position: 0 .2em; + margin-left: -2em; + padding-left: 1.5em; +} +.done1 { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABtSURBVCiR1ZO7DYAwDER9BDmTeZQMFXmUbGYpOjrEryA0wOvO8itOslFrJYAug5BMM4BeSkmjsrv3aVTa8p48Xw1JSkSsWVUFwD05IqS1tmYzk5zzae9jnVVVzGyXb8sALjse+euRkEzu/uirFomVIdDGOLjuAAAAAElFTkSuQmCC); + background-repeat: no-repeat; + background-position: 0 .15em; + margin-left: -2em; + padding-left: 1.5em; +} +.done2 { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAB1SURBVCiRzdO5DcAgDAVQGxjAYgTvxlDIu1FTIRYAp8qlFISkSH7l5kk+ZIwxKiI2mIyqWoeILYRgZ7GINDOLjnmF3VqklKCUMgTee2DmM661Qs55iI3Zm/1u5h9sm4ig9z4ERHTFzLyd4G4+nFlVrYg8+qoF/c0kdpeMsmcAAAAASUVORK5CYII=); + background-repeat: no-repeat; + background-position: 0 .15em; + margin-left: -2em; + padding-left: 1.5em; +} +.done3 { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABoSURBVCiR7dOxDcAgDATA/0DtUdiKoZC3YhLkHjkVKF3idJHiztKfvrHZWnOSE8Fx95RJzlprimJVnXktvXeY2S0SEZRSAAAbmxnGGKH2I5T+8VfxPhIReQSuuY3XyYWa3T2p6quvOgGrvSFGlewuUAAAAABJRU5ErkJggg==); + background-repeat: no-repeat; + background-position: 0 .15em; + margin-left: -2em; + padding-left: 1.5em; +} +.done4 { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAzgAAAM4BlP6ToAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIISURBVDiNnZQ9SFtRFMd/773kpTaGJoQk1im4VDpWQcTNODhkFBcVTCNCF0NWyeDiIIiCm82QoIMIUkHUxcFBg1SEQoZszSat6cdTn1qNue92CMbEr9Sey+XC/Z/zu+f8h6ukUil3sVg0+M+4cFxk42/jH2wAqqqKSCSiPQdwcHHAnDHH9s/tN1h8V28ETdP+eU8fT9Nt62ancYdIPvJNtsu87bmjrJlrTDVM4RROJs1JrHPrD4Bar7A6cpc54iKOaTdJXCUI2UMVrQZ0Js7YPN18ECKkYNQcJe/OE/4dZsw7VqNXQMvHy3QZXQypQ6ycrtwDjf8aJ+PNEDSCzLpn7+m2pD8ZKHlKarYhy6XjEoCYGcN95qansQeA3fNdki+SaJZGTMQIOoL3W/Z89rxv+tokubNajlvk/vm+LFpF2XnUKZHI0I+QrI7Dw0OZTqdzUkpsM7mZTyfy5OPGyw1tK7AFSvmB/Ks8w8YwbUYbe6/3QEKv0vugfxWPnMLJun+d/kI/WLdizpNjMbAIKrhMF4OuwadBALqqs+RfInwUvuNi+fBd+wjogfogAFVRmffO02q01mZZ0HHdgXIzdz0QQLPezIQygX6llxNKKgOFARYCC49CqhoHIUTlss/Vx2phlYwjw8j1CAlfAiwQiJpiy7o1VHnsG5FISkoJu7Q/2YmmaV+i0ei7v38L2CBguSi5AAAAAElFTkSuQmCC); + background-repeat: no-repeat; + background-position: 0 .15em; + margin-left: -2em; + padding-left: 1.5em; +} + +code { + font-family: Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box; + padding: 0px 3px; + display: inline-block; + color: #52595d; + border: 1px solid #ccc; + background-color: #f9f9f9; +} diff --git a/autoload/vimwiki/tbl.vim b/autoload/vimwiki/tbl.vim @@ -2,7 +2,7 @@ " Vimwiki autoload plugin file " Desc: Tables " | Easily | manageable | text | tables | ! | -" |--------+------------+-------+--------+---------| +" |--------|------------|-------|--------|---------| " | Have | fun! | Drink | tea | Period. | " " Author: Maxim Kim <habamax@gmail.com> @@ -16,6 +16,8 @@ let g:loaded_vimwiki_tbl_auto = 1 "}}} let s:textwidth = &tw +let s:rxSep = g:vimwiki_rxTableSep + " Misc functions {{{ function! s:wide_len(str) "{{{ @@ -40,21 +42,37 @@ function! s:wide_len(str) "{{{ return ret endfunction "}}} +function! s:cell_splitter() "{{{ + return '\s*'.s:rxSep.'\s*' +endfunction "}}} + +function! s:sep_splitter() "{{{ + return '-'.s:rxSep.'-' +endfunction "}}} + function! s:is_table(line) "{{{ - return a:line =~ '^\s*\%(|[^|]\+\)\+|\s*$' || s:is_separator(a:line) + return s:is_separator(a:line) || (a:line !~ s:rxSep.s:rxSep && a:line =~ '^\s*'.s:rxSep.'.\+'.s:rxSep.'\s*$') endfunction "}}} function! s:is_separator(line) "{{{ - return a:line =~ '^\s*[|+]\s*--[-|+]\+' + return a:line =~ '^\s*'.s:rxSep.'\(--\+'.s:rxSep.'\)\+\s*$' +endfunction "}}} + +function! s:is_separator_tail(line) "{{{ + return a:line =~ '^\{-1}\%(\s*\|-*\)\%('.s:rxSep.'-\+\)\+'.s:rxSep.'\s*$' endfunction "}}} function! s:is_last_column(lnum, cnum) "{{{ - return strpart(getline(a:lnum), a:cnum - 1) =~ '^[^|]*|\s*$' + let line = strpart(getline(a:lnum), a:cnum - 1) + "echomsg "DEBUG is_last_column> ".(line =~ s:rxSep.'\s*$' && line !~ s:rxSep.'.*'.s:rxSep.'\s*$') + return line =~ s:rxSep.'\s*$' && line !~ s:rxSep.'.*'.s:rxSep.'\s*$' + endfunction "}}} function! s:is_first_column(lnum, cnum) "{{{ let line = strpart(getline(a:lnum), 0, a:cnum - 1) - return line =~ '^\s*|[^|]*$' || line =~ '^\s*$' + "echomsg "DEBUG is_first_column> ".(line =~ '^\s*'.s:rxSep && line !~ '^\s*'.s:rxSep.'.*'.s:rxSep) + return line =~ '^\s*$' || (line =~ '^\s*'.s:rxSep && line !~ '^\s*'.s:rxSep.'.*'.s:rxSep) endfunction "}}} function! s:count_separators_up(lnum) "{{{ @@ -82,11 +100,10 @@ function! s:count_separators_down(lnum) "{{{ endfunction "}}} function! s:create_empty_row(cols) "{{{ - let first_cell = "| |" - let cell = " |" - let row = first_cell + let row = s:rxSep + let cell = " ".s:rxSep - for c in range(a:cols - 1) + for c in range(a:cols) let row .= cell endfor @@ -94,36 +111,71 @@ function! s:create_empty_row(cols) "{{{ endfunction "}}} function! s:create_row_sep(cols) "{{{ - let first_cell = "|---+" - let cell = "---+" - let last_cell = "---|" - - if a:cols < 2 - return "|---|" - endif + let row = s:rxSep + let cell = "---".s:rxSep - let row = first_cell - - for c in range(a:cols - 2) + for c in range(a:cols) let row .= cell endfor - let row .= last_cell - return row endfunction "}}} -function! s:get_values(line) "{{{ - return split(a:line, '\s*|\s*', 1)[1:-2] +function! vimwiki#tbl#get_cells(line) "{{{ + let result = [] + let cell = '' + let quote = '' + let state = 'NONE' + + " 'Simple' FSM + for idx in range(strlen(a:line)) + " The only way I know Vim can do Unicode... + let ch = a:line[idx] + if state == 'NONE' + if ch == '|' + let state = 'CELL' + endif + elseif state == 'CELL' + if ch == '[' || ch == '{' + let state = 'BEFORE_QUOTE_START' + let quote = ch + elseif ch == '|' + call add(result, vimwiki#u#trim(cell)) + let cell = "" + else + let cell .= ch + endif + elseif state == 'BEFORE_QUOTE_START' + if ch == '[' || ch == '{' + let state = 'QUOTE' + let quote .= ch + else + let state = 'CELL' + let cell .= quote.ch + let quote = '' + endif + elseif state == 'QUOTE' + if ch == ']' || ch == '}' + let state = 'BEFORE_QUOTE_END' + endif + let quote .= ch + elseif state == 'BEFORE_QUOTE_END' + if ch == ']' || ch == '}' + let state = 'CELL' + endif + let cell .= quote.ch + let quote = '' + endif + endfor + + if cell.quote != '' + call add(result, vimwiki#u#trim(cell.quote, '|')) + endif + return result 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 + return len(vimwiki#tbl#get_cells(getline(a:lnum))) endfunction "}}} function! s:get_indent(lnum) "{{{ @@ -155,7 +207,7 @@ function! s:get_rows(lnum) "{{{ let lower_rows = [] let lnum = a:lnum - 1 - while lnum > 1 + while lnum >= 1 let line = getline(lnum) if s:is_table(line) call add(upper_rows, [lnum, line]) @@ -186,7 +238,7 @@ function! s:get_cell_max_lens(lnum) "{{{ if s:is_separator(row) continue endif - let cells = s:get_values(row) + let cells = vimwiki#tbl#get_cells(row) for idx in range(len(cells)) let value = cells[idx] if has_key(max_lens, idx) @@ -219,17 +271,13 @@ function! s:cur_column() "{{{ if !s:is_table(line) return -1 endif - if s:is_separator(line) - let sep = '[+|]' - else - let sep = '|' - endif + " TODO: do we need conditional: if s:is_separator(line) let curs_pos = col('.') - let mpos = match(line, '|', 0) + let mpos = match(line, s:rxSep, 0) let col = -1 while mpos < curs_pos && mpos != -1 - let mpos = match(line, sep, mpos+1) + let mpos = match(line, s:rxSep, mpos+1) if mpos != -1 let col += 1 endif @@ -253,8 +301,8 @@ function! s:fmt_cell(cell, max_len) "{{{ endfunction "}}} function! s:fmt_row(line, max_lens, col1, col2) "{{{ - let new_line = '|' - let cells = s:get_values(a:line) + let new_line = s:rxSep + let cells = vimwiki#tbl#get_cells(a:line) for idx in range(len(cells)) if idx == a:col1 let idx = a:col2 @@ -262,12 +310,12 @@ function! s:fmt_row(line, max_lens, col1, col2) "{{{ let idx = a:col1 endif let value = cells[idx] - let new_line .= s:fmt_cell(value, a:max_lens[idx]).'|' + let new_line .= s:fmt_cell(value, a:max_lens[idx]).s:rxSep endfor let idx = len(cells) while idx < len(a:max_lens) - let new_line .= s:fmt_cell('', a:max_lens[idx]).'|' + let new_line .= s:fmt_cell('', a:max_lens[idx]).s:rxSep let idx += 1 endwhile return new_line @@ -282,17 +330,16 @@ function! s:fmt_cell_sep(max_len) "{{{ endfunction "}}} function! s:fmt_sep(max_lens, col1, col2) "{{{ - let sep = '|' + let new_line = s:rxSep 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]).'+' + let new_line .= s:fmt_cell_sep(a:max_lens[idx]).s:rxSep endfor - let sep = substitute(sep, '+$', '|', '') - return sep + return new_line endfunction "}}} "}}} @@ -300,41 +347,94 @@ endfunction "}}} 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>" + let cmd .= "\<ESC>0" if a:goto_first - let cmd .= "\<ESC>0:call search('|', 'c', line('.'))\<CR>la" + let cmd .= ":call search('\\(".s:rxSep."\\)\\zs', 'c', line('.'))\<CR>" else - let cmd .= "0".(col('.')-1)."lT|a" + let cmd .= (col('.')-1)."l" + let cmd .= ":call search('\\(".s:rxSep."\\)\\zs', 'bc', line('.'))\<CR>" endif + let cmd .= "a" + return cmd endfunction "}}} function! s:kbd_goto_next_row() "{{{ - let cmd = "\<ESC>jt|T|a" + let cmd = "\<ESC>j" + let cmd .= ":call search('.\\(".s:rxSep."\\)', 'c', line('.'))\<CR>" + let cmd .= ":call search('\\(".s:rxSep."\\)\\zs', 'bc', line('.'))\<CR>" + let cmd .= "a" return cmd endfunction "}}} function! s:kbd_goto_prev_row() "{{{ - let cmd = "\<ESC>jt|T|a" + let cmd = "\<ESC>k" + let cmd .= ":call search('.\\(".s:rxSep."\\)', 'c', line('.'))\<CR>" + let cmd .= ":call search('\\(".s:rxSep."\\)\\zs', 'bc', line('.'))\<CR>" + let cmd .= "a" return cmd endfunction "}}} -function! s:kbd_goto_next_col(last) "{{{ - if a:last +" Used in s:kbd_goto_next_col +function! vimwiki#tbl#goto_next_col() "{{{ + let curcol = virtcol('.') + let lnum = line('.') + let newcol = s:get_indent(lnum) + let max_lens = s:get_cell_max_lens(lnum) + for cell_len in values(max_lens) + if newcol >= curcol-1 + break + endif + let newcol += cell_len + 3 " +3 == 2 spaces + 1 separator |<space>...<space> + endfor + let newcol += 2 " +2 == 1 separator + 1 space |<space + call vimwiki#u#cursor(lnum, newcol) +endfunction "}}} + +function! s:kbd_goto_next_col(jumpdown) "{{{ + let cmd = "\<ESC>" + if a:jumpdown let seps = s:count_separators_down(line('.')) - let cmd = "\<ESC>".seps."j0:call search('|', 'c', line('.'))\<CR>la" - else - let cmd = "\<ESC>:call search('|', 'c', line('.'))\<CR>la" + let cmd .= seps."j0" endif + let cmd .= ":call vimwiki#tbl#goto_next_col()\<CR>a" return cmd endfunction "}}} -function! s:kbd_goto_prev_col(first) "{{{ - if a:first +" Used in s:kbd_goto_prev_col +function! vimwiki#tbl#goto_prev_col() "{{{ + let curcol = virtcol('.') + let lnum = line('.') + let newcol = s:get_indent(lnum) + let max_lens = s:get_cell_max_lens(lnum) + let prev_cell_len = 0 + echom string(max_lens) + for cell_len in values(max_lens) + let delta = cell_len + 3 " +3 == 2 spaces + 1 separator |<space>...<space> + if newcol + delta > curcol-1 + let newcol -= (prev_cell_len + 3) " +3 == 2 spaces + 1 separator |<space>...<space> + break + elseif newcol + delta == curcol-1 + break + endif + let prev_cell_len = cell_len + let newcol += delta + endfor + let newcol += 2 " +2 == 1 separator + 1 space |<space + call vimwiki#u#cursor(lnum, newcol) +endfunction "}}} + +function! s:kbd_goto_prev_col(jumpup) "{{{ + let cmd = "\<ESC>" + if a:jumpup let seps = s:count_separators_up(line('.')) - let cmd = "\<ESC>".seps."k$:call search('|', 'b', line('.'))\<CR>la" - else - let cmd = "\<ESC>2F|la" + let cmd .= seps."k" + let cmd .= "$" endif + let cmd .= ":call vimwiki#tbl#goto_prev_col()\<CR>a" + " let cmd .= ":call search('\\(".s:rxSep."\\)\\zs', 'b', line('.'))\<CR>" + " let cmd .= "a" + "echomsg "DEBUG kbd_goto_prev_col> ".cmd return cmd endfunction "}}} @@ -348,7 +448,7 @@ function! vimwiki#tbl#kbd_cr() "{{{ endif if s:is_separator(getline(lnum+1)) || !s:is_table(getline(lnum+1)) - let cols = len(s:get_values(getline(lnum))) + let cols = len(vimwiki#tbl#get_cells(getline(lnum))) return s:kbd_create_new_row(cols, 0) else return s:kbd_goto_next_row() @@ -362,11 +462,13 @@ function! vimwiki#tbl#kbd_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))) + let is_sep = s:is_separator_tail(getline(lnum)) + "echomsg "DEBUG kbd_tab> last=".last.", is_sep=".is_sep + if (is_sep || last) && !s:is_table(getline(lnum+1)) + let cols = len(vimwiki#tbl#get_cells(getline(lnum))) return s:kbd_create_new_row(cols, 1) endif - return s:kbd_goto_next_col(last) + return s:kbd_goto_next_col(is_sep || last) endfunction "}}} function! vimwiki#tbl#kbd_shift_tab() "{{{ @@ -376,10 +478,12 @@ function! vimwiki#tbl#kbd_shift_tab() "{{{ endif let first = s:is_first_column(lnum, col('.')) - if first && !s:is_table(getline(lnum-1)) + let is_sep = s:is_separator_tail(getline(lnum)) + "echomsg "DEBUG kbd_tab> ".first + if (is_sep || first) && !s:is_table(getline(lnum-1)) return "" endif - return s:kbd_goto_prev_col(first) + return s:kbd_goto_prev_col(is_sep || first) endfunction "}}} function! vimwiki#tbl#format(lnum, ...) "{{{ @@ -462,7 +566,12 @@ 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('.')) + + "echomsg "DEBUG move_column_left: " + + let line = getline('.') + + if !s:is_table(line) return endif @@ -474,16 +583,28 @@ function! vimwiki#tbl#move_column_left() "{{{ 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 + + let sep = '\('.s:rxSep.'\).\zs' + let mpos = -1 + let col = -1 + while col < cur_col-1 + let mpos = match(line, sep, mpos+1) + if mpos != -1 + let col += 1 + else + break + endif + endwhile + endif + endfunction "}}} function! vimwiki#tbl#move_column_right() "{{{ - if !s:is_table(getline('.')) + + let line = getline('.') + + if !s:is_table(line) return endif @@ -495,16 +616,41 @@ function! vimwiki#tbl#move_column_right() "{{{ 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 + + let sep = '\('.s:rxSep.'\).\zs' + let mpos = -1 + let col = -1 + while col < cur_col+1 + let mpos = match(line, sep, mpos+1) + if mpos != -1 + let col += 1 + else + break + endif + endwhile + endif + endfunction "}}} function! vimwiki#tbl#get_rows(lnum) "{{{ return s:get_rows(a:lnum) endfunction "}}} +function! vimwiki#tbl#is_table(line) "{{{ + return s:is_table(a:line) +endfunction "}}} + +function! vimwiki#tbl#is_separator(line) "{{{ + return s:is_separator(a:line) +endfunction "}}} + +function! vimwiki#tbl#cell_splitter() "{{{ + return s:cell_splitter() +endfunction "}}} + +function! vimwiki#tbl#sep_splitter() "{{{ + return s:sep_splitter() +endfunction "}}} + "}}} diff --git a/autoload/vimwiki/u.vim b/autoload/vimwiki/u.vim @@ -0,0 +1,77 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" Vimwiki autoload plugin file +" Utility functions +" Author: Maxim Kim <habamax@gmail.com> +" Home: http://code.google.com/p/vimwiki/ + +function! vimwiki#u#trim(string, ...) "{{{ + let chars = '' + if a:0 > 0 + let chars = a:1 + endif + let res = substitute(a:string, '^[[:space:]'.chars.']\+', '', '') + let res = substitute(res, '[[:space:]'.chars.']\+$', '', '') + return res +endfunction "}}} + + +" Builtin cursor doesn't work right with unicode characters. +function! vimwiki#u#cursor(lnum, cnum) "{{{ + exe a:lnum + exe 'normal! 0'.a:cnum.'|' +endfunction "}}} + +function! vimwiki#u#is_windows() "{{{ + return has("win32") || has("win64") || has("win95") || has("win16") +endfunction "}}} + +function! vimwiki#u#chomp_slash(str) "{{{ + return substitute(a:str, '[/\\]\+$', '', '') +endfunction "}}} + +function! vimwiki#u#time(starttime) "{{{ + " measure the elapsed time and cut away miliseconds and smaller + return matchstr(reltimestr(reltime(a:starttime)),'\d\+\(\.\d\d\)\=') +endfunction "}}} + +function! vimwiki#u#path_norm(path) "{{{ + " /-slashes + let path = substitute(a:path, '\', '/', 'g') + " treat multiple consecutive slashes as one path separator + let path = substitute(path, '/\+', '/', 'g') + " ensure that we are not fooled by a symbolic link + return resolve(path) +endfunction "}}} + +function! vimwiki#u#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 +endfunction " }}} + +function! vimwiki#u#count_first_sym(line) "{{{ + let first_sym = matchstr(a:line, '\S') + return len(matchstr(a:line, first_sym.'\+')) +endfunction "}}} + +" return longest common path prefix of 2 given paths. +" '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki' +function! vimwiki#u#path_common_pfx(path1, path2) "{{{ + let p1 = split(a:path1, '[/\\]', 1) + let p2 = split(a:path2, '[/\\]', 1) + + let idx = 0 + let minlen = min([len(p1), len(p2)]) + while (idx < minlen) && (p1[idx] ==? p2[idx]) + let idx = idx + 1 + endwhile + if idx == 0 + return '' + else + return join(p1[: idx-1], '/') + endif +endfunction "}}} + diff --git a/doc/vimwiki.txt b/doc/vimwiki.txt @@ -9,7 +9,7 @@ |___| |___| |_| |_||__| |__||___| |___| |_||___| ~ - Version: 1.2 + Version: 2.0 'stu' ============================================================================== CONTENTS *vimwiki-contents* @@ -31,15 +31,23 @@ CONTENTS *vimwiki-contents* 5.5. Lists |vimwiki-syntax-lists| 5.6. Tables |vimwiki-syntax-tables| 5.7. Preformatted text |vimwiki-syntax-preformatted| - 5.8. Blockquotes |vimwiki-syntax-blockquotes| - 5.9. Comments |vimwiki-syntax-comments| - 5.10. Horizontal line |vimwiki-syntax-hr| + 5.8. Mathematical formulae |vimwiki-syntax-math| + 5.9. Blockquotes |vimwiki-syntax-blockquotes| + 5.10. Comments |vimwiki-syntax-comments| + 5.11. Horizontal line |vimwiki-syntax-hr| + 5.12. Schemes |vimwiki-syntax-schemes| + 5.13. Transclusions |vimwiki-syntax-transclude| + 5.14. Thumbnails |vimwiki-syntax-thumbnails| 6. Folding/Outline |vimwiki-folding| 7. Placeholders |vimwiki-placeholders| 8. Todo lists |vimwiki-todo-lists| 9. Tables |vimwiki-tables| 10. Diary |vimwiki-diary| 11. Options |vimwiki-options| + 11.1. Registered Wiki |vimwiki-register-wiki| + 11.2. Temporary Wiki |vimwiki-temporary-wiki| + 11.3. Per-Wiki Options |vimwiki-local-options| + 11.4. Global Options |viwmiki-global-options| 12. Help |vimwiki-help| 13. Developers |vimwiki-developers| 14. Changelog |vimwiki-changelog| @@ -58,26 +66,29 @@ With vimwiki you can: - write documentation. To do a quick start press <Leader>ww (this is usually \ww) to go to your index -wiki file. By default it is located in: > +wiki file. By default it is located in: > ~/vimwiki/index.wiki Feed it with the following example: = My knowledge base = - * MyUrgentTasks -- things to be done _yesterday_!!! - * ProjectGutenberg -- good books are power. - * ScratchPad -- various temporary stuff. + * Tasks -- things to be done _yesterday_!!! + * Project Gutenberg -- good books are power. + * Scratchpad -- various temporary stuff. +Place your cursor on 'Tasks' and press Enter to create a link. Once pressed, +'Tasks' will become '[[Tasks]]' -- a vimwiki link. Press Enter again to +open it. Edit the file, save it, and then press Backspace to jump back to your +index. -Notice that ProjectGutenberg, MyUrgentTasks and ScratchPad are highlighted as -errors. These are links in CamelCase form that do not exists yet. (CamelCase -form -- capitalized word connected with other capitalized words) - -Place cursor on ProjectGutenberg and press <Enter>. Now you are in -ProjectGutenberg. Edit and save it, then press Backspace to return to previous -wiki file. You should see the difference now -- ProjectGutenberg is -highlighted as a link. +A vimwiki link can be constructed from more than one word. Just visually +select the words to be linked and press Enter. Try it with 'Project +Gutenberg'. The result should look something like: += My knowledge base = + * [[Tasks]] -- things to be done _yesterday_!!! + * [[Project Gutenberg]] -- good books are power. + * Scratchpad -- various temporary stuff. ============================================================================== 2. Prerequisites *vimwiki-prerequisites* @@ -107,7 +118,7 @@ There are global and local mappings in vimwiki. 3<Leader>ww opens the third wiki from |g:vimwiki_list|. etc. To remap: > - :map <Leader>w <Plug>VimwikiIndex + :nmap <Leader>w <Plug>VimwikiIndex < See also |:VimwikiIndex| @@ -121,7 +132,7 @@ See also |:VimwikiIndex| 3<Leader>wt tabopens the third wiki from |g:vimwiki_list|. etc. To remap: > - :map <Leader>t <Plug>VimwikiTabIndex + :nmap <Leader>t <Plug>VimwikiTabIndex < See also |:VimwikiTabIndex| @@ -129,7 +140,7 @@ See also |:VimwikiTabIndex| <Leader>ws or <Plug>VimwikiUISelect List and select available wikies. To remap: > - :map <Leader>wq <Plug>VimwikiUISelect + :nmap <Leader>wq <Plug>VimwikiUISelect < See also |:VimwikiUISelect| @@ -144,7 +155,7 @@ See also |:VimwikiUISelect| |g:vimwiki_list|. etc. To remap: > - :map <Leader>i <Plug>VimwikiDiaryIndex + :nmap <Leader>i <Plug>VimwikiDiaryIndex See also |:VimwikiDiaryIndex| @@ -162,7 +173,7 @@ See also |:VimwikiDiaryIndex| from |g:vimwiki_list|. etc. To remap: > - :map <Leader>d <Plug>VimwikiMakeDiaryNote + :nmap <Leader>d <Plug>VimwikiMakeDiaryNote < See also |:VimwikiMakeDiaryNote| @@ -180,7 +191,7 @@ See also |:VimwikiMakeDiaryNote| wiki from |g:vimwiki_list|. etc. To remap: > - :map <Leader>dt <Plug>VimwikiTabMakeDiaryNote + :nmap <Leader>dt <Plug>VimwikiTabMakeDiaryNote < See also |:VimwikiTabMakeDiaryNote| @@ -193,27 +204,35 @@ NORMAL MODE *vimwiki-local-mappings* <Leader>wh Convert current wiki page to HTML. Maps to |:Vimwiki2HTML| To remap: > - :map <Leader>wc <Plug>Vimwiki2HTML + :nmap <Leader>wc <Plug>Vimwiki2HTML < *vimwiki_<Leader>whh* <Leader>whh Convert current wiki page to HTML and open it in webbrowser. Maps to |:Vimwiki2HTML| To remap: > - :map <Leader>wcc <Plug>Vimwiki2HTMLBrowse + :nmap <Leader>wcc <Plug>Vimwiki2HTMLBrowse +< + *vimwiki_<Leader>w<Leader>i* +<Leader>w<Leader>i Update diary section (delete old, insert new) + Only works from the diary index. + Maps to |:VimwikiDiaryGenerateLinks| + To remap: > + :nmap <Leader>wcr <Plug>VimwikiDiaryGenerateLinks < *vimwiki_<CR>* -<CR> Follow wiki link (create target wiki page if needed). +<CR> Follow/create wiki link (create target wiki page if + needed). Maps to |:VimwikiFollowLink|. To remap: > - :map <Leader>wf <Plug>VimwikiFollowLink + :nmap <Leader>wf <Plug>VimwikiFollowLink < *vimwiki_<S-CR>* <S-CR> Split and follow (create target wiki page if needed). May not work in some terminals. Remapping could help. Maps to |:VimwikiSplitLink|. To remap: > - :map <Leader>we <Plug>VimwikiSplitLink + :nmap <Leader>we <Plug>VimwikiSplitLink < *vimwiki_<C-CR>* <C-CR> Vertical split and follow (create target wiki page if @@ -221,7 +240,7 @@ NORMAL MODE *vimwiki-local-mappings* May not work in some terminals. Remapping could help. Maps to |:VimwikiVSplitLink|. To remap: > - :map <Leader>wq <Plug>VimwikiVSplitLink + :nmap <Leader>wq <Plug>VimwikiVSplitLink < *vimwiki_<C-S-CR>* *vimwiki_<D-CR>* <C-S-CR>, <D-CR> Follow wiki link (create target wiki page if needed), @@ -229,53 +248,87 @@ NORMAL MODE *vimwiki-local-mappings* May not work in some terminals. Remapping could help. Maps to |:VimwikiTabnewLink|. To remap: > - :map <Leader>wt <Plug>VimwikiTabnewLink + :nmap <Leader>wt <Plug>VimwikiTabnewLink < *vimwiki_<Backspace>* <Backspace> Go back to previous wiki page. Maps to |:VimwikiGoBackLink|. To remap: > - :map <Leader>wb <Plug>VimwikiGoBackLink + :nmap <Leader>wb <Plug>VimwikiGoBackLink < *vimwiki_<Tab>* <Tab> Find next link on the current page. Maps to |:VimwikiNextLink|. To remap: > - :map <Leader>wn <Plug>VimwikiNextLink + :nmap <Leader>wn <Plug>VimwikiNextLink < *vimwiki_<S-Tab>* <S-Tab> Find previous link on the current page. Maps to |:VimwikiPrevLink|. To remap: > - :map <Leader>wp <Plug>VimwikiPrevLink + :nmap <Leader>wp <Plug>VimwikiPrevLink < *vimwiki_<Leader>wd* <Leader>wd Delete wiki page you are in. Maps to |:VimwikiDeleteLink|. To remap: > - :map <Leader>dd <Plug>VimwikiDeleteLink + :nmap <Leader>dd <Plug>VimwikiDeleteLink < *vimwiki_<Leader>wr* <Leader>wr Rename wiki page you are in. Maps to |:VimwikiRenameLink|. To remap: > - :map <Leader>rr <Plug>VimwikiRenameLink + :nmap <Leader>rr <Plug>VimwikiRenameLink < *vimwiki_<C-Space>* <C-Space> Toggle list item on/off (checked/unchecked) Maps to |:VimwikiToggleListItem|. To remap: > - :map <leader>tt <Plug>VimwikiToggleListItem + :nmap <leader>tt <Plug>VimwikiToggleListItem < See |vimwiki-todo-lists|. *vimwiki_=* = Add header level. Create if needed. There is nothing to indent with '==' command in vimwiki, so it should be ok to use '=' here. - + To remap: > + :nmap == <Plug>VimwikiAddHeaderLevel +< *vimwiki_-* - Remove header level. + To remap: > + :nmap -- <Plug>VimwikiRemoveHeaderLevel +< + *vimwiki_+* ++ Create and/or decorate links. Depending on the + context, this command will: convert words into + Wikilinks; convert raw URLs into Wikilinks; and add + placeholder text to Wiki- or Weblinks that are missing + descriptions. Can be activated in normal mode with + the cursor over a word or link, or in visual mode with + the selected text . + + *vimwiki_glm* +glm Increase the indent of a single-line list item. + + *vimwiki_gll* +gll Decrease the indent of a single-line list item. + + *vimwiki_glstar* *vimwiki_gl8* +gl* or gl8 Switch or insert a "*" symbol. Only available in + supported syntaxes. + + *vimwiki_gl#* *vimwiki_gl3* +gl# or gl3 Switch or insert a "#" symbol. Only available in + supported syntaxes. + + *vimwiki_gl-* +gl- Switch or insert a "-" symbol. Only available in + supported syntaxes. + *vimwiki_gl1* +gl1 Switch or insert a "1." symbol. Only available in + supported syntaxes. *vimwiki_gqq* *vimwiki_gww* gqq Format table. If you made some changes to a table @@ -286,13 +339,13 @@ gww will reformat it. <A-Left> Move current table column to the left. See |:VimwikiTableMoveColumnLeft| To remap: > - :map <Leader>wtl <Plug>VimwikiTableMoveColumnLeft + :nmap <Leader>wtl <Plug>VimwikiTableMoveColumnLeft < *vimwiki_<A-Right>* <A-Right> Move current table column to the right. See |:VimwikiTableMoveColumnRight| To remap: > - :map <Leader>wtr <Plug>VimwikiTableMoveColumnRight + :nmap <Leader>wtr <Plug>VimwikiTableMoveColumnRight < *vimwiki_<C-Up>* <C-Up> Open the previous day's diary link if available. @@ -326,9 +379,7 @@ INSERT MODE *vimwiki-table-mappings* *vimwiki_i_<Tab>* <Tab> Go to the next table cell, create a new row if on the last cell. - - *vimwiki_i_<S-CR>* -<S-CR> Insert <br /> and a newline. +See |g:vimwiki_table_mappings| to turn them off. ------------------------------------------------------------------------------ @@ -408,18 +459,26 @@ ic An inner column in a table. Rename the wiki page that you are in. *:Vimwiki2HTML* - Convert current wiki page to HTML. + Convert current wiki page to HTML using vimwiki's own converter or a + user-supplied script (see |vimwiki-option-custom_wiki2html|). *:Vimwiki2HTMLBrowse* - Convert current wiki page to HTML and open in in webbrowser. + Convert current wiki page to HTML and open it in webbrowser. *:VimwikiAll2HTML* Convert all wiki pages to HTML. + Default css file (style.css) is created if there is no one. *:VimwikiToggleListItem* Toggle list item on/off (checked/unchecked) See |vimwiki-todo-lists|. +*:VimwikiListChangeLevel* CMD + Change the nesting level, or symbol, for a single-line list item. + CMD may be ">>" or "<<" to change the indentation of the item, or + one of the syntax-specific bullets: "*", "#", "1.", "-". + See |vimwiki-todo-lists|. + *:VimwikiSearch* /pattern/ *:VWS* /pattern/ Search for /pattern/ in all files of current wiki. @@ -427,6 +486,14 @@ ic An inner column in a table. To display next match use |:lnext| command. To display previous match use |:lprevious| command. +*:VimwikiBacklinks* +*:VWB* + Search for wikilinks to the [[current wiki page]] + in all files of current wiki. + To display all matches use |:lopen| command. + To display next match use |:lnext| command. + To display previous match use |:lprevious| command. + *:VimwikiTable* Create a table with 5 cols and 2 rows. @@ -443,7 +510,7 @@ ic An inner column in a table. Example: > | head1 | head2 | head3 | head4 | head5 | - |--------+--------+--------+--------+--------| + |--------|--------|--------|--------|--------| | value1 | value2 | value3 | value4 | value5 | @@ -451,14 +518,14 @@ ic An inner column in a table. :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 | < @@ -468,6 +535,9 @@ ic An inner column in a table. *:VimwikiGenerateLinks* Insert all available links into current buffer. +*:VimwikiDiaryGenerateLinks* + Delete old, insert new diary section into diary index file. + *:VimwikiDiaryNextDay* Open next day diary link if available. Mapped to <C-Down>. @@ -480,14 +550,24 @@ ic An inner column in a table. ============================================================================== 5. Wiki syntax *vimwiki-syntax* + 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. +syntax and vimwiki's default syntax is not an exception here. + +Vimwiki has evolved its own syntax that closely resembles google's wiki +markup. This syntax is described in detail below. -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|. +Vimwiki also supports alternative syntaxes, like Markdown and MediaWiki, to +varying degrees; see |vimwiki-option-syntax|. Static elements like headers, +quotations, and lists are customized in syntax/vimwiki_xxx.vim, where xxx +stands for the chosen syntax. +Interactive elements such as links and vimwiki commands are supported by +definitions and routines in syntax/vimwiki_xxx_custom.vim and +autoload/vimwiki/xxx_base.vim. Currently, only Markdown includes this level +of support. + +Vimwiki2HTML is currently functional only for the default syntax. ------------------------------------------------------------------------------ 5.1. Typefaces *vimwiki-syntax-typefaces* @@ -505,81 +585,48 @@ text should be decorated: > ------------------------------------------------------------------------------ 5.2. Links *vimwiki-syntax-links* -Internal links~ -WikiWords: > - CapitalizedWordsConnected - -You can prevent linking of WikiWords by adding an exclamation mark in front of -them: > - !CapitalizedWordsConnected - -Or disable it completely with |g:vimwiki_camel_case|. +Wikilinks~ Link with spaces in it: > [[This is a link]] or: > [[This is a link source|Description of the link]] -or: > - [[This is a link source][Description of the link]] - -External links~ -Plain link: > - http://code.google.com/p/vimwiki - mailto:habamax@gmail.com - ftp://vim.org - -Link with description: > - [http://habamax.ru/blog habamax home page] - [mailto:habamax@gmail.com Drop a line to Maxim Kim] - -Images and image links~ -An image link is a link to a file with a jpg, png or gif extension. -Plain image link: > - http://someaddr.com/picture.jpg -in HTML: > - <img src="http://someaddr.com/picture.jpg" /> -Link to a local image: > - [[images/pabloymoira.jpg]] -in HTML: > - <img src="images/pabloymoira.jpg" /> -Path to image (ie. images/pabloymoira.jpg) is relative to -|vimwiki-option-path_html|. +Links to directories (ending with a "/") are also supported: > + [[/home/somebody/|Home Directory]] -Double bracketed link to an image: > - [[http://habamax.ru/blog/wp-content/uploads/2009/01/2740254sm.jpg]] -in HTML: > - <img src="http://habamax.ru/ ... /.jpg" /> +Use |g:vimwiki_dir_link| to control the behaviour when opening directories. -Double bracketed link to an image with description text: > - [[http://habamax.ru/blog/wp-content/uploads/2009/01/2740254sm.jpg|dance]] -in HTML: > - <a href="http://habamax.ru/ ... /.jpg">dance</a> +Raw URLs~ -Double bracketed link to an image with alternate text: > - [[http://habamax.ru/blog/wp-content/uploads/2009/01/2740254sm.jpg|dance|]] -in HTML: > - <img src="http://habamax.ru/ ... /.jpg" alt="dance"/> +Raw URLs are also supported: > + http://code.google.com/p/vimwiki + mailto:habamax@gmail.com + ftp://vim.org -Double bracketed link to an image with alternate text and some style: > - [[http://helloworld.com/blabla.jpg|cool stuff|width:150px; height: 120px;]] -in HTML: > - <img src="http://helloworld.com/ ... /.jpg" alt="cool stuff" - style="width:150px; height:120px"/> -Double bracketed link to an image without alternate text and some style: > - [[http://helloworld.com/blabla.jpg||width:150px; height: 120px;]] -in HTML: > - <img src="http://helloworld.com/ ... /.jpg" alt="" - style="width:150px; height:120px"/> +Markdown Links~ -Thumbnail link: > - [http://someaddr.com/bigpicture.jpg http://someaddr.com/thumbnail.jpg] -or > - [[http://someaddr.com/bigpicture.jpg|http://someaddr.com/thumbnail.jpg]] -in HTML: > - <a href="http://someaddr.com/ ... /.jpg"> - <img src="http://../thumbnail.jpg /></a> +These links are only available for Markdown syntax. See +http://daringfireball.net/projects/markdown/syntax#link. + +Inline links: > + [Looks like this](URL) + +Image links: > + ![Looks like this](URL) + +The URL can be anything recognized by vimwiki as a raw URL. + + +Reference-style links: > + a) [Link Name][Id] + b) [Id][], using the "implicit link name" shortcut + +Vimwiki treats reference style links just like default "Wikilinks". In the +current implementation: the Id field must be a valid wiki page name, +reference style links must always include *two* consecutive pairs of +[-brackets, and entries can not use "[" or "]". ------------------------------------------------------------------------------ @@ -702,7 +749,7 @@ typeface formatting and links. For example: > | Year | Temperature (low) | Temperature (high) | - |------+-------------------+--------------------| + |------|-------------------|--------------------| | 1900 | -10 | 25 | | 1910 | -15 | 30 | | 1920 | -10 | 32 | @@ -712,7 +759,7 @@ For example: > In HTML the following part > | Year | Temperature (low) | Temperature (high) | - |------+-------------------+--------------------| + |------|-------------------|--------------------| > is higlighted as a table header. @@ -730,9 +777,6 @@ For example: > See |vimwiki-tables| for more details on how to manage tables. -Note: You can not use [[link|description]] type of links in tables. Use -[[link][description]] instead. - ------------------------------------------------------------------------------ 5.7. Preformatted text *vimwiki-syntax-preformatted* @@ -772,7 +816,72 @@ See |vimwiki-option-nested_syntaxes| ------------------------------------------------------------------------------ -5.8. Blockquotes *vimwiki-syntax-blockquotes* +5.8. Mathematical formulae *vimwiki-syntax-math* + +Mathematical formulae are highlighted, and can be rendered in HTML using the +powerful open source display engine MathJax (http://www.mathjax.org/). + +There are three supported syntaxes, which are inline, block display and +block environment. + +Inline math is for short formulae within text. It is enclosed by single +dollar signs, e.g.: + $ \sum_i a_i^2 = 1 $ + +Block display creates a centered formula with some spacing before and after +it. It must start with a line including only {{$, then an arbitrary number +of mathematical text are allowed, and it must end with a line including only +}}$. +E.g.: + {{$ + \sum_i a_i^2 + = + 1 + }}$ + +Note: no matter how many lines are used in the text file, the HTML will +compress it to *one* line only. + +Block environment is similar to block display, but is able to use specific +LaTeX environments, such as 'align'. The syntax is the same as for block +display, except for the first line which is {{$%environment%. +E.g.: + {{$%align% + \sum_i a_i^2 &= 1 + 1 \\ + &= 2. + }}$ + +Similar compression rules for the HTML page hold (as MathJax interprets the +LaTeX code). + +Note: the highlighting in VIM is automatic. For the rendering in HTML, you +have two *alternative* options: + +1. using the MathJax server for rendering (needs an internet connection). +Add to your HTML template the following line: + +<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> + +2. installing MathJax locally (faster, no internet required). Choose a +folder on your hard drive and save MathJax in it. Then add to your HTML +template the following line: + +<script type="text/javascript" src="<mathjax_folder>/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> + +where <mathjax_folder> is the folder on your HD, as a relative path to the +template folder. For instance, a sensible folder structure could be: + +- wiki + - text + - html + - templates + - mathjax + +In this case, <mathjax_folder> would be "../mathjax" (without quotes). + + +------------------------------------------------------------------------------ +5.9. Blockquotes *vimwiki-syntax-blockquotes* Text started with 4 or more spaces is a blockquote. @@ -782,7 +891,7 @@ Text started with 4 or more spaces is a blockquote. ------------------------------------------------------------------------------ -5.9. Comments *vimwiki-syntax-comments* +5.10. Comments *vimwiki-syntax-comments* Text line started with %% is a comment. E.g.: > @@ -791,12 +900,128 @@ E.g.: > ------------------------------------------------------------------------------ -5.10. Horizontal line *vimwiki-syntax-hr* +5.11. Horizontal line *vimwiki-syntax-hr* 4 or more dashes at the start of the line is a 'horizontal line' (<hr />): > ---- < +------------------------------------------------------------------------------ +5.12. Schemes *vimwiki-syntax-schemes* + +In addition to standard web schemes (e.g. `http:`, `https:`, `ftp:`, etc.) a +number of special schemes are supported: "wiki#:", "local:", "diary:", +"file:", and schemeless. + +While "wiki:#", "diary" and schemeless links are automatically opened in Vi, +all other links are opened with the system command. To customize this +behavior, see |VimwikiLinkHandler|. + +Interwiki:~ + +If you maintain more than one wiki, you can create interwiki links between them +by adding a numbered prefix "wiki#:" in front of a link: > + [[wiki#:This is a link]] +or: > + [[wiki#:This is a link source|Description of the link]] + +The number "#", in the range 0..N-1, identifies the destination wiki in +|g:vimwiki_list|. + +Diary:~ + +The diary scheme is used to concisely link to diary entries: > + [[diary:2012-03-05]] + +This scheme precludes explicit inclusion of |vimwiki-option-diary_rel_path|, +and is most useful on subwiki pages to avoid links such as: > + [[../../diary/2012-03-05]] + +Local:~ + +A local resource that is not a wiki page may be specified with a path relative +to the current page: > + [[local:../assets/data.csv|data (CSV)]] + +When followed or converted to HTML, extensions of local-scheme links are not +modified. + +File:~ + +The file scheme allows you to directly link to arbitray resources using +absolute paths and extensions: > + [[file:///home/somebody/a/b/c/music.mp3]] + +Schemeless:~ + +Schemeless URLs, which are the default, are treated internally as "wiki#:" +URLs in all respects except when converted to Html. + +Schemeless links convert to plain relative path URLs, nearly verbatim: > + relpath/wikipage.html + +The "wiki#:", "local:", and "diary:" schemes use absolute paths as URLs: > + file:///abs_path_to_html#/relpath/wikipage.html + +When |vimwiki-option-maxhi| equals 1, a distinct highlighting style is used to +identify schemeless links whose targets are not found. All other links appear +as regular links even if the files to which they refer do not exist. + + +------------------------------------------------------------------------------ +5.13. Transclusions *vimwiki-syntax-transclude* + +Transclusion (Wiki-Include) Links~ + +Links that use "{{" and "}}" delimiters signify content that is to be +included into the Html output, rather than referenced via hyperlink. + +Wiki-include URLs may use any of the supported schemes, may be absolute or +relative, and need not end with an extension. + +The primary purpose for wiki-include links is to include images. + +Transclude from a local URL: > + {{local:../../images/vimwiki_logo.png}} +or from a universal URL: > + {{http://vimwiki.googlecode.com/hg/images/vimwiki_logo.png}} + +Transclude image with alternate text: > + {{http://vimwiki.googlecode.com/hg/images/vimwiki_logo.png|Vimwiki}} +in HTML: > + <img src="http://vimwiki.googlecode.com/hg/images/vimwiki_logo.png" + alt="Vimwiki"/> + +Transclude image with alternate text and some style: > + {{http://.../vimwiki_logo.png|cool stuff|style="width:150px; height: 120px;"}} +in HTML: > + <img src="http://vimwiki.googlecode.com/hg/images/vimwiki_logo.png" + alt="cool stuff" style="width:150px; height:120px"/> + +Transclude image _without_ alternate text and with css class: > + {{http://.../vimwiki_logo.png||class="center flow blabla"}} +in HTML: > + <img src="http://vimwiki.googlecode.com/hg/images/vimwiki_logo.png" + alt="" class="center flow blabla"/> + +A trial feature allows you to supply your own handler for wiki-include links. +See |VimwikiWikiIncludeHandler|. + + +------------------------------------------------------------------------------ +5.14. Thumbnails *vimwiki-syntax-thumbnails* + +Thumbnail links~ +> +Thumbnail links are constructed like this: > + [[http://someaddr.com/bigpicture.jpg|{{http://someaddr.com/thumbnail.jpg}}]] + +in HTML: > + <a href="http://someaddr.com/ ... /.jpg"> + <img src="http://../thumbnail.jpg /></a> + + + ============================================================================== 6. Folding/Outline *vimwiki-folding* @@ -832,7 +1057,7 @@ Hit |zr| one more time: * [ ] Do stuff 2~ * [ ] Do stuff 3~ -NOTE:If you use default vimwiki syntax, folding on list items will work +NOTE:If you use the default vimwiki syntax, folding on list items will work properly only if all of them are indented using current |shiftwidth|. For MediaWiki, * or # should be in the first column. @@ -944,7 +1169,23 @@ between [ ] depends on the percentage of toggled child items (see also It is possible to toggle several list items using visual mode. - + *vimwiki-list-manipulation* +The indentation and bullet symbols for list items can be manipulated using +several mappings. Examples below demonstrate this behavior for the 'default' +syntax and with |vimwiki-option-list_margin| = 1. > + + Mapping | Input | Output + ---------------------------------------------------- + glm | ^item | ^ - item + glm | ^ item | ^ - item + gll | ^ - item | ^item + glm | ^ # item | ^ item + gl* | ^ item | ^ * item + gl- | ^ item | ^ - item + gl3 | ^ item | ^ # item + +See |vimwiki_gll|, |vimwiki_glm|, |vimwiki_glstar|, |vimwiki_gl8| +|vimwiki_gl#|, |vimwiki_gl3|, |vimwiki_gl-|, |vimwiki_gl1| ============================================================================== 9. Tables *vimwiki-tables* @@ -987,35 +1228,26 @@ To indent table indent the first row. Then format it with 'gqq'. The diary helps you make daily notes. You can easily add information into vimwiki that should be sorted out later. Just hit <Leader>w<Leader>w to create -new daily note with name based on current date. The link to this newly created -file is added to a diary wiki file. +new daily note with name based on current date. -Usage example with default settings: > - Consider today is 2010-01-27. +To generate diary section with all available links one can use +|:VimwikiDiaryGenerateLinks| or <Leader>w<Leader>i . - Hit \w\w . - ~/vimwiki/diary.wiki is created. +Note: it works only for diary index file. - 2 following lines are added to ~/vimwiki/diary/diary.wiki : - = Diary = - | [[2010-01-27]] | +Example of diary section: > + = Diary = - ~/vimwiki/diary/2010-01-27.wiki is created. - You are ready to add your information there. - ------------------------------------------- + == 2011 == - On the next day. - Hit \w\w . + === December === + * [[2011-12-09]] + * [[2011-12-08]] - The first line after = Diary = is changed in ~/vimwiki/diary/diary.wiki : - = Diary = - | [[2010-01-28]] | [[2010-01-27]] | - ~/vimwiki/diary/2010-01-28.wiki is created. - You are ready to add your information there. -> +See |g:vimwiki_diary_months| if you would like to rename months. + -By default there are 4 links on the line. All links are sorted by their dates. Calendar integration *vimwiki-calendar* ------------------------------------------------------------------------------ @@ -1028,43 +1260,51 @@ Get it from http://www.vim.org/scripts/script.php?script_id=52 See |g:vimwiki_use_calendar| option to turn it off/on. + ============================================================================== 11. Options *vimwiki-options* -There are global and per-wiki (local) options available to tune vimwiki. -All global options are set using the following pattern: > - let g:option_name=option_value +There are global options and local (per-wiki) options available to tune +vimwiki. + +Global options are configured via global variables. For a complete list of +them, see |viwmiki-global-options|. + +Local options for multiple independent wikis are stored in a single global +variable |g:vimwiki_list|. The per-wiki options can be registered in advance, +as described in |vimwiki-register-wiki|, or may be registered on the fly as +described in |vimwiki-temporary-wiki|. For a list of per-wiki options, see +|vimwiki-local-options|. -All per-wiki options are dictionaries (see |Dictionary|) in a list of wikies. -See |g:vimwiki_list| option for more details. ------------------------------------------------------------------------------ -*g:vimwiki_list* *vimwiki-multiple-wikies* +11.1 Registered Wiki *g:vimwiki_list* *vimwiki-register-wiki* -Each item in g:vimwiki_list is a |Dictionary| that holds all customization -available for a wiki represented by that item. It is in the form: > +One or more wikis can be registered using the |g:vimwiki_list| variable. + +Each item in |g:vimwiki_list| is a |Dictionary| that holds all customizations +available for a distinct wiki. The options dictionary has the form: > {'option1': 'value1', 'option2: 'value2', ...} -Consider the following example: > +Consider the following: > let g:vimwiki_list = [{'path': '~/my_site/', 'path_html': '~/public_html/'}] -It gives us one wiki located at ~/my_site/ that could be htmlized to +This defines one wiki located at ~/my_site/ that could be htmlized to ~/public_html/ -The next example: > +Another example: > let g:vimwiki_list = [{'path': '~/my_site/', 'path_html': '~/public_html/'}, \ {'path': '~/my_docs/', 'ext': '.mdox'}] -gives us 2 wikies, the first wiki as in the previous example, and the second -one located in ~/my_docs/, with files that have the .mdox extension. + +defines two wikis: the first as before, and the second one located in +~/my_docs/, with files that have the .mdox extension. An empty |Dictionary| in g:vimwiki_list is the wiki with default options: > let g:vimwiki_list = [{}, \ {'path': '~/my_docs/', 'ext': '.mdox'}] -< - -You can also create wikis as separate |Dictionary|s. > - +For clarity, in your .vimrc file you can define wiki options using separate +|Dictionary| variables and subsequently compose them into |g:vimwiki_list|. > let wiki_1 = {} let wiki_1.path = '~/my_docs/' let wiki_1.html_template = '~/public_html/template.tpl' @@ -1075,10 +1315,38 @@ You can also create wikis as separate |Dictionary|s. > let wiki_2.index = 'main' let g:vimwiki_list = [wiki_1, wiki_2] - < -PER WIKI OPTIONS *viwmiki-local-options* + +------------------------------------------------------------------------------ +11.2 Temporary Wiki *vimwiki-temporary-wiki* + + +The creation of temporary wikis allows you to open files that would not +normally be recognized by vimwiki. + +If a file with a registered wiki extension (see |vimwiki-register-extension|) +is opened in a directory that: 1) is not listed in |g:vimwiki_list|, and 2) is +not a subdirectory of any such directory, then a temporary wiki may be created +and appended to the list of configured wikis in |g:vimwiki_list|. + +In addition to vimwiki's editing functionality, the temporary wiki enables: 1) +wiki-linking to other files in the same subtree, 2) highlighting of existing +wiki pages when |vimwiki-option-maxhi| is activated, and 3) html generation to +|vimwiki-option-path_html|. + +Temporary wikis are configured using default |vimwiki-local-options|, except +for the path, extension, and syntax options. The path and extension are set +using the file's location and extension. The syntax is set to vimwiki's +default unless another syntax is registered via |vimwiki-register-extension|. + +Use |g:vimwiki_global_ext| to turn off creation of temporary wikis. + +NOTE: Vimwiki assumes that the locations of distinct wikis do not overlap. + + +------------------------------------------------------------------------------ +11.3 Per-Wiki Options *vimwiki-local-options* *vimwiki-option-path* @@ -1094,19 +1362,20 @@ Wiki files location: > *vimwiki-option-path_html* ------------------------------------------------------------------------------ Key Default value~ -path_html ~/vimwiki_html/ +path_html '' Description~ Location of HTML files converted from wiki files: > let g:vimwiki_list = [{'path': '~/my_site/', - \ 'path_html': '~/my_site_html/'}] + \ 'path_html': '~/html_site/'}] -If you omit this option, the value of path_html would be set to the value of -path with the trailing slash ('/') removed and '_html' added; i.e. for: > +If path_html is an empty string, the location is derived from +|vimwiki-option-path| by adding '_html'; i.e. for: > let g:vimwiki_list = [{'path': '~/okidoki/'}] path_html will be set to '~/okidoki_html/'. + *vimwiki-option-auto_export* ------------------------------------------------------------------------------ Key Default value Values~ @@ -1145,15 +1414,16 @@ Extension of wiki files: > *vimwiki-option-syntax* ------------------------------------------------------------------------------ Key Default value Values~ -syntax default default, media +syntax default default, markdown, or media Description~ -Wiki syntax. -You can use different markup languages (currently default vimwiki and -MediaWiki), but only vimwiki's default markup will be converted to HTML at the -moment. -To use MediaWiki's wiki markup: > - let g:vimwiki_list = [{'path': '~/my_site/', 'syntax': 'media'}] +Wiki syntax. You can use different markup languages (currently: vimwiki's +default, Markdown, and MediaWiki), but only vimwiki's default markup will be +converted to HTML at the moment. + +To use Markdown's wiki markup: > + let g:vimwiki_list = [{'path': '~/my_site/', + \ 'syntax': 'markdown', 'ext': '.md'}] < *vimwiki-option-template_path* @@ -1246,12 +1516,12 @@ or even > *vimwiki-option-maxhi* ------------------------------------------------------------------------------ Key Default value Values~ -maxhi 1 0, 1 +maxhi 0 0, 1 Description~ -Non-existent wiki links highlighting can be quite slow. If you don't want it, -set maxhi to 0: > - let g:vimwiki_list = [{'path': '~/my_site/', 'maxhi': 0}] +Non-existent wiki links highlighting can be quite slow. If you still want it, +set maxhi to 1: > + let g:vimwiki_list = [{'path': '~/my_site/', 'maxhi': 1}] This disables filesystem checks for wiki links. @@ -1327,26 +1597,64 @@ Name of the header in |vimwiki-option-diary_index| where links to dated wiki-files are located. -*vimwiki-option-diary_link_count* +*vimwiki-option-diary_sort* +------------------------------------------------------------------------------ +Key Default value Values~ +diary_sort desc desc, asc + +Description~ +Sort links in a diary index page. + + +*vimwiki-option-custom_wiki2html* +------------------------------------------------------------------------------ +Key Default value~ +custom_wiki2html '' + +Description~ +The full path to an user-provided script that converts a wiki page to HTML. +Vimwiki calls the provided |vimwiki-option-custom_wiki2html| script from the +command-line, using '!' invocation. + +The following arguments, in this order, are passed to the +|vimwiki-option-custom_wiki2html| script: + +1. force : [0/1] overwrite an existing file +2. syntax : the syntax chosen for this wiki +3. extension : the file extension for this wiki +4. output_dir : the full path of the output directory, i.e. 'path_html' +5. input_file : the full path of the wiki page +6. css_file : the full path of the css file for this wiki + +For an example and further instructions, refer to the following script: + + $VIMHOME/autoload/vimwiki/customwiki2html.sh + +To use the internal wiki2html converter, use an empty string (the default). + + +*vimwiki-option-list_margin* ------------------------------------------------------------------------------ Key Default value~ -diary_link_count 4 +list_margin -1 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]] | +Width of left-hand margin for lists. When negative, the current |shiftwidth| +is used. This affects the behavior of the list manipulation commands +|VimwikiListChangeLevel| and local mappings |vimwiki_gll|, |vimwiki_glm|, +|vimwiki_glstar|, |vimwiki_gl8|, |vimwiki_gl#|, |vimwiki_gl3|, +|vimwiki_gl-| and |vimwiki_gl1|. + +------------------------------------------------------------------------------ +11.4 Global Options *viwmiki-global-options* + +Global options are configured using the following pattern: > -GLOBAL OPTIONS *viwmiki-global-options* + let g:option_name = option_value -Use: > - let g:option_name=option_value -to set them. ----------------------------------------------------------------------------- *g:vimwiki_hl_headers* @@ -1376,35 +1684,43 @@ Default: 0 ------------------------------------------------------------------------------ -*g:vimwiki_global_ext* *vimwiki-temporary-wiki* +*g:vimwiki_global_ext* -If a file with a registered wiki extension is opened in a directory that is -not listed in |g:vimwiki_list| then: +Control the creation of |vimwiki-temporary-wiki|s. + +If a file with a registered extension (see |vimwiki-register-extension|) is +opened in a directory that is: 1) not listed in |g:vimwiki_list|, and 2) not a +subdirectory of any such directory, then: Value Description~ -1 make a temporary wiki in that dir. +1 make temporary wiki and append it to |g:vimwiki_list|. 0 don't make temporary wiki in that dir. -A temporary wiki is created to scan the filesystem for available links to -highlight. - -Consider your wiki extension is .txt then you can > +If your preferred wiki extension is .txt then you can > let g:vimwiki_global_ext = 0 -to make it local to vimwiki paths listed in g:vimwiki_list. So other text -files wouldn't be treated as wiki pages. +to restrict vimwiki's operation to only those paths listed in g:vimwiki_list. +Other text files wouldn't be treated as wiki pages. Default: 1 ------------------------------------------------------------------------------ -*g:vimwiki_upper* *g:vimwiki_lower* +*g:vimwiki_ext2syntax* *vimwiki-register-extension* -This affects WikiWord detection. -By default WikiWord detection uses English and Russian letters. -You can set up your own: > - let g:vimwiki_upper = "A-Z\u0410-\u042f" - let g:vimwiki_lower = "a-z\u0430-\u044f" +A many-to-one map between file extensions and syntaxes whose purpose is to +register the extensions with vimwiki. + +E.g.: > + let g:vimwiki_ext2syntax = {'.md': 'markdown', + \ '.mkd': 'markdown', + \ '.wiki': 'media'} +An extension that is registered with vimwiki can trigger creation of a +|vimwiki-temporary-wiki| with the associated syntax. File extensions used in +|g:vimwiki_list| are automatically registered with vimwiki using the default +syntax. + +Default: {'.md': 'markdown'} ------------------------------------------------------------------------------ *g:vimwiki_auto_checkbox* @@ -1440,31 +1756,6 @@ Default: 'Vimwiki' ------------------------------------------------------------------------------ -*g:vimwiki_stripsym* - -Change strip symbol -- in Windows you cannot use /*?<>:" in filenames, so -vimwiki replaces them with a neutral symbol (_ is default): > - let g:vimwiki_stripsym = '_' - -You can change it to a <space> for example: > - let g:vimwiki_stripsym = ' ' - - ------------------------------------------------------------------------------- -*g:vimwiki_badsyms* - -If you do not like spaces in filenames (as some vimwiki users do), you can set -up bad symbols to include spaces, so that they are also converted: -|g:vimwiki_stripsym|: > - let g:vimwiki_badsyms = ' ' - -Now files for all [[links with spaces]] would be created like -'links_with_spaces'. - -This option is a complement one to |g:vimwiki_stripsym|. - - ------------------------------------------------------------------------------- *g:vimwiki_listsyms* String of 5 symbols for list items with checkboxes. @@ -1512,30 +1803,6 @@ Default: 0 ------------------------------------------------------------------------------ -*g:vimwiki_fold_trailing_empty_lines* - -Fold or do not fold empty lines between folded headers. - -Value Description~ -0 Fold only one empty line. Leave the rest of the empty lines. -1 Fold in all empty lines. - -Default: 0 - - ------------------------------------------------------------------------------- -*g:vimwiki_camel_case* - -If you do not want WikiWord to be a link, this setting is just for you. - -Value Description~ -0 Do not make links from CamelCased words. -1 Make links from CamelCased words. - -Default: 1 - - ------------------------------------------------------------------------------- *g:vimwiki_list_ignore_newline* This is HTML related. @@ -1562,34 +1829,110 @@ Default: 1 ------------------------------------------------------------------------------ -*g:vimwiki_browsers* *VimwikiWeblinkHandler* +*VimwikiLinkHandler* + +A customizable link handler, |VimwikiLinkHandler|, can be defined to override +Vimwiki's opening of links. Each recognized link, whether it is a wikilink, +wiki-include link or a weblink, is first passed to |VimwikiLinkHandler| to see +if it can be handled. The return value 1/0 indicates success. + +If the link is not handled successfully, the behaviour of Vimwiki depends on +the scheme. Wiki:, diary: or schemeless links are opened in Vim. All others, +including local: and file: schemes, are opened with a system default handler; +i.e. Linux (!xdg-open), Mac (!open), and Windows (!start). + +You can redefine |VimwikiLinkHandler| function to do something else: > + + function! VimwikiLinkHandler(link) + try + let browser = 'C:\Program Files\Firefox\firefox.exe' + execute '!start "'.browser.'" ' . a:link + return 1 + catch + echo "This can happen for a variety of reasons ..." + endtry + return 0 + endfunction -You can open external weblinks in a webbrowser. Webbrowsers are listed in -|g:vimwiki_browsers|. +A second example handles two new schemes, 'vlocal:' and 'vfile:', which behave +similar to 'local:' and 'file:' schemes, but are always opened with Vim: > + + function! VimwikiLinkHandler(link) "{{{ Use Vim to open links with the + " 'vlocal:' or 'vfile:' schemes. E.g.: + " 1) [[vfile:///~/Code/PythonProject/abc123.py]], and + " 2) [[vlocal:./|Wiki Home]] + let link = a:link + if link =~ "vlocal:" || link =~ "vfile:" + let link = link[1:] + else + return 0 + endif + let [idx, scheme, path, subdir, lnk, ext, url] = + \ vimwiki#base#resolve_scheme(link, 0) + if g:vimwiki_debug + echom 'LinkHandler: idx='.idx.', scheme=[v]'.scheme.', path='.path. + \ ', subdir='.subdir.', lnk='.lnk.', ext='.ext.', url='.url + endif + if url == '' + echom 'Vimwiki Error: Unable to resolve link!' + return 0 + else + call vimwiki#base#edit_file('tabnew', url, [], 0) + return 1 + endif + endfunction " }}} -For win32 it is: chrome, opera, firefox and explorer. -For other OSes it is: opera, firefox and konqueror. -The first available browser from the list is used to open the weblink. -If you have opera and firefox and want weblinks to be opened in the latter, -just specify: > - let g:vimwiki_browsers=['C:\Program Files\Firefox\firefox.exe'] +----------------------------------------------------------------------------- +*VimwikiWikiIncludeHandler*~ -or redefine VimwikiWeblinkHandler function: > - function! VimwikiWeblinkHandler(weblink) - let browser = 'C:\Program Files\Firefox\firefox.exe' - execute '!start "'.browser.'" ' . a:weblink - endfunction +Vimwiki includes the contents of a wiki-include URL as an image by default. + +A trial feature allows you to supply your own handler for wiki-include links. +The handler should return the empty string when it does not recognize or +cannot otherwise convert the link. A customized handler might look like this: > + + " Convert {{URL|#|ID}} -> URL#ID + function! VimwikiWikiIncludeHandler(value) "{{{ + let str = a:value + + " complete URL + let url_0 = matchstr(str, g:vimwiki_rxWikiInclMatchUrl) + " URL parts + let [scheme, path, subdir, lnk, ext, url] = + \ vimwiki#base#resolve_scheme(url_0, VimwikiGet('ext')) + let arg1 = matchstr(str, VimwikiWikiInclMatchArg(1)) + let arg2 = matchstr(str, VimwikiWikiInclMatchArg(2)) + + if arg1 =~ '#' + return url.'#'.arg2 + endif + + " Return the empty string when unable to process link + return '' + endfunction "}}} +< + +------------------------------------------------------------------------------ +*g:vimwiki_table_mappings* + +Enable/disable table mappings for INSERT mode. + +Value Description~ +0 Disable table mappings. +1 Enable table mappings. + +Default: 1 ------------------------------------------------------------------------------ *g:vimwiki_table_auto_fmt* -Turn on/off table auto-formatting. +Enable/disable table auto formatting after leaving INSERT mode. Value Description~ -0 Do not auto-format tables. -1 Auto-format tables. +0 Disable table auto formatting. +1 Enable table auto formatting. Default: 1 @@ -1691,7 +2034,7 @@ Value Description~ etc. With - let g:vimwiki_html_header_numbering = '.' + let g:vimwiki_html_header_numbering_sym = '.' headers would look like: > 1. Header1 1.1. Header2 @@ -1707,20 +2050,6 @@ Default: '' (empty) ------------------------------------------------------------------------------ -*g:vimwiki_file_exts* - -Comma-separated list of file extensions. - -Consider you have the following link: [[my_script.php][my script]]. -If there is a 'php' extension in g:vimwiki_file_exts, this link would be -htmlized to <a href="my_script.php">my script</a>. -Otherwise it would be <a href="my_script.php.html">my script</a> (note .html) - - -Default: 'pdf,txt,doc,rtf,xls,php,zip,rar,7z,html,gz' - - ------------------------------------------------------------------------------- *g:vimwiki_valid_html_tags* Comma-separated list of HTML tags that can be used in vimwiki. @@ -1752,7 +2081,67 @@ a new tab or window, it would be set to default value. Vimwiki sets |conceallevel| to g:vimwiki_conceallevel everytime vimwiki buffer is entered. -Default: 3 +Default: 2 + + +------------------------------------------------------------------------------ +*g:vimwiki_url_mingain* + +The minimum number of characters that should be gained by concealing URLs. If +the length of the concealed part of the URL would be less than +|g:vimwiki_url_mingain|, the URL is not concealed at all. +The conceal feature works only with vim >= 7.3. + +Default: 12 + + +------------------------------------------------------------------------------ +*g:vimwiki_url_maxsave* + +The maximum number of characters that is retained at the end after concealing +URLs. At most there will be |g:vimwiki_url_maxsave| characters left at the end of the URL. +However, it could be less when one of /,#,? can be found at the end. +In that case the URL will be concealed right before the last occurrence of one +of these characters. +The conceal feature works only with vim >= 7.3. Beware: when using the default +'wrap' option, the effect is not always pleasing. + +Default: 15 + + +------------------------------------------------------------------------------ +*g:vimwiki_debug* + +Controls verbosity of debugging output, for example, the diagnostic +information about HTML conversion. + +Value Description~ +0 Do not show debug messages. +1 Show debug messages. + +Default: 0 + +------------------------------------------------------------------------------ +*g:vimwiki_diary_months* + +It is a |Dictionary| with the numbers of months and corresponding names. Diary +uses it. + +Redefine it in your .vimrc to get localized months in your diary: +let g:vimwiki_diary_months = { + \ 1: 'Январь', 2: 'Февраль', 3: 'Март', + \ 4: 'Апрель', 5: 'Май', 6: 'Июнь', + \ 7: 'Июль', 8: 'Август', 9: 'Сентябрь', + \ 10: 'Октябрь', 11: 'Ноябрь', 12: 'Декабрь' + \ } + +Default: +let g:vimwiki_diary_months = { + \ 1: 'January', 2: 'February', 3: 'March', + \ 4: 'April', 5: 'May', 6: 'June', + \ 7: 'July', 8: 'August', 9: 'September', + \ 10: 'October', 11: 'November', 12: 'December' + \ } ============================================================================== @@ -1769,6 +2158,8 @@ Issues can be filed at http://code.google.com/p/vimwiki/issues . 13. Developers *vimwiki-developers* - Maxim Kim <habamax@gmail.com> as original author. + - Stuart Andrews + - Tomas Pospichal - See the http://code.google.com/p/vimwiki/people/list for the others. Web: http://code.google.com/p/vimwiki/ @@ -1779,6 +2170,42 @@ Vim plugins: http://www.vim.org/scripts/script.php?script_id=2226 ============================================================================== 14. Changelog *vimwiki-changelog* +2.0 'stu'~ + +This release is partly incompatible with previous. + +Summary ~ + + * Quick page-link creation. + * Redesign of link syntaxes (!) + * No more CamelCase links. Check the ways to convert them + https://groups.google.com/forum/?fromgroups#!topic/vimwiki/NdS9OBG2dys + * No more [[link][desc]] links. + * No more [http://link description] links. + * No more plain image links. Use transclusions. + * No more image links identified by extension. Use transclusions. + * Interwiki links. See |vimwiki-syntax-schemes|. + * Link schemes. See |vimwiki-syntax-schemes|. + * Transclusions. See |vimwiki-syntax-transclude|. + * Normalize link command. See |vimwiki_+|. + * Improved diary organization and generation. See |vimwiki-diary|. + * List manipulation. See |vimwiki-list-manipulation|. + * Markdown support. + * Mathjax support. See |vimwiki-syntax-math|. + * Improved handling of special characters and punctuation in filenames and + urls. + * Back links command: list links referring to the current page. + * Highlighting nonexisted links are off by default. + * Table syntax change. Row separator uses | instead of +. + * Fold multilined list items. + * Custom wiki to HTML converters. See |vimwiki-option-custom_wiki2html|. + * Conceal long weblinks. See |g:vimwiki_url_mingain|. + * Option to disable table mappings. See |g:vimwiki_table_mappings|. + +For detailed information see issues list on +http://code.google.com/p/vimwiki/issues/list + + 1.2~ * Issue 70: Table spanning cell support. * Issue 72: Do not convert again for unchanged file. |:VimwikiAll2HTML| @@ -1842,468 +2269,11 @@ Vim plugins: http://www.vim.org/scripts/script.php?script_id=2226 * NEW: Added <Leader>wh mapping to call |:Vimwiki2HTML| -1.1.1~ - * FIX: Issue 122: Dot character in vimwiki's directory path isn't escaped. - * FIX: Issue 123: Where is Vimwiki2HTML and other commands? Sometimes - filetype is not set up to vimwiki. - * FIX: Issue 124: Highlight group not found: Normal - -1.1~ - * NEW: Issue 57: Make it possible to have pre block inside list item. - * NEW: Issue 82: Add quick goto command. See |:VimwikiGoto|. - * NEW: Issue 83: Quick switch in diary. See |:VimwikiDiaryNextDay| and - |:VimwikiDiaryPrevDay| commands. - * FIX: Issue 84: Vimwiki rename removed the WikiWord display name. - * FIX: Issue 85: Errors if you have '~' subdirectory in a wiki directory. - * FIX: Issue 86: Existed links '[[WikiLink1|Alias1]] | [[WikiLink2]]' are - highlighted as a single link. - * FIX: Issue 88: Underline text. See |g:vimwiki_valid_html_tags|. - * FIX: Issue 92: Wikies in a subdir could be renamed to an empty file. - * FIX: Issue 93: Use alias name in HTML title. See |vimwiki-title|. - * FIX: Issue 94: Relative links to PHP files are broken. See - |g:vimwiki_file_exts| for details. - * FIX: Issue 96: Closing bracket at the end of weblink shouldn't be a part - of that link. - * FIX: Issue 97: Error opening weblink in a browser if it has # inside. - * FIX: Issue 99: Vim is not responding while opening arbitrary wiki file. - * FIX: Issue 100: Additional content on diary index page could be - corrupted. - * NEW: Issue 101: Customized HTML tags. See |g:vimwiki_valid_html_tags| - * NEW: Issue 102: Conceal feature usage. See |g:vimwiki_conceallevel|. - * FIX: Issue 103: Always highlight links to non-wiki files as existed. - * FIX: Issue 104: vimwiki#nested_syntax needs 'keepend' to avoid contained - language syntax eat needed '}}}'. - * FIX: Issue 105: <i_CR> on a todo list item with [ ] doesn't create new - todo list item. - * FIX: Issue 106: With MediaWiki syntax <C-Space> on a child todo list - item produce errors. - * FIX: Issue 107: With MediaWiki syntax <C-Space> on a list item creates - todo list item without space between * and [ ]. - * FIX: Issue 110: Syntax highlighting doesn't work for indented codeblock. - * FIX: Issue 115: Nested Perl syntax highlighting differs from regular - one. - * MISC: Many vimwiki commands were renamed from Vimwiki.*Word to - Vimwiki.*Link. VimwikiGoHome is renamed to VimwikiIndex, - VimwikiTabGoHome to VimwikiTabIndex. - * MISC: vimwiki-option-gohome is removed. - -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 - 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 |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 |vimwiki-option-auto_export|. - - -0.9.8~ - * NEW: Rename |g:vimwiki_fold_empty_lines| to - |g:vimwiki_fold_trailing_empty_lines|. - * NEW: One can use '-' along with '*' to start unordered list item. - * NEW: List items could be started from the first column. - As a result some limitations appeared: - - a space after *, - or # for a list item is mandatory. - - |g:vimwiki_fold_trailing_empty_lines| if set to 0 folds one trailing - empty line. - * NEW: Folding is off by default. Use |g:vimwiki_folding| to enable it. - * NEW: Speed up vimwiki's folding a bit. Should lag a bit less in a long - todo lists. - * NEW: Centered headers. Start header with at least one space to make it - HTML centered. - * NEW: Change in default CSS: header's colors. - * NEW: Vimwiki is aware of |GetLatestVimScripts| now. - * FIX: Use <del> tag instead of custom <span class="strike"> in HTML. - * FIX: There are no text styling in htmlized quoted text. - * FIX: set default value of g:vimwiki_fold_lists to 0 as written in this - help. - * FIX: Issue 33: Folded list items have wrong indentation when 'tabs' are - used. - * FIX: Issue 34: vimwiki#subdir got wrong dir when VimwikiGet('path') is a - symbolic link. Thanks lilydjwg for the patch. - * FIX: Issue 28: todo-list auto-indent enhancement. New item should always - be unchecked. - * Issue 36: Change the name of the Search command to VimwikiSearch as it - conflicts with MultipleSearch. Alias :VWS is also available. - * NEW: You can generate 'Table of contents' of your wiki page. See - |vimwiki-toc| for details. - -0.9.701~ - * FIX: Issue 30: Highlighting doesn't work for checked list item. - -0.9.7~ - * NEW: Default checkbox symbols are changed to [ ], [.], [o], [O], [X]. - You can change them using |g:vimwiki_listsyms| variable. - * NEW: Color group names are renamed from wikiBold, wikiItalic, etc to - VimwikiBold, VimwikiItalic, etc. - * NEW: Open external links in a browser. There are default browsers - defined in |g:vimwiki_browsers| list. You can also redefine - |VimwikiWeblinkHandler| function to open weblinks in other programs. - * NEW: Issue 25: Toggle the states of multiple TODO list items at a time - (in VISUAL and in VISUAL LINE modes) - * NEW: Issue 26: Highlight code snippets in vimwiki's pre. See - |vimwiki-option-nested_syntaxes|. Thanks kriomant. - * NEW: Issue 27: Automatic garbage deletion from HTML directory. - * NEW: Save all open vimwiki buffers before export to HTML. - * NEW: Issue 29: Custom :Search command. - * NEW: Header text objects are now expandable in VISUAL mode. Tap 'vah' to - select a header. Tap again 'ah' to expand selection further. Thanks Andy - Wokula. - * FIX: Folding settings are reset to vim defaults in a new tab (think of - \wt) so you cannot hide things in folds. - * FIX: https links in form of [https://hello.world.com] are not exported - into HTML. Thanks Saurabh Sarpal for the patch. - -0.9.6~ - * NEW: You can have multiline list items. See |vimwiki-syntax-lists|. - * NEW: You can ignore newlines in multiline list items when do export to - HTML. See |g:vimwiki_list_ignore_newline| option. - * NEW: Different checkbox symbols [.], [:], [o] are added. See - |vimwiki-todo-lists|. - * NEW: Now there is no longer syntax of preformatted text that is started - by a whitespace. - * NEW: Blockquotes. See |vimwiki-syntax-blockquote|. - * NEW: Per wiki folding option (vimwiki-option-folding) is removed. Global - |g:vimwiki_folding| and |g:vimwiki_fold_lists| are added. - * NEW: Due to being quite slow folding of list items is off by default. - Use |g:vimwiki_fold_lists| to turn it on. - * NEW: If you want replace some symbols in a wikifilename use - |g:vimwiki_badsyms| option (Andreas Baldeau). - * FIX: Command |:VimwikiToggleListItem| doesn't work for one of the two - wikies opened at the same time with different syntaxes. - * FIX: Command |:VimwikiToggleListItem| do not switch parent checkboxes if - there are non-checkbox list items available. - * FIX: Issue 24: Link error in HTML when write [[one.two.three]]. - * FIX: Rename WikiWord to something with a colon (:) does nasty things. - * FIX: Command |:VimwikiToggleListItem| do not switch right if there are - list items without checkboxes in the list. - -0.9.5~ - * NEW: Added |g:vimwiki_global_ext| to control creation of temporary - wikies in dirs that are not listed in |g:vimwiki_list|. - * NEW: Added |g:vimwiki_hl_headers| to highlight headers with different - predefined colors. - * NEW: Checked [X] items are not highlighted with Comment syntax group by - default. Use |g:vimwiki_hl_cb_checked| to turn it on. - * NEW: Added new syntax for links: [[link address][link description]]. - * NEW: Added <C-@> allias of <C-Space> mapping for *nix systems. - * NEW: Added |g:vimwiki_camel_case|. Set it to 0 if you do not want - CamelCased WikiWords to be linkified. - * FIX: Links with g:vimwiki_stripsym (default '_') [[My_Link|Text]] are - not highlighted when created. - * FIX: indent/vimwiki.vim is obsolete. If you upgrade from previous - versions remove it. It causes wrong list indentation if noexpandtab is - set. - * FIX: If tabs and spaces are used to indent list items HTML export gives - error. Thanks Klaus Ethgen for report. - * FIX: Some HTML export fixes. - -0.9.4~ - * NEW: Links with directories: [[dir1/dir2/Link|Text]]. Thanks Jie Wu. - * NEW: Added %root_path% template variable to get relative root dir of - path_html. See |vimwiki-option-html_header|. - * FIX: Indent is incorrect for vim without "float" compile option. Thanks - Julian Kooij. - * FIX: Convert to HTML doesn't work right with links like [[foo::bar]]. - * FIX: Rename wikiword doesn't work right when rename WikiWord to - [[WikiWord blablabla]]. - * FIX: Renaming of links with description doesn't work. - * FIX: Weblinks with commas are not highlighted. - * MISC: Some changes in default CSS file. - -0.9.3~ - * NEW: g:vimwiki_menu option is a string which is menu path. So one can - use let g:vimwiki_menu = 'Plugin.Vimwiki' to set the menu to the right - place. - * NEW: g:vimwiki_fold_empty_lines -- don't or do fold in empty lines - between headers. See |g:vimwiki_fold_empty_lines| - * FIX: Encoding error when running vimwiki in Windows XP Japanese. - Thanks KarasAya. - -0.9.2c~ - * FIX: Regression: Export HTML link error with [[Link|Text]]. - -0.9.2b~ - * FIX: Installation on Linux doesn't work. (Dos line endings in Vimball - archive file). - * FIX: Clear out FlexWiki ftplugin's setup. Now you don't have to hack - filetype.vim to get rid of unexpected ':setlocal bomb' from FlexWiki's - ftplugin. - * FIX: When write done: it will show another done: in HTML file. - -0.9.2a~ - * FIX: Installation on Linux doesn't work. (Dos line endings in - autoload/vimwiki_lst.vim and indent/vimwiki.vim). - -0.9.2~ - * NEW: Option 'folding' added to turn folding on/off. - * NEW: Header text object. See |vimwiki-text-objects|. - * NEW: Add/remove Header levels with '=' and '-'. See |vimwiki_=|. - * NEW: Vimwiki GUI menu to select available wikies. See |g:vimwiki_menu|. - * NEW: You can specify the name of your CSS file now. See - |vimwiki-option-css_name| - * NEW: You can add styles to image links, see |vimwiki-syntax-links|. - * FIX: History doesn't work after |VimwikiRenameWord|. - * FIX: Some of wikipedia links are not correctly highlighted. Links with - parentheses. - * MISC: Renamed vimwiki_gtd to vimwiki_lst. - -0.9.1~ - * NEW: HTML Table cell text alignment, see |vimwiki-syntax-tables| - * NEW: Wikipage history simplified. Each vimwiki buffer now holds - b:vimwiki_prev_word which is list of [PrevWord, getpos()]. - * NEW: If highlight for groups wikiHeader1..wikiHeader6 exist (defined in - a colorscheme) -- use it. Otherwise use Title highlight for all Headers. - * FIX: Warn only once if 'html_header' or 'html_footer' does not exist. - * FIX: Wrong folding for the text after the last nested list item. - * FIX: Bold and Italic aren't highlighted in tables without spaces - between || and * or _. ||*bold*||_asdf_ || (Thanks Brett Stahlman) - -0.9.0~ - * NEW: You can add classes to 'pre' tag -- |vimwiki-syntax-preformatted|. - This might be useful for coloring some programming code with external js - tools like google syntax highlighter. - * NEW: !WikiPage is not highlighted. It is just a plain word WikiPage in - HTML, without exclamation mark - * NEW: Definition lists, see |vimwiki-syntax-lists|. - * NEW: New implementation of |:VimwikiRenameWord|. CAUTION: It was tested - on 2 computers only, backup your wiki before use it. Email me if it - doesn't work for you. - * FIX: Less than 3 symbols are not highlighted in Bold and Italic. - * FIX: Added vimwiki autocmd group to avoid clashes with user defined - autocmds. - * FIX: Pressing ESC while |:VimwikiUISelect| opens current wiki index - file. Should cancel wiki selection. - -0.8.3~ - * NEW: <C-Space> on a list item creates checkbox. - * FIX: With * in the first column, <CR> shouldn't insert more * (default - syntax). - * FIX: With MediaWiki's ** [ ], <CR> should insert it on the next line. - * FIX: HTML export should use 'fileencoding' instead of 'encoding'. - * FIX: Code cleanup. - -0.8.2~ - * DEL: Removed google syntax file. - * NEW: Default vimwiki syntax is a subset of google's one. Header's has - been changed from !Header to =Header=. It is easier to maintain only 2 - syntaxes. See |vimwiki-syntax-headers|. - * NEW: Multiline paragraphs -- less longlines. - * NEW: Comments. See |vimwiki-syntax-comments|. - * DEL: Removed setlocal textwidth = 0 from ftplugin. - * FIX: New regexps for bold, italic, bolditalic. - * FIX: The last item in List sometimes fold-in incorrectly. - * FIX: Minor tweaks on default CSS. - -0.8.1~ - * NEW: Vimwiki's foldmethod changed from syntax to expr. Foldtext is - changed to be nicer with folded list items. - * NEW: Fold/outline list items. - * NEW: It is possible now to edit wiki files in arbitrary directories - which is not in g:vimwiki_list's paths. New WikiWords are created in the - path of the current WikiWord. - * NEW: User can remap Vimwiki's built in mappings. - * NEW: Added |g:vimwiki_use_mouse|. It is off by default. - * FIX: Removed <C-h> mapping. - -0.8.0~ - * NEW: Multiple wikies support. A lot of options have been changed, see - |vimwiki-options| - * NEW: Auto create directories. - * NEW: Checked list item highlighted as comment. - * FIX: Multiple 'set ft=vimwiki' for each buffer disabled. Vimwiki should - load its buffers a bit faster now. - -0.7.1~ - * NEW: <Plug>VimwikiToggleListItem added to be able to remap <C-Space> to - anything user prefers more. - * FIX: Toggleable list items do not work with MediaWiki markup. - * FIX: Changing g:vimwiki_home_html to path with ~ while vimwiki is - loaded gives errors for HTML export. - * DEL: Command :VimwikiExploreHome. - -0.7.0~ - * NEW: GTD stuff -- toggleable list items. See |vimwiki-todo-lists|. - * FIX: Headers do not fold inner headers. (Thanks Brett Stahlman) - * FIX: Remove last blank lines from preformatted text at the end of file. - * DEL: Removed g:vimwiki_smartCR option. - -0.6.2~ - * NEW: [[link|description]] is available now. - * FIX: Barebone links (ie: http://bla-bla-bla.org/h.pl?id=98) get extra - escaping of ? and friends so they become invalid in HTML. - * FIX: In linux going to [[wiki with whitespaces]] and then pressing BS - to go back to prev wikipage produce error. (Thanks Brendon Bensel for - the fix) - * FIX: Remove setlocal encoding and fileformat from vimwiki ftplugin. - * FIX: Some tweaks on default style.css - -0.6.1~ - * FIX: [blablabla bla] shouldn't be converted to a link. - * FIX: Remove extra annoing empty strings from PRE tag made from - whitespaces in HTML export. - * FIX: Moved functions related to HTML converting to new autoload module - to increase a bit vimwiki startup time. - -0.6~ - * NEW: Header and footer templates. See|g:vimwiki_html_header| and - |g:vimwiki_html_footer|. - * FIX: |:Vimwiki2HTML| does not recognize ~ as part of a valid path. - -0.5.3~ - * FIX: Fixed |:VimwikiRenameWord|. Error when g:vimwiki_home had - whitespaces in path. - * FIX: |:VimwikiSplitWord| and |:VimwikiVSplitWord| didn't work. - -0.5.2~ - * NEW: Added |:VimwikiGoHome|, |:VimwikiTabGoHome| and - |:VimwikiExploreHome| commands. - * NEW: Added <Leader>wt mapping to open vimwiki index file in a new tab. - * NEW: Added g:vimwiki_gohome option that controls how|:VimwikiGoHome| - works when current buffer is changed. (Thanks Timur Zaripov) - * FIX: Fixed |:VimwikiRenameWord|. Very bad behaviour when autochdir - isn't set up. - * FIX: Fixed commands :Wiki2HTML and :WikiAll2HTML to be available only - for vimwiki buffers. - * FIX: Renamed :Wiki2HTML and :WikiAll2HTML to |:Vimwiki2HTML| and - |:VimwikiAll2HTML| commands. - * FIX: Help file corrections. - -0.5.1~ - * NEW: This help is created. - * NEW: Now you can fold headers. - * NEW: <Plug>VimwikiGoHome and <Plug>VimwikiExploreHome were added. - * FIX: Bug with {{{HelloWikiWord}}} export to HTML is fixed. - * DEL: Sync option removed from: Syntax highlighting for preformatted - text {{{ }}}. - -0.5~ - * NEW: vimwiki default markup to HTML conversion improved. - * NEW: Added basic GoogleWiki and MediaWiki markup languages. - * NEW: Chinese [[complex wiki words]]. - -0.4~ - * NEW: vimwiki=>HTML converter in plain Vim language. - * NEW: Plugin autoload. - -0.3.4~ - * FIX: Backup files (.wiki~) caused a bunch of errors while opening wiki - files. - -0.3.3~ - * FIX: [[wiki word with dots at the end...]] didn't work. - * NEW: Added error handling for delete wiki word function. - * NEW: Added keybindings o and O for list items when g:vimwiki_smartCR=1. - * NEW: Added keybinding <Leader>wh to visit wiki home directory. - -0.3.2~ - * FIX: Renaming -- error if complex wiki word contains %. - * FIX: Syntax highlighting for preformatted text {{{ }}}. Sync option - added. - * FIX: smartCR bug fix. - -0.3.1~ - * FIX: Renaming -- [[hello world?]] to [[hello? world]] links are not - updated. - * FIX: Buffers menu is a bit awkward after renaming. - * NEW: Use mouse to follow links. Left double-click to follow WikiWord, - Rightclick then Leftclick to go back. - -0.3~ - * NEW: Highlight non-existent WikiWords. - * NEW: Delete current WikiWord (<Leader>wd). - * NEW: g:vimwiki_smartCR=2 => use Vim comments (see :h comments :h - formatoptions) feature to deal with list items. (thx -- Dmitry - Alexandrov) - * NEW: Highlight TODO:, DONE:, FIXED:, FIXME:. - * NEW: Rename current WikiWord -- be careful on Windows you cannot rename - wikiword to WikiWord. After renaming update all links to that renamed - WikiWord. - * FIX: Bug -- do not duplicate WikiWords in wiki history. - * FIX: After renaming [[wiki word]] twice buffers are not deleted. - * FIX: Renaming from [[wiki word]] to WikiWord result is [[WikiWord]] - * FIX: More than one complex words on one line is bugging each other when - try go to one of them. [[bla bla bla]] [[dodo dodo dodo]] becomes bla - bla bla]] [[dodo dodo dodo. - - -0.2.2~ - * NEW: Added keybinding <S-CR> -- split WikiWord - * NEW: Added keybinding <C-CR> -- vertical split WikiWord - -0.2.1~ - * NEW: Install on Linux now works. - -0.2~ - * NEW: Added part of Google's Wiki syntax. - * NEW: Added auto insert # with ENTER. - * NEW: On/Off auto insert bullet with ENTER. - * NEW: Strip [[complex wiki name]] from symbols that cannot be used in - file names. - * NEW: Links to non-wiki files. Non wiki files are files with extensions - ie [[hello world.txt]] or [[my homesite.html]] +... + +39 releases + +... 0.1~ * First public version. diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim @@ -35,13 +35,17 @@ setlocal isfname-=[,] " Autocreate list items {{{ " for list items, and list items with checkboxes +setlocal formatoptions+=tnro +setlocal formatoptions-=cq if VimwikiGet('syntax') == 'default' setl comments=b:*,b:#,b:- setl formatlistpat=^\\s*[*#-]\\s* +elseif VimwikiGet('syntax') == 'markdown' + setlocal comments=fb:*,fb:-,fb:+,nb:> commentstring=\ >\ %s + setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\|^[-*+]\\s\\+j else setl comments=n:*,n:# endif -setlocal formatoptions=tnro if !empty(&langmap) " Valid only if langmap is a comma separated pairs of chars @@ -64,23 +68,15 @@ function! VimwikiFoldLevel(lnum) "{{{ " Header folding... if line =~ g:vimwiki_rxHeader - let n = vimwiki#base#count_first_sym(line) + let n = vimwiki#u#count_first_sym(line) return '>'.n endif - if g:vimwiki_fold_trailing_empty_lines == 0 && line =~ '^\s*$' - let nnline = getline(nextnonblank(a:lnum + 1)) - else - let nnline = getline(a:lnum + 1) - endif - if nnline =~ g:vimwiki_rxHeader - let n = vimwiki#base#count_first_sym(nnline) - return '<'.n - endif + let base_level = s:get_base_level(a:lnum) " List item folding... if g:vimwiki_fold_lists - let base_level = s:get_base_level(a:lnum) + let nnline = getline(a:lnum + 1) let rx_list_item = '\('. \ g:vimwiki_rxListBullet.'\|'.g:vimwiki_rxListNumber. @@ -95,6 +91,10 @@ function! VimwikiFoldLevel(lnum) "{{{ if leveln > level return ">".(base_level+leveln-adj) + " check if multilined list item + elseif (nnum-a:lnum) > 1 + \ && nline =~ rx_list_item && nnline !~ '^\s*$' + return ">".(base_level+level+1-adj) else return (base_level+level-adj) endif @@ -102,34 +102,23 @@ function! VimwikiFoldLevel(lnum) "{{{ " process multilined list items let [pnum, pline] = s:find_backward(rx_list_item, a:lnum) if pline =~ rx_list_item - if indent(a:lnum) > indent(pnum) + if indent(a:lnum) >= indent(pnum) && line !~ '^\s*$' let level = s:get_li_level(pnum) let adj = s:get_li_level(s:get_start_list(rx_list_item, pnum)) - - let [nnum, nline] = s:find_forward(rx_list_item, a:lnum) - if nline =~ rx_list_item - let leveln = s:get_li_level(nnum) - if leveln > level - return (base_level+leveln-adj) - endif - endif - - return (base_level+level-adj) + return (base_level+level+1-adj) endif endif endif - - return base_level endif - return -1 + return base_level endfunction "}}} function! s:get_base_level(lnum) "{{{ let lnum = a:lnum - 1 while lnum > 0 if getline(lnum) =~ g:vimwiki_rxHeader - return vimwiki#base#count_first_sym(getline(lnum)) + return vimwiki#u#count_first_sym(getline(lnum)) endif let lnum -= 1 endwhile @@ -169,7 +158,7 @@ endfunction "}}} function! s:get_li_level(lnum) "{{{ if VimwikiGet('syntax') == 'media' - let level = vimwiki#base#count_first_sym(getline(a:lnum)) + let level = vimwiki#u#count_first_sym(getline(a:lnum)) else let level = (indent(a:lnum) / &sw) endif @@ -198,12 +187,16 @@ endfunction "}}} " COMMANDS {{{ command! -buffer Vimwiki2HTML - \ w <bar> call vimwiki#html#Wiki2HTML(expand(VimwikiGet('path_html')), + \ silent w <bar> + \ let res = vimwiki#html#Wiki2HTML(expand(VimwikiGet('path_html')), \ expand('%')) + \<bar> + \ if res != '' | echo 'Vimwiki: HTML conversion is done.' | endif command! -buffer Vimwiki2HTMLBrowse - \ w <bar> call VimwikiWeblinkHandler( - \ vimwiki#html#Wiki2HTML(expand(VimwikiGet('path_html')), - \ expand('%'))) + \ silent w <bar> + \ call vimwiki#base#system_open_link(vimwiki#html#Wiki2HTML( + \ expand(VimwikiGet('path_html')), + \ expand('%'))) command! -buffer VimwikiAll2HTML \ call vimwiki#html#WikiAll2HTML(expand(VimwikiGet('path_html'))) @@ -216,12 +209,17 @@ command! -buffer VimwikiGoBackLink call vimwiki#base#go_back_link() command! -buffer VimwikiSplitLink call vimwiki#base#follow_link('split') command! -buffer VimwikiVSplitLink call vimwiki#base#follow_link('vsplit') +command! -buffer -nargs=? VimwikiNormalizeLink call vimwiki#base#normalize_link(<f-args>) + command! -buffer VimwikiTabnewLink call vimwiki#base#follow_link('tabnew') command! -buffer -range VimwikiToggleListItem call vimwiki#lst#ToggleListItem(<line1>, <line2>) command! -buffer VimwikiGenerateLinks call vimwiki#base#generate_links() +command! -buffer -nargs=0 VimwikiBacklinks call vimwiki#base#backlinks() +command! -buffer -nargs=0 VWB call vimwiki#base#backlinks() + exe 'command! -buffer -nargs=* VimwikiSearch lvimgrep <args> '. \ escape(VimwikiGet('path').'**/*'.VimwikiGet('ext'), ' ') @@ -230,6 +228,10 @@ exe 'command! -buffer -nargs=* VWS lvimgrep <args> '. command! -buffer -nargs=1 VimwikiGoto call vimwiki#base#goto("<args>") + +" list commands +command! -buffer -nargs=* VimwikiListChangeLevel call vimwiki#lst#change_level(<f-args>) + " table commands command! -buffer -nargs=* VimwikiTable call vimwiki#tbl#create(<f-args>) command! -buffer VimwikiTableAlignQ call vimwiki#tbl#align_or_cmd('gqq') @@ -247,7 +249,7 @@ command! -buffer VimwikiDiaryPrevDay call vimwiki#diary#goto_prev_day() if g:vimwiki_use_mouse nmap <buffer> <S-LeftMouse> <NOP> nmap <buffer> <C-LeftMouse> <NOP> - nnoremap <silent><buffer> <2-LeftMouse> :VimwikiFollowLink<CR> + nnoremap <silent><buffer> <2-LeftMouse> :call vimwiki#base#follow_link("nosplit", "\<lt>2-LeftMouse>")<CR> nnoremap <silent><buffer> <S-2-LeftMouse> <LeftMouse>:VimwikiSplitLink<CR> nnoremap <silent><buffer> <C-2-LeftMouse> <LeftMouse>:VimwikiVSplitLink<CR> nnoremap <silent><buffer> <RightMouse><LeftMouse> :VimwikiGoBackLink<CR> @@ -284,6 +286,24 @@ endif nnoremap <silent><script><buffer> \ <Plug>VimwikiVSplitLink :VimwikiVSplitLink<CR> +if !hasmapto('<Plug>VimwikiNormalizeLink') + nmap <silent><buffer> + <Plug>VimwikiNormalizeLink +endif +nnoremap <silent><script><buffer> + \ <Plug>VimwikiNormalizeLink :VimwikiNormalizeLink 0<CR> + +if !hasmapto('<Plug>VimwikiNormalizeLinkVisual') + vmap <silent><buffer> + <Plug>VimwikiNormalizeLinkVisual +endif +vnoremap <silent><script><buffer> + \ <Plug>VimwikiNormalizeLinkVisual :<C-U>VimwikiNormalizeLink 1<CR> + +if !hasmapto('<Plug>VimwikiNormalizeLinkVisualCR') + vmap <silent><buffer> <CR> <Plug>VimwikiNormalizeLinkVisualCR +endif +vnoremap <silent><script><buffer> + \ <Plug>VimwikiNormalizeLinkVisualCR :<C-U>VimwikiNormalizeLink 1<CR> + if !hasmapto('<Plug>VimwikiTabnewLink') nmap <silent><buffer> <D-CR> <Plug>VimwikiTabnewLink nmap <silent><buffer> <C-S-CR> <Plug>VimwikiTabnewLink @@ -345,7 +365,7 @@ nnoremap <silent><script><buffer> function! s:CR() "{{{ let res = vimwiki#lst#kbd_cr() - if res == "\<CR>" && g:vimwiki_table_auto_fmt + if res == "\<CR>" && g:vimwiki_table_mappings let res = vimwiki#tbl#kbd_cr() endif return res @@ -357,9 +377,25 @@ inoremap <buffer> <expr> <CR> <SID>CR() " List mappings nnoremap <buffer> o :<C-U>call vimwiki#lst#kbd_oO('o')<CR> nnoremap <buffer> O :<C-U>call vimwiki#lst#kbd_oO('O')<CR> +nnoremap <buffer> gll :VimwikiListChangeLevel <<<CR> +nnoremap <buffer> glm :VimwikiListChangeLevel >><CR> +nnoremap <buffer> gl* :VimwikiListChangeLevel *<CR> +nnoremap <buffer> gl8 :VimwikiListChangeLevel *<CR> +if VimwikiGet('syntax') == 'default' + nnoremap <buffer> gl- :VimwikiListChangeLevel -<CR> + nnoremap <buffer> gl# :VimwikiListChangeLevel #<CR> + nnoremap <buffer> gl3 :VimwikiListChangeLevel #<CR> +elseif VimwikiGet('syntax') == 'markdown' + nnoremap <buffer> gl- :VimwikiListChangeLevel -<CR> + nnoremap <buffer> gl1 :VimwikiListChangeLevel 1.<CR> +elseif VimwikiGet('syntax') == 'media' + nnoremap <buffer> gl# :VimwikiListChangeLevel #<CR> + nnoremap <buffer> gl3 :VimwikiListChangeLevel #<CR> +endif + " Table mappings -if g:vimwiki_table_auto_fmt +if g:vimwiki_table_mappings inoremap <expr> <buffer> <Tab> vimwiki#tbl#kbd_tab() inoremap <expr> <buffer> <S-Tab> vimwiki#tbl#kbd_shift_tab() endif @@ -377,8 +413,6 @@ endif nnoremap <silent><script><buffer> \ <Plug>VimwikiTableMoveColumnRight :VimwikiTableMoveColumnRight<CR> -" Misc mappings -inoremap <buffer> <S-CR> <br /><CR> " Text objects {{{ @@ -400,8 +434,18 @@ vnoremap <silent><buffer> ac :<C-U>call vimwiki#base#TO_table_col(0, 1)<CR> onoremap <silent><buffer> ic :<C-U>call vimwiki#base#TO_table_col(1, 0)<CR> vnoremap <silent><buffer> ic :<C-U>call vimwiki#base#TO_table_col(1, 1)<CR> -nnoremap <silent><buffer> = :call vimwiki#base#AddHeaderLevel()<CR> -nnoremap <silent><buffer> - :call vimwiki#base#RemoveHeaderLevel()<CR> +if !hasmapto('<Plug>VimwikiAddHeaderLevel') + nmap <silent><buffer> = <Plug>VimwikiAddHeaderLevel +endif +nnoremap <silent><buffer> <Plug>VimwikiAddHeaderLevel : + \<C-U>call vimwiki#base#AddHeaderLevel()<CR> + +if !hasmapto('<Plug>VimwikiRemoveHeaderLevel') + nmap <silent><buffer> - <Plug>VimwikiRemoveHeaderLevel +endif +nnoremap <silent><buffer> <Plug>VimwikiRemoveHeaderLevel : + \<C-U>call vimwiki#base#RemoveHeaderLevel()<CR> + " }}} @@ -411,8 +455,21 @@ nnoremap <silent><buffer> - :call vimwiki#base#RemoveHeaderLevel()<CR> if VimwikiGet('auto_export') " Automatically generate HTML on page write. augroup vimwiki - au BufWritePost <buffer> Vimwiki2HTML + au BufWritePost <buffer> + \ call vimwiki#html#Wiki2HTML(expand(VimwikiGet('path_html')), + \ expand('%')) augroup END endif " AUTOCOMMANDS }}} + +" PASTE, CAT URL {{{ +" html commands +command! -buffer VimwikiPasteUrl call vimwiki#html#PasteUrl(expand('%:p')) +command! -buffer VimwikiCatUrl call vimwiki#html#CatUrl(expand('%:p')) +" }}} + +" DEBUGGING {{{ +command! VimwikiPrintWikiState call vimwiki#base#print_wiki_state() +command! VimwikiReadLocalOptions call vimwiki#base#read_wiki_options(1) +" }}} diff --git a/plugin/vimwiki.vim b/plugin/vimwiki.vim @@ -12,6 +12,19 @@ let loaded_vimwiki = 1 let s:old_cpo = &cpo set cpo&vim +" Logging and performance instrumentation "{{{ +let g:VimwikiLog = {} +let g:VimwikiLog.path = 0 " # of calls to VimwikiGet with path or path_html +let g:VimwikiLog.path_html = 0 " # of calls to path_html() +let g:VimwikiLog.normalize_path = 0 " # of calls to normalize_path() +let g:VimwikiLog.subdir = 0 " # of calls to vimwiki#base#subdir() +let g:VimwikiLog.timing = [] " various timing measurements +let g:VimwikiLog.html = [] " html conversion timing +function! VimwikiLog_extend(what,...) "{{{ + call extend(g:VimwikiLog[a:what],a:000) +endfunction "}}} +"}}} + " HELPER functions {{{ function! s:default(varname, value) "{{{ if !exists('g:vimwiki_'.a:varname) @@ -19,87 +32,141 @@ function! s:default(varname, value) "{{{ endif endfunction "}}} -" return longest common path prefix of 2 given paths. -" '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki' -function! s:path_common_pfx(path1, path2) "{{{ - let p1 = split(a:path1, '[/\\]', 1) - let p2 = split(a:path2, '[/\\]', 1) - - let idx = 0 - let minlen = min([len(p1), len(p2)]) - while (idx < minlen) && (p1[idx] ==? p2[idx]) - let idx = idx + 1 - endwhile - if idx == 0 - return '' - else - return join(p1[: idx-1], '/') - endif -endfunction "}}} - function! s:find_wiki(path) "{{{ + " XXX: find_wiki() does not (yet) take into consideration the ext + let path = vimwiki#u#path_norm(vimwiki#u#chomp_slash(a:path)) let idx = 0 while idx < len(g:vimwiki_list) - let path = vimwiki#base#chomp_slash(expand(VimwikiGet('path', idx))) - let path = vimwiki#base#path_norm(path) - if s:path_common_pfx(path, a:path) == path + let idx_path = expand(VimwikiGet('path', idx)) + let idx_path = vimwiki#u#path_norm(vimwiki#u#chomp_slash(idx_path)) + if vimwiki#u#path_common_pfx(idx_path, path) == idx_path return idx endif let idx += 1 endwhile return -1 + " an orphan page has been detected endfunction "}}} -function! s:setup_buffer_leave()"{{{ - if &filetype == 'vimwiki' && !exists("b:vimwiki_idx") - let b:vimwiki_idx = g:vimwiki_current_idx + +function! s:vimwiki_idx() " {{{ + if exists('b:vimwiki_idx') + return b:vimwiki_idx + else + return -1 + endif +endfunction " }}} + +function! s:setup_buffer_leave() "{{{ + if g:vimwiki_debug ==3 + echom "Setup_buffer_leave g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + if &filetype == 'vimwiki' + " cache global vars of current state XXX: SLOW!? + call vimwiki#base#cache_buffer_state() + endif + if g:vimwiki_debug ==3 + echom " Setup_buffer_leave g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" endif " Set up menu if g:vimwiki_menu != "" exe 'nmenu disable '.g:vimwiki_menu.'.Table' endif -endfunction"}}} +endfunction "}}} function! s:setup_filetype() "{{{ - " Find what wiki current buffer belongs to. - let path = expand('%:p:h') - let ext = '.'.expand('%:e') - let idx = s:find_wiki(path) + if g:vimwiki_debug ==3 + echom "Setup_filetype g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + let time0 = reltime() " start the clock "XXX + " Find what wiki current buffer belongs to. + let path = expand('%:p:h') + " XXX: find_wiki() does not (yet) take into consideration the ext + let idx = s:find_wiki(path) + if g:vimwiki_debug ==3 + echom " Setup_filetype g:curr_idx=".g:vimwiki_current_idx." find_idx=".idx." b:curr_idx=".s:vimwiki_idx()."" + endif - if idx == -1 && g:vimwiki_global_ext == 0 - return + if idx == -1 && g:vimwiki_global_ext == 0 + return + endif + "XXX when idx = -1? (an orphan page has been detected) + + "TODO: refactor (same code in setup_buffer_enter) + " The buffer's file is not in the path and user *does* want his wiki + " extension(s) to be global -- Add new wiki. + if idx == -1 + let ext = '.'.expand('%:e') + " lookup syntax using g:vimwiki_ext2syntax + if has_key(g:vimwiki_ext2syntax, ext) + let syn = g:vimwiki_ext2syntax[ext] + else + let syn = s:vimwiki_defaults.syntax endif + call add(g:vimwiki_list, {'path': path, 'ext': ext, 'syntax': syn, 'temp': 1}) + let idx = len(g:vimwiki_list) - 1 + endif + call vimwiki#base#validate_wiki_options(idx) + " initialize and cache global vars of current state + call vimwiki#base#setup_buffer_state(idx) + if g:vimwiki_debug ==3 + echom " Setup_filetype g:curr_idx=".g:vimwiki_current_idx." (reset_wiki_state) b:curr_idx=".s:vimwiki_idx()."" + endif + unlet! b:vimwiki_fs_rescan set filetype=vimwiki + if g:vimwiki_debug ==3 + echom " Setup_filetype g:curr_idx=".g:vimwiki_current_idx." (set ft=vimwiki) b:curr_idx=".s:vimwiki_idx()."" + endif + let time1 = vimwiki#u#time(time0) "XXX + call VimwikiLog_extend('timing',['plugin:setup_filetype:time1',time1]) endfunction "}}} function! s:setup_buffer_enter() "{{{ - if exists("b:vimwiki_idx") - let g:vimwiki_current_idx = b:vimwiki_idx - else + if g:vimwiki_debug ==3 + echom "Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + let time0 = reltime() " start the clock "XXX + if !vimwiki#base#recall_buffer_state() " Find what wiki current buffer belongs to. " If wiki does not exist in g:vimwiki_list -- add new wiki there with " buffer's path and ext. " Else set g:vimwiki_current_idx to that wiki index. let path = expand('%:p:h') - let ext = '.'.expand('%:e') + " XXX: find_wiki() does not (yet) take into consideration the ext let idx = s:find_wiki(path) - " The buffer's file is not in the path and user do not want his wiki - " extension to be global -- do not add new wiki. + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." find_idx=".idx." b:curr_idx=".s:vimwiki_idx()."" + endif + " The buffer's file is not in the path and user *does NOT* want his wiki + " extension to be global -- Do not add new wiki. if idx == -1 && g:vimwiki_global_ext == 0 return endif + "TODO: refactor (same code in setup_filetype) + " The buffer's file is not in the path and user *does* want his wiki + " extension(s) to be global -- Add new wiki. if idx == -1 - call add(g:vimwiki_list, {'path': path, 'ext': ext, 'temp': 1}) - let g:vimwiki_current_idx = len(g:vimwiki_list) - 1 - else - let g:vimwiki_current_idx = idx + let ext = '.'.expand('%:e') + " lookup syntax using g:vimwiki_ext2syntax + if has_key(g:vimwiki_ext2syntax, ext) + let syn = g:vimwiki_ext2syntax[ext] + else + let syn = s:vimwiki_defaults.syntax + endif + call add(g:vimwiki_list, {'path': path, 'ext': ext, 'syntax': syn, 'temp': 1}) + let idx = len(g:vimwiki_list) - 1 + endif + call vimwiki#base#validate_wiki_options(idx) + " initialize and cache global vars of current state + call vimwiki#base#setup_buffer_state(idx) + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." (reset_wiki_state) b:curr_idx=".s:vimwiki_idx()."" endif - let b:vimwiki_idx = g:vimwiki_current_idx endif " If you have @@ -108,10 +175,22 @@ function! s:setup_buffer_enter() "{{{ " au GUIEnter * nested VimwikiIndex if &filetype == '' set filetype=vimwiki + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." (set ft vimwiki) b:curr_idx=".s:vimwiki_idx()."" + endif + elseif &syntax == 'vimwiki' + " to force a rescan of the filesystem which may have changed + " and update VimwikiLinks syntax group that depends on it; + " b:vimwiki_fs_rescan indicates that setup_filetype() has not been run + if exists("b:vimwiki_fs_rescan") && VimwikiGet('maxhi') + set syntax=vimwiki + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." (set syntax=vimwiki) b:curr_idx=".s:vimwiki_idx()."" + endif + endif + let b:vimwiki_fs_rescan = 1 endif - - " Update existed/non-existed links highlighting. - call vimwiki#base#highlight_links() + let time1 = vimwiki#u#time(time0) "XXX " Settings foldmethod, foldexpr and foldtext are local to window. Thus in a " new tab with the same buffer folding is reset to vim defaults. So we @@ -131,86 +210,125 @@ function! s:setup_buffer_enter() "{{{ if g:vimwiki_menu != "" exe 'nmenu enable '.g:vimwiki_menu.'.Table' endif + "let time2 = vimwiki#u#time(time0) "XXX + call VimwikiLog_extend('timing',['plugin:setup_buffer_enter:time1',time1]) endfunction "}}} -" OPTION get/set functions {{{ -" return value of option for current wiki or if second parameter exists for -" wiki with a given index. -function! VimwikiGet(option, ...) "{{{ - if a:0 == 0 - let idx = g:vimwiki_current_idx - else - let idx = a:1 +function! s:setup_buffer_reenter() "{{{ + if g:vimwiki_debug ==3 + echom "Setup_buffer_reenter g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" endif - if !has_key(g:vimwiki_list[idx], a:option) && - \ has_key(s:vimwiki_defaults, a:option) - if a:option == 'path_html' - let g:vimwiki_list[idx][a:option] = - \VimwikiGet('path', idx)[:-2].'_html/' - else - let g:vimwiki_list[idx][a:option] = - \s:vimwiki_defaults[a:option] - endif + if !vimwiki#base#recall_buffer_state() + " Do not repeat work of s:setup_buffer_enter() and s:setup_filetype() + " Once should be enough ... + endif + if g:vimwiki_debug ==3 + echom " Setup_buffer_reenter g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" endif +endfunction "}}} + +function! s:setup_cleared_syntax() "{{{ highlight groups that get cleared + " on colorscheme change because they are not linked to Vim-predefined groups + hi def VimwikiBold term=bold cterm=bold gui=bold + hi def VimwikiItalic term=italic cterm=italic gui=italic + hi def VimwikiBoldItalic term=bold cterm=bold gui=bold,italic + hi def VimwikiUnderline gui=underline + if g:vimwiki_hl_headers == 1 + for i in range(1,6) + execute 'hi def VimwikiHeader'.i.' guibg=bg guifg='.g:vimwiki_hcolor_guifg_{&bg}[i-1].' gui=bold ctermfg='.g:vimwiki_hcolor_ctermfg_{&bg}[i-1].' term=bold cterm=bold' + endfor + endif +endfunction "}}} - " if path's ending is not a / or \ - " then add it - if a:option == 'path' || a:option == 'path_html' - let p = g:vimwiki_list[idx][a:option] - " resolve doesn't work quite right with symlinks ended with / or \ - let p = substitute(p, '[/\\]\+$', '', '') - let p = resolve(expand(p)) - let g:vimwiki_list[idx][a:option] = p.'/' +" OPTION get/set functions {{{ +" return complete list of options +function! VimwikiGetOptionNames() "{{{ + return keys(s:vimwiki_defaults) +endfunction "}}} + +function! VimwikiGetOptions(...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + let option_dict = {} + for kk in keys(s:vimwiki_defaults) + let option_dict[kk] = VimwikiGet(kk, idx) + endfor + return option_dict +endfunction "}}} + +" Return value of option for current wiki or if second parameter exists for +" wiki with a given index. +" If the option is not found, it is assumed to have been previously cached in a +" buffer local dictionary, that acts as a cache. +" If the option is not found in the buffer local dictionary, an error is thrown +function! VimwikiGet(option, ...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + + if has_key(g:vimwiki_list[idx], a:option) + let val = g:vimwiki_list[idx][a:option] + elseif has_key(s:vimwiki_defaults, a:option) + let val = s:vimwiki_defaults[a:option] + let g:vimwiki_list[idx][a:option] = val + else + let val = b:vimwiki_list[a:option] endif - return g:vimwiki_list[idx][a:option] + " XXX no call to vimwiki#base here or else the whole autoload/base gets loaded! + return val endfunction "}}} -" set option for current wiki or if third parameter exists for -" wiki with a given index. +" Set option for current wiki or if third parameter exists for +" wiki with a given index. +" If the option is not found or recognized (i.e. does not exist in +" s:vimwiki_defaults), it is saved in a buffer local dictionary, that acts +" as a cache. +" If the option is not found in the buffer local dictionary, an error is thrown function! VimwikiSet(option, value, ...) "{{{ - if a:0 == 0 - let idx = g:vimwiki_current_idx + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + + if has_key(s:vimwiki_defaults, a:option) || + \ has_key(g:vimwiki_list[idx], a:option) + let g:vimwiki_list[idx][a:option] = a:value + elseif exists('b:vimwiki_list') + let b:vimwiki_list[a:option] = a:value else - let idx = a:1 + let b:vimwiki_list = {} + let b:vimwiki_list[a:option] = a:value endif - let g:vimwiki_list[idx][a:option] = a:value + endfunction "}}} " }}} " }}} -" CALLBACK function "{{{ +" CALLBACK functions "{{{ " User can redefine it. -if !exists("*VimwikiWeblinkHandler") "{{{ - function VimwikiWeblinkHandler(weblink) - for browser in g:vimwiki_browsers - if executable(browser) - if has("win32") - execute '!start "'.browser.'" "' . a:weblink . '"' - else - execute '!'.browser.' "' . a:weblink . '"' - endif - return - endif - endfor +if !exists("*VimwikiLinkHandler") "{{{ + function VimwikiLinkHandler(url) + return 0 endfunction endif "}}} + +if !exists("*VimwikiWikiIncludeHandler") "{{{ + function! VimwikiWikiIncludeHandler(value) "{{{ + " Return the empty string when unable to process link + return '' + endfunction "}}} +endif "}}} " CALLBACK }}} " DEFAULT wiki {{{ let s:vimwiki_defaults = {} let s:vimwiki_defaults.path = '~/vimwiki/' -let s:vimwiki_defaults.path_html = '~/vimwiki_html/' +let s:vimwiki_defaults.path_html = '' " '' is replaced by derived path.'_html/' let s:vimwiki_defaults.css_name = 'style.css' let s:vimwiki_defaults.index = 'index' let s:vimwiki_defaults.ext = '.wiki' -let s:vimwiki_defaults.maxhi = 1 +let s:vimwiki_defaults.maxhi = 0 let s:vimwiki_defaults.syntax = 'default' -let s:vimwiki_defaults.template_path = '~/vimwiki/templates/' -let s:vimwiki_defaults.template_default = 'default' -let s:vimwiki_defaults.template_ext = '.html' +let s:vimwiki_defaults.template_path = '' +let s:vimwiki_defaults.template_default = '' +let s:vimwiki_defaults.template_ext = '' let s:vimwiki_defaults.nested_syntaxes = {} let s:vimwiki_defaults.auto_export = 0 @@ -222,26 +340,20 @@ let s:vimwiki_defaults.temp = 0 let s:vimwiki_defaults.diary_rel_path = 'diary/' let s:vimwiki_defaults.diary_index = 'diary' let s:vimwiki_defaults.diary_header = 'Diary' +let s:vimwiki_defaults.diary_sort = 'desc' " 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 - +" NEW! in v2.0 +" custom_wiki2html +let s:vimwiki_defaults.custom_wiki2html = '' +" +let s:vimwiki_defaults.list_margin = -1 "}}} " DEFAULT options {{{ call s:default('list', [s:vimwiki_defaults]) -if &encoding == 'utf-8' - call s:default('upper', 'A-Z\u0410-\u042f') - call s:default('lower', 'a-z\u0430-\u044f') -else - call s:default('upper', 'A-Z') - call s:default('lower', 'a-z') -endif -call s:default('other', '0-9') -call s:default('stripsym', '_') -call s:default('badsyms', '') call s:default('auto_checkbox', 1) call s:default('use_mouse', 0) call s:default('folding', 0) @@ -249,77 +361,61 @@ call s:default('fold_trailing_empty_lines', 0) call s:default('fold_lists', 0) call s:default('menu', 'Vimwiki') call s:default('global_ext', 1) +call s:default('ext2syntax', {'.md': 'markdown'}) " syntax map keyed on extension call s:default('hl_headers', 0) call s:default('hl_cb_checked', 0) -call s:default('camel_case', 1) call s:default('list_ignore_newline', 1) call s:default('listsyms', ' .oOX') -if has("win32") - call s:default('browsers', - \ [ - \ expand('~').'\Local Settings\Application Data\Google\Chrome\Application\chrome.exe', - \ 'C:\Program Files\Opera\opera.exe', - \ 'C:\Program Files\Mozilla Firefox\firefox.exe', - \ 'C:\Program Files\Internet Explorer\iexplore.exe', - \ ]) -else - call s:default('browsers', - \ [ - \ 'chromium-browser', - \ 'opera', - \ 'firefox', - \ 'konqueror', - \ ]) -endif - call s:default('use_calendar', 1) +call s:default('table_mappings', 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('file_exts', 'pdf,txt,doc,rtf,xls,php,zip,rar,7z,html,gz') call s:default('valid_html_tags', 'b,i,s,u,sub,sup,kbd,br,hr,div,center,strong,em') call s:default('user_htmls', '') call s:default('html_header_numbering', 0) call s:default('html_header_numbering_sym', '') -call s:default('conceallevel', 3) +call s:default('conceallevel', 2) +call s:default('url_mingain', 12) +call s:default('url_maxsave', 15) +call s:default('debug', 0) + +call s:default('diary_months', + \ { + \ 1: 'January', 2: 'February', 3: 'March', + \ 4: 'April', 5: 'May', 6: 'June', + \ 7: 'July', 8: 'August', 9: 'September', + \ 10: 'October', 11: 'November', 12: 'December' + \ }) + call s:default('current_idx', 0) -let upp = g:vimwiki_upper -let low = g:vimwiki_lower -let oth = g:vimwiki_other -let nup = low.oth -let nlo = upp.oth -let any = upp.nup - -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_rxWikiLink = g:vimwiki_rxWikiWord.'\|'. - \ g:vimwiki_rxWikiLink1.'\|'.g:vimwiki_rxWikiLink2 -else - let g:vimwiki_rxWikiLink = g:vimwiki_rxWikiLink1.'\|'.g:vimwiki_rxWikiLink2 -endif -let g:vimwiki_rxWeblink = '\%("[^"(]\+\((\([^)]\+\))\)\?":\)\?'. - \'\%('. - \'\%('. - \'\%(https\?\|ftp\|gopher\|telnet\|file\|notes\|ms-help\):'. - \'\%(\%(//\)\|\%(\\\\\)\)'. - \'\)'. - \'\|\%(mailto:\)'. - \'\)'. - \'\+\S\+'. - \'[().,?\]]\@<!' +" Scheme regexes should be defined even if syntax file is not loaded yet +" cause users should be able to <leader>w<leader>w without opening any +" vimwiki file first +" Scheme regexes {{{ +call s:default('schemes', 'wiki\d\+,diary,local') +call s:default('web_schemes1', 'http,https,file,ftp,gopher,telnet,nntp,ldap,'. + \ 'rsync,imap,pop,irc,ircs,cvs,svn,svn+ssh,git,ssh,fish,sftp') +call s:default('web_schemes2', 'mailto,news,xmpp,sip,sips,doi,urn,tel') + +let rxSchemes = '\%('. + \ join(split(g:vimwiki_schemes, '\s*,\s*'), '\|').'\|'. + \ join(split(g:vimwiki_web_schemes1, '\s*,\s*'), '\|').'\|'. + \ join(split(g:vimwiki_web_schemes2, '\s*,\s*'), '\|'). + \ '\)' + +call s:default('rxSchemeUrl', rxSchemes.':.*') +call s:default('rxSchemeUrlMatchScheme', '\zs'.rxSchemes.'\ze:.*') +call s:default('rxSchemeUrlMatchUrl', rxSchemes.':\zs.*\ze') +" scheme regexes }}} "}}} " AUTOCOMMANDS for all known wiki extensions {{{ -" Getting all extensions that different wikies could have +" Getting all extensions that different wikis could have let extensions = {} for wiki in g:vimwiki_list if has_key(wiki, 'ext') @@ -328,6 +424,10 @@ for wiki in g:vimwiki_list let extensions['.wiki'] = 1 endif endfor +" append map g:vimwiki_ext2syntax +for ext in keys(g:vimwiki_ext2syntax) + let extensions[ext] = 1 +endfor augroup filetypedetect " clear FlexWiki's stuff @@ -337,16 +437,11 @@ augroup end augroup vimwiki autocmd! for ext in keys(extensions) + exe 'autocmd BufEnter *'.ext.' call s:setup_buffer_reenter()' exe 'autocmd BufWinEnter *'.ext.' call s:setup_buffer_enter()' exe 'autocmd BufLeave,BufHidden *'.ext.' call s:setup_buffer_leave()' exe 'autocmd BufNewFile,BufRead, *'.ext.' call s:setup_filetype()' - - " ColorScheme could have or could have not a - " VimwikiHeader1..VimwikiHeader6 highlight groups. We need to refresh - " syntax after colorscheme change. - exe 'autocmd ColorScheme *'.ext.' syntax enable'. - \ ' | call vimwiki#base#highlight_links()' - + exe 'autocmd ColorScheme *'.ext.' call s:setup_cleared_syntax()' " Format tables when exit from insert mode. Do not use textwidth to " autowrap tables. if g:vimwiki_table_auto_fmt @@ -359,17 +454,22 @@ augroup END " COMMANDS {{{ command! VimwikiUISelect call vimwiki#base#ui_select() -command! -count VimwikiIndex - \ call vimwiki#base#goto_index(v:count1) -command! -count VimwikiTabIndex tabedit <bar> +" XXX: why not using <count> instead of v:count1? +" See Issue 324. +command! -count=1 VimwikiIndex \ call vimwiki#base#goto_index(v:count1) +command! -count=1 VimwikiTabIndex + \ call vimwiki#base#goto_index(v:count1, 1) -command! -count VimwikiDiaryIndex - \ call vimwiki#diary#goto_index(v:count1) -command! -count VimwikiMakeDiaryNote - \ call vimwiki#diary#make_note(v:count1) -command! -count VimwikiTabMakeDiaryNote tabedit <bar> +command! -count=1 VimwikiDiaryIndex + \ call vimwiki#diary#goto_diary_index(v:count1) +command! -count=1 VimwikiMakeDiaryNote \ call vimwiki#diary#make_note(v:count1) +command! -count=1 VimwikiTabMakeDiaryNote + \ call vimwiki#diary#make_note(v:count1, 1) + +command! VimwikiDiaryGenerateLinks + \ call vimwiki#diary#generate_diary_section() "}}} " MAPPINGS {{{ @@ -393,6 +493,11 @@ if !hasmapto('<Plug>VimwikiDiaryIndex') endif nnoremap <unique><script> <Plug>VimwikiDiaryIndex :VimwikiDiaryIndex<CR> +if !hasmapto('<Plug>VimwikiDiaryGenerateLinks') + nmap <silent><unique> <Leader>w<Leader>i <Plug>VimwikiDiaryGenerateLinks +endif +nnoremap <unique><script> <Plug>VimwikiDiaryGenerateLinks :VimwikiDiaryGenerateLinks<CR> + if !hasmapto('<Plug>VimwikiMakeDiaryNote') nmap <silent><unique> <Leader>w<Leader>w <Plug>VimwikiMakeDiaryNote endif @@ -429,6 +534,7 @@ function! s:build_table_menu(topmenu) exe 'nmenu disable '.a:topmenu.'.Table' endfunction +"XXX make sure anything below does not cause autoload/base to be loaded if !empty(g:vimwiki_menu) call s:build_menu(g:vimwiki_menu) call s:build_table_menu(g:vimwiki_menu) @@ -442,4 +548,5 @@ if g:vimwiki_use_calendar endif "}}} + let &cpo = s:old_cpo diff --git a/syntax/vimwiki.vim b/syntax/vimwiki.vim @@ -9,30 +9,331 @@ if version < 600 elseif exists("b:current_syntax") finish endif +"TODO do nothing if ...? (?) +let starttime = reltime() " start the clock +if VimwikiGet('maxhi') + let b:existing_wikifiles = vimwiki#base#get_links('*'.VimwikiGet('ext')) + let b:existing_wikidirs = vimwiki#base#get_links('*/') +endif +let timescans = vimwiki#u#time(starttime) "XXX + "let b:xxx = 1 + "TODO ? update wikilink syntax group here if really needed (?) for :e and such + "if VimwikiGet('maxhi') + " ... + "endif + +" LINKS: assume this is common to all syntaxes "{{{ + +" LINKS: WebLinks {{{ +" match URL for common protocols; +" see http://en.wikipedia.org/wiki/URI_scheme http://tools.ietf.org/html/rfc3986 +let g:vimwiki_rxWebProtocols = ''. + \ '\%('. + \ '\%('. + \ '\%('.join(split(g:vimwiki_web_schemes1, '\s*,\s*'), '\|').'\):'. + \ '\%(//\)'. + \ '\)'. + \ '\|'. + \ '\%('.join(split(g:vimwiki_web_schemes2, '\s*,\s*'), '\|').'\):'. + \ '\)' +" +let g:vimwiki_rxWeblinkUrl = g:vimwiki_rxWebProtocols . + \ '\S\{-1,}'. '\%(([^ \t()]*)\)\=' +" }}} + +" }}} + +" ------------------------------------------------------------------------- +" Load concrete Wiki syntax: sets regexes and templates for headers and links +execute 'runtime! syntax/vimwiki_'.VimwikiGet('syntax').'.vim' +" ------------------------------------------------------------------------- +let time0 = vimwiki#u#time(starttime) "XXX + + +" LINKS: setup of larger regexes {{{ + +" LINKS: setup wikilink regexps {{{ +let g:vimwiki_rxWikiLinkPrefix = '[[' +let g:vimwiki_rxWikiLinkSuffix = ']]' +let g:vimwiki_rxWikiLinkSeparator = '|' +" [[URL]] +let g:vimwiki_WikiLinkTemplate1 = g:vimwiki_rxWikiLinkPrefix . '__LinkUrl__'. + \ g:vimwiki_rxWikiLinkSuffix +" [[URL|DESCRIPTION]] +let g:vimwiki_WikiLinkTemplate2 = g:vimwiki_rxWikiLinkPrefix . '__LinkUrl__'. + \ g:vimwiki_rxWikiLinkSeparator. '__LinkDescription__'. + \ g:vimwiki_rxWikiLinkSuffix +" +let magic_chars = '.*[]\^$' +let valid_chars = '[^\\]' + +let g:vimwiki_rxWikiLinkPrefix = escape(g:vimwiki_rxWikiLinkPrefix, magic_chars) +let g:vimwiki_rxWikiLinkSuffix = escape(g:vimwiki_rxWikiLinkSuffix, magic_chars) +let g:vimwiki_rxWikiLinkSeparator = escape(g:vimwiki_rxWikiLinkSeparator, magic_chars) +let g:vimwiki_rxWikiLinkUrl = valid_chars.'\{-}' +let g:vimwiki_rxWikiLinkDescr = valid_chars.'\{-}' + +let g:vimwiki_rxWord = '[^[:blank:]()\\]\+' + +" +" [[URL]], or [[URL|DESCRIPTION]] +" a) match [[URL|DESCRIPTION]] +let g:vimwiki_rxWikiLink = g:vimwiki_rxWikiLinkPrefix. + \ g:vimwiki_rxWikiLinkUrl.'\%('.g:vimwiki_rxWikiLinkSeparator. + \ g:vimwiki_rxWikiLinkDescr.'\)\?'.g:vimwiki_rxWikiLinkSuffix +" b) match URL within [[URL|DESCRIPTION]] +let g:vimwiki_rxWikiLinkMatchUrl = g:vimwiki_rxWikiLinkPrefix. + \ '\zs'. g:vimwiki_rxWikiLinkUrl.'\ze\%('. g:vimwiki_rxWikiLinkSeparator. + \ g:vimwiki_rxWikiLinkDescr.'\)\?'.g:vimwiki_rxWikiLinkSuffix +" c) match DESCRIPTION within [[URL|DESCRIPTION]] +let g:vimwiki_rxWikiLinkMatchDescr = g:vimwiki_rxWikiLinkPrefix. + \ g:vimwiki_rxWikiLinkUrl.g:vimwiki_rxWikiLinkSeparator.'\%('. + \ '\zs'. g:vimwiki_rxWikiLinkDescr. '\ze\)\?'. g:vimwiki_rxWikiLinkSuffix +" }}} + +" LINKS: Syntax helper {{{ +let g:vimwiki_rxWikiLinkPrefix1 = g:vimwiki_rxWikiLinkPrefix. + \ g:vimwiki_rxWikiLinkUrl.g:vimwiki_rxWikiLinkSeparator +let g:vimwiki_rxWikiLinkSuffix1 = g:vimwiki_rxWikiLinkSuffix +" }}} + + +" LINKS: setup of wikiincl regexps {{{ +let g:vimwiki_rxWikiInclPrefix = '{{' +let g:vimwiki_rxWikiInclSuffix = '}}' +let g:vimwiki_rxWikiInclSeparator = '|' +" +" '{{__LinkUrl__}}' +let g:vimwiki_WikiInclTemplate1 = g:vimwiki_rxWikiInclPrefix . '__LinkUrl__'. + \ g:vimwiki_rxWikiInclSuffix +" '{{__LinkUrl____LinkDescription__}}' +let g:vimwiki_WikiInclTemplate2 = g:vimwiki_rxWikiInclPrefix . '__LinkUrl__'. + \ '__LinkDescription__'. + \ g:vimwiki_rxWikiInclSuffix + +let g:vimwiki_rxWikiInclPrefix = escape(g:vimwiki_rxWikiInclPrefix, magic_chars) +let g:vimwiki_rxWikiInclSuffix = escape(g:vimwiki_rxWikiInclSuffix, magic_chars) +let g:vimwiki_rxWikiInclSeparator = escape(g:vimwiki_rxWikiInclSeparator, magic_chars) +let g:vimwiki_rxWikiInclUrl = valid_chars.'\{-}' +let g:vimwiki_rxWikiInclArg = valid_chars.'\{-}' +let g:vimwiki_rxWikiInclArgs = '\%('. g:vimwiki_rxWikiInclSeparator. g:vimwiki_rxWikiInclArg. '\)'.'\{-}' +" +" +" *. {{URL}[{...}]} - i.e. {{URL}}, {{URL|ARG1}}, {{URL|ARG1|ARG2}}, etc. +" *a) match {{URL}[{...}]} +let g:vimwiki_rxWikiIncl = g:vimwiki_rxWikiInclPrefix. + \ g:vimwiki_rxWikiInclUrl. + \ g:vimwiki_rxWikiInclArgs. g:vimwiki_rxWikiInclSuffix +" *b) match URL within {{URL}[{...}]} +let g:vimwiki_rxWikiInclMatchUrl = g:vimwiki_rxWikiInclPrefix. + \ '\zs'. g:vimwiki_rxWikiInclUrl. '\ze'. + \ g:vimwiki_rxWikiInclArgs. g:vimwiki_rxWikiInclSuffix +" }}} + +" LINKS: Syntax helper {{{ +let g:vimwiki_rxWikiInclPrefix1 = g:vimwiki_rxWikiInclPrefix. + \ g:vimwiki_rxWikiInclUrl.g:vimwiki_rxWikiInclSeparator +let g:vimwiki_rxWikiInclSuffix1 = g:vimwiki_rxWikiInclArgs. + \ g:vimwiki_rxWikiInclSuffix +" }}} + +" LINKS: Setup weblink regexps {{{ +" 0. URL : free-standing links: keep URL UR(L) strip trailing punct: URL; URL) UR(L)) +" let g:vimwiki_rxWeblink = '[\["(|]\@<!'. g:vimwiki_rxWeblinkUrl . + " \ '\%([),:;.!?]\=\%([ \t]\|$\)\)\@=' +" Maxim: +" Simplify free-standing links: URL starts with non(letter|digit)scheme till +" the whitespace. +" Stuart, could you check it with markdown templated links? [](http://...), as +" the last bracket is the part of URL now? +let g:vimwiki_rxWeblink = '[[:alnum:]]\@<!'. g:vimwiki_rxWeblinkUrl . '\S*' +" 0a) match URL within URL +let g:vimwiki_rxWeblinkMatchUrl = g:vimwiki_rxWeblink +" 0b) match DESCRIPTION within URL +let g:vimwiki_rxWeblinkMatchDescr = '' +" }}} + + +" LINKS: Setup anylink regexps {{{ +let g:vimwiki_rxAnyLink = g:vimwiki_rxWikiLink.'\|'. + \ g:vimwiki_rxWikiIncl.'\|'.g:vimwiki_rxWeblink +" }}} + + +" }}} end of Links + +" LINKS: highlighting is complicated due to "nonexistent" links feature {{{ +function! s:add_target_syntax_ON(target, type) " {{{ + if g:vimwiki_debug > 1 + echom '[vimwiki_debug] syntax target > '.a:target + endif + let prefix0 = 'syntax match '.a:type.' `' + let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,'.a:type.'Char' + let prefix1 = 'syntax match '.a:type.'T `' + let suffix1 = '` display contained' + execute prefix0. a:target. suffix0 + execute prefix1. a:target. suffix1 +endfunction "}}} + +function! s:add_target_syntax_OFF(target) " {{{ + if g:vimwiki_debug > 1 + echom '[vimwiki_debug] syntax target > '.a:target + endif + let prefix0 = 'syntax match VimwikiNoExistsLink `' + let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,VimwikiLinkChar' + let prefix1 = 'syntax match VimwikiNoExistsLinkT `' + let suffix1 = '` display contained' + execute prefix0. a:target. suffix0 + execute prefix1. a:target. suffix1 +endfunction "}}} + +function! s:highlight_existing_links() "{{{ + " Wikilink + " Conditional highlighting that depends on the existence of a wiki file or + " directory is only available for *schemeless* wiki links + " Links are set up upon BufEnter (see plugin/...) + let safe_links = vimwiki#base#file_pattern(b:existing_wikifiles) + " Wikilink Dirs set up upon BufEnter (see plugin/...) + let safe_dirs = vimwiki#base#file_pattern(b:existing_wikidirs) + + " match [[URL]] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate1, + \ safe_links, g:vimwiki_rxWikiLinkDescr, '') + call s:add_target_syntax_ON(target, 'VimwikiLink') + " match [[URL|DESCRIPTION]] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate2, + \ safe_links, g:vimwiki_rxWikiLinkDescr, '') + call s:add_target_syntax_ON(target, 'VimwikiLink') + + " match {{URL}} + let target = vimwiki#base#apply_template(g:vimwiki_WikiInclTemplate1, + \ safe_links, g:vimwiki_rxWikiInclArgs, '') + call s:add_target_syntax_ON(target, 'VimwikiLink') + " match {{URL|...}} + let target = vimwiki#base#apply_template(g:vimwiki_WikiInclTemplate2, + \ safe_links, g:vimwiki_rxWikiInclArgs, '') + call s:add_target_syntax_ON(target, 'VimwikiLink') + " match [[DIRURL]] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate1, + \ safe_dirs, g:vimwiki_rxWikiLinkDescr, '') + call s:add_target_syntax_ON(target, 'VimwikiLink') + " match [[DIRURL|DESCRIPTION]] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate2, + \ safe_dirs, g:vimwiki_rxWikiLinkDescr, '') + call s:add_target_syntax_ON(target, 'VimwikiLink') +endfunction "}}} + + +" use max highlighting - could be quite slow if there are too many wikifiles +if VimwikiGet('maxhi') + " WikiLink + call s:add_target_syntax_OFF(g:vimwiki_rxWikiLink) + " WikiIncl + call s:add_target_syntax_OFF(g:vimwiki_rxWikiIncl) + + " Subsequently, links verified on vimwiki's path are highlighted as existing + let time01 = vimwiki#u#time(starttime) "XXX + call s:highlight_existing_links() + let time02 = vimwiki#u#time(starttime) "XXX +else + let time01 = vimwiki#u#time(starttime) "XXX + " Wikilink + call s:add_target_syntax_ON(g:vimwiki_rxWikiLink, 'VimwikiLink') + " WikiIncl + call s:add_target_syntax_ON(g:vimwiki_rxWikiIncl, 'VimwikiLink') + let time02 = vimwiki#u#time(starttime) "XXX +endif -" Links highlighting is controlled by vimwiki#base#highlight_links() function. -" It is called from setup_buffer_enter() function in the BufEnter autocommand. +" Weblink +call s:add_target_syntax_ON(g:vimwiki_rxWeblink, 'VimwikiLink') + +" WikiLink +" All remaining schemes are highlighted automatically +let rxSchemes = '\%('. + \ join(split(g:vimwiki_schemes, '\s*,\s*'), '\|').'\|'. + \ join(split(g:vimwiki_web_schemes1, '\s*,\s*'), '\|'). + \ '\):' + +" a) match [[nonwiki-scheme-URL]] +let target = vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate1, + \ rxSchemes.g:vimwiki_rxWikiLinkUrl, g:vimwiki_rxWikiLinkDescr, '') +call s:add_target_syntax_ON(target, 'VimwikiLink') +" b) match [[nonwiki-scheme-URL|DESCRIPTION]] +let target = vimwiki#base#apply_template(g:vimwiki_WikiLinkTemplate2, + \ rxSchemes.g:vimwiki_rxWikiLinkUrl, g:vimwiki_rxWikiLinkDescr, '') +call s:add_target_syntax_ON(target, 'VimwikiLink') + +" a) match {{nonwiki-scheme-URL}} +let target = vimwiki#base#apply_template(g:vimwiki_WikiInclTemplate1, + \ rxSchemes.g:vimwiki_rxWikiInclUrl, g:vimwiki_rxWikiInclArgs, '') +call s:add_target_syntax_ON(target, 'VimwikiLink') +" b) match {{nonwiki-scheme-URL}[{...}]} +let target = vimwiki#base#apply_template(g:vimwiki_WikiInclTemplate2, + \ rxSchemes.g:vimwiki_rxWikiInclUrl, g:vimwiki_rxWikiInclArgs, '') +call s:add_target_syntax_ON(target, 'VimwikiLink') + +" }}} + + +" generic headers "{{{ +if g:vimwiki_symH + "" symmetric + for i in range(1,6) + let g:vimwiki_rxH{i}_Template = repeat(g:vimwiki_rxH, i).' __Header__ '.repeat(g:vimwiki_rxH, i) + let g:vimwiki_rxH{i} = '^\s*'.g:vimwiki_rxH.'\{'.i.'}[^'.g:vimwiki_rxH.'].*[^'.g:vimwiki_rxH.']'.g:vimwiki_rxH.'\{'.i.'}\s*$' + endfor + let g:vimwiki_rxHeader = '^\s*\('.g:vimwiki_rxH.'\{1,6}\)\zs[^'.g:vimwiki_rxH.'].*[^'.g:vimwiki_rxH.']\ze\1\s*$' +else + " asymmetric + for i in range(1,6) + let g:vimwiki_rxH{i}_Template = repeat(g:vimwiki_rxH, i).' __Header__' + let g:vimwiki_rxH{i} = '^\s*'.g:vimwiki_rxH.'\{'.i.'}[^'.g:vimwiki_rxH.'].*$' + endfor + let g:vimwiki_rxHeader = '^\s*\('.g:vimwiki_rxH.'\{1,6}\)\zs[^'.g:vimwiki_rxH.'].*\ze$' +endif -" Load concrete Wiki syntax -execute 'runtime! syntax/vimwiki_'.VimwikiGet('syntax').'.vim' +" Header levels, 1-6 +for i in range(1,6) + execute 'syntax match VimwikiHeader'.i.' /'.g:vimwiki_rxH{i}.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiCode,VimwikiLink,@Spell' +endfor -" Concealed chars +" }}} + +" concealed chars " {{{ if exists("+conceallevel") syntax conceal on endif syntax spell toplevel -syn match VimwikiLinkChar contained /\[\[/ -syn match VimwikiLinkChar contained /\]\]/ -syn match VimwikiLinkChar contained /\[\[[^\[\]\|]\{-}|\ze.\{-}]]/ -syn match VimwikiLinkChar contained /\[\[[^\[\]\|]\{-}]\[\ze.\{-}]]/ - -syn match VimwikiNoLinkChar contained /\[\[/ -syn match VimwikiNoLinkChar contained /\]\]/ -syn match VimwikiNoLinkChar contained /\[\[[^\[\]\|]\{-}|\ze.*]]/ -syn match VimwikiNoLinkChar contained /\[\[[^\[\]\|]\{-}]\[\ze.*]]/ +if g:vimwiki_debug > 1 + echom 'WikiLink Prefix: '.g:vimwiki_rxWikiLinkPrefix1 + echom 'WikiLink Suffix: '.g:vimwiki_rxWikiLinkSuffix1 + echom 'WikiIncl Prefix: '.g:vimwiki_rxWikiInclPrefix1 + echom 'WikiIncl Suffix: '.g:vimwiki_rxWikiInclSuffix1 +endif +" VimwikiLinkChar is for syntax markers (and also URL when a description +" is present) and may be concealed +let options = ' contained transparent contains=NONE' +" conceal wikilinks +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiLinkPrefix.'/'.options +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiLinkSuffix.'/'.options +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiLinkPrefix1.'/'.options +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiLinkSuffix1.'/'.options + +" conceal wikiincls +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiInclPrefix.'/'.options +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiInclSuffix.'/'.options +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiInclPrefix1.'/'.options +execute 'syn match VimwikiLinkChar /'.g:vimwiki_rxWikiInclSuffix1.'/'.options + +" A shortener for long URLs: LinkRest (a middle part of the URL) is concealed +execute 'syn match VimwikiLinkRest contained `\%(///\=[^/ \t]\+/\)\zs\S\{' + \.g:vimwiki_url_mingain.',}\ze\%([/#?]\w\|\S\{' + \.g:vimwiki_url_maxsave.'}\)` cchar=~ '.options + +execute 'syn match VimwikiEqInChar contained /'.g:vimwiki_char_eqin.'/' execute 'syn match VimwikiBoldChar contained /'.g:vimwiki_char_bold.'/' execute 'syn match VimwikiItalicChar contained /'.g:vimwiki_char_italic.'/' execute 'syn match VimwikiBoldItalicChar contained /'.g:vimwiki_char_bolditalic.'/' @@ -44,9 +345,11 @@ execute 'syn match VimwikiSubScript contained /'.g:vimwiki_char_subscript.'/' if exists("+conceallevel") syntax conceal off endif +" }}} -" Non concealed chars -syn match VimwikiHeaderChar contained /\%(^\s*=\+\)\|\%(=\+\s*$\)/ +" non concealed chars " {{{ +execute 'syn match VimwikiHeaderChar contained /\%(^\s*'.g:vimwiki_rxH.'\+\)\|\%('.g:vimwiki_rxH.'\+\s*$\)/' +execute 'syn match VimwikiEqInCharT contained /'.g:vimwiki_char_eqin.'/' execute 'syn match VimwikiBoldCharT contained /'.g:vimwiki_char_bold.'/' execute 'syn match VimwikiItalicCharT contained /'.g:vimwiki_char_italic.'/' execute 'syn match VimwikiBoldItalicCharT contained /'.g:vimwiki_char_bolditalic.'/' @@ -56,21 +359,32 @@ execute 'syn match VimwikiDelTextCharT contained /'.g:vimwiki_char_deltext.'/' execute 'syn match VimwikiSuperScriptT contained /'.g:vimwiki_char_superscript.'/' execute 'syn match VimwikiSubScriptT contained /'.g:vimwiki_char_subscript.'/' - " Emoticons -syntax match VimwikiEmoticons /\%((.)\|:[()|$@]\|:-[DOPS()\]|$@]\|;)\|:'(\)/ +"syntax match VimwikiEmoticons /\%((.)\|:[()|$@]\|:-[DOPS()\]|$@]\|;)\|:'(\)/ let g:vimwiki_rxTodo = '\C\%(TODO:\|DONE:\|STARTED:\|FIXME:\|FIXED:\|XXX:\)' execute 'syntax match VimwikiTodo /'. g:vimwiki_rxTodo .'/' +" }}} +" main syntax groups {{{ " Tables syntax match VimwikiTableRow /^\s*|.\+|\s*$/ - \ transparent contains=VimwikiCellSeparator,VimwikiLinkT, - \ VimwikiNoExistsLinkT,VimwikiEmoticons,VimwikiTodo, - \ VimwikiBoldT,VimwikiItalicT,VimwikiBoldItalicT,VimwikiItalicBoldT, - \ VimwikiDelTextT,VimwikiSuperScriptT,VimwikiSubScriptT,VimwikiCodeT, - \ @Spell + \ transparent contains=VimwikiCellSeparator, + \ VimwikiLinkT, + \ VimwikiNoExistsLinkT, + \ VimwikiEmoticons, + \ VimwikiTodo, + \ VimwikiBoldT, + \ VimwikiItalicT, + \ VimwikiBoldItalicT, + \ VimwikiItalicBoldT, + \ VimwikiDelTextT, + \ VimwikiSuperScriptT, + \ VimwikiSubScriptT, + \ VimwikiCodeT, + \ VimwikiEqInT, + \ @Spell syntax match VimwikiCellSeparator \ /\%(|\)\|\%(-\@<=+\-\@=\)\|\%([|+]\@<=-\+\)/ contained @@ -78,6 +392,23 @@ syntax match VimwikiCellSeparator execute 'syntax match VimwikiList /'.g:vimwiki_rxListBullet.'/' execute 'syntax match VimwikiList /'.g:vimwiki_rxListNumber.'/' execute 'syntax match VimwikiList /'.g:vimwiki_rxListDefine.'/' +" List item checkbox +"syntax match VimwikiCheckBox /\[.\?\]/ +let g:vimwiki_rxCheckBox = '\s*\[['.g:vimwiki_listsyms.']\?\]\s' +" Todo lists have a checkbox +execute 'syntax match VimwikiListTodo /'.g:vimwiki_rxListBullet.g:vimwiki_rxCheckBox.'/' +execute 'syntax match VimwikiListTodo /'.g:vimwiki_rxListNumber.g:vimwiki_rxCheckBox.'/' +if g:vimwiki_hl_cb_checked + execute 'syntax match VimwikiCheckBoxDone /'. + \ g:vimwiki_rxListBullet.'\s*\['.g:vimwiki_listsyms[4].'\]\s.*$/'. + \ ' contains=VimwikiNoExistsLink,VimwikiLink' + execute 'syntax match VimwikiCheckBoxDone /'. + \ g:vimwiki_rxListNumber.'\s*\['.g:vimwiki_listsyms[4].'\]\s.*$/'. + \ ' contains=VimwikiNoExistsLink,VimwikiLink' +endif + +execute 'syntax match VimwikiEqIn /'.g:vimwiki_rxEqIn.'/ contains=VimwikiEqInChar' +execute 'syntax match VimwikiEqInT /'.g:vimwiki_rxEqIn.'/ contained contains=VimwikiEqInCharT' execute 'syntax match VimwikiBold /'.g:vimwiki_rxBold.'/ contains=VimwikiBoldChar,@Spell' execute 'syntax match VimwikiBoldT /'.g:vimwiki_rxBold.'/ contained contains=VimwikiBoldCharT,@Spell' @@ -103,23 +434,15 @@ execute 'syntax match VimwikiSubScriptT /'.g:vimwiki_rxSubScript.'/ contained co execute 'syntax match VimwikiCode /'.g:vimwiki_rxCode.'/ contains=VimwikiCodeChar' execute 'syntax match VimwikiCodeT /'.g:vimwiki_rxCode.'/ contained contains=VimwikiCodeCharT' - " <hr> horizontal rule execute 'syntax match VimwikiHR /'.g:vimwiki_rxHR.'/' execute 'syntax region VimwikiPre start=/^\s*'.g:vimwiki_rxPreStart. \ '/ end=/^\s*'.g:vimwiki_rxPreEnd.'\s*$/ contains=@Spell' -" List item checkbox -syntax match VimwikiCheckBox /\[.\?\]/ -if g:vimwiki_hl_cb_checked - execute 'syntax match VimwikiCheckBoxDone /'. - \ g:vimwiki_rxListBullet.'\s*\['.g:vimwiki_listsyms[4].'\].*$/'. - \ ' contains=VimwikiNoExistsLink,VimwikiLink' - execute 'syntax match VimwikiCheckBoxDone /'. - \ g:vimwiki_rxListNumber.'\s*\['.g:vimwiki_listsyms[4].'\].*$/'. - \ ' contains=VimwikiNoExistsLink,VimwikiLink' -endif +execute 'syntax region VimwikiMath start=/^\s*'.g:vimwiki_rxMathStart. + \ '/ end=/^\s*'.g:vimwiki_rxMathEnd.'\s*$/ contains=@Spell' + " placeholders syntax match VimwikiPlaceholder /^\s*%toc\%(\s.*\)\?$/ contains=VimwikiPlaceholderParam @@ -129,51 +452,48 @@ syntax match VimwikiPlaceholder /^\s*%template\%(\s.*\)\?$/ contains=VimwikiPlac syntax match VimwikiPlaceholderParam /\s.*/ contained " html tags -let html_tags = join(split(g:vimwiki_valid_html_tags, '\s*,\s*'), '\|') -exe 'syntax match VimwikiHTMLtag #\c</\?\%('.html_tags.'\)\%(\s\{-1}\S\{-}\)\{-}\s*/\?>#' -execute 'syntax match VimwikiBold #\c<b>.\{-}</b># contains=VimwikiHTMLTag' -execute 'syntax match VimwikiItalic #\c<i>.\{-}</i># contains=VimwikiHTMLTag' -execute 'syntax match VimwikiUnderline #\c<u>.\{-}</u># contains=VimwikiHTMLTag' - -execute 'syntax match VimwikiComment /'.g:vimwiki_rxComment.'/ contains=@Spell' - -" Header levels, 1-6 -execute 'syntax match VimwikiHeader1 /'.g:vimwiki_rxH1.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiLink,@Spell' -execute 'syntax match VimwikiHeader2 /'.g:vimwiki_rxH2.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiLink,@Spell' -execute 'syntax match VimwikiHeader3 /'.g:vimwiki_rxH3.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiLink,@Spell' -execute 'syntax match VimwikiHeader4 /'.g:vimwiki_rxH4.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiLink,@Spell' -execute 'syntax match VimwikiHeader5 /'.g:vimwiki_rxH5.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiLink,@Spell' -execute 'syntax match VimwikiHeader6 /'.g:vimwiki_rxH6.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiLink,@Spell' +if g:vimwiki_valid_html_tags != '' + let html_tags = join(split(g:vimwiki_valid_html_tags, '\s*,\s*'), '\|') + exe 'syntax match VimwikiHTMLtag #\c</\?\%('.html_tags.'\)\%(\s\{-1}\S\{-}\)\{-}\s*/\?>#' + execute 'syntax match VimwikiBold #\c<b>.\{-}</b># contains=VimwikiHTMLTag' + execute 'syntax match VimwikiItalic #\c<i>.\{-}</i># contains=VimwikiHTMLTag' + execute 'syntax match VimwikiUnderline #\c<u>.\{-}</u># contains=VimwikiHTMLTag' + + execute 'syntax match VimwikiComment /'.g:vimwiki_rxComment.'/ contains=@Spell' +endif +" }}} -" group names "{{{ +" header groups highlighting "{{{ if g:vimwiki_hl_headers == 0 - hi link VimwikiHeader1 Title - hi link VimwikiHeader2 Title - hi link VimwikiHeader3 Title - hi link VimwikiHeader4 Title - hi link VimwikiHeader5 Title - hi link VimwikiHeader6 Title -else - if &background == 'light' - hi def VimwikiHeader1 guibg=bg guifg=#aa5858 gui=bold ctermfg=DarkRed term=bold cterm=bold - hi def VimwikiHeader2 guibg=bg guifg=#507030 gui=bold ctermfg=DarkGreen term=bold cterm=bold - hi def VimwikiHeader3 guibg=bg guifg=#1030a0 gui=bold ctermfg=DarkBlue term=bold cterm=bold - hi def VimwikiHeader4 guibg=bg guifg=#103040 gui=bold ctermfg=Black term=bold cterm=bold - hi def VimwikiHeader5 guibg=bg guifg=#505050 gui=bold ctermfg=Black term=bold cterm=bold - hi def VimwikiHeader6 guibg=bg guifg=#636363 gui=bold ctermfg=Black term=bold cterm=bold - else - hi def VimwikiHeader1 guibg=bg guifg=#e08090 gui=bold ctermfg=Red term=bold cterm=bold - hi def VimwikiHeader2 guibg=bg guifg=#80e090 gui=bold ctermfg=Green term=bold cterm=bold - hi def VimwikiHeader3 guibg=bg guifg=#6090e0 gui=bold ctermfg=Blue term=bold cterm=bold - hi def VimwikiHeader4 guibg=bg guifg=#c0c0f0 gui=bold ctermfg=White term=bold cterm=bold - hi def VimwikiHeader5 guibg=bg guifg=#e0e0f0 gui=bold ctermfg=White term=bold cterm=bold - hi def VimwikiHeader6 guibg=bg guifg=#f0f0f0 gui=bold ctermfg=White term=bold cterm=bold + " Strangely in default colorscheme Title group is not set to bold for cterm... + if !exists("g:colors_name") + hi Title cterm=bold endif + for i in range(1,6) + execute 'hi def link VimwikiHeader'.i.' Title' + endfor +else + " default colors when headers of different levels are highlighted differently + " not making it yet another option; needed by ColorScheme autocommand + let g:vimwiki_hcolor_guifg_light = ['#aa5858','#507030','#1030a0','#103040','#505050','#636363'] + let g:vimwiki_hcolor_ctermfg_light = ['DarkRed','DarkGreen','DarkBlue','Black','Black','Black'] + let g:vimwiki_hcolor_guifg_dark = ['#e08090','#80e090','#6090e0','#c0c0f0','#e0e0f0','#f0f0f0'] + let g:vimwiki_hcolor_ctermfg_dark = ['Red','Green','Blue','White','White','White'] + for i in range(1,6) + execute 'hi def VimwikiHeader'.i.' guibg=bg guifg='.g:vimwiki_hcolor_guifg_{&bg}[i-1].' gui=bold ctermfg='.g:vimwiki_hcolor_ctermfg_{&bg}[i-1].' term=bold cterm=bold' + endfor endif +"}}} + + +" syntax group highlighting "{{{ hi def link VimwikiMarkers Normal +hi def link VimwikiEqIn Number +hi def link VimwikiEqInT VimwikiEqIn + hi def VimwikiBold term=bold cterm=bold gui=bold hi def link VimwikiBoldT VimwikiBold @@ -193,6 +513,9 @@ hi def link VimwikiCodeT VimwikiCode hi def link VimwikiPre PreProc hi def link VimwikiPreT VimwikiPre +hi def link VimwikiMath Number +hi def link VimwikiMathT VimwikiMath + hi def link VimwikiNoExistsLink SpellBad hi def link VimwikiNoExistsLinkT VimwikiNoExistsLink @@ -200,9 +523,11 @@ hi def link VimwikiLink Underlined hi def link VimwikiLinkT VimwikiLink hi def link VimwikiList Identifier -hi def link VimwikiCheckBox VimwikiList +hi def link VimwikiListTodo VimwikiList +"hi def link VimwikiCheckBox VimwikiList hi def link VimwikiCheckBoxDone Comment hi def link VimwikiEmoticons Character +hi def link VimwikiHR Identifier hi def link VimwikiDelText Constant hi def link VimwikiDelTextT VimwikiDelText @@ -220,6 +545,7 @@ hi def link VimwikiPlaceholder SpecialKey hi def link VimwikiPlaceholderParam String hi def link VimwikiHTMLtag SpecialKey +hi def link VimwikiEqInChar VimwikiMarkers hi def link VimwikiCellSeparator VimwikiMarkers hi def link VimwikiBoldChar VimwikiMarkers hi def link VimwikiItalicChar VimwikiMarkers @@ -230,9 +556,8 @@ hi def link VimwikiSuperScriptChar VimwikiMarkers hi def link VimwikiSubScriptChar VimwikiMarkers hi def link VimwikiCodeChar VimwikiMarkers hi def link VimwikiHeaderChar VimwikiMarkers -hi def link VimwikiLinkChar VimwikiLink -hi def link VimwikiNoLinkChar VimwikiNoExistsLink +hi def link VimwikiEqInCharT VimwikiMarkers hi def link VimwikiBoldCharT VimwikiMarkers hi def link VimwikiItalicCharT VimwikiMarkers hi def link VimwikiBoldItalicCharT VimwikiMarkers @@ -243,9 +568,14 @@ hi def link VimwikiSubScriptCharT VimwikiMarkers hi def link VimwikiCodeCharT VimwikiMarkers hi def link VimwikiHeaderCharT VimwikiMarkers hi def link VimwikiLinkCharT VimwikiLinkT -hi def link VimwikiNoLinkCharT VimwikiNoExistsLinkT +hi def link VimwikiNoExistsLinkCharT VimwikiNoExistsLinkT "}}} +" ------------------------------------------------------------------------- +" Load syntax-specific functionality +execute 'runtime! syntax/vimwiki_'.VimwikiGet('syntax').'_custom.vim' +" ------------------------------------------------------------------------- + let b:current_syntax="vimwiki" " EMBEDDED syntax setup "{{{ @@ -253,9 +583,16 @@ let nested = VimwikiGet('nested_syntaxes') if !empty(nested) for [hl_syntax, vim_syntax] in items(nested) call vimwiki#base#nested_syntax(vim_syntax, - \ '^\s*{{{\%(.*[[:blank:][:punct:]]\)\?'. + \ '^\s*'.g:vimwiki_rxPreStart.'\%(.*[[:blank:][:punct:]]\)\?'. \ hl_syntax.'\%([[:blank:][:punct:]].*\)\?', - \ '^\s*}}}', 'VimwikiPre') + \ '^\s*'.g:vimwiki_rxPreEnd, 'VimwikiPre') +" call vimwiki#base#nested_syntax(vim_syntax, +" \ '^\s*{{\$\%(.*[[:blank:][:punct:]]\)\?'. +" \ hl_syntax.'\%([[:blank:][:punct:]].*\)\?', +" \ '^\s*}}\$', 'VimwikiMath') endfor endif "}}} + +let timeend = vimwiki#u#time(starttime) "XXX +call VimwikiLog_extend('timing',['syntax:scans',timescans],['syntax:regexloaded',time0],['syntax:beforeHLexisting',time01],['syntax:afterHLexisting',time02],['syntax:end',timeend]) diff --git a/syntax/vimwiki_default.vim b/syntax/vimwiki_default.vim @@ -4,6 +4,13 @@ " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ +" placeholder for math environments +let b:vimwiki_mathEnv = "" + +" text: $ equation_inline $ +let g:vimwiki_rxEqIn = '\$[^$`]\+\$' +let g:vimwiki_char_eqin = '\$' + " text: *strong* " let g:vimwiki_rxBold = '\*[^*]\+\*' let g:vimwiki_rxBold = '\%(^\|\s\|[[:punct:]]\)\@<='. @@ -53,27 +60,20 @@ let g:vimwiki_char_superscript = '^' let g:vimwiki_rxSubScript = ',,[^,`]\+,,' let g:vimwiki_char_subscript = ',,' -" Header levels, 1-6 -let g:vimwiki_rxH1 = '^\s*=\{1}[^=]\+.*[^=]\+=\{1}\s*$' -let g:vimwiki_rxH2 = '^\s*=\{2}[^=]\+.*[^=]\+=\{2}\s*$' -let g:vimwiki_rxH3 = '^\s*=\{3}[^=]\+.*[^=]\+=\{3}\s*$' -let g:vimwiki_rxH4 = '^\s*=\{4}[^=]\+.*[^=]\+=\{4}\s*$' -let g:vimwiki_rxH5 = '^\s*=\{5}[^=]\+.*[^=]\+=\{5}\s*$' -let g:vimwiki_rxH6 = '^\s*=\{6}[^=]\+.*[^=]\+=\{6}\s*$' -let g:vimwiki_rxHeader = '\%('.g:vimwiki_rxH1.'\)\|'. - \ '\%('.g:vimwiki_rxH2.'\)\|'. - \ '\%('.g:vimwiki_rxH3.'\)\|'. - \ '\%('.g:vimwiki_rxH4.'\)\|'. - \ '\%('.g:vimwiki_rxH5.'\)\|'. - \ '\%('.g:vimwiki_rxH6.'\)' - -let g:vimwiki_char_header = '\%(^\s*=\+\)\|\%(=\+\s*$\)' +" generic headers +let g:vimwiki_rxH = '=' +let g:vimwiki_symH = 1 + + " <hr>, horizontal rule -let g:vimwiki_rxHR = '^----.*$' +let g:vimwiki_rxHR = '^-----*$' + +" Tables. Each line starts and ends with '|'; each cell is separated by '|' +let g:vimwiki_rxTableSep = '|' " List items start with optional whitespace(s) then '* ' or '# ' -let g:vimwiki_rxListBullet = '^\s*\%(\*\|-\)\s' +let g:vimwiki_rxListBullet = '^\s*[*-]\s' let g:vimwiki_rxListNumber = '^\s*#\s' let g:vimwiki_rxListDefine = '::\(\s\|$\)' @@ -82,4 +82,8 @@ let g:vimwiki_rxListDefine = '::\(\s\|$\)' let g:vimwiki_rxPreStart = '{{{' let g:vimwiki_rxPreEnd = '}}}' +" Math block +let g:vimwiki_rxMathStart = '{{\$' +let g:vimwiki_rxMathEnd = '}}\$' + let g:vimwiki_rxComment = '^\s*%%.*$' diff --git a/syntax/vimwiki_markdown.vim b/syntax/vimwiki_markdown.vim @@ -0,0 +1,89 @@ +" 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/ + +" placeholder for math environments +let b:vimwiki_mathEnv = "" + +" text: $ equation_inline $ +let g:vimwiki_rxEqIn = '\$[^$`]\+\$' +let g:vimwiki_char_eqin = '\$' + +" text: *strong* +" let g:vimwiki_rxBold = '\*[^*]\+\*' +let g:vimwiki_rxBold = '\%(^\|\s\|[[:punct:]]\)\@<='. + \'\*'. + \'\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)'. + \'\*'. + \'\%([[:punct:]]\|\s\|$\)\@=' +let g:vimwiki_char_bold = '*' + +" text: _emphasis_ +" let g:vimwiki_rxItalic = '_[^_]\+_' +let g:vimwiki_rxItalic = '\%(^\|\s\|[[:punct:]]\)\@<='. + \'_'. + \'\%([^_`[:space:]][^_`]*[^_`[:space:]]\|[^_`[:space:]]\)'. + \'_'. + \'\%([[:punct:]]\|\s\|$\)\@=' +let g:vimwiki_char_italic = '_' + +" text: *_bold italic_* or _*italic bold*_ +let g:vimwiki_rxBoldItalic = '\%(^\|\s\|[[:punct:]]\)\@<='. + \'\*_'. + \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'. + \'_\*'. + \'\%([[:punct:]]\|\s\|$\)\@=' +let g:vimwiki_char_bolditalic = '\*_' + +let g:vimwiki_rxItalicBold = '\%(^\|\s\|[[:punct:]]\)\@<='. + \'_\*'. + \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'. + \'\*_'. + \'\%([[:punct:]]\|\s\|$\)\@=' +let g:vimwiki_char_italicbold = '_\*' + +" text: `code` +let g:vimwiki_rxCode = '`[^`]\+`' +let g:vimwiki_char_code = '`' + +" text: ~~deleted text~~ +let g:vimwiki_rxDelText = '\~\~[^~`]\+\~\~' +let g:vimwiki_char_deltext = '\~\~' + +" text: ^superscript^ +let g:vimwiki_rxSuperScript = '\^[^^`]\+\^' +let g:vimwiki_char_superscript = '^' + +" text: ,,subscript,, +let g:vimwiki_rxSubScript = ',,[^,`]\+,,' +let g:vimwiki_char_subscript = ',,' + +" generic headers +let g:vimwiki_rxH = '#' +let g:vimwiki_symH = 0 + + + +" <hr>, horizontal rule +let g:vimwiki_rxHR = '^-----*$' + +" Tables. Each line starts and ends with '|'; each cell is separated by '|' +let g:vimwiki_rxTableSep = '|' + +" List items start with optional whitespace(s) then '* ' or '1. ', '2. ', etc. +let g:vimwiki_rxListBullet = '^\s*[*+-]\s' +let g:vimwiki_rxListNumber = '^\s*[0-9]\+\.\s' + +let g:vimwiki_rxListDefine = '::\%(\s\|$\)' + +" Preformatted text +let g:vimwiki_rxPreStart = '```' +let g:vimwiki_rxPreEnd = '```' + +" Math block +let g:vimwiki_rxMathStart = '{{\$' +let g:vimwiki_rxMathEnd = '}}\$' + +let g:vimwiki_rxComment = '^\s*%%.*$' diff --git a/syntax/vimwiki_markdown_custom.vim b/syntax/vimwiki_markdown_custom.vim @@ -0,0 +1,367 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" Vimwiki syntax file +" Author: Stuart Andrews <stu.andrews@gmail.com> +" Home: http://code.google.com/p/vimwiki/ + +" LINKS: assume this is common to all syntaxes "{{{ + +" }}} + +" ------------------------------------------------------------------------- +" Load concrete Wiki syntax: sets regexes and templates for headers and links + +" ------------------------------------------------------------------------- + + + +" LINKS: setup of larger regexes {{{ + +" LINKS: setup wikilink0 regexps {{{ +" 0. [[URL]], or [[URL|DESCRIPTION]] + +" 0a) match [[URL|DESCRIPTION]] +let g:vimwiki_rxWikiLink0 = g:vimwiki_rxWikiLink +" 0b) match URL within [[URL|DESCRIPTION]] +let g:vimwiki_rxWikiLink0MatchUrl = g:vimwiki_rxWikiLinkMatchUrl +" 0c) match DESCRIPTION within [[URL|DESCRIPTION]] +let g:vimwiki_rxWikiLink0MatchDescr = g:vimwiki_rxWikiLinkMatchDescr +" }}} + +" LINKS: setup wikilink1 regexps {{{ +" 1. [URL][], or [DESCRIPTION][URL] + +let g:vimwiki_rxWikiLink1Prefix = '[' +let g:vimwiki_rxWikiLink1Suffix = ']' +let g:vimwiki_rxWikiLink1Separator = '][' + +" [URL][] +let g:vimwiki_WikiLink1Template1 = g:vimwiki_rxWikiLink1Prefix . '__LinkUrl__'. + \ g:vimwiki_rxWikiLink1Separator. g:vimwiki_rxWikiLink1Suffix +" [DESCRIPTION][URL] +let g:vimwiki_WikiLink1Template2 = g:vimwiki_rxWikiLink1Prefix . '__LinkDescription__'. + \ g:vimwiki_rxWikiLink1Separator. '__LinkUrl__'. + \ g:vimwiki_rxWikiLink1Suffix +" +let magic_chars = '.*[]\^$' +let valid_chars = '[^\\\[\]]' + +let g:vimwiki_rxWikiLink1Prefix = escape(g:vimwiki_rxWikiLink1Prefix, magic_chars) +let g:vimwiki_rxWikiLink1Suffix = escape(g:vimwiki_rxWikiLink1Suffix, magic_chars) +let g:vimwiki_rxWikiLink1Separator = escape(g:vimwiki_rxWikiLink1Separator, magic_chars) +let g:vimwiki_rxWikiLink1Url = valid_chars.'\{-}' +let g:vimwiki_rxWikiLink1Descr = valid_chars.'\{-}' + +let g:vimwiki_rxWikiLink1InvalidPrefix = '[\]\[]\@<!' +let g:vimwiki_rxWikiLink1InvalidSuffix = '[\]\[]\@!' +let g:vimwiki_rxWikiLink1Prefix = g:vimwiki_rxWikiLink1InvalidPrefix. + \ g:vimwiki_rxWikiLink1Prefix +let g:vimwiki_rxWikiLink1Suffix = g:vimwiki_rxWikiLink1Suffix. + \ g:vimwiki_rxWikiLink1InvalidSuffix + +" +" 1. [URL][], [DESCRIPTION][URL] +" 1a) match [URL][], [DESCRIPTION][URL] +let g:vimwiki_rxWikiLink1 = g:vimwiki_rxWikiLink1Prefix. + \ g:vimwiki_rxWikiLink1Url. g:vimwiki_rxWikiLink1Separator. + \ g:vimwiki_rxWikiLink1Suffix. + \ '\|'. g:vimwiki_rxWikiLink1Prefix. + \ g:vimwiki_rxWikiLink1Descr.g:vimwiki_rxWikiLink1Separator. + \ g:vimwiki_rxWikiLink1Url.g:vimwiki_rxWikiLink1Suffix +" 1b) match URL within [URL][], [DESCRIPTION][URL] +let g:vimwiki_rxWikiLink1MatchUrl = g:vimwiki_rxWikiLink1Prefix. + \ '\zs'. g:vimwiki_rxWikiLink1Url. '\ze'. g:vimwiki_rxWikiLink1Separator. + \ g:vimwiki_rxWikiLink1Suffix. + \ '\|'. g:vimwiki_rxWikiLink1Prefix. + \ g:vimwiki_rxWikiLink1Descr. g:vimwiki_rxWikiLink1Separator. + \ '\zs'. g:vimwiki_rxWikiLink1Url. '\ze'. g:vimwiki_rxWikiLink1Suffix +" 1c) match DESCRIPTION within [DESCRIPTION][URL] +let g:vimwiki_rxWikiLink1MatchDescr = g:vimwiki_rxWikiLink1Prefix. + \ '\zs'. g:vimwiki_rxWikiLink1Descr.'\ze'. g:vimwiki_rxWikiLink1Separator. + \ g:vimwiki_rxWikiLink1Url.g:vimwiki_rxWikiLink1Suffix +" }}} + +" LINKS: Syntax helper {{{ +let g:vimwiki_rxWikiLink1Prefix1 = g:vimwiki_rxWikiLink1Prefix +let g:vimwiki_rxWikiLink1Suffix1 = g:vimwiki_rxWikiLink1Separator. + \ g:vimwiki_rxWikiLink1Url.g:vimwiki_rxWikiLink1Suffix +" }}} + +" *. ANY wikilink {{{ +" *a) match ANY wikilink +let g:vimwiki_rxWikiLink = ''. + \ g:vimwiki_rxWikiLink0.'\|'. + \ g:vimwiki_rxWikiLink1 +" *b) match URL within ANY wikilink +let g:vimwiki_rxWikiLinkMatchUrl = ''. + \ g:vimwiki_rxWikiLink0MatchUrl.'\|'. + \ g:vimwiki_rxWikiLink1MatchUrl +" *c) match DESCRIPTION within ANY wikilink +let g:vimwiki_rxWikiLinkMatchDescr = ''. + \ g:vimwiki_rxWikiLink0MatchDescr.'\|'. + \ g:vimwiki_rxWikiLink1MatchDescr +" }}} + + +" LINKS: setup of wikiincl regexps {{{ +" }}} + +" LINKS: Syntax helper {{{ +" }}} + +" LINKS: Setup weblink0 regexps {{{ +" 0. URL : free-standing links: keep URL UR(L) strip trailing punct: URL; URL) UR(L)) +let g:vimwiki_rxWeblink0 = g:vimwiki_rxWeblink +" 0a) match URL within URL +let g:vimwiki_rxWeblinkMatchUrl0 = g:vimwiki_rxWeblinkMatchUrl +" 0b) match DESCRIPTION within URL +let g:vimwiki_rxWeblinkMatchDescr0 = g:vimwiki_rxWeblinkMatchDescr +" }}} + +" LINKS: Setup weblink1 regexps {{{ +let g:vimwiki_rxWeblink1Prefix = '[' +let g:vimwiki_rxWeblink1Suffix = ')' +let g:vimwiki_rxWeblink1Separator = '](' +" [DESCRIPTION](URL) +let g:vimwiki_Weblink1Template = g:vimwiki_rxWeblink1Prefix . '__LinkDescription__'. + \ g:vimwiki_rxWeblink1Separator. '__LinkUrl__'. + \ g:vimwiki_rxWeblink1Suffix + +let magic_chars = '.*[]\^$' +let valid_chars = '[^\\]' + +let g:vimwiki_rxWeblink1Prefix = escape(g:vimwiki_rxWeblink1Prefix, magic_chars) +let g:vimwiki_rxWeblink1Suffix = escape(g:vimwiki_rxWeblink1Suffix, magic_chars) +let g:vimwiki_rxWeblink1Separator = escape(g:vimwiki_rxWeblink1Separator, magic_chars) +let g:vimwiki_rxWeblink1Url = valid_chars.'\{-}' +let g:vimwiki_rxWeblink1Descr = valid_chars.'\{-}' + +" +" " 2012-02-04 TODO not starting with [[ or ][ ? ... prefix = '[\[\]]\@<!\[' +" 1. [DESCRIPTION](URL) +" 1a) match [DESCRIPTION](URL) +let g:vimwiki_rxWeblink1 = g:vimwiki_rxWeblink1Prefix. + \ g:vimwiki_rxWeblink1Url.g:vimwiki_rxWeblink1Separator. + \ g:vimwiki_rxWeblink1Descr.g:vimwiki_rxWeblink1Suffix +" 1b) match URL within [DESCRIPTION](URL) +let g:vimwiki_rxWeblink1MatchUrl = g:vimwiki_rxWeblink1Prefix. + \ g:vimwiki_rxWeblink1Descr. g:vimwiki_rxWeblink1Separator. + \ '\zs'.g:vimwiki_rxWeblink1Url.'\ze'. g:vimwiki_rxWeblink1Suffix +" 1c) match DESCRIPTION within [DESCRIPTION](URL) +let g:vimwiki_rxWeblink1MatchDescr = g:vimwiki_rxWeblink1Prefix. + \ '\zs'.g:vimwiki_rxWeblink1Descr.'\ze'. g:vimwiki_rxWeblink1Separator. + \ g:vimwiki_rxWeblink1Url. g:vimwiki_rxWeblink1Suffix +" }}} + +" Syntax helper {{{ +" TODO: image links too !! +" let g:vimwiki_rxWeblink1Prefix1 = '!\?'. g:vimwiki_rxWeblink1Prefix +let g:vimwiki_rxWeblink1Prefix1 = g:vimwiki_rxWeblink1Prefix +let g:vimwiki_rxWeblink1Suffix1 = g:vimwiki_rxWeblink1Separator. + \ g:vimwiki_rxWeblink1Url.g:vimwiki_rxWeblink1Suffix +" }}} + +" *. ANY weblink {{{ +" *a) match ANY weblink +let g:vimwiki_rxWeblink = ''. + \ g:vimwiki_rxWeblink1.'\|'. + \ g:vimwiki_rxWeblink0 +" *b) match URL within ANY weblink +let g:vimwiki_rxWeblinkMatchUrl = ''. + \ g:vimwiki_rxWeblink1MatchUrl.'\|'. + \ g:vimwiki_rxWeblinkMatchUrl0 +" *c) match DESCRIPTION within ANY weblink +let g:vimwiki_rxWeblinkMatchDescr = ''. + \ g:vimwiki_rxWeblink1MatchDescr.'\|'. + \ g:vimwiki_rxWeblinkMatchDescr0 +" }}} + + +" LINKS: Setup anylink regexps {{{ +let g:vimwiki_rxAnyLink = g:vimwiki_rxWikiLink.'\|'. + \ g:vimwiki_rxWikiIncl.'\|'.g:vimwiki_rxWeblink +" }}} + + +" }}} end of Links + +" LINKS: highlighting is complicated due to "nonexistent" links feature {{{ +function! s:add_target_syntax_ON(target, type) " {{{ + if g:vimwiki_debug > 1 + echom '[vimwiki_debug] syntax target > '.a:target + endif + let prefix0 = 'syntax match '.a:type.' `' + let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,'.a:type.'Char' + let prefix1 = 'syntax match '.a:type.'T `' + let suffix1 = '` display contained' + execute prefix0. a:target. suffix0 + execute prefix1. a:target. suffix1 +endfunction "}}} + +function! s:add_target_syntax_OFF(target, type) " {{{ + if g:vimwiki_debug > 1 + echom '[vimwiki_debug] syntax target > '.a:target + endif + let prefix0 = 'syntax match VimwikiNoExistsLink `' + let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,'.a:type.'Char' + let prefix1 = 'syntax match VimwikiNoExistsLinkT `' + let suffix1 = '` display contained' + execute prefix0. a:target. suffix0 + execute prefix1. a:target. suffix1 +endfunction "}}} + +function! s:wrap_wikilink1_rx(target) "{{{ + return g:vimwiki_rxWikiLink1InvalidPrefix.a:target. + \ g:vimwiki_rxWikiLink1InvalidSuffix +endfunction "}}} + +function! s:highlight_existing_links() "{{{ + " Wikilink1 + " Conditional highlighting that depends on the existence of a wiki file or + " directory is only available for *schemeless* wiki links + " Links are set up upon BufEnter (see plugin/...) + let safe_links = vimwiki#base#file_pattern(b:existing_wikifiles) + " Wikilink1 Dirs set up upon BufEnter (see plugin/...) + let safe_dirs = vimwiki#base#file_pattern(b:existing_wikidirs) + + " match [URL] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLink1Template1, + \ safe_links, g:vimwiki_rxWikiLink1Descr, '') + call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1') + " match [DESCRIPTION][URL] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLink1Template2, + \ safe_links, g:vimwiki_rxWikiLink1Descr, '') + call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1') + + " match [DIRURL] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLink1Template1, + \ safe_dirs, g:vimwiki_rxWikiLink1Descr, '') + call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1') + " match [DESCRIPTION][DIRURL] + let target = vimwiki#base#apply_template(g:vimwiki_WikiLink1Template2, + \ safe_dirs, g:vimwiki_rxWikiLink1Descr, '') + call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1') +endfunction "}}} + + +" use max highlighting - could be quite slow if there are too many wikifiles +if VimwikiGet('maxhi') + " WikiLink + call s:add_target_syntax_OFF(g:vimwiki_rxWikiLink1, 'VimwikiWikiLink1') + + " Subsequently, links verified on vimwiki's path are highlighted as existing + let time01 = vimwiki#u#time(starttime) "XXX + call s:highlight_existing_links() + let time02 = vimwiki#u#time(starttime) "XXX +else + let time01 = vimwiki#u#time(starttime) "XXX + " Wikilink + call s:add_target_syntax_ON(g:vimwiki_rxWikiLink1, 'VimwikiWikiLink1') + let time02 = vimwiki#u#time(starttime) "XXX +endif + +" Weblink +call s:add_target_syntax_ON(g:vimwiki_rxWeblink1, 'VimwikiWeblink1') + +" WikiLink +" All remaining schemes are highlighted automatically +let rxSchemes = '\%('. + \ join(split(g:vimwiki_schemes, '\s*,\s*'), '\|').'\|'. + \ join(split(g:vimwiki_web_schemes1, '\s*,\s*'), '\|'). + \ '\):' + +" a) match [nonwiki-scheme-URL] +let target = vimwiki#base#apply_template(g:vimwiki_WikiLink1Template1, + \ rxSchemes.g:vimwiki_rxWikiLink1Url, g:vimwiki_rxWikiLink1Descr, '') +call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1') +" b) match [DESCRIPTION][nonwiki-scheme-URL] +let target = vimwiki#base#apply_template(g:vimwiki_WikiLink1Template2, + \ rxSchemes.g:vimwiki_rxWikiLink1Url, g:vimwiki_rxWikiLink1Descr, '') +call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1') +" }}} + + +" generic headers "{{{ + +" Header levels, 1-6 +for i in range(1,6) + execute 'syntax match VimwikiHeader'.i.' /'.g:vimwiki_rxH{i}.'/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiCode,VimwikiLink,VimwikiWeblink1,VimwikiWikiLink1,@Spell' +endfor + +" }}} + +" concealed chars " {{{ +if exists("+conceallevel") + syntax conceal on +endif + +syntax spell toplevel + +if g:vimwiki_debug > 1 + echom 'WikiLink1 Prefix: '.g:vimwiki_rxWikiLink1Prefix1 + echom 'WikiLink1 Suffix: '.g:vimwiki_rxWikiLink1Suffix1 + echom 'Weblink1 Prefix: '.g:vimwiki_rxWeblink1Prefix1 + echom 'Weblink1 Suffix: '.g:vimwiki_rxWeblink1Suffix1 +endif + +" VimwikiWikiLink1Char is for syntax markers (and also URL when a description +" is present) and may be concealed +let options = ' contained transparent contains=NONE' +" conceal wikilink1 +execute 'syn match VimwikiWikiLink1Char /'.g:vimwiki_rxWikiLink1Prefix.'/'.options +execute 'syn match VimwikiWikiLink1Char /'.g:vimwiki_rxWikiLink1Suffix.'/'.options +execute 'syn match VimwikiWikiLink1Char /'.g:vimwiki_rxWikiLink1Prefix1.'/'.options +execute 'syn match VimwikiWikiLink1Char /'.g:vimwiki_rxWikiLink1Suffix1.'/'.options + +" conceal weblink1 +execute 'syn match VimwikiWeblink1Char "'.g:vimwiki_rxWeblink1Prefix1.'"'.options +execute 'syn match VimwikiWeblink1Char "'.g:vimwiki_rxWeblink1Suffix1.'"'.options + +if exists("+conceallevel") + syntax conceal off +endif +" }}} + +" non concealed chars " {{{ +" }}} + +" main syntax groups {{{ + +" Tables +syntax match VimwikiTableRow /^\s*|.\+|\s*$/ + \ transparent contains=VimwikiCellSeparator, + \ VimwikiLinkT, + \ VimwikiWeblink1T, + \ VimwikiWikiLink1T, + \ VimwikiNoExistsLinkT, + \ VimwikiEmoticons, + \ VimwikiTodo, + \ VimwikiBoldT, + \ VimwikiItalicT, + \ VimwikiBoldItalicT, + \ VimwikiItalicBoldT, + \ VimwikiDelTextT, + \ VimwikiSuperScriptT, + \ VimwikiSubScriptT, + \ VimwikiCodeT, + \ VimwikiEqInT, + \ @Spell + +" }}} + +" header groups highlighting "{{{ +"}}} + + +" syntax group highlighting "{{{ +hi def link VimwikiWeblink1 VimwikiLink +hi def link VimwikiWeblink1T VimwikiLink + +hi def link VimwikiWikiLink1 VimwikiLink +hi def link VimwikiWikiLink1T VimwikiLink +"}}} + + + +" EMBEDDED syntax setup "{{{ +"}}} +" diff --git a/syntax/vimwiki_media.vim b/syntax/vimwiki_media.vim @@ -4,6 +4,13 @@ " Author: Maxim Kim <habamax@gmail.com> " Home: http://code.google.com/p/vimwiki/ +" placeholder for math environments +let b:vimwiki_mathEnv = "" + +" text: $ equation_inline $ +let g:vimwiki_rxEqIn = '\$[^$`]\+\$' +let g:vimwiki_char_eqin = '\$' + " text: '''strong''' let g:vimwiki_rxBold = "'''[^']\\+'''" let g:vimwiki_char_bold = "'''" @@ -34,31 +41,22 @@ let g:vimwiki_char_superscript = '^' let g:vimwiki_rxSubScript = ',,[^,]\+,,' let g:vimwiki_char_subscript = ',,' -" Header levels, 1-6 -let g:vimwiki_rxH1 = '^\s*=\{1}[^=]\+.*[^=]\+=\{1}\s*$' -let g:vimwiki_rxH2 = '^\s*=\{2}[^=]\+.*[^=]\+=\{2}\s*$' -let g:vimwiki_rxH3 = '^\s*=\{3}[^=]\+.*[^=]\+=\{3}\s*$' -let g:vimwiki_rxH4 = '^\s*=\{4}[^=]\+.*[^=]\+=\{4}\s*$' -let g:vimwiki_rxH5 = '^\s*=\{5}[^=]\+.*[^=]\+=\{5}\s*$' -let g:vimwiki_rxH6 = '^\s*=\{6}[^=]\+.*[^=]\+=\{6}\s*$' -let g:vimwiki_rxHeader = '\%('.g:vimwiki_rxH1.'\)\|'. - \ '\%('.g:vimwiki_rxH2.'\)\|'. - \ '\%('.g:vimwiki_rxH3.'\)\|'. - \ '\%('.g:vimwiki_rxH4.'\)\|'. - \ '\%('.g:vimwiki_rxH5.'\)\|'. - \ '\%('.g:vimwiki_rxH6.'\)' -let g:vimwiki_char_header = '\%(^\s*=\+\)\|\%(=\+\s*$\)' +" generic headers +let g:vimwiki_rxH = '=' +let g:vimwiki_symH = 1 + + " <hr>, horizontal rule -let g:vimwiki_rxHR = '^----.*$' +let g:vimwiki_rxHR = '^-----*$' -" Tables. Each line starts and ends with '||'; each cell is separated by '||' -let g:vimwiki_rxTable = '||' +" Tables. Each line starts and ends with '|'; each cell is separated by '|' +let g:vimwiki_rxTableSep = '|' " Bulleted list items start with whitespace(s), then '*' " highlight only bullets and digits. -let g:vimwiki_rxListBullet = '^\s*\*\+\([^*]*$\)\@=' -let g:vimwiki_rxListNumber = '^\s*#\+' +let g:vimwiki_rxListBullet = '^\s*\*\+\s\%([^*]*$\)\@=' +let g:vimwiki_rxListNumber = '^\s*#\+\s' let g:vimwiki_rxListDefine = '^\%(;\|:\)\s' @@ -66,4 +64,8 @@ let g:vimwiki_rxListDefine = '^\%(;\|:\)\s' let g:vimwiki_rxPreStart = '<pre>' let g:vimwiki_rxPreEnd = '<\/pre>' +" Math block +let g:vimwiki_rxMathStart = '{{\$' +let g:vimwiki_rxMathEnd = '}}\$' + let g:vimwiki_rxComment = '^\s*%%.*$'