Skip to content
Browse files

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
  • Loading branch information...
1 parent 84297c9 commit d5a6d097da1c67e07b3fb073f22217c7462f5088 @habamax habamax committed with Jun 7, 2012
View
39 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:
View
1,178 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,61 +1291,212 @@ 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
"}}}
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 "}}}
" }}}
View
400 autoload/vimwiki/diary.vim
@@ -11,17 +11,16 @@ 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
endif
return a:num
endfunction "}}}
-function! s:desc(d1, d2) "{{{
- return a:d1 == a:d2 ? 0 : a:d1 < a:d2 ? 1 : -1
-endfunction "}}}
-
function! s:get_date_link(fmt) "{{{
return strftime(a:fmt)
endfunction "}}}
@@ -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 }}}
+
View
684 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]]