2018-04-20 07:03:53 +02:00
|
|
|
" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
|
2010-01-20 01:00:00 +01:00
|
|
|
" Vimwiki autoload plugin file
|
2015-02-23 12:10:42 +01:00
|
|
|
" Desc: Basic functionality
|
|
|
|
" Home: https://github.com/vimwiki/vimwiki/
|
2010-01-20 01:00:00 +01:00
|
|
|
|
|
|
|
if exists("g:loaded_vimwiki_auto") || &cp
|
|
|
|
finish
|
|
|
|
endif
|
|
|
|
let g:loaded_vimwiki_auto = 1
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:safesubstitute(text, search, replace, mode)
|
2018-02-19 07:44:19 +01:00
|
|
|
" Substitute regexp but do not interpret replace
|
|
|
|
let escaped = escape(a:replace, '\&')
|
|
|
|
return substitute(a:text, a:search, escaped, a:mode)
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2018-02-19 07:44:19 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:vimwiki_get_known_syntaxes()
|
2012-07-07 02:00:00 +02:00
|
|
|
" Getting all syntaxes that different wikis could have
|
|
|
|
let syntaxes = {}
|
|
|
|
let syntaxes['default'] = 1
|
2016-12-23 20:05:53 +01:00
|
|
|
for wiki_nr in range(vimwiki#vars#number_of_wikis())
|
|
|
|
let wiki_syntax = vimwiki#vars#get_wikilocal('syntax', wiki_nr)
|
|
|
|
let syntaxes[wiki_syntax] = 1
|
2012-07-07 02:00:00 +02:00
|
|
|
endfor
|
2016-12-21 19:43:34 +01:00
|
|
|
" also consider the syntaxes from g:vimwiki_ext2syntax
|
|
|
|
for syn in values(vimwiki#vars#get_global('ext2syntax'))
|
2012-07-07 02:00:00 +02:00
|
|
|
let syntaxes[syn] = 1
|
|
|
|
endfor
|
|
|
|
return keys(syntaxes)
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#file_pattern(files)
|
|
|
|
" Get search regex from glob()
|
2012-06-07 02:00:00 +02:00
|
|
|
" 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, ...).
|
2015-11-23 13:10:46 +01:00
|
|
|
" See: https://github.com/vimwiki-backup/vimwiki/issues/316
|
2018-04-20 07:03:53 +02:00
|
|
|
" Change / to [/\\] to allow "Windows paths"
|
2014-12-04 21:27:02 +01:00
|
|
|
return '\V\%('.join(a:files, '\|').'\)\m'
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
"FIXME TODO slow and faulty
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#subdir(path, filename)
|
2012-06-07 02:00:00 +02:00
|
|
|
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?
|
2013-11-06 13:34:45 +01:00
|
|
|
if a:filename !~# '^scp:'
|
|
|
|
let filename = resolve(a:filename)
|
|
|
|
else
|
|
|
|
let filename = a:filename
|
|
|
|
endif
|
2010-01-20 01:00:00 +01:00
|
|
|
let idx = 0
|
2012-06-07 02:00:00 +02:00
|
|
|
"FIXME this can terminate in the middle of a path component!
|
2010-05-12 02:00:00 +02:00
|
|
|
while path[idx] ==? filename[idx]
|
2010-01-20 01:00:00 +01:00
|
|
|
let idx = idx + 1
|
|
|
|
endwhile
|
|
|
|
|
|
|
|
let p = split(strpart(filename, idx), '[/\\]')
|
2012-06-07 02:00:00 +02:00
|
|
|
let res = join(p[:-2], '/')
|
2010-01-20 01:00:00 +01:00
|
|
|
if len(res) > 0
|
2012-06-07 02:00:00 +02:00
|
|
|
let res = res.'/'
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
|
|
|
return res
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#current_subdir()
|
2017-01-07 21:51:15 +01:00
|
|
|
return vimwiki#base#subdir(vimwiki#vars#get_wikilocal('path'), expand('%:p'))
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#invsubdir(subdir)
|
2012-06-07 02:00:00 +02:00
|
|
|
return substitute(a:subdir, '[^/\.]\+/', '../', 'g')
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2015-03-13 16:31:15 +01:00
|
|
|
|
2018-04-17 07:13:37 +02:00
|
|
|
" Returns: the number of the wiki a file belongs to or -1 if it doesn't belong
|
|
|
|
" to any registered wiki.
|
|
|
|
" The path can be the full path or just the directory of the file
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#find_wiki(path)
|
2018-04-27 14:48:21 +02:00
|
|
|
let bestmatch = -1
|
|
|
|
let bestlen = 0
|
2015-03-13 16:31:15 +01:00
|
|
|
let path = vimwiki#path#path_norm(vimwiki#path#chomp_slash(a:path))
|
2016-12-28 22:17:08 +01:00
|
|
|
for idx in range(vimwiki#vars#number_of_wikis())
|
2016-12-22 19:55:20 +01:00
|
|
|
let idx_path = expand(vimwiki#vars#get_wikilocal('path', idx))
|
2015-03-13 16:31:15 +01:00
|
|
|
let idx_path = vimwiki#path#path_norm(vimwiki#path#chomp_slash(idx_path))
|
2018-04-27 14:48:21 +02:00
|
|
|
let common_pfx = vimwiki#path#path_common_pfx(idx_path, path)
|
|
|
|
if vimwiki#path#is_equal(common_pfx, idx_path)
|
|
|
|
if len(common_pfx) > bestlen
|
|
|
|
let bestlen = len(common_pfx)
|
|
|
|
let bestmatch = idx
|
|
|
|
endif
|
2015-03-13 16:31:15 +01:00
|
|
|
endif
|
2017-01-16 22:09:49 +01:00
|
|
|
endfor
|
2015-03-13 16:31:15 +01:00
|
|
|
|
2018-04-27 14:48:21 +02:00
|
|
|
return bestmatch
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2015-03-13 16:31:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
" THE central function of Vimwiki. Extract infos about the target from a link.
|
|
|
|
" If the second parameter is present, which should be an absolute file path, it
|
|
|
|
" is assumed that the link appears in that file. Without it, the current file
|
|
|
|
" is used.
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#resolve_link(link_text, ...)
|
2015-03-13 16:31:15 +01:00
|
|
|
if a:0
|
|
|
|
let source_wiki = vimwiki#base#find_wiki(a:1)
|
|
|
|
let source_file = a:1
|
|
|
|
else
|
2016-12-28 22:17:08 +01:00
|
|
|
let source_wiki = vimwiki#vars#get_bufferlocal('wiki_nr')
|
2018-02-16 17:47:32 +01:00
|
|
|
let source_file = vimwiki#path#current_wiki_file()
|
2015-03-13 16:31:15 +01:00
|
|
|
endif
|
|
|
|
|
|
|
|
let link_text = a:link_text
|
|
|
|
|
|
|
|
|
|
|
|
let link_infos = {
|
|
|
|
\ 'index': -1,
|
|
|
|
\ 'scheme': '',
|
|
|
|
\ 'filename': '',
|
|
|
|
\ 'anchor': '',
|
|
|
|
\ }
|
|
|
|
|
2018-05-20 15:18:05 +02:00
|
|
|
if link_text == ''
|
2015-03-13 16:31:15 +01:00
|
|
|
return link_infos
|
|
|
|
endif
|
2018-05-20 15:18:05 +02:00
|
|
|
|
|
|
|
let scheme = matchstr(link_text, '^\zs'.vimwiki#vars#get_global('rxSchemes').'\ze:')
|
|
|
|
if scheme == ''
|
|
|
|
let link_infos.scheme = 'wiki'.source_wiki
|
|
|
|
else
|
|
|
|
let link_infos.scheme = scheme
|
|
|
|
|
|
|
|
if link_infos.scheme !~# '\mwiki\d\+\|diary\|local\|file'
|
|
|
|
let link_infos.filename = link_text " unknown scheme, may be a weblink
|
|
|
|
return link_infos
|
|
|
|
endif
|
|
|
|
|
|
|
|
let link_text = matchstr(link_text, '^'.vimwiki#vars#get_global('rxSchemes').':\zs.*\ze')
|
2015-04-09 14:48:26 +02:00
|
|
|
endif
|
2015-03-13 16:31:15 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
let is_wiki_link = link_infos.scheme =~# '\mwiki\d\+' || link_infos.scheme ==# 'diary'
|
2015-03-13 16:31:15 +01:00
|
|
|
|
|
|
|
" extract anchor
|
|
|
|
if is_wiki_link
|
|
|
|
let split_lnk = split(link_text, '#', 1)
|
|
|
|
let link_text = split_lnk[0]
|
|
|
|
if len(split_lnk) > 1 && split_lnk[-1] != ''
|
|
|
|
let link_infos.anchor = join(split_lnk[1:], '#')
|
|
|
|
endif
|
|
|
|
if link_text == '' " because the link was of the form '#anchor'
|
|
|
|
let link_text = fnamemodify(source_file, ':p:t:r')
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
|
|
|
" check if absolute or relative path
|
|
|
|
if is_wiki_link && link_text[0] == '/'
|
2015-04-29 14:59:10 +02:00
|
|
|
if link_text != '/'
|
|
|
|
let link_text = link_text[1:]
|
|
|
|
endif
|
|
|
|
let is_relative = 0
|
2015-04-09 14:48:26 +02:00
|
|
|
elseif !is_wiki_link && vimwiki#path#is_absolute(link_text)
|
2015-04-29 14:59:10 +02:00
|
|
|
let is_relative = 0
|
2015-03-13 16:31:15 +01:00
|
|
|
else
|
2015-04-29 14:59:10 +02:00
|
|
|
let is_relative = 1
|
2015-03-13 16:31:15 +01:00
|
|
|
let root_dir = fnamemodify(source_file, ':p:h') . '/'
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
|
|
" extract the other items depending on the scheme
|
|
|
|
if link_infos.scheme =~# '\mwiki\d\+'
|
|
|
|
let link_infos.index = eval(matchstr(link_infos.scheme, '\D\+\zs\d\+\ze'))
|
2016-12-28 22:17:08 +01:00
|
|
|
if link_infos.index < 0 || link_infos.index >= vimwiki#vars#number_of_wikis()
|
2015-03-13 16:31:15 +01:00
|
|
|
let link_infos.filename = ''
|
|
|
|
return link_infos
|
|
|
|
endif
|
|
|
|
|
2015-04-29 14:59:10 +02:00
|
|
|
if !is_relative || link_infos.index != source_wiki
|
2016-12-22 19:55:20 +01:00
|
|
|
let root_dir = vimwiki#vars#get_wikilocal('path', link_infos.index)
|
2015-03-13 16:31:15 +01:00
|
|
|
endif
|
|
|
|
|
|
|
|
let link_infos.filename = root_dir . link_text
|
|
|
|
|
|
|
|
if vimwiki#path#is_link_to_dir(link_text)
|
2016-12-21 19:43:34 +01:00
|
|
|
if vimwiki#vars#get_global('dir_link') != ''
|
|
|
|
let link_infos.filename .= vimwiki#vars#get_global('dir_link') .
|
2016-12-22 21:00:19 +01:00
|
|
|
\ vimwiki#vars#get_wikilocal('ext', link_infos.index)
|
2015-03-13 16:31:15 +01:00
|
|
|
endif
|
|
|
|
else
|
2016-12-22 21:00:19 +01:00
|
|
|
let link_infos.filename .= vimwiki#vars#get_wikilocal('ext', link_infos.index)
|
2015-03-13 16:31:15 +01:00
|
|
|
endif
|
|
|
|
|
|
|
|
elseif link_infos.scheme ==# 'diary'
|
|
|
|
let link_infos.index = source_wiki
|
|
|
|
|
|
|
|
let link_infos.filename =
|
2016-12-22 19:55:20 +01:00
|
|
|
\ vimwiki#vars#get_wikilocal('path', link_infos.index) .
|
2016-12-22 18:16:05 +01:00
|
|
|
\ vimwiki#vars#get_wikilocal('diary_rel_path', link_infos.index) .
|
2015-03-13 16:31:15 +01:00
|
|
|
\ link_text .
|
2016-12-22 21:00:19 +01:00
|
|
|
\ vimwiki#vars#get_wikilocal('ext', link_infos.index)
|
2018-04-20 07:03:53 +02:00
|
|
|
elseif (link_infos.scheme ==# 'file' || link_infos.scheme ==# 'local') && is_relative
|
2015-04-09 14:48:26 +02:00
|
|
|
let link_infos.filename = simplify(root_dir . link_text)
|
2015-03-13 16:31:15 +01:00
|
|
|
else " absolute file link
|
|
|
|
" collapse repeated leading "/"'s within a link
|
2015-04-09 14:48:26 +02:00
|
|
|
let link_text = substitute(link_text, '\m^/\+', '/', '')
|
|
|
|
" expand ~/
|
|
|
|
let link_text = fnamemodify(link_text, ':p')
|
|
|
|
let link_infos.filename = simplify(link_text)
|
2015-03-13 16:31:15 +01:00
|
|
|
endif
|
|
|
|
|
|
|
|
let link_infos.filename = vimwiki#path#normalize(link_infos.filename)
|
|
|
|
return link_infos
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2015-03-13 16:31:15 +01:00
|
|
|
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#system_open_link(url)
|
2012-06-07 02:00:00 +02:00
|
|
|
" handlers
|
|
|
|
function! s:win32_handler(url)
|
|
|
|
"http://vim.wikia.com/wiki/Opening_current_Vim_file_in_your_Windows_browser
|
2014-07-04 11:23:28 +02:00
|
|
|
"disable 'shellslash', otherwise the url will be enclosed in single quotes,
|
|
|
|
"which is problematic
|
|
|
|
"see https://github.com/vimwiki/vimwiki/issues/54#issuecomment-48011289
|
|
|
|
if exists('+shellslash')
|
|
|
|
let old_ssl = &shellslash
|
|
|
|
set noshellslash
|
|
|
|
let url = shellescape(a:url, 1)
|
|
|
|
let &shellslash = old_ssl
|
|
|
|
else
|
|
|
|
let url = shellescape(a:url, 1)
|
|
|
|
endif
|
2016-12-12 23:49:05 +01:00
|
|
|
if &l:shell ==? "powershell"
|
|
|
|
execute 'silent ! start ' . a:url
|
|
|
|
else
|
|
|
|
execute 'silent ! start "Title" /B ' . a:url
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
endfunction
|
|
|
|
function! s:macunix_handler(url)
|
2015-11-26 04:54:32 +01:00
|
|
|
call system('open ' . shellescape(a:url).' &')
|
2012-06-07 02:00:00 +02:00
|
|
|
endfunction
|
|
|
|
function! s:linux_handler(url)
|
2014-03-03 09:19:59 +01:00
|
|
|
call system('xdg-open ' . shellescape(a:url).' &')
|
2012-06-07 02:00:00 +02:00
|
|
|
endfunction
|
2014-02-24 12:16:23 +01:00
|
|
|
try
|
2012-06-07 02:00:00 +02:00
|
|
|
if vimwiki#u#is_windows()
|
|
|
|
call s:win32_handler(a:url)
|
|
|
|
return
|
2015-09-14 15:11:14 +02:00
|
|
|
elseif vimwiki#u#is_macos()
|
2012-06-07 02:00:00 +02:00
|
|
|
call s:macunix_handler(a:url)
|
|
|
|
return
|
|
|
|
else
|
|
|
|
call s:linux_handler(a:url)
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
endtry
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki Error: Default Vimwiki link handler was unable to open the HTML file!'
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#open_link(cmd, link, ...)
|
2018-04-02 21:34:21 +02:00
|
|
|
let link_infos = {}
|
|
|
|
if a:0
|
|
|
|
let link_infos = vimwiki#base#resolve_link(a:link, a:1)
|
|
|
|
else
|
|
|
|
let link_infos = vimwiki#base#resolve_link(a:link)
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2015-03-13 16:31:15 +01:00
|
|
|
if link_infos.filename == ''
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki Error: Unable to resolve link!'
|
2012-06-07 02:00:00 +02:00
|
|
|
return
|
2010-05-12 02:00:00 +02:00
|
|
|
endif
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
let is_wiki_link = link_infos.scheme =~# '\mwiki\d\+' || link_infos.scheme =~# 'diary'
|
2010-05-12 02:00:00 +02:00
|
|
|
|
2015-03-13 16:31:15 +01:00
|
|
|
let update_prev_link = is_wiki_link &&
|
2018-02-16 17:47:32 +01:00
|
|
|
\ !vimwiki#path#is_equal(link_infos.filename, vimwiki#path#current_wiki_file())
|
2010-05-12 02:00:00 +02:00
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
let vimwiki_prev_link = []
|
|
|
|
" update previous link for wiki pages
|
|
|
|
if update_prev_link
|
|
|
|
if a:0
|
|
|
|
let vimwiki_prev_link = [a:1, []]
|
2015-02-09 20:05:25 +01:00
|
|
|
elseif &ft ==# 'vimwiki'
|
2018-02-16 17:47:32 +01:00
|
|
|
let vimwiki_prev_link = [vimwiki#path#current_wiki_file(), getpos('.')]
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
2010-05-12 02:00:00 +02:00
|
|
|
endif
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" open/edit
|
2015-03-13 16:31:15 +01:00
|
|
|
if is_wiki_link
|
|
|
|
call vimwiki#base#edit_file(a:cmd, link_infos.filename, link_infos.anchor,
|
2012-06-07 02:00:00 +02:00
|
|
|
\ vimwiki_prev_link, update_prev_link)
|
2015-03-13 16:31:15 +01:00
|
|
|
else
|
|
|
|
call vimwiki#base#system_open_link(link_infos.filename)
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#get_globlinks_escaped() abort
|
|
|
|
" only get links from the current dir
|
2012-06-07 02:00:00 +02:00
|
|
|
" change to the directory of the current file
|
|
|
|
let orig_pwd = getcwd()
|
|
|
|
lcd! %:h
|
2018-04-20 07:03:53 +02:00
|
|
|
" all path are relative to the current file's location
|
2016-12-22 21:00:19 +01:00
|
|
|
let globlinks = glob('*'.vimwiki#vars#get_wikilocal('ext'), 1)."\n"
|
2012-06-07 02:00:00 +02:00
|
|
|
" remove extensions
|
2016-12-22 21:00:19 +01:00
|
|
|
let globlinks = substitute(globlinks, '\'.vimwiki#vars#get_wikilocal('ext').'\ze\n', '', 'g')
|
2012-06-07 02:00:00 +02:00
|
|
|
" restore the original working directory
|
|
|
|
exe 'lcd! '.orig_pwd
|
2014-11-11 21:12:03 +01:00
|
|
|
" convert to a List
|
2014-11-10 21:04:06 +01:00
|
|
|
let lst = split(globlinks, '\n')
|
2014-11-11 21:12:03 +01:00
|
|
|
" Apply fnameescape() to each item
|
2014-11-10 21:04:06 +01:00
|
|
|
call map(lst, 'fnameescape(v:val)')
|
2014-11-11 21:12:03 +01:00
|
|
|
" Convert back to newline-separated list
|
2014-11-10 21:04:06 +01:00
|
|
|
let globlinks = join(lst, "\n")
|
2014-11-11 21:12:03 +01:00
|
|
|
" return all escaped links as a single newline-separated string
|
2014-11-10 21:04:06 +01:00
|
|
|
return globlinks
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2014-11-10 21:04:06 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#generate_links()
|
2015-11-09 15:45:56 +01:00
|
|
|
let lines = []
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2016-12-28 22:17:08 +01:00
|
|
|
let links = vimwiki#base#get_wikilinks(vimwiki#vars#get_bufferlocal('wiki_nr'), 0)
|
2010-05-12 02:00:00 +02:00
|
|
|
call sort(links)
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
let bullet = repeat(' ', vimwiki#lst#get_list_margin()) . vimwiki#lst#default_symbol().' '
|
2010-05-12 02:00:00 +02:00
|
|
|
for link in links
|
2014-12-04 21:27:02 +01:00
|
|
|
let abs_filepath = vimwiki#path#abs_path_of_link(link)
|
|
|
|
if !s:is_diary_file(abs_filepath)
|
2015-11-09 15:45:56 +01:00
|
|
|
call add(lines, bullet.
|
2018-02-19 07:44:19 +01:00
|
|
|
\ s:safesubstitute(vimwiki#vars#get_global('WikiLinkTemplate1'),
|
|
|
|
\ '__LinkUrl__', link, ''))
|
2014-12-04 21:27:02 +01:00
|
|
|
endif
|
2010-05-12 02:00:00 +02:00
|
|
|
endfor
|
2015-11-09 15:45:56 +01:00
|
|
|
|
|
|
|
let links_rx = '\m^\s*'.vimwiki#u#escape(vimwiki#lst#default_symbol()).' '
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
call vimwiki#base#update_listing_in_buffer(lines, 'Generated Links', links_rx, line('$')+1, 1)
|
|
|
|
endfunction
|
|
|
|
|
2010-05-12 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#goto(...)
|
2014-02-13 12:42:24 +01:00
|
|
|
let key = a:1
|
|
|
|
let anchor = a:0 > 1 ? a:2 : ''
|
|
|
|
|
|
|
|
call vimwiki#base#edit_file(':e',
|
2016-12-22 21:00:19 +01:00
|
|
|
\ vimwiki#vars#get_wikilocal('path') . key . vimwiki#vars#get_wikilocal('ext'),
|
2014-02-13 12:42:24 +01:00
|
|
|
\ anchor)
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-08-24 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#backlinks()
|
2014-12-07 11:59:56 +01:00
|
|
|
let current_filename = expand("%:p")
|
|
|
|
let locations = []
|
2016-12-28 22:17:08 +01:00
|
|
|
for idx in range(vimwiki#vars#number_of_wikis())
|
2016-12-23 20:05:53 +01:00
|
|
|
let syntax = vimwiki#vars#get_wikilocal('syntax', idx)
|
2015-02-24 09:39:03 +01:00
|
|
|
let wikifiles = vimwiki#base#find_files(idx, 0)
|
2014-12-07 11:59:56 +01:00
|
|
|
for source_file in wikifiles
|
|
|
|
let links = s:get_links(source_file, idx)
|
|
|
|
for [target_file, _, lnum, col] in links
|
|
|
|
" don't include links from the current file to itself
|
2015-02-09 20:05:25 +01:00
|
|
|
if vimwiki#path#is_equal(target_file, current_filename) &&
|
|
|
|
\ !vimwiki#path#is_equal(target_file, source_file)
|
2014-12-07 11:59:56 +01:00
|
|
|
call add(locations, {'filename':source_file, 'lnum':lnum, 'col':col})
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
endfor
|
|
|
|
endfor
|
|
|
|
|
|
|
|
if empty(locations)
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki: No other file links to this file'
|
2014-12-07 11:59:56 +01:00
|
|
|
else
|
|
|
|
call setloclist(0, locations, 'r')
|
|
|
|
lopen
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-05-12 02:00:00 +02:00
|
|
|
|
2014-12-04 21:18:58 +01:00
|
|
|
" Returns: a list containing all files of the given wiki as absolute file path.
|
|
|
|
" If the given wiki number is negative, the diary of the current wiki is used
|
|
|
|
" If the second argument is not zero, only directories are found
|
2015-02-24 09:39:03 +01:00
|
|
|
function! vimwiki#base#find_files(wiki_nr, directories_only)
|
2014-12-04 21:18:58 +01:00
|
|
|
let wiki_nr = a:wiki_nr
|
|
|
|
if wiki_nr >= 0
|
2016-12-22 19:55:20 +01:00
|
|
|
let root_directory = vimwiki#vars#get_wikilocal('path', wiki_nr)
|
2014-12-04 21:18:58 +01:00
|
|
|
else
|
2018-04-20 07:03:53 +02:00
|
|
|
let root_directory = vimwiki#vars#get_wikilocal('path') .
|
|
|
|
\ vimwiki#vars#get_wikilocal('diary_rel_path')
|
2016-12-28 22:17:08 +01:00
|
|
|
let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr')
|
2014-12-04 21:18:58 +01:00
|
|
|
endif
|
|
|
|
if a:directories_only
|
|
|
|
let ext = '/'
|
|
|
|
else
|
2016-12-22 21:00:19 +01:00
|
|
|
let ext = vimwiki#vars#get_wikilocal('ext', wiki_nr)
|
2014-12-04 21:18:58 +01:00
|
|
|
endif
|
2010-08-24 02:00:00 +02:00
|
|
|
" 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
|
|
|
|
" wiki file was created in $HOME or C:/ dirs.
|
2017-11-11 21:52:07 +01:00
|
|
|
if vimwiki#vars#get_wikilocal('is_temporary_wiki', wiki_nr)
|
2014-12-04 21:18:58 +01:00
|
|
|
let pattern = '*'.ext
|
2010-08-24 02:00:00 +02:00
|
|
|
else
|
2014-12-04 21:18:58 +01:00
|
|
|
let pattern = '**/*'.ext
|
2010-08-24 02:00:00 +02:00
|
|
|
endif
|
2014-12-04 21:18:58 +01:00
|
|
|
return split(globpath(root_directory, pattern), '\n')
|
|
|
|
endfunction
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
2015-03-17 10:33:43 +01:00
|
|
|
" Returns: a list containing the links to get from the current file to all wiki
|
|
|
|
" files in the given wiki.
|
|
|
|
" If the given wiki number is negative, the diary of the current wiki is used.
|
|
|
|
" If also_absolute_links is nonzero, also return links of the form /file
|
|
|
|
function! vimwiki#base#get_wikilinks(wiki_nr, also_absolute_links)
|
2015-02-24 09:39:03 +01:00
|
|
|
let files = vimwiki#base#find_files(a:wiki_nr, 0)
|
2016-12-28 22:17:08 +01:00
|
|
|
if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
|
2014-12-04 21:18:58 +01:00
|
|
|
let cwd = vimwiki#path#wikify_path(expand('%:p:h'))
|
|
|
|
elseif a:wiki_nr < 0
|
2016-12-22 19:55:20 +01:00
|
|
|
let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path')
|
2012-06-07 02:00:00 +02:00
|
|
|
else
|
2016-12-22 19:55:20 +01:00
|
|
|
let cwd = vimwiki#vars#get_wikilocal('path', a:wiki_nr)
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
2014-12-04 21:18:58 +01:00
|
|
|
let result = []
|
|
|
|
for wikifile in files
|
|
|
|
let wikifile = fnamemodify(wikifile, ':r') " strip extension
|
|
|
|
let wikifile = vimwiki#path#relpath(cwd, wikifile)
|
|
|
|
call add(result, wikifile)
|
2012-06-07 02:00:00 +02:00
|
|
|
endfor
|
2015-03-17 10:33:43 +01:00
|
|
|
if a:also_absolute_links
|
|
|
|
for wikifile in files
|
2016-12-28 22:17:08 +01:00
|
|
|
if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
|
2016-12-22 19:55:20 +01:00
|
|
|
let cwd = vimwiki#vars#get_wikilocal('path')
|
2015-03-17 10:33:43 +01:00
|
|
|
elseif a:wiki_nr < 0
|
2016-12-22 19:55:20 +01:00
|
|
|
let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path')
|
2015-03-17 10:33:43 +01:00
|
|
|
endif
|
|
|
|
let wikifile = fnamemodify(wikifile, ':r') " strip extension
|
|
|
|
let wikifile = '/'.vimwiki#path#relpath(cwd, wikifile)
|
|
|
|
call add(result, wikifile)
|
|
|
|
endfor
|
|
|
|
endif
|
2014-12-04 21:18:58 +01:00
|
|
|
return result
|
|
|
|
endfunction
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
2015-03-17 10:33:43 +01:00
|
|
|
" Returns: a list containing the links to all directories from the current file
|
2014-12-04 21:18:58 +01:00
|
|
|
function! vimwiki#base#get_wiki_directories(wiki_nr)
|
2015-02-24 09:39:03 +01:00
|
|
|
let dirs = vimwiki#base#find_files(a:wiki_nr, 1)
|
2016-12-28 22:17:08 +01:00
|
|
|
if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
|
2014-12-04 21:18:58 +01:00
|
|
|
let cwd = vimwiki#path#wikify_path(expand('%:p:h'))
|
2016-12-22 19:55:20 +01:00
|
|
|
let root_dir = vimwiki#vars#get_wikilocal('path')
|
2014-12-04 21:18:58 +01:00
|
|
|
else
|
2016-12-22 19:55:20 +01:00
|
|
|
let cwd = vimwiki#vars#get_wikilocal('path', a:wiki_nr)
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
2014-12-04 21:18:58 +01:00
|
|
|
let result = ['./']
|
|
|
|
for wikidir in dirs
|
2015-04-30 13:52:33 +02:00
|
|
|
let wikidir_relative = vimwiki#path#relpath(cwd, wikidir)
|
2015-03-17 10:33:43 +01:00
|
|
|
call add(result, wikidir_relative)
|
2016-12-28 22:17:08 +01:00
|
|
|
if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
|
2015-04-30 13:52:33 +02:00
|
|
|
let wikidir_absolute = '/'.vimwiki#path#relpath(root_dir, wikidir)
|
2015-03-17 10:33:43 +01:00
|
|
|
call add(result, wikidir_absolute)
|
|
|
|
endif
|
2014-12-04 21:18:58 +01:00
|
|
|
endfor
|
|
|
|
return result
|
|
|
|
endfunction
|
2010-05-12 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#get_anchors(filename, syntax)
|
2014-08-14 13:08:24 +02:00
|
|
|
if !filereadable(a:filename)
|
|
|
|
return []
|
|
|
|
endif
|
|
|
|
|
2016-12-28 22:17:08 +01:00
|
|
|
let rxheader = vimwiki#vars#get_syntaxlocal('header_search', a:syntax)
|
|
|
|
let rxbold = vimwiki#vars#get_syntaxlocal('bold_search', a:syntax)
|
|
|
|
let rxtag = vimwiki#vars#get_syntaxlocal('tag_search', a:syntax)
|
2014-08-14 13:08:24 +02:00
|
|
|
|
|
|
|
let anchor_level = ['', '', '', '', '', '', '']
|
|
|
|
let anchors = []
|
2014-11-11 13:43:44 +01:00
|
|
|
let current_complete_anchor = ''
|
2014-08-14 13:08:24 +02:00
|
|
|
for line in readfile(a:filename)
|
|
|
|
|
|
|
|
" collect headers
|
|
|
|
let h_match = matchlist(line, rxheader)
|
|
|
|
if !empty(h_match)
|
|
|
|
let header = vimwiki#u#trim(h_match[2])
|
|
|
|
let level = len(h_match[1])
|
2014-11-11 13:43:44 +01:00
|
|
|
call add(anchors, header)
|
2014-08-14 13:08:24 +02:00
|
|
|
let anchor_level[level-1] = header
|
|
|
|
for l in range(level, 6)
|
|
|
|
let anchor_level[l] = ''
|
|
|
|
endfor
|
2014-11-11 13:43:44 +01:00
|
|
|
if level == 1
|
|
|
|
let current_complete_anchor = header
|
|
|
|
else
|
|
|
|
let current_complete_anchor = ''
|
|
|
|
for l in range(level-1)
|
|
|
|
if anchor_level[l] != ''
|
|
|
|
let current_complete_anchor .= anchor_level[l].'#'
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
let current_complete_anchor .= header
|
|
|
|
call add(anchors, current_complete_anchor)
|
|
|
|
endif
|
2014-08-14 13:08:24 +02:00
|
|
|
endif
|
|
|
|
|
|
|
|
" collect bold text (there can be several in one line)
|
2015-01-10 14:12:40 +01:00
|
|
|
let bold_count = 1
|
2014-08-14 13:08:24 +02:00
|
|
|
while 1
|
2014-11-11 13:43:44 +01:00
|
|
|
let bold_text = matchstr(line, rxbold, 0, bold_count)
|
|
|
|
if bold_text == ''
|
2014-08-14 13:08:24 +02:00
|
|
|
break
|
|
|
|
endif
|
|
|
|
call add(anchors, bold_text)
|
2014-11-11 13:43:44 +01:00
|
|
|
if current_complete_anchor != ''
|
|
|
|
call add(anchors, current_complete_anchor.'#'.bold_text)
|
|
|
|
endif
|
2014-08-14 13:08:24 +02:00
|
|
|
let bold_count += 1
|
|
|
|
endwhile
|
|
|
|
|
2015-01-10 14:39:11 +01:00
|
|
|
" collect tags text (there can be several in one line)
|
|
|
|
let tag_count = 1
|
|
|
|
while 1
|
2015-01-23 21:13:27 +01:00
|
|
|
let tag_group_text = matchstr(line, rxtag, 0, tag_count)
|
|
|
|
if tag_group_text == ''
|
2015-01-10 14:39:11 +01:00
|
|
|
break
|
|
|
|
endif
|
2015-01-23 21:13:27 +01:00
|
|
|
for tag_text in split(tag_group_text, ':')
|
|
|
|
call add(anchors, tag_text)
|
|
|
|
if current_complete_anchor != ''
|
|
|
|
call add(anchors, current_complete_anchor.'#'.tag_text)
|
|
|
|
endif
|
|
|
|
endfor
|
2015-01-10 14:39:11 +01:00
|
|
|
let tag_count += 1
|
|
|
|
endwhile
|
|
|
|
|
2014-08-14 13:08:24 +02:00
|
|
|
endfor
|
|
|
|
|
|
|
|
return anchors
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2014-08-14 13:08:24 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:jump_to_anchor(anchor)
|
2014-02-13 12:42:24 +01:00
|
|
|
let oldpos = getpos('.')
|
|
|
|
call cursor(1, 1)
|
|
|
|
|
|
|
|
let anchor = vimwiki#u#escape(a:anchor)
|
|
|
|
|
|
|
|
let segments = split(anchor, '#', 0)
|
2016-12-23 20:05:53 +01:00
|
|
|
|
2014-02-13 12:42:24 +01:00
|
|
|
for segment in segments
|
|
|
|
|
2018-02-19 07:44:19 +01:00
|
|
|
let anchor_header = s:safesubstitute(
|
2016-12-28 22:17:08 +01:00
|
|
|
\ vimwiki#vars#get_syntaxlocal('header_match'),
|
2018-02-19 07:44:19 +01:00
|
|
|
\ '__Header__', segment, '')
|
|
|
|
let anchor_bold = s:safesubstitute(
|
2016-12-28 22:17:08 +01:00
|
|
|
\ vimwiki#vars#get_syntaxlocal('bold_match'),
|
2018-02-19 07:44:19 +01:00
|
|
|
\ '__Text__', segment, '')
|
|
|
|
let anchor_tag = s:safesubstitute(
|
2016-12-28 22:17:08 +01:00
|
|
|
\ vimwiki#vars#get_syntaxlocal('tag_match'),
|
2018-02-19 07:44:19 +01:00
|
|
|
\ '__Tag__', segment, '')
|
2014-02-13 12:42:24 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
if !search(anchor_tag, 'Wc') && !search(anchor_header, 'Wc') && !search(anchor_bold, 'Wc')
|
2014-02-13 12:42:24 +01:00
|
|
|
call setpos('.', oldpos)
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
let oldpos = getpos('.')
|
|
|
|
endfor
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2014-02-13 12:42:24 +01:00
|
|
|
|
2014-12-07 11:58:08 +01:00
|
|
|
" Params: full path to a wiki file and its wiki number
|
|
|
|
" Returns: a list of all links inside the wiki file
|
|
|
|
" Every list item has the form
|
|
|
|
" [target file, anchor, line number of the link in source file, column number]
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:get_links(wikifile, idx)
|
2014-12-04 21:18:58 +01:00
|
|
|
if !filereadable(a:wikifile)
|
|
|
|
return []
|
|
|
|
endif
|
|
|
|
|
2016-12-23 20:05:53 +01:00
|
|
|
let syntax = vimwiki#vars#get_wikilocal('syntax', a:idx)
|
2016-12-28 22:17:08 +01:00
|
|
|
let rx_link = vimwiki#vars#get_syntaxlocal('wikilink', syntax)
|
2014-12-04 21:18:58 +01:00
|
|
|
let links = []
|
|
|
|
let lnum = 0
|
|
|
|
|
|
|
|
for line in readfile(a:wikifile)
|
|
|
|
let lnum += 1
|
|
|
|
|
|
|
|
let link_count = 1
|
|
|
|
while 1
|
2014-12-07 11:58:08 +01:00
|
|
|
let col = match(line, rx_link, 0, link_count)+1
|
|
|
|
let link_text = matchstr(line, rx_link, 0, link_count)
|
2014-12-04 21:18:58 +01:00
|
|
|
if link_text == ''
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
let link_count += 1
|
2015-03-13 16:31:15 +01:00
|
|
|
let target = vimwiki#base#resolve_link(link_text, a:wikifile)
|
2018-04-20 07:03:53 +02:00
|
|
|
if target.filename != '' && target.scheme =~# '\mwiki\d\+\|diary\|file\|local'
|
2015-03-13 16:31:15 +01:00
|
|
|
call add(links, [target.filename, target.anchor, lnum, col])
|
2014-12-04 21:18:58 +01:00
|
|
|
endif
|
|
|
|
endwhile
|
|
|
|
endfor
|
|
|
|
|
|
|
|
return links
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2014-12-04 21:18:58 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#check_links()
|
2014-12-04 21:18:58 +01:00
|
|
|
let anchors_of_files = {}
|
|
|
|
let links_of_files = {}
|
|
|
|
let errors = []
|
2016-12-28 22:17:08 +01:00
|
|
|
for idx in range(vimwiki#vars#number_of_wikis())
|
2016-12-23 20:05:53 +01:00
|
|
|
let syntax = vimwiki#vars#get_wikilocal('syntax', idx)
|
2015-02-24 09:39:03 +01:00
|
|
|
let wikifiles = vimwiki#base#find_files(idx, 0)
|
2014-12-04 21:18:58 +01:00
|
|
|
for wikifile in wikifiles
|
2014-12-07 11:58:08 +01:00
|
|
|
let links_of_files[wikifile] = s:get_links(wikifile, idx)
|
2014-12-04 21:18:58 +01:00
|
|
|
let anchors_of_files[wikifile] = vimwiki#base#get_anchors(wikifile, syntax)
|
|
|
|
endfor
|
|
|
|
endfor
|
|
|
|
|
|
|
|
for wikifile in keys(links_of_files)
|
|
|
|
for [target_file, target_anchor, lnum, col] in links_of_files[wikifile]
|
|
|
|
if target_file == '' && target_anchor == ''
|
|
|
|
call add(errors, {'filename':wikifile, 'lnum':lnum, 'col':col,
|
|
|
|
\ 'text': "numbered scheme refers to a non-existent wiki"})
|
|
|
|
elseif has_key(anchors_of_files, target_file)
|
|
|
|
if target_anchor != '' && index(anchors_of_files[target_file], target_anchor) < 0
|
|
|
|
call add(errors, {'filename':wikifile, 'lnum':lnum, 'col':col,
|
|
|
|
\'text': "there is no such anchor: ".target_anchor})
|
|
|
|
endif
|
|
|
|
else
|
2015-11-20 11:50:31 +01:00
|
|
|
if target_file =~ '\m/$' " maybe it's a link to a directory
|
2015-03-19 13:22:28 +01:00
|
|
|
if !isdirectory(target_file)
|
|
|
|
call add(errors, {'filename':wikifile, 'lnum':lnum, 'col':col,
|
|
|
|
\'text': "there is no such directory: ".target_file})
|
|
|
|
endif
|
2015-11-20 11:50:31 +01:00
|
|
|
else " maybe it's a non-wiki file
|
|
|
|
if filereadable(target_file)
|
2015-03-19 13:22:28 +01:00
|
|
|
let anchors_of_files[target_file] = []
|
|
|
|
else
|
|
|
|
call add(errors, {'filename':wikifile, 'lnum':lnum, 'col':col,
|
|
|
|
\'text': "there is no such file: ".target_file})
|
|
|
|
endif
|
2014-12-04 21:18:58 +01:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
endfor
|
|
|
|
|
2015-11-20 11:50:31 +01:00
|
|
|
|
|
|
|
" Check which wiki files are reachable from at least one of the index files.
|
|
|
|
" First, all index files are marked as reachable. Then, pick a reachable file
|
|
|
|
" and mark all files to which it links as reachable, too. Repeat until the
|
|
|
|
" links of all reachable files have been checked.
|
|
|
|
|
|
|
|
" Map every wiki file to a number. 0 means not reachable from any index file,
|
|
|
|
" 1 means reachable, but the outgoing links are not checked yet, 2 means
|
|
|
|
" reachable and done.
|
2014-12-04 21:18:58 +01:00
|
|
|
let reachable_wikifiles = {}
|
2015-11-20 11:50:31 +01:00
|
|
|
|
|
|
|
" first, all files are considered not reachable
|
2014-12-04 21:18:58 +01:00
|
|
|
for wikifile in keys(links_of_files)
|
|
|
|
let reachable_wikifiles[wikifile] = 0
|
|
|
|
endfor
|
2015-11-20 11:50:31 +01:00
|
|
|
|
|
|
|
" mark every index file as reachable
|
2016-12-28 22:17:08 +01:00
|
|
|
for idx in range(vimwiki#vars#number_of_wikis())
|
2018-04-20 07:03:53 +02:00
|
|
|
let index_file = vimwiki#vars#get_wikilocal('path', idx) .
|
|
|
|
\ vimwiki#vars#get_wikilocal('index', idx) . vimwiki#vars#get_wikilocal('ext', idx)
|
2015-11-20 11:50:31 +01:00
|
|
|
if filereadable(index_file)
|
|
|
|
let reachable_wikifiles[index_file] = 1
|
|
|
|
endif
|
2014-12-04 21:18:58 +01:00
|
|
|
endfor
|
2015-11-20 11:50:31 +01:00
|
|
|
|
2014-12-04 21:18:58 +01:00
|
|
|
while 1
|
2015-11-20 11:50:31 +01:00
|
|
|
let next_unvisited_wikifile = ''
|
2014-12-04 21:18:58 +01:00
|
|
|
for wf in keys(reachable_wikifiles)
|
|
|
|
if reachable_wikifiles[wf] == 1
|
2015-11-20 11:50:31 +01:00
|
|
|
let next_unvisited_wikifile = wf
|
2014-12-04 21:18:58 +01:00
|
|
|
let reachable_wikifiles[wf] = 2
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
endfor
|
2015-11-20 11:50:31 +01:00
|
|
|
if next_unvisited_wikifile == ''
|
2014-12-04 21:18:58 +01:00
|
|
|
break
|
|
|
|
endif
|
2015-11-20 11:50:31 +01:00
|
|
|
for [target_file, target_anchor, lnum, col] in links_of_files[next_unvisited_wikifile]
|
2014-12-04 21:18:58 +01:00
|
|
|
if has_key(reachable_wikifiles, target_file) && reachable_wikifiles[target_file] == 0
|
|
|
|
let reachable_wikifiles[target_file] = 1
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
endwhile
|
2015-11-20 11:50:31 +01:00
|
|
|
|
2014-12-04 21:18:58 +01:00
|
|
|
for wf in keys(reachable_wikifiles)
|
|
|
|
if reachable_wikifiles[wf] == 0
|
|
|
|
call add(errors, {'text':wf." is not reachable from the index file"})
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
|
|
|
|
if empty(errors)
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki: All links are OK'
|
2014-12-04 21:18:58 +01:00
|
|
|
else
|
|
|
|
call setqflist(errors, 'r')
|
|
|
|
copen
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2014-12-04 21:18:58 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#edit_file(command, filename, anchor, ...)
|
2018-02-19 07:44:19 +01:00
|
|
|
let fname = escape(a:filename, '% *|#`')
|
2012-06-07 02:00:00 +02:00
|
|
|
let dir = fnamemodify(a:filename, ":p:h")
|
2014-12-04 21:12:04 +01:00
|
|
|
|
|
|
|
let ok = vimwiki#path#mkdir(dir, 1)
|
|
|
|
|
|
|
|
if !ok
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg ' '
|
|
|
|
echomsg 'Vimwiki Error: Unable to edit file in non-existent directory: '.dir
|
2014-12-04 21:12:04 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2018-03-16 21:39:24 +01:00
|
|
|
" Check if the file we want to open is already the current file
|
2014-12-04 21:12:04 +01:00
|
|
|
" which happens if we jump to an achor in the current file.
|
|
|
|
" This hack is necessary because apparently Vim messes up the result of
|
|
|
|
" getpos() directly after this command. Strange.
|
2015-02-09 20:05:25 +01:00
|
|
|
if !(a:command ==# ':e ' && vimwiki#path#is_equal(a:filename, expand('%:p')))
|
2018-07-27 02:46:12 +02:00
|
|
|
if &autowriteall && !&hidden " in this case, the file is saved before switching to the
|
|
|
|
" new buffer. This causes Vim to show two messages in the command line which triggers
|
|
|
|
" the annoying hit-enter prompt. Solution: show no messages at all.
|
|
|
|
silent execute a:command fname
|
|
|
|
else
|
|
|
|
try
|
2018-03-16 21:39:24 +01:00
|
|
|
execute a:command fname
|
2018-07-27 02:46:12 +02:00
|
|
|
catch /E37:/
|
|
|
|
echomsg 'Vimwiki: The current file is modified. Hint: Take a look at'
|
|
|
|
\ ''':h g:vimwiki_autowriteall'' to see how to save automatically.'
|
|
|
|
return
|
|
|
|
endtry
|
|
|
|
endif
|
2017-11-11 21:52:07 +01:00
|
|
|
|
|
|
|
" If the opened file was not already loaded by Vim, an autocommand is
|
|
|
|
" triggered at this point
|
|
|
|
|
2015-04-09 14:29:50 +02:00
|
|
|
" Make sure no other plugin takes ownership over the new file. Vimwiki
|
|
|
|
" rules them all! Well, except for directories, which may be opened with
|
|
|
|
" Netrw
|
|
|
|
if &filetype != 'vimwiki' && fname !~ '\m/$'
|
2017-11-11 21:52:07 +01:00
|
|
|
setfiletype vimwiki
|
2015-03-31 14:31:58 +02:00
|
|
|
endif
|
2014-12-04 21:12:04 +01:00
|
|
|
endif
|
|
|
|
if a:anchor != ''
|
|
|
|
call s:jump_to_anchor(a:anchor)
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" 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
|
2017-01-13 16:33:41 +01:00
|
|
|
call vimwiki#vars#set_bufferlocal('prev_link', a:1)
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#search_word(wikiRx, cmd)
|
2010-01-20 01:00:00 +01:00
|
|
|
let match_line = search(a:wikiRx, 's'.a:cmd)
|
|
|
|
if match_line == 0
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki: Wiki link not found'
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" Returns part of the line that matches wikiRX at cursor
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#matchstr_at_cursor(wikiRX)
|
2010-01-20 01:00:00 +01:00
|
|
|
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
|
|
|
|
endwh
|
|
|
|
if ebeg >= 0
|
|
|
|
return strpart(line, ebeg, elen)
|
|
|
|
else
|
|
|
|
return ""
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#replacestr_at_cursor(wikiRX, sub)
|
2012-06-07 02:00:00 +02:00
|
|
|
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)
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
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)
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:print_wiki_list()
|
2010-01-20 01:00:00 +01:00
|
|
|
let idx = 0
|
2016-12-28 22:17:08 +01:00
|
|
|
while idx < vimwiki#vars#number_of_wikis()
|
|
|
|
if idx == vimwiki#vars#get_bufferlocal('wiki_nr')
|
2010-01-20 01:00:00 +01:00
|
|
|
let sep = ' * '
|
|
|
|
echohl PmenuSel
|
|
|
|
else
|
|
|
|
let sep = ' '
|
|
|
|
echohl None
|
|
|
|
endif
|
2016-12-22 19:55:20 +01:00
|
|
|
echo (idx + 1) . sep . vimwiki#vars#get_wikilocal('path', idx)
|
2010-01-20 01:00:00 +01:00
|
|
|
let idx += 1
|
|
|
|
endwhile
|
|
|
|
echohl None
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:update_wiki_link(fname, old, new)
|
2010-01-20 01:00:00 +01:00
|
|
|
echo "Updating links in ".a:fname
|
|
|
|
let has_updates = 0
|
|
|
|
let dest = []
|
|
|
|
for line in readfile(a:fname)
|
|
|
|
if !has_updates && match(line, a:old) != -1
|
|
|
|
let has_updates = 1
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
" XXX: any other characters to escape!?
|
2010-01-20 01:00:00 +01:00
|
|
|
call add(dest, substitute(line, a:old, escape(a:new, "&"), "g"))
|
|
|
|
endfor
|
|
|
|
" add exception handling...
|
|
|
|
if has_updates
|
|
|
|
call rename(a:fname, a:fname.'#vimwiki_upd#')
|
|
|
|
call writefile(dest, a:fname)
|
|
|
|
call delete(a:fname.'#vimwiki_upd#')
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:update_wiki_links_dir(dir, old_fname, new_fname)
|
2010-01-20 01:00:00 +01:00
|
|
|
let old_fname = substitute(a:old_fname, '[/\\]', '[/\\\\]', 'g')
|
|
|
|
let new_fname = a:new_fname
|
|
|
|
|
2014-06-19 15:36:11 +02:00
|
|
|
let old_fname_r = vimwiki#base#apply_template(
|
2017-01-11 22:12:33 +01:00
|
|
|
\ vimwiki#vars#get_syntaxlocal('WikiLinkMatchUrlTemplate'), old_fname, '', '')
|
2010-08-24 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
let files = split(glob(vimwiki#vars#get_wikilocal('path').a:dir.'*'.
|
|
|
|
\ vimwiki#vars#get_wikilocal('ext')), '\n')
|
2010-01-20 01:00:00 +01:00
|
|
|
for fname in files
|
2014-06-19 15:36:11 +02:00
|
|
|
call s:update_wiki_link(fname, old_fname_r, new_fname)
|
2010-01-20 01:00:00 +01:00
|
|
|
endfor
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:tail_name(fname)
|
2010-01-20 01:00:00 +01:00
|
|
|
let result = substitute(a:fname, ":", "__colon__", "g")
|
|
|
|
let result = fnamemodify(result, ":t:r")
|
|
|
|
let result = substitute(result, "__colon__", ":", "g")
|
|
|
|
return result
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:update_wiki_links(old_fname, new_fname)
|
2013-08-17 18:10:00 +02:00
|
|
|
let old_fname = a:old_fname
|
|
|
|
let new_fname = a:new_fname
|
2010-01-20 01:00:00 +01:00
|
|
|
|
|
|
|
let subdirs = split(a:old_fname, '[/\\]')[: -2]
|
|
|
|
|
|
|
|
" TODO: Use Dictionary here...
|
|
|
|
let dirs_keys = ['']
|
|
|
|
let dirs_vals = ['']
|
|
|
|
if len(subdirs) > 0
|
|
|
|
let dirs_keys = ['']
|
|
|
|
let dirs_vals = [join(subdirs, '/').'/']
|
|
|
|
let idx = 0
|
|
|
|
while idx < len(subdirs) - 1
|
|
|
|
call add(dirs_keys, join(subdirs[: idx], '/').'/')
|
|
|
|
call add(dirs_vals, join(subdirs[idx+1 :], '/').'/')
|
|
|
|
let idx = idx + 1
|
|
|
|
endwhile
|
|
|
|
call add(dirs_keys,join(subdirs, '/').'/')
|
|
|
|
call add(dirs_vals, '')
|
|
|
|
endif
|
|
|
|
|
|
|
|
let idx = 0
|
|
|
|
while idx < len(dirs_keys)
|
|
|
|
let dir = dirs_keys[idx]
|
|
|
|
let new_dir = dirs_vals[idx]
|
2018-04-20 07:03:53 +02:00
|
|
|
call s:update_wiki_links_dir(dir, new_dir.old_fname, new_dir.new_fname)
|
2010-01-20 01:00:00 +01:00
|
|
|
let idx = idx + 1
|
|
|
|
endwhile
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:get_wiki_buffers()
|
2010-01-20 01:00:00 +01:00
|
|
|
let blist = []
|
|
|
|
let bcount = 1
|
|
|
|
while bcount<=bufnr("$")
|
|
|
|
if bufexists(bcount)
|
|
|
|
let bname = fnamemodify(bufname(bcount), ":p")
|
2017-01-13 16:33:41 +01:00
|
|
|
" this may find buffers that are not part of the current wiki, but that
|
|
|
|
" doesn't hurt
|
2016-12-22 21:00:19 +01:00
|
|
|
if bname =~# vimwiki#vars#get_wikilocal('ext')."$"
|
2017-01-13 16:33:41 +01:00
|
|
|
let bitem = [bname, vimwiki#vars#get_bufferlocal('prev_link', bcount)]
|
2010-01-20 01:00:00 +01:00
|
|
|
call add(blist, bitem)
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
let bcount = bcount + 1
|
|
|
|
endwhile
|
|
|
|
return blist
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:open_wiki_buffer(item)
|
2014-02-13 12:42:24 +01:00
|
|
|
call vimwiki#base#edit_file(':e', a:item[0], '')
|
2010-01-20 01:00:00 +01:00
|
|
|
if !empty(a:item[1])
|
2017-01-13 16:33:41 +01:00
|
|
|
call vimwiki#vars#set_bufferlocal('prev_link', a:item[1], a:item[0])
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#nested_syntax(filetype, start, end, textSnipHl) abort
|
2010-01-20 01:00:00 +01:00
|
|
|
" From http://vim.wikia.com/wiki/VimTip857
|
|
|
|
let ft=toupper(a:filetype)
|
|
|
|
let group='textGroup'.ft
|
|
|
|
if exists('b:current_syntax')
|
|
|
|
let s:current_syntax=b:current_syntax
|
|
|
|
" Remove current syntax definition, as some syntax files (e.g. cpp.vim)
|
|
|
|
" do nothing if b:current_syntax is defined.
|
|
|
|
unlet b:current_syntax
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Some syntax files set up iskeyword which might scratch vimwiki a bit.
|
|
|
|
" Let us save and restore it later.
|
|
|
|
" let b:skip_set_iskeyword = 1
|
|
|
|
let is_keyword = &iskeyword
|
|
|
|
|
|
|
|
try
|
2012-07-07 02:00:00 +02:00
|
|
|
" keep going even if syntax file is not found
|
|
|
|
execute 'syntax include @'.group.' syntax/'.a:filetype.'.vim'
|
2010-01-20 01:00:00 +01:00
|
|
|
execute 'syntax include @'.group.' after/syntax/'.a:filetype.'.vim'
|
|
|
|
catch
|
|
|
|
endtry
|
|
|
|
|
|
|
|
let &iskeyword = is_keyword
|
|
|
|
|
|
|
|
if exists('s:current_syntax')
|
|
|
|
let b:current_syntax=s:current_syntax
|
|
|
|
else
|
|
|
|
unlet b:current_syntax
|
|
|
|
endif
|
2016-11-24 16:46:56 +01:00
|
|
|
|
|
|
|
" Fix issue #236: tell Vimwiki to think in maths when encountering maths
|
|
|
|
" blocks like {{$ }}$. Here, we don't want the tex highlight group, but the
|
|
|
|
" group for tex math.
|
|
|
|
if a:textSnipHl ==# 'VimwikiMath'
|
|
|
|
let group='texMathZoneGroup'
|
|
|
|
endif
|
|
|
|
|
2010-08-24 02:00:00 +02:00
|
|
|
execute 'syntax region textSnip'.ft.
|
|
|
|
\ ' matchgroup='.a:textSnipHl.
|
|
|
|
\ ' start="'.a:start.'" end="'.a:end.'"'.
|
|
|
|
\ ' contains=@'.group.' keepend'
|
|
|
|
|
|
|
|
" A workaround to Issue 115: Nested Perl syntax highlighting differs from
|
|
|
|
" regular one.
|
|
|
|
" Perl syntax file has perlFunctionName which is usually has no effect due to
|
|
|
|
" 'contained' flag. Now we have 'syntax include' that makes all the groups
|
2018-04-20 07:03:53 +02:00
|
|
|
" included as 'contained' into specific group.
|
2010-08-24 02:00:00 +02:00
|
|
|
" Here perlFunctionName (with quite an angry regexp "\h\w*[^:]") clashes with
|
|
|
|
" the rest syntax rules as now it has effect being really 'contained'.
|
|
|
|
" Clear it!
|
2015-02-09 20:47:11 +01:00
|
|
|
if ft =~? 'perl'
|
2018-04-20 07:03:53 +02:00
|
|
|
syntax clear perlFunctionName
|
2010-08-24 02:00:00 +02:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2015-11-09 15:45:56 +01:00
|
|
|
" creates or updates auto-generated listings in a wiki file, like TOC, diary
|
|
|
|
" links, tags list etc.
|
|
|
|
" - the listing consists of a level 1 header and a list of strings as content
|
|
|
|
" - a:content_regex is used to determine how long a potentially existing list is
|
|
|
|
" - a:default_lnum is the line number where the new listing should be placed if
|
|
|
|
" it's not already present
|
|
|
|
" - if a:create is true, it will be created if it doesn't exist, otherwise it
|
|
|
|
" will only be updated if it already exists
|
|
|
|
function! vimwiki#base#update_listing_in_buffer(strings, start_header,
|
2018-04-20 07:03:53 +02:00
|
|
|
\ content_regex, default_lnum, create)
|
2015-11-09 15:45:56 +01:00
|
|
|
" apparently, Vim behaves strange when files change while in diff mode
|
|
|
|
if &diff || &readonly
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
|
|
|
" check if the listing is already there
|
|
|
|
let already_there = 0
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
let header_rx = '\m^\s*'.substitute(vimwiki#vars#get_syntaxlocal('rxH1_Template'),
|
|
|
|
\ '__Header__', a:start_header, '') .'\s*$'
|
2015-11-09 15:45:56 +01:00
|
|
|
|
|
|
|
let start_lnum = 1
|
|
|
|
while start_lnum <= line('$')
|
|
|
|
if getline(start_lnum) =~# header_rx
|
|
|
|
let already_there = 1
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
let start_lnum += 1
|
|
|
|
endwhile
|
|
|
|
|
|
|
|
if !already_there && !a:create
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2015-11-27 01:20:44 +01:00
|
|
|
let winview_save = winsaveview()
|
|
|
|
let cursor_line = winview_save.lnum
|
2015-11-27 01:05:39 +01:00
|
|
|
let is_cursor_after_listing = 0
|
|
|
|
|
2015-11-27 01:13:25 +01:00
|
|
|
let is_fold_closed = 1
|
|
|
|
|
2015-11-27 01:05:39 +01:00
|
|
|
let lines_diff = 0
|
2015-11-09 15:45:56 +01:00
|
|
|
|
|
|
|
if already_there
|
2015-12-04 12:33:03 +01:00
|
|
|
let is_fold_closed = ( foldclosed(start_lnum) > -1 )
|
2015-11-09 15:45:56 +01:00
|
|
|
" delete the old listing
|
|
|
|
let whitespaces_in_first_line = matchstr(getline(start_lnum), '\m^\s*')
|
|
|
|
let end_lnum = start_lnum + 1
|
|
|
|
while end_lnum <= line('$') && getline(end_lnum) =~# a:content_regex
|
|
|
|
let end_lnum += 1
|
|
|
|
endwhile
|
2015-11-27 01:05:39 +01:00
|
|
|
let is_cursor_after_listing = ( cursor_line >= end_lnum )
|
|
|
|
" We'll be removing a range. But, apparently, if folds are enabled, Vim
|
|
|
|
" won't let you remove a range that overlaps with closed fold -- the entire
|
|
|
|
" fold gets deleted. So we temporarily disable folds, and then reenable
|
|
|
|
" them right back.
|
|
|
|
let foldenable_save = &l:foldenable
|
|
|
|
setlo nofoldenable
|
2015-11-09 15:45:56 +01:00
|
|
|
silent exe start_lnum.','.string(end_lnum - 1).'delete _'
|
2015-11-27 01:05:39 +01:00
|
|
|
let &l:foldenable = foldenable_save
|
|
|
|
let lines_diff = 0 - (end_lnum - start_lnum)
|
2015-11-09 15:45:56 +01:00
|
|
|
else
|
|
|
|
let start_lnum = a:default_lnum
|
2015-11-27 01:05:39 +01:00
|
|
|
let is_cursor_after_listing = ( cursor_line > a:default_lnum )
|
2015-11-09 15:45:56 +01:00
|
|
|
let whitespaces_in_first_line = ''
|
|
|
|
endif
|
|
|
|
|
2015-12-01 20:41:50 +01:00
|
|
|
let start_of_listing = start_lnum
|
|
|
|
|
2015-11-09 15:45:56 +01:00
|
|
|
" write new listing
|
|
|
|
let new_header = whitespaces_in_first_line
|
2018-02-19 07:44:19 +01:00
|
|
|
\ . s:safesubstitute(vimwiki#vars#get_syntaxlocal('rxH1_Template'),
|
|
|
|
\ '__Header__', a:start_header, '')
|
2015-11-09 15:45:56 +01:00
|
|
|
call append(start_lnum - 1, new_header)
|
|
|
|
let start_lnum += 1
|
2015-11-27 01:05:39 +01:00
|
|
|
let lines_diff += 1 + len(a:strings)
|
2015-11-09 15:45:56 +01:00
|
|
|
for string in a:strings
|
|
|
|
call append(start_lnum - 1, string)
|
|
|
|
let start_lnum += 1
|
|
|
|
endfor
|
|
|
|
" append an empty line if there is not one
|
|
|
|
if start_lnum <= line('$') && getline(start_lnum) !~# '\m^\s*$'
|
|
|
|
call append(start_lnum - 1, '')
|
2015-11-27 01:05:39 +01:00
|
|
|
let lines_diff += 1
|
2015-11-09 15:45:56 +01:00
|
|
|
endif
|
|
|
|
|
2015-11-27 01:13:25 +01:00
|
|
|
" Open fold, if needed
|
2015-12-04 12:33:03 +01:00
|
|
|
if !is_fold_closed && ( foldclosed(start_of_listing) > -1 )
|
2015-12-01 20:41:50 +01:00
|
|
|
exe start_of_listing
|
|
|
|
norm! zo
|
2015-11-27 01:13:25 +01:00
|
|
|
endif
|
|
|
|
|
2015-11-27 01:05:39 +01:00
|
|
|
if is_cursor_after_listing
|
2015-11-27 01:20:44 +01:00
|
|
|
let winview_save.lnum += lines_diff
|
2015-11-27 01:05:39 +01:00
|
|
|
endif
|
2015-11-27 01:20:44 +01:00
|
|
|
call winrestview(winview_save)
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2015-11-09 15:45:56 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#find_next_link()
|
2017-01-11 22:12:33 +01:00
|
|
|
call vimwiki#base#search_word(vimwiki#vars#get_syntaxlocal('rxAnyLink'), '')
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#find_prev_link()
|
2014-01-06 13:37:33 +01:00
|
|
|
"Jump 2 times if the cursor is in the middle of a link
|
2015-02-09 20:47:11 +01:00
|
|
|
if synIDattr(synID(line('.'), col('.'), 0), "name") =~# "VimwikiLink.*" &&
|
|
|
|
\ synIDattr(synID(line('.'), col('.')-1, 0), "name") =~# "VimwikiLink.*"
|
2017-01-11 22:12:33 +01:00
|
|
|
call vimwiki#base#search_word(vimwiki#vars#get_syntaxlocal('rxAnyLink'), 'b')
|
2014-01-06 13:37:33 +01:00
|
|
|
endif
|
2017-01-11 22:12:33 +01:00
|
|
|
call vimwiki#base#search_word(vimwiki#vars#get_syntaxlocal('rxAnyLink'), 'b')
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-06-26 21:38:55 +02:00
|
|
|
function! vimwiki#base#follow_link(split, ...)
|
|
|
|
let reuse_other_split_window = a:0 >= 1 ? a:1 : 0
|
|
|
|
let move_cursor_to_new_window = a:0 >= 2 ? a:2 : 1
|
|
|
|
|
2018-02-16 17:47:32 +01:00
|
|
|
" Parse link at cursor and pass to VimwikiLinkHandler, or failing that, the
|
|
|
|
" default open_link handler
|
|
|
|
|
|
|
|
" try WikiLink
|
|
|
|
let lnk = matchstr(vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink')),
|
|
|
|
\ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'))
|
|
|
|
" try WikiIncl
|
|
|
|
if lnk == ""
|
2018-02-20 17:42:13 +01:00
|
|
|
let lnk = matchstr(vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWikiIncl')),
|
|
|
|
\ vimwiki#vars#get_global('rxWikiInclMatchUrl'))
|
2018-02-16 17:47:32 +01:00
|
|
|
endif
|
|
|
|
" try Weblink
|
|
|
|
if lnk == ""
|
|
|
|
let lnk = matchstr(vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink')),
|
|
|
|
\ vimwiki#vars#get_syntaxlocal('rxWeblinkMatchUrl'))
|
|
|
|
endif
|
|
|
|
|
|
|
|
if lnk != "" " cursor is indeed on a link
|
|
|
|
let processed_by_user_defined_handler = VimwikiLinkHandler(lnk)
|
|
|
|
if processed_by_user_defined_handler
|
|
|
|
return
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
2018-02-16 17:47:32 +01:00
|
|
|
|
|
|
|
if a:split ==# "hsplit"
|
2012-06-07 02:00:00 +02:00
|
|
|
let cmd = ":split "
|
2015-02-09 20:05:25 +01:00
|
|
|
elseif a:split ==# "vsplit"
|
2012-06-07 02:00:00 +02:00
|
|
|
let cmd = ":vsplit "
|
2018-02-16 17:47:32 +01:00
|
|
|
elseif a:split ==# "tab"
|
2012-06-07 02:00:00 +02:00
|
|
|
let cmd = ":tabnew "
|
|
|
|
else
|
|
|
|
let cmd = ":e "
|
|
|
|
endif
|
|
|
|
|
2018-02-16 17:47:32 +01:00
|
|
|
" if we want to and can reuse a split window, jump to that window and open
|
|
|
|
" the new file there
|
2018-06-26 21:38:55 +02:00
|
|
|
if (a:split ==# 'hsplit' || a:split ==# 'vsplit') && reuse_other_split_window
|
2018-02-16 17:47:32 +01:00
|
|
|
let previous_window_nr = winnr('#')
|
|
|
|
if previous_window_nr > 0 && previous_window_nr != winnr()
|
|
|
|
execute previous_window_nr . 'wincmd w'
|
|
|
|
let cmd = ':e'
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
2018-02-16 17:47:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
if vimwiki#vars#get_wikilocal('syntax') == 'markdown'
|
|
|
|
let processed_by_markdown_reflink = vimwiki#markdown_base#open_reflink(lnk)
|
|
|
|
if processed_by_markdown_reflink
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
|
|
|
" remove the extension from the filename if exists, because non-vimwiki
|
|
|
|
" markdown files usually include the extension in links
|
2018-02-17 21:30:01 +01:00
|
|
|
let lnk = substitute(lnk, '\'.vimwiki#vars#get_wikilocal('ext').'$', '', '')
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-02-16 17:47:32 +01:00
|
|
|
let current_tab_page = tabpagenr()
|
|
|
|
|
|
|
|
call vimwiki#base#open_link(cmd, lnk)
|
|
|
|
|
2018-06-26 21:38:55 +02:00
|
|
|
if !move_cursor_to_new_window
|
2018-02-16 17:47:32 +01:00
|
|
|
if (a:split ==# 'hsplit' || a:split ==# 'vsplit')
|
|
|
|
execute 'wincmd p'
|
|
|
|
elseif a:split ==# 'tab'
|
|
|
|
execute 'tabnext ' . current_tab_page
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2018-02-16 17:47:32 +01:00
|
|
|
else
|
2018-06-26 21:38:55 +02:00
|
|
|
if a:0 >= 3
|
|
|
|
execute "normal! ".a:3
|
2018-04-20 07:03:53 +02:00
|
|
|
else
|
2012-06-07 02:00:00 +02:00
|
|
|
call vimwiki#base#normalize_link(0)
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#go_back_link()
|
2017-01-13 16:33:41 +01:00
|
|
|
let prev_link = vimwiki#vars#get_bufferlocal('prev_link')
|
2017-01-16 22:09:49 +01:00
|
|
|
if !empty(prev_link)
|
2012-06-07 02:00:00 +02:00
|
|
|
" go back to saved wiki link
|
2018-03-16 21:39:24 +01:00
|
|
|
call vimwiki#base#edit_file(':e ', prev_link[0], '')
|
2017-01-13 16:33:41 +01:00
|
|
|
call setpos('.', prev_link[1])
|
2015-05-15 11:04:53 +02:00
|
|
|
else
|
|
|
|
" maybe we came here by jumping to a tag -> pop from the tag stack
|
|
|
|
silent! pop!
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#goto_index(wnum, ...)
|
2018-03-25 21:51:08 +02:00
|
|
|
if a:wnum > vimwiki#vars#number_of_wikis()
|
|
|
|
echomsg 'Vimwiki Error: Wiki '.a:wnum.' is not registered in your Vimwiki settings!'
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" usually a:wnum is greater then 0 but with the following command it is == 0:
|
2016-12-25 21:35:56 +01:00
|
|
|
" vim -n -c ":VimwikiIndex"
|
2012-06-07 02:00:00 +02:00
|
|
|
if a:wnum > 0
|
|
|
|
let idx = a:wnum - 1
|
|
|
|
else
|
|
|
|
let idx = 0
|
|
|
|
endif
|
|
|
|
|
|
|
|
if a:0
|
2018-02-19 07:44:19 +01:00
|
|
|
if a:1 == 1
|
|
|
|
let cmd = 'tabedit'
|
|
|
|
elseif a:1 == 2
|
|
|
|
let cmd = 'split'
|
|
|
|
elseif a:1 == 3
|
|
|
|
let cmd = 'vsplit'
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
else
|
|
|
|
let cmd = 'edit'
|
|
|
|
endif
|
|
|
|
|
2016-12-25 21:35:56 +01:00
|
|
|
let index_file = vimwiki#vars#get_wikilocal('path', idx).
|
|
|
|
\ vimwiki#vars#get_wikilocal('index', idx).
|
|
|
|
\ vimwiki#vars#get_wikilocal('ext', idx)
|
|
|
|
|
|
|
|
call vimwiki#base#edit_file(cmd, index_file, '')
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#delete_link()
|
|
|
|
" Delete wiki file you are in from filesystem
|
2015-02-07 22:01:20 +01:00
|
|
|
let val = input('Delete "'.expand('%').'" [y]es/[N]o? ')
|
|
|
|
if val !~? '^y'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
let fname = expand('%:p')
|
|
|
|
try
|
|
|
|
call delete(fname)
|
|
|
|
catch /.*/
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki Error: Cannot delete "'.expand('%:t:r').'"!'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endtry
|
2012-06-07 02:00:00 +02:00
|
|
|
|
|
|
|
call vimwiki#base#go_back_link()
|
2010-01-20 01:00:00 +01:00
|
|
|
execute "bdelete! ".escape(fname, " ")
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" reread buffer => deleted wiki link should appear as non-existent
|
2010-01-20 01:00:00 +01:00
|
|
|
if expand('%:p') != ""
|
|
|
|
execute "e"
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2014-12-07 11:58:08 +01:00
|
|
|
" Rename current file, update all links to it
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#rename_link()
|
2017-01-07 21:51:15 +01:00
|
|
|
let subdir = vimwiki#vars#get_bufferlocal('subdir')
|
2010-01-20 01:00:00 +01:00
|
|
|
let old_fname = subdir.expand('%:t')
|
|
|
|
|
|
|
|
" there is no file (new one maybe)
|
|
|
|
if glob(expand('%:p')) == ''
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki Error: Cannot rename "'.expand('%:p').
|
2010-01-20 01:00:00 +01:00
|
|
|
\'". It does not exist! (New file? Save it before renaming.)'
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2015-02-07 22:01:20 +01:00
|
|
|
let val = input('Rename "'.expand('%:t:r').'" [y]es/[N]o? ')
|
|
|
|
if val !~? '^y'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2015-02-07 22:01:20 +01:00
|
|
|
let new_link = input('Enter new name: ')
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2015-02-09 20:47:11 +01:00
|
|
|
if new_link =~# '[/\\]'
|
2010-01-20 01:00:00 +01:00
|
|
|
" It is actually doable but I do not have free time to do it.
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki Error: Cannot rename to a filename with path!'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
|
|
|
" check new_fname - it should be 'good', not empty
|
|
|
|
if substitute(new_link, '\s', '', 'g') == ''
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki Error: Cannot rename to an empty filename!'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2017-01-11 22:12:33 +01:00
|
|
|
let url = matchstr(new_link, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'))
|
2012-06-07 02:00:00 +02:00
|
|
|
if url != ''
|
|
|
|
let new_link = url
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
|
2010-08-24 02:00:00 +02:00
|
|
|
let new_link = subdir.new_link
|
2016-12-22 21:00:19 +01:00
|
|
|
let new_fname = vimwiki#vars#get_wikilocal('path') . new_link . vimwiki#vars#get_wikilocal('ext')
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" do not rename if file with such name exists
|
2010-01-20 01:00:00 +01:00
|
|
|
let fname = glob(new_fname)
|
|
|
|
if fname != ''
|
2018-04-20 07:03:53 +02:00
|
|
|
echomsg 'Vimwiki Error: Cannot rename to "'.new_fname.'". File with that name exist!'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
" rename wiki link file
|
2010-01-20 01:00:00 +01:00
|
|
|
try
|
2016-12-22 19:55:20 +01:00
|
|
|
echomsg 'Vimwiki: Renaming '.vimwiki#vars#get_wikilocal('path').old_fname.' to '.new_fname
|
2010-01-20 01:00:00 +01:00
|
|
|
let res = rename(expand('%:p'), expand(new_fname))
|
|
|
|
if res != 0
|
|
|
|
throw "Cannot rename!"
|
|
|
|
end
|
|
|
|
catch /.*/
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki Error: Cannot rename "'.expand('%:t:r').'" to "'.new_fname.'"'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endtry
|
|
|
|
|
|
|
|
let &buftype="nofile"
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
let cur_buffer = [expand('%:p'), vimwiki#vars#get_bufferlocal('prev_link')]
|
2010-01-20 01:00:00 +01:00
|
|
|
|
|
|
|
let blist = s:get_wiki_buffers()
|
|
|
|
|
|
|
|
" save wiki buffers
|
|
|
|
for bitem in blist
|
|
|
|
execute ':b '.escape(bitem[0], ' ')
|
|
|
|
execute ':update'
|
|
|
|
endfor
|
|
|
|
|
|
|
|
execute ':b '.escape(cur_buffer[0], ' ')
|
|
|
|
|
|
|
|
" remove wiki buffers
|
|
|
|
for bitem in blist
|
|
|
|
execute 'bwipeout '.escape(bitem[0], ' ')
|
|
|
|
endfor
|
|
|
|
|
|
|
|
let setting_more = &more
|
|
|
|
setlocal nomore
|
|
|
|
|
|
|
|
" update links
|
2013-08-17 18:10:00 +02:00
|
|
|
call s:update_wiki_links(s:tail_name(old_fname), new_link)
|
2010-01-20 01:00:00 +01:00
|
|
|
|
|
|
|
" restore wiki buffers
|
|
|
|
for bitem in blist
|
2015-02-09 20:24:18 +01:00
|
|
|
if !vimwiki#path#is_equal(bitem[0], cur_buffer[0])
|
2010-01-20 01:00:00 +01:00
|
|
|
call s:open_wiki_buffer(bitem)
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
call s:open_wiki_buffer([new_fname, cur_buffer[1]])
|
2010-01-20 01:00:00 +01:00
|
|
|
" execute 'bwipeout '.escape(cur_buffer[0], ' ')
|
|
|
|
|
2016-03-19 21:29:42 +01:00
|
|
|
echomsg 'Vimwiki: '.old_fname.' is renamed to '.new_fname
|
2010-01-20 01:00:00 +01:00
|
|
|
|
|
|
|
let &more = setting_more
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#ui_select()
|
2010-01-20 01:00:00 +01:00
|
|
|
call s:print_wiki_list()
|
|
|
|
let idx = input("Select Wiki (specify number): ")
|
|
|
|
if idx == ""
|
|
|
|
return
|
|
|
|
endif
|
2011-06-11 02:00:00 +02:00
|
|
|
call vimwiki#base#goto_index(idx)
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-01-20 01:00:00 +01:00
|
|
|
|
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
function! vimwiki#base#TO_header(inner, including_subheaders, count)
|
|
|
|
let headers = s:collect_headers()
|
|
|
|
if empty(headers)
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
let current_line = line('.')
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-06 21:11:40 +02:00
|
|
|
let current_header_index = s:current_header(headers, current_line)
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
if current_header_index < 0
|
|
|
|
return
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
" from which to which header
|
|
|
|
if !a:including_subheaders && a:count <= 1
|
|
|
|
let first_line = headers[current_header_index][0]
|
|
|
|
let last_line = current_header_index == len(headers)-1 ? line('$') :
|
|
|
|
\ headers[current_header_index + 1][0] - 1
|
|
|
|
else
|
|
|
|
let first_header_index = current_header_index
|
|
|
|
for _ in range(a:count - 1)
|
|
|
|
let parent = s:get_another_header(headers, first_header_index, -1, '<')
|
|
|
|
if parent < 0
|
|
|
|
break
|
|
|
|
else
|
|
|
|
let first_header_index = parent
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
|
|
|
|
let next_sibling_or_higher = s:get_another_header(headers, first_header_index, +1, '<=')
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
let first_line = headers[first_header_index][0]
|
|
|
|
let last_line =
|
|
|
|
\ next_sibling_or_higher >= 0 ? headers[next_sibling_or_higher][0] - 1 : line('$')
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
if a:inner
|
|
|
|
let first_line += 1
|
|
|
|
let last_line = prevnonblank(last_line)
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
if first_line > last_line
|
|
|
|
" this can happen e.g. when doing vih on a header with another header in the very next line
|
|
|
|
return
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-06 07:16:07 +02:00
|
|
|
|
|
|
|
call cursor(first_line, 1)
|
|
|
|
normal! V
|
|
|
|
call cursor(last_line, 1)
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#TO_table_cell(inner, visual)
|
2010-05-12 02:00:00 +02:00
|
|
|
if col('.') == col('$')-1
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
|
|
|
if a:visual
|
|
|
|
normal! `>
|
|
|
|
let sel_end = getpos('.')
|
|
|
|
normal! `<
|
|
|
|
let sel_start = getpos('.')
|
|
|
|
|
|
|
|
let firsttime = sel_start == sel_end
|
|
|
|
|
|
|
|
if firsttime
|
|
|
|
if !search('|\|\(-+-\)', 'cb', line('.'))
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
if getline('.')[virtcol('.')] == '+'
|
|
|
|
normal! l
|
|
|
|
endif
|
|
|
|
if a:inner
|
|
|
|
normal! 2l
|
|
|
|
endif
|
|
|
|
let sel_start = getpos('.')
|
|
|
|
endif
|
|
|
|
|
|
|
|
normal! `>
|
|
|
|
call search('|\|\(-+-\)', '', line('.'))
|
|
|
|
if getline('.')[virtcol('.')] == '+'
|
|
|
|
normal! l
|
|
|
|
endif
|
|
|
|
if a:inner
|
|
|
|
if firsttime || abs(sel_end[2] - getpos('.')[2]) != 2
|
|
|
|
normal! 2h
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
let sel_end = getpos('.')
|
|
|
|
|
|
|
|
call setpos('.', sel_start)
|
|
|
|
exe "normal! \<C-v>"
|
|
|
|
call setpos('.', sel_end)
|
|
|
|
|
|
|
|
" XXX: WORKAROUND.
|
|
|
|
" if blockwise selection is ended at | character then pressing j to extend
|
2018-04-20 07:03:53 +02:00
|
|
|
" selection further fails. But if we shake the cursor left and right then
|
2010-05-12 02:00:00 +02:00
|
|
|
" it works.
|
|
|
|
normal! hl
|
|
|
|
else
|
|
|
|
if !search('|\|\(-+-\)', 'cb', line('.'))
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
if a:inner
|
|
|
|
normal! 2l
|
|
|
|
endif
|
|
|
|
normal! v
|
|
|
|
call search('|\|\(-+-\)', '', line('.'))
|
|
|
|
if !a:inner && getline('.')[virtcol('.')-1] == '|'
|
|
|
|
normal! h
|
|
|
|
elseif a:inner
|
|
|
|
normal! 2h
|
|
|
|
endif
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-05-12 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#TO_table_col(inner, visual)
|
2012-06-07 02:00:00 +02:00
|
|
|
let t_rows = vimwiki#tbl#get_rows(line('.'))
|
2010-05-12 02:00:00 +02:00
|
|
|
if empty(t_rows)
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
|
|
|
" TODO: refactor it!
|
|
|
|
if a:visual
|
|
|
|
normal! `>
|
|
|
|
let sel_end = getpos('.')
|
|
|
|
normal! `<
|
|
|
|
let sel_start = getpos('.')
|
|
|
|
|
|
|
|
let firsttime = sel_start == sel_end
|
|
|
|
|
|
|
|
if firsttime
|
|
|
|
" place cursor to the top row of the table
|
2012-06-07 02:00:00 +02:00
|
|
|
call vimwiki#u#cursor(t_rows[0][0], virtcol('.'))
|
2010-05-12 02:00:00 +02:00
|
|
|
" do not accept the match at cursor position if cursor is next to column
|
|
|
|
" separator of the table separator (^ is a cursor):
|
|
|
|
" |-----^-+-------|
|
|
|
|
" | bla | bla |
|
|
|
|
" |-------+-------|
|
|
|
|
" or it will select wrong column.
|
2015-02-09 20:47:11 +01:00
|
|
|
if strpart(getline('.'), virtcol('.')-1) =~# '^-+'
|
2010-05-12 02:00:00 +02:00
|
|
|
let s_flag = 'b'
|
|
|
|
else
|
|
|
|
let s_flag = 'cb'
|
|
|
|
endif
|
|
|
|
" search the column separator backwards
|
|
|
|
if !search('|\|\(-+-\)', s_flag, line('.'))
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
" -+- column separator is matched --> move cursor to the + sign
|
|
|
|
if getline('.')[virtcol('.')] == '+'
|
|
|
|
normal! l
|
|
|
|
endif
|
|
|
|
" inner selection --> reduce selection
|
|
|
|
if a:inner
|
|
|
|
normal! 2l
|
|
|
|
endif
|
|
|
|
let sel_start = getpos('.')
|
|
|
|
endif
|
|
|
|
|
|
|
|
normal! `>
|
|
|
|
if !firsttime && getline('.')[virtcol('.')] == '|'
|
|
|
|
normal! l
|
2015-02-09 20:47:11 +01:00
|
|
|
elseif a:inner && getline('.')[virtcol('.')+1] =~# '[|+]'
|
2010-05-12 02:00:00 +02:00
|
|
|
normal! 2l
|
|
|
|
endif
|
|
|
|
" search for the next column separator
|
|
|
|
call search('|\|\(-+-\)', '', line('.'))
|
|
|
|
" Outer selection selects a column without border on the right. So we move
|
|
|
|
" our cursor left if the previous search finds | border, not -+-.
|
|
|
|
if getline('.')[virtcol('.')] != '+'
|
|
|
|
normal! h
|
|
|
|
endif
|
|
|
|
if a:inner
|
|
|
|
" reduce selection a bit more if inner.
|
|
|
|
normal! h
|
|
|
|
endif
|
|
|
|
" expand selection to the bottom line of the table
|
2012-06-07 02:00:00 +02:00
|
|
|
call vimwiki#u#cursor(t_rows[-1][0], virtcol('.'))
|
2010-05-12 02:00:00 +02:00
|
|
|
let sel_end = getpos('.')
|
|
|
|
|
|
|
|
call setpos('.', sel_start)
|
|
|
|
exe "normal! \<C-v>"
|
|
|
|
call setpos('.', sel_end)
|
|
|
|
|
|
|
|
else
|
|
|
|
" place cursor to the top row of the table
|
2012-06-07 02:00:00 +02:00
|
|
|
call vimwiki#u#cursor(t_rows[0][0], virtcol('.'))
|
2010-05-12 02:00:00 +02:00
|
|
|
" do not accept the match at cursor position if cursor is next to column
|
|
|
|
" separator of the table separator (^ is a cursor):
|
|
|
|
" |-----^-+-------|
|
|
|
|
" | bla | bla |
|
|
|
|
" |-------+-------|
|
|
|
|
" or it will select wrong column.
|
2015-02-09 20:47:11 +01:00
|
|
|
if strpart(getline('.'), virtcol('.')-1) =~# '^-+'
|
2010-05-12 02:00:00 +02:00
|
|
|
let s_flag = 'b'
|
|
|
|
else
|
|
|
|
let s_flag = 'cb'
|
|
|
|
endif
|
|
|
|
" search the column separator backwards
|
|
|
|
if !search('|\|\(-+-\)', s_flag, line('.'))
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
" -+- column separator is matched --> move cursor to the + sign
|
|
|
|
if getline('.')[virtcol('.')] == '+'
|
|
|
|
normal! l
|
|
|
|
endif
|
|
|
|
" inner selection --> reduce selection
|
|
|
|
if a:inner
|
|
|
|
normal! 2l
|
|
|
|
endif
|
|
|
|
|
|
|
|
exe "normal! \<C-V>"
|
|
|
|
|
|
|
|
" search for the next column separator
|
|
|
|
call search('|\|\(-+-\)', '', line('.'))
|
|
|
|
" Outer selection selects a column without border on the right. So we move
|
|
|
|
" our cursor left if the previous search finds | border, not -+-.
|
|
|
|
if getline('.')[virtcol('.')] != '+'
|
|
|
|
normal! h
|
|
|
|
endif
|
|
|
|
" reduce selection a bit more if inner.
|
|
|
|
if a:inner
|
|
|
|
normal! h
|
|
|
|
endif
|
|
|
|
" expand selection to the bottom line of the table
|
2012-06-07 02:00:00 +02:00
|
|
|
call vimwiki#u#cursor(t_rows[-1][0], virtcol('.'))
|
2010-05-12 02:00:00 +02:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-05-12 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#AddHeaderLevel()
|
2010-01-20 01:00:00 +01:00
|
|
|
let lnum = line('.')
|
|
|
|
let line = getline(lnum)
|
2016-12-28 22:17:08 +01:00
|
|
|
let rxHdr = vimwiki#vars#get_syntaxlocal('rxH')
|
2015-02-09 20:47:11 +01:00
|
|
|
if line =~# '^\s*$'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2016-12-28 22:17:08 +01:00
|
|
|
if line =~# vimwiki#vars#get_syntaxlocal('rxHeader')
|
2012-06-07 02:00:00 +02:00
|
|
|
let level = vimwiki#u#count_first_sym(line)
|
2010-01-20 01:00:00 +01:00
|
|
|
if level < 6
|
2016-12-28 22:17:08 +01:00
|
|
|
if vimwiki#vars#get_syntaxlocal('symH')
|
2012-06-07 02:00:00 +02:00
|
|
|
let line = substitute(line, '\('.rxHdr.'\+\).\+\1', rxHdr.'&'.rxHdr, '')
|
|
|
|
else
|
|
|
|
let line = substitute(line, '\('.rxHdr.'\+\).\+', rxHdr.'&', '')
|
|
|
|
endif
|
2010-01-20 01:00:00 +01:00
|
|
|
call setline(lnum, line)
|
|
|
|
endif
|
|
|
|
else
|
2018-04-20 07:03:53 +02:00
|
|
|
let line = substitute(line, '^\s*', '&'.rxHdr.' ', '')
|
2016-12-28 22:17:08 +01:00
|
|
|
if vimwiki#vars#get_syntaxlocal('symH')
|
2012-06-07 02:00:00 +02:00
|
|
|
let line = substitute(line, '\s*$', ' '.rxHdr.'&', '')
|
|
|
|
endif
|
|
|
|
call setline(lnum, line)
|
2010-01-20 01:00:00 +01:00
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#RemoveHeaderLevel()
|
2010-01-20 01:00:00 +01:00
|
|
|
let lnum = line('.')
|
|
|
|
let line = getline(lnum)
|
2016-12-28 22:17:08 +01:00
|
|
|
let rxHdr = vimwiki#vars#get_syntaxlocal('rxH')
|
2015-02-09 20:47:11 +01:00
|
|
|
if line =~# '^\s*$'
|
2010-01-20 01:00:00 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2016-12-28 22:17:08 +01:00
|
|
|
if line =~# vimwiki#vars#get_syntaxlocal('rxHeader')
|
2012-06-07 02:00:00 +02:00
|
|
|
let level = vimwiki#u#count_first_sym(line)
|
|
|
|
let old = repeat(rxHdr, level)
|
|
|
|
let new = repeat(rxHdr, level - 1)
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2015-02-09 20:47:11 +01:00
|
|
|
let chomp = line =~# rxHdr.'\s'
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2016-12-28 22:17:08 +01:00
|
|
|
if vimwiki#vars#get_syntaxlocal('symH')
|
2012-06-07 02:00:00 +02:00
|
|
|
let line = substitute(line, old, new, 'g')
|
|
|
|
else
|
|
|
|
let line = substitute(line, old, new, '')
|
|
|
|
endif
|
2010-01-20 01:00:00 +01:00
|
|
|
|
|
|
|
if level == 1 && chomp
|
|
|
|
let line = substitute(line, '^\s', '', 'g')
|
|
|
|
let line = substitute(line, '\s$', '', 'g')
|
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
|
|
|
|
let line = substitute(line, '\s*$', '', '')
|
|
|
|
|
2010-01-20 01:00:00 +01:00
|
|
|
call setline(lnum, line)
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2014-02-13 12:42:24 +01:00
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
|
|
|
|
" Returns all the headers in the current buffer as a list of the form
|
|
|
|
" [[line_number, header_level, header_text], [...], [...], ...]
|
|
|
|
function! s:collect_headers()
|
|
|
|
let is_inside_pre_or_math = 0 " 1: inside pre, 2: inside math, 0: outside
|
|
|
|
let headers = []
|
|
|
|
for lnum in range(1, line('$'))
|
|
|
|
let line_content = getline(lnum)
|
|
|
|
if (is_inside_pre_or_math == 1 && line_content =~# vimwiki#vars#get_syntaxlocal('rxPreEnd')) ||
|
|
|
|
\ (is_inside_pre_or_math == 2 && line_content =~# vimwiki#vars#get_syntaxlocal('rxMathEnd'))
|
|
|
|
let is_inside_pre_or_math = 0
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
if is_inside_pre_or_math > 0
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
if line_content =~# vimwiki#vars#get_syntaxlocal('rxPreStart')
|
|
|
|
let is_inside_pre_or_math = 1
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
if line_content =~# vimwiki#vars#get_syntaxlocal('rxMathStart')
|
|
|
|
let is_inside_pre_or_math = 2
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
if line_content !~# vimwiki#vars#get_syntaxlocal('rxHeader')
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
let header_level = vimwiki#u#count_first_sym(line_content)
|
2018-04-20 07:03:53 +02:00
|
|
|
let header_text =
|
|
|
|
\ vimwiki#u#trim(matchstr(line_content, vimwiki#vars#get_syntaxlocal('rxHeader')))
|
2018-04-06 07:16:07 +02:00
|
|
|
call add(headers, [lnum, header_level, header_text])
|
|
|
|
endfor
|
|
|
|
|
|
|
|
return headers
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
2018-04-06 21:11:40 +02:00
|
|
|
function! s:current_header(headers, line_number)
|
|
|
|
if empty(a:headers)
|
|
|
|
return -1
|
|
|
|
endif
|
|
|
|
|
|
|
|
if a:line_number >= a:headers[-1][0]
|
|
|
|
return len(a:headers) - 1
|
|
|
|
endif
|
|
|
|
|
|
|
|
let current_header_index = -1
|
|
|
|
while a:headers[current_header_index+1][0] <= a:line_number
|
|
|
|
let current_header_index += 1
|
|
|
|
endwhile
|
|
|
|
return current_header_index
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
function! s:get_another_header(headers, current_index, direction, operation)
|
|
|
|
if empty(a:headers) || a:current_index < 0
|
|
|
|
return -1
|
|
|
|
endif
|
|
|
|
let current_level = a:headers[a:current_index][1]
|
|
|
|
let index = a:current_index + a:direction
|
|
|
|
|
|
|
|
while 1
|
|
|
|
if index < 0 || index >= len(a:headers)
|
|
|
|
return -1
|
|
|
|
endif
|
|
|
|
if eval('a:headers[index][1] ' . a:operation . ' current_level')
|
|
|
|
return index
|
|
|
|
endif
|
|
|
|
let index += a:direction
|
|
|
|
endwhile
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
function! vimwiki#base#goto_parent_header()
|
|
|
|
let headers = s:collect_headers()
|
|
|
|
let current_header_index = s:current_header(headers, line('.'))
|
|
|
|
let parent_header = s:get_another_header(headers, current_header_index, -1, '<')
|
|
|
|
if parent_header >= 0
|
|
|
|
call cursor(headers[parent_header][0], 1)
|
|
|
|
else
|
|
|
|
echo 'Vimwiki: no parent header found'
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
function! vimwiki#base#goto_next_header()
|
|
|
|
let headers = s:collect_headers()
|
|
|
|
let current_header_index = s:current_header(headers, line('.'))
|
|
|
|
if current_header_index >= 0 && current_header_index < len(headers) - 1
|
|
|
|
call cursor(headers[current_header_index + 1][0], 1)
|
2018-04-17 08:53:08 +02:00
|
|
|
elseif current_header_index < 0 && !empty(headers) " we're above the first header
|
|
|
|
call cursor(headers[0][0], 1)
|
2018-04-06 21:11:40 +02:00
|
|
|
else
|
|
|
|
echo 'Vimwiki: no next header found'
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
function! vimwiki#base#goto_prev_header()
|
|
|
|
let headers = s:collect_headers()
|
|
|
|
let current_header_index = s:current_header(headers, line('.'))
|
|
|
|
" if the cursor already was on a header, jump to the previous one
|
|
|
|
if current_header_index >= 1 && headers[current_header_index][0] == line('.')
|
|
|
|
let current_header_index -= 1
|
|
|
|
endif
|
|
|
|
if current_header_index >= 0
|
|
|
|
call cursor(headers[current_header_index][0], 1)
|
|
|
|
else
|
2018-04-17 08:53:08 +02:00
|
|
|
echo 'Vimwiki: no previous header found'
|
2018-04-06 21:11:40 +02:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
|
|
function! vimwiki#base#goto_sibling(direction)
|
|
|
|
let headers = s:collect_headers()
|
|
|
|
let current_header_index = s:current_header(headers, line('.'))
|
2018-04-20 07:03:53 +02:00
|
|
|
let next_potential_sibling =
|
|
|
|
\ s:get_another_header(headers, current_header_index, a:direction, '<=')
|
2018-04-06 21:11:40 +02:00
|
|
|
if next_potential_sibling >= 0 && headers[next_potential_sibling][1] ==
|
|
|
|
\ headers[current_header_index][1]
|
|
|
|
call cursor(headers[next_potential_sibling][0], 1)
|
|
|
|
else
|
|
|
|
echo 'Vimwiki: no sibling header found'
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
2014-02-18 14:47:42 +01:00
|
|
|
" a:create == 1: creates or updates TOC in current file
|
|
|
|
" a:create == 0: update if TOC exists
|
|
|
|
function! vimwiki#base#table_of_contents(create)
|
2018-04-08 20:41:27 +02:00
|
|
|
let headers = s:collect_headers()
|
2016-12-21 19:43:34 +01:00
|
|
|
let numbering = vimwiki#vars#get_global('html_header_numbering')
|
2014-02-13 12:42:24 +01:00
|
|
|
let headers_levels = [['', 0], ['', 0], ['', 0], ['', 0], ['', 0], ['', 0]]
|
2018-04-08 20:41:27 +02:00
|
|
|
let complete_header_infos = []
|
|
|
|
for header in headers
|
|
|
|
let h_text = header[2]
|
|
|
|
let h_level = header[1]
|
2016-12-21 21:28:48 +01:00
|
|
|
if h_text ==# vimwiki#vars#get_global('toc_header') " don't include the TOC's header itself
|
2015-11-09 15:45:56 +01:00
|
|
|
continue
|
|
|
|
endif
|
2014-02-13 12:42:24 +01:00
|
|
|
let headers_levels[h_level-1] = [h_text, headers_levels[h_level-1][1]+1]
|
|
|
|
for idx in range(h_level, 5) | let headers_levels[idx] = ['', 0] | endfor
|
|
|
|
|
|
|
|
let h_complete_id = ''
|
|
|
|
for l in range(h_level-1)
|
|
|
|
if headers_levels[l][0] != ''
|
|
|
|
let h_complete_id .= headers_levels[l][0].'#'
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
let h_complete_id .= headers_levels[h_level-1][0]
|
|
|
|
|
2018-04-06 07:16:07 +02:00
|
|
|
if numbering > 0 && numbering <= h_level
|
|
|
|
let h_number = join(map(copy(headers_levels[numbering-1 : h_level-1]), 'v:val[1]'), '.')
|
2016-12-21 19:43:34 +01:00
|
|
|
let h_number .= vimwiki#vars#get_global('html_header_numbering_sym')
|
2014-02-13 12:42:24 +01:00
|
|
|
let h_text = h_number.' '.h_text
|
|
|
|
endif
|
|
|
|
|
2018-04-08 20:41:27 +02:00
|
|
|
call add(complete_header_infos, [h_level, h_complete_id, h_text])
|
2014-02-13 12:42:24 +01:00
|
|
|
endfor
|
|
|
|
|
2015-11-09 15:45:56 +01:00
|
|
|
let lines = []
|
2014-02-13 12:42:24 +01:00
|
|
|
let startindent = repeat(' ', vimwiki#lst#get_list_margin())
|
2015-01-08 17:14:16 +01:00
|
|
|
let indentstring = repeat(' ', vimwiki#u#sw())
|
2015-11-09 15:45:56 +01:00
|
|
|
let bullet = vimwiki#lst#default_symbol().' '
|
2018-04-08 20:41:27 +02:00
|
|
|
for [lvl, link, desc] in complete_header_infos
|
2014-02-13 12:42:24 +01:00
|
|
|
let esc_link = substitute(link, "'", "''", 'g')
|
|
|
|
let esc_desc = substitute(desc, "'", "''", 'g')
|
2018-05-01 21:22:07 +02:00
|
|
|
let link_tpl = vimwiki#vars#get_global('WikiLinkTemplate2')
|
|
|
|
if vimwiki#vars#get_wikilocal('syntax') == 'markdown'
|
|
|
|
let link_tpl = vimwiki#vars#get_syntaxlocal('Weblink1Template')
|
|
|
|
endif
|
|
|
|
let link = s:safesubstitute(link_tpl, '__LinkUrl__',
|
2018-02-19 07:44:19 +01:00
|
|
|
\ '#'.esc_link, '')
|
|
|
|
let link = s:safesubstitute(link, '__LinkDescription__', esc_desc, '')
|
2015-11-09 15:45:56 +01:00
|
|
|
call add(lines, startindent.repeat(indentstring, lvl-1).bullet.link)
|
2014-02-13 12:42:24 +01:00
|
|
|
endfor
|
2015-11-09 15:45:56 +01:00
|
|
|
|
|
|
|
let links_rx = '\m^\s*'.vimwiki#u#escape(vimwiki#lst#default_symbol()).' '
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
call vimwiki#base#update_listing_in_buffer(lines,
|
|
|
|
\ vimwiki#vars#get_global('toc_header'), links_rx, 1, a:create)
|
2014-02-13 12:42:24 +01:00
|
|
|
endfunction
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
2012-07-07 02:00:00 +02:00
|
|
|
" Construct a regular expression matching from template (with special
|
2012-06-07 02:00:00 +02:00
|
|
|
" 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.
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#apply_template(template, rxUrl, rxDesc, rxStyle)
|
2014-06-19 15:36:11 +02:00
|
|
|
let lnk = a:template
|
2012-06-07 02:00:00 +02:00
|
|
|
if a:rxUrl != ""
|
2018-02-19 07:44:19 +01:00
|
|
|
let lnk = s:safesubstitute(lnk, '__LinkUrl__', a:rxUrl, 'g')
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
|
|
|
if a:rxDesc != ""
|
2018-02-19 07:44:19 +01:00
|
|
|
let lnk = s:safesubstitute(lnk, '__LinkDescription__', a:rxDesc, 'g')
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
|
|
|
if a:rxStyle != ""
|
2018-02-19 07:44:19 +01:00
|
|
|
let lnk = s:safesubstitute(lnk, '__LinkStyle__', a:rxStyle, 'g')
|
2012-06-07 02:00:00 +02:00
|
|
|
endif
|
|
|
|
return lnk
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:clean_url(url)
|
2018-06-17 16:10:44 +02:00
|
|
|
" remove protocol and tld
|
2018-09-17 12:20:17 +02:00
|
|
|
let url = substitute(a:url, '^\a\+\d*:', '', '')
|
|
|
|
let url = substitute(url, '^//', '', '')
|
2018-06-17 16:10:44 +02:00
|
|
|
let url = substitute(url, '^\([^/]\+\).\a\{2,4}/', '\1/', '')
|
|
|
|
let url = split(url, '/\|=\|-\|&\|?\|\.')
|
2015-02-09 20:24:18 +01:00
|
|
|
let url = filter(url, 'v:val !=# ""')
|
2018-06-17 16:10:44 +02:00
|
|
|
if url[0] == "www"
|
|
|
|
let url = url[1:]
|
|
|
|
endif
|
|
|
|
if url[-1] =~ '^\(htm\|html\|php\)$'
|
|
|
|
let url = url[0:-2]
|
|
|
|
endif
|
2018-06-17 15:31:57 +02:00
|
|
|
" remove words consisting of only hexadecimal digits or non-word characters
|
|
|
|
let url = filter(url, 'v:val !~ "^\\A\\{4,}$"')
|
|
|
|
let url = filter(url, 'v:val !~ "^\\x\\{4,}$" || v:val !~ "\\d"')
|
2012-06-07 02:00:00 +02:00
|
|
|
return join(url, " ")
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:is_diary_file(filename)
|
2014-12-04 21:27:02 +01:00
|
|
|
let file_path = vimwiki#path#path_norm(a:filename)
|
2016-12-22 18:16:05 +01:00
|
|
|
let rel_path = vimwiki#vars#get_wikilocal('diary_rel_path')
|
2016-12-22 19:55:20 +01:00
|
|
|
let diary_path = vimwiki#path#path_norm(vimwiki#vars#get_wikilocal('path') . rel_path)
|
2018-04-20 07:03:53 +02:00
|
|
|
return rel_path != '' && file_path =~# '^'.vimwiki#u#escape(diary_path)
|
|
|
|
endfunction
|
|
|
|
|
2014-09-15 21:44:32 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#normalize_link_helper(str, rxUrl, rxDesc, template)
|
2018-04-17 07:13:37 +02:00
|
|
|
let url = matchstr(a:str, a:rxUrl)
|
|
|
|
let descr = matchstr(a:str, a:rxDesc)
|
2012-06-07 02:00:00 +02:00
|
|
|
if descr == ""
|
|
|
|
let descr = s:clean_url(url)
|
|
|
|
endif
|
2018-04-17 07:13:37 +02:00
|
|
|
let lnk = s:safesubstitute(a:template, '__LinkDescription__', descr, '')
|
2018-02-19 07:44:19 +01:00
|
|
|
let lnk = s:safesubstitute(lnk, '__LinkUrl__', url, '')
|
2012-06-07 02:00:00 +02:00
|
|
|
return lnk
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#normalize_imagelink_helper(str, rxUrl, rxDesc, rxStyle, template)
|
2012-06-07 02:00:00 +02:00
|
|
|
let lnk = vimwiki#base#normalize_link_helper(a:str, a:rxUrl, a:rxDesc, a:template)
|
2014-02-24 12:16:23 +01:00
|
|
|
let style = matchstr(a:str, a:rxStyle)
|
2018-02-19 07:44:19 +01:00
|
|
|
let lnk = s:safesubstitute(lnk, '__LinkStyle__', style, '')
|
2012-06-07 02:00:00 +02:00
|
|
|
return lnk
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:normalize_link_in_diary(lnk)
|
2016-12-22 21:00:19 +01:00
|
|
|
let link = a:lnk . vimwiki#vars#get_wikilocal('ext')
|
2016-12-22 19:55:20 +01:00
|
|
|
let link_wiki = vimwiki#vars#get_wikilocal('path') . '/' . link
|
|
|
|
let link_diary = vimwiki#vars#get_wikilocal('path') . '/'
|
2016-12-22 18:16:05 +01:00
|
|
|
\ . vimwiki#vars#get_wikilocal('diary_rel_path') . '/' . link
|
2014-09-17 23:26:16 +02:00
|
|
|
let link_exists_in_diary = filereadable(link_diary)
|
|
|
|
let link_exists_in_wiki = filereadable(link_wiki)
|
|
|
|
let link_is_date = a:lnk =~# '\d\d\d\d-\d\d-\d\d'
|
|
|
|
|
|
|
|
if ! link_exists_in_wiki || link_exists_in_diary || link_is_date
|
|
|
|
let str = a:lnk
|
2017-02-16 21:54:10 +01:00
|
|
|
let rxUrl = vimwiki#vars#get_global('rxWord')
|
2014-09-17 23:10:49 +02:00
|
|
|
let rxDesc = ''
|
2016-12-28 22:17:08 +01:00
|
|
|
let template = vimwiki#vars#get_global('WikiLinkTemplate1')
|
2014-09-15 21:44:32 +02:00
|
|
|
else
|
2016-12-22 18:16:05 +01:00
|
|
|
let depth = len(split(vimwiki#vars#get_wikilocal('diary_rel_path'), '/'))
|
2014-11-06 20:01:16 +01:00
|
|
|
let str = repeat('../', depth) . a:lnk . '|' . a:lnk
|
|
|
|
let rxUrl = '^.*\ze|'
|
|
|
|
let rxDesc = '|\zs.*$'
|
2016-12-28 22:17:08 +01:00
|
|
|
let template = vimwiki#vars#get_global('WikiLinkTemplate2')
|
2014-09-15 21:44:32 +02:00
|
|
|
endif
|
|
|
|
|
2014-09-17 23:10:49 +02:00
|
|
|
return vimwiki#base#normalize_link_helper(str, rxUrl, rxDesc, template)
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2014-09-15 21:44:32 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! s:normalize_link_syntax_n()
|
2012-06-07 02:00:00 +02:00
|
|
|
|
|
|
|
" try WikiLink
|
2017-01-11 22:12:33 +01:00
|
|
|
let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink'))
|
2012-06-07 02:00:00 +02:00
|
|
|
if !empty(lnk)
|
|
|
|
let sub = vimwiki#base#normalize_link_helper(lnk,
|
2018-04-20 07:03:53 +02:00
|
|
|
\ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'),
|
|
|
|
\ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr'),
|
2016-12-28 22:17:08 +01:00
|
|
|
\ vimwiki#vars#get_global('WikiLinkTemplate2'))
|
2017-01-11 22:12:33 +01:00
|
|
|
call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink'), sub)
|
2012-06-07 02:00:00 +02:00
|
|
|
return
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" try WikiIncl
|
2016-12-28 22:17:08 +01:00
|
|
|
let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWikiIncl'))
|
2012-06-07 02:00:00 +02:00
|
|
|
if !empty(lnk)
|
|
|
|
" NO-OP !!
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2016-03-21 09:02:22 +01:00
|
|
|
" try Weblink
|
2017-01-12 21:45:09 +01:00
|
|
|
let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'))
|
2016-03-21 09:02:22 +01:00
|
|
|
if !empty(lnk)
|
|
|
|
let sub = vimwiki#base#normalize_link_helper(lnk,
|
2016-12-28 22:17:08 +01:00
|
|
|
\ lnk, '', vimwiki#vars#get_global('WikiLinkTemplate2'))
|
2017-01-12 21:45:09 +01:00
|
|
|
call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'), sub)
|
2016-03-21 09:02:22 +01:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
" try Word (any characters except separators)
|
|
|
|
" rxWord is less permissive than rxWikiLinkUrl which is used in
|
|
|
|
" normalize_link_syntax_v
|
2017-02-16 21:54:10 +01:00
|
|
|
let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWord'))
|
2012-06-07 02:00:00 +02:00
|
|
|
if !empty(lnk)
|
2014-12-04 21:27:02 +01:00
|
|
|
if s:is_diary_file(expand("%:p"))
|
2014-09-15 21:44:32 +02:00
|
|
|
let sub = s:normalize_link_in_diary(lnk)
|
|
|
|
else
|
|
|
|
let sub = vimwiki#base#normalize_link_helper(lnk,
|
2017-02-16 21:54:10 +01:00
|
|
|
\ vimwiki#vars#get_global('rxWord'), '',
|
2016-12-28 22:17:08 +01:00
|
|
|
\ vimwiki#vars#get_global('WikiLinkTemplate1'))
|
2014-09-15 21:44:32 +02:00
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
call vimwiki#base#replacestr_at_cursor('\V'.lnk, sub)
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
|
|
|
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! s:normalize_link_syntax_v()
|
2012-06-07 02:00:00 +02:00
|
|
|
let sel_save = &selection
|
|
|
|
let &selection = "old"
|
2018-04-17 07:13:37 +02:00
|
|
|
let default_register_save = @"
|
|
|
|
let registertype_save = getregtype('"')
|
2012-06-07 02:00:00 +02:00
|
|
|
|
|
|
|
try
|
2014-09-15 21:44:32 +02:00
|
|
|
" Save selected text to register "
|
|
|
|
normal! gv""y
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2014-09-15 21:44:32 +02:00
|
|
|
" Set substitution
|
2014-12-04 21:27:02 +01:00
|
|
|
if s:is_diary_file(expand("%:p"))
|
2014-09-15 21:44:32 +02:00
|
|
|
let sub = s:normalize_link_in_diary(@")
|
|
|
|
else
|
2018-02-19 07:44:19 +01:00
|
|
|
let sub = s:safesubstitute(vimwiki#vars#get_global('WikiLinkTemplate1'),
|
|
|
|
\ '__LinkUrl__', @", '')
|
2014-09-15 21:44:32 +02:00
|
|
|
endif
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2014-09-15 21:44:32 +02:00
|
|
|
" Put substitution in register " and change text
|
2018-04-22 20:58:39 +02:00
|
|
|
call setreg('"', substitute(sub, '\n', '', ''), visualmode())
|
2014-09-15 21:44:32 +02:00
|
|
|
normal! `>""pgvd
|
2012-06-07 02:00:00 +02:00
|
|
|
finally
|
2018-04-17 07:13:37 +02:00
|
|
|
call setreg('"', default_register_save, registertype_save)
|
2012-06-07 02:00:00 +02:00
|
|
|
let &selection = sel_save
|
|
|
|
endtry
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2012-06-07 02:00:00 +02:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#normalize_link(is_visual_mode)
|
2016-12-23 20:05:53 +01:00
|
|
|
if exists('*vimwiki#'.vimwiki#vars#get_wikilocal('syntax').'_base#normalize_link')
|
2012-06-07 02:00:00 +02:00
|
|
|
" Syntax-specific links
|
2016-12-23 20:05:53 +01:00
|
|
|
call vimwiki#{vimwiki#vars#get_wikilocal('syntax')}_base#normalize_link(a:is_visual_mode)
|
2012-06-07 02:00:00 +02:00
|
|
|
else
|
|
|
|
if !a:is_visual_mode
|
|
|
|
call s:normalize_link_syntax_n()
|
2018-04-22 20:58:39 +02:00
|
|
|
elseif line("'<") == line("'>")
|
|
|
|
" action undefined for multi-line visual mode selections
|
2012-06-07 02:00:00 +02:00
|
|
|
call s:normalize_link_syntax_v()
|
|
|
|
endif
|
|
|
|
endif
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2010-01-20 01:00:00 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
|
|
|
|
function! vimwiki#base#detect_nested_syntax()
|
2016-01-27 13:14:49 +01:00
|
|
|
let last_word = '\v.*<(\w+)\s*$'
|
2016-10-29 06:58:15 +02:00
|
|
|
let lines = map(filter(getline(1, "$"), 'v:val =~ "\\%({{{\\|```\\)" && v:val =~ last_word'),
|
2016-01-27 13:14:49 +01:00
|
|
|
\ 'substitute(v:val, last_word, "\\=submatch(1)", "")')
|
|
|
|
let dict = {}
|
|
|
|
for elem in lines
|
2016-01-28 10:52:40 +01:00
|
|
|
let dict[elem] = elem
|
2016-01-27 13:14:49 +01:00
|
|
|
endfor
|
|
|
|
return dict
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2012-07-07 02:00:00 +02:00
|
|
|
|
2014-11-06 22:02:37 +01:00
|
|
|
|
2018-04-20 07:03:53 +02:00
|
|
|
function! vimwiki#base#complete_links_escaped(ArgLead, CmdLine, CursorPos) abort
|
2014-11-10 21:04:06 +01:00
|
|
|
" We can safely ignore args if we use -custom=complete option, Vim engine
|
|
|
|
" will do the job of filtering.
|
|
|
|
return vimwiki#base#get_globlinks_escaped()
|
2018-04-20 07:03:53 +02:00
|
|
|
endfunction
|
2014-11-10 21:04:06 +01:00
|
|
|
|
2014-11-06 22:02:37 +01:00
|
|
|
|
2012-07-07 02:00:00 +02:00
|
|
|
" -------------------------------------------------------------------------
|
|
|
|
" Load syntax-specific Wiki functionality
|
2015-01-23 20:41:36 +01:00
|
|
|
for s:syn in s:vimwiki_get_known_syntaxes()
|
2014-02-24 12:16:23 +01:00
|
|
|
execute 'runtime! autoload/vimwiki/'.s:syn.'_base.vim'
|
2018-04-20 07:03:53 +02:00
|
|
|
endfor
|
2012-07-07 02:00:00 +02:00
|
|
|
" -------------------------------------------------------------------------
|
|
|
|
|