Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
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...
commit d5a6d097da1c67e07b3fb073f22217c7462f5088 1 parent 84297c9
@habamax habamax authored committed
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,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 "}}}
" }}}
View
400 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 }}}
+
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]]
- " 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?