commit f458b6c01e6f343d176242febb21d6c05ffc07b3
parent fbd0b79b0e8711a4d944f31321e5da22e24ecd32
Author: Hayden Hamilton <hayden@haydenvh.com>
Date: Wed, 11 Mar 2020 22:38:19 +0000
nvim is coming along again
Diffstat:
36 files changed, 9923 insertions(+), 47 deletions(-)
diff --git a/.config/nvim/autoload/vimwiki/base.vim b/.config/nvim/autoload/vimwiki/base.vim
@@ -0,0 +1,2096 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Desc: Basic functionality
+" Home: https://github.com/vimwiki/vimwiki/
+
+if exists("g:loaded_vimwiki_auto") || &cp
+ finish
+endif
+let g:loaded_vimwiki_auto = 1
+
+
+function! s:safesubstitute(text, search, replace, mode)
+ " Substitute regexp but do not interpret replace
+ let escaped = escape(a:replace, '\&')
+ return substitute(a:text, a:search, escaped, a:mode)
+endfunction
+
+
+function! s:vimwiki_get_known_syntaxes()
+ " Getting all syntaxes that different wikis could have
+ let syntaxes = {}
+ let syntaxes['default'] = 1
+ 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
+ endfor
+ " also consider the syntaxes from g:vimwiki_ext2syntax
+ for syn in values(vimwiki#vars#get_global('ext2syntax'))
+ let syntaxes[syn] = 1
+ endfor
+ return keys(syntaxes)
+endfunction
+
+
+function! vimwiki#base#file_pattern(files)
+ " Get search regex from glob()
+ " string. Aim to support *all* special characters, forcing the user to choose
+ " names that are compatible with any external restrictions that they
+ " encounter (e.g. filesystem, wiki conventions, other syntaxes, ...).
+ " See: https://github.com/vimwiki-backup/vimwiki/issues/316
+ " Change / to [/\\] to allow "Windows paths"
+ return '\V\%('.join(a:files, '\|').'\)\m'
+endfunction
+
+
+"FIXME TODO slow and faulty
+function! vimwiki#base#subdir(path, filename)
+ 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?
+ if a:filename !~# '^scp:'
+ let filename = resolve(a:filename)
+ else
+ let filename = a:filename
+ endif
+ let idx = 0
+ "FIXME this can terminate in the middle of a path component!
+ while path[idx] ==? filename[idx]
+ let idx = idx + 1
+ endwhile
+
+ let p = split(strpart(filename, idx), '[/\\]')
+ let res = join(p[:-2], '/')
+ if len(res) > 0
+ let res = res.'/'
+ endif
+ return res
+endfunction
+
+
+function! vimwiki#base#current_subdir()
+ return vimwiki#base#subdir(vimwiki#vars#get_wikilocal('path'), expand('%:p'))
+endfunction
+
+
+function! vimwiki#base#invsubdir(subdir)
+ return substitute(a:subdir, '[^/\.]\+/', '../', 'g')
+endfunction
+
+
+" 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
+function! vimwiki#base#find_wiki(path)
+ let bestmatch = -1
+ let bestlen = 0
+ let path = vimwiki#path#path_norm(vimwiki#path#chomp_slash(a:path))
+ for idx in range(vimwiki#vars#number_of_wikis())
+ let idx_path = expand(vimwiki#vars#get_wikilocal('path', idx))
+ let idx_path = vimwiki#path#path_norm(vimwiki#path#chomp_slash(idx_path))
+ 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
+ endif
+ endfor
+
+ return bestmatch
+endfunction
+
+
+" 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.
+function! vimwiki#base#resolve_link(link_text, ...)
+ if a:0
+ let source_wiki = vimwiki#base#find_wiki(a:1)
+ let source_file = a:1
+ else
+ let source_wiki = vimwiki#vars#get_bufferlocal('wiki_nr')
+ let source_file = vimwiki#path#current_wiki_file()
+ endif
+
+ let link_text = a:link_text
+
+
+ let link_infos = {
+ \ 'index': -1,
+ \ 'scheme': '',
+ \ 'filename': '',
+ \ 'anchor': '',
+ \ }
+
+ if link_text == ''
+ return link_infos
+ endif
+
+ 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')
+ endif
+
+ let is_wiki_link = link_infos.scheme =~# '\mwiki\d\+' || link_infos.scheme ==# 'diary'
+
+ " 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 expected_ext = vimwiki#u#escape(vimwiki#vars#get_wikilocal('ext')).'$'
+ if source_file =~# expected_ext
+ " Source file has expected extension. Remove it, it will be added later on
+ let ext_len = strlen(vimwiki#vars#get_wikilocal('ext'))
+ let link_text = fnamemodify(source_file, ':p:t')[:-ext_len-1]
+ endif
+
+ endif
+ endif
+
+ " check if absolute or relative path
+ if is_wiki_link && link_text[0] == '/'
+ if link_text != '/'
+ let link_text = link_text[1:]
+ endif
+ let is_relative = 0
+ elseif !is_wiki_link && vimwiki#path#is_absolute(link_text)
+ let is_relative = 0
+ else
+ let is_relative = 1
+ 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'))
+ if link_infos.index < 0 || link_infos.index >= vimwiki#vars#number_of_wikis()
+ let link_infos.index = -1
+ let link_infos.filename = ''
+ return link_infos
+ endif
+
+ if !is_relative || link_infos.index != source_wiki
+ let root_dir = vimwiki#vars#get_wikilocal('path', link_infos.index)
+ endif
+
+ let link_infos.filename = root_dir . link_text
+
+ if vimwiki#path#is_link_to_dir(link_text)
+ if vimwiki#vars#get_global('dir_link') != ''
+ let link_infos.filename .= vimwiki#vars#get_global('dir_link') .
+ \ vimwiki#vars#get_wikilocal('ext', link_infos.index)
+ endif
+ else
+ let link_infos.filename .= vimwiki#vars#get_wikilocal('ext', link_infos.index)
+ endif
+
+ elseif link_infos.scheme ==# 'diary'
+ let link_infos.index = source_wiki
+
+ let link_infos.filename =
+ \ vimwiki#vars#get_wikilocal('path', link_infos.index) .
+ \ vimwiki#vars#get_wikilocal('diary_rel_path', link_infos.index) .
+ \ link_text .
+ \ vimwiki#vars#get_wikilocal('ext', link_infos.index)
+ elseif (link_infos.scheme ==# 'file' || link_infos.scheme ==# 'local') && is_relative
+ let link_infos.filename = simplify(root_dir . link_text)
+ else " absolute file link
+ " collapse repeated leading "/"'s within a link
+ let link_text = substitute(link_text, '\m^/\+', '/', '')
+ " expand ~/
+ let link_text = fnamemodify(link_text, ':p')
+ let link_infos.filename = simplify(link_text)
+ endif
+
+ let link_infos.filename = vimwiki#path#normalize(link_infos.filename)
+ return link_infos
+endfunction
+
+
+function! vimwiki#base#system_open_link(url)
+ " handlers
+ function! s:win32_handler(url)
+ "Disable shellslash for cmd and command.com, but enable for all other shells
+ "See Issue #560
+ if (&shell =~? "cmd") || (&shell =~? "command.com")
+
+ 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
+ execute 'silent ! start "Title" /B ' . url
+
+ else
+
+ if exists('+shellslash')
+ let old_ssl = &shellslash
+ set shellslash
+ let url = shellescape(a:url, 1)
+ let &shellslash = old_ssl
+ else
+ let url = shellescape(a:url, 1)
+ endif
+ execute 'silent ! start ' . url
+
+ endif
+ endfunction
+ function! s:macunix_handler(url)
+ call system('open ' . shellescape(a:url).' &')
+ endfunction
+ function! s:linux_handler(url)
+ call system('xdg-open ' . shellescape(a:url).' &')
+ endfunction
+ try
+ if vimwiki#u#is_windows()
+ call s:win32_handler(a:url)
+ return
+ elseif vimwiki#u#is_macos()
+ call s:macunix_handler(a:url)
+ return
+ else
+ call s:linux_handler(a:url)
+ return
+ endif
+ endtry
+ echomsg 'Vimwiki Error: Default Vimwiki link handler was unable to open the HTML file!'
+endfunction
+
+
+function! vimwiki#base#open_link(cmd, link, ...)
+ 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
+
+ if link_infos.filename == ''
+ if link_infos.index == -1
+ echomsg 'Vimwiki Error: No registered wiki ''' . link_infos.scheme . '''.'
+ else
+ echomsg 'Vimwiki Error: Unable to resolve link!'
+ endif
+ return
+ endif
+
+ let is_wiki_link = link_infos.scheme =~# '\mwiki\d\+' || link_infos.scheme =~# 'diary'
+
+ let update_prev_link = is_wiki_link &&
+ \ !vimwiki#path#is_equal(link_infos.filename, vimwiki#path#current_wiki_file())
+
+ let vimwiki_prev_link = []
+ " update previous link for wiki pages
+ if update_prev_link
+ if a:0
+ let vimwiki_prev_link = [a:1, []]
+ elseif &ft ==# 'vimwiki'
+ let vimwiki_prev_link = [vimwiki#path#current_wiki_file(), getpos('.')]
+ endif
+ endif
+
+ " open/edit
+ if is_wiki_link
+ call vimwiki#base#edit_file(a:cmd, link_infos.filename, link_infos.anchor,
+ \ vimwiki_prev_link, update_prev_link)
+ else
+ call vimwiki#base#system_open_link(link_infos.filename)
+ endif
+endfunction
+
+
+function! vimwiki#base#get_globlinks_escaped() abort
+ " only get links from the current dir
+ " change to the directory of the current file
+ let orig_pwd = getcwd()
+ lcd! %:h
+ " all path are relative to the current file's location
+ let globlinks = glob('*'.vimwiki#vars#get_wikilocal('ext'), 1)."\n"
+ " remove extensions
+ let globlinks = substitute(globlinks, '\'.vimwiki#vars#get_wikilocal('ext').'\ze\n', '', 'g')
+ " restore the original working directory
+ exe 'lcd! '.orig_pwd
+ " convert to a List
+ let lst = split(globlinks, '\n')
+ " Apply fnameescape() to each item
+ call map(lst, 'fnameescape(v:val)')
+ " Convert back to newline-separated list
+ let globlinks = join(lst, "\n")
+ " return all escaped links as a single newline-separated string
+ return globlinks
+endfunction
+
+
+function! vimwiki#base#generate_links()
+ let lines = []
+
+ let links = vimwiki#base#get_wikilinks(vimwiki#vars#get_bufferlocal('wiki_nr'), 0)
+ call sort(links)
+
+ let bullet = repeat(' ', vimwiki#lst#get_list_margin()) . vimwiki#lst#default_symbol().' '
+ for link in links
+ let abs_filepath = vimwiki#path#abs_path_of_link(link)
+ if !s:is_diary_file(abs_filepath)
+ call add(lines, bullet.
+ \ s:safesubstitute(vimwiki#vars#get_global('WikiLinkTemplate1'),
+ \ '__LinkUrl__', link, ''))
+ endif
+ endfor
+
+ let links_rx = '\m^\s*'.vimwiki#u#escape(vimwiki#lst#default_symbol()).' '
+
+ call vimwiki#base#update_listing_in_buffer(lines, 'Generated Links', links_rx, line('$')+1, 1)
+endfunction
+
+
+function! vimwiki#base#goto(...)
+ let key = a:1
+ let anchor = a:0 > 1 ? a:2 : ''
+
+ call vimwiki#base#edit_file(':e',
+ \ vimwiki#vars#get_wikilocal('path') . key . vimwiki#vars#get_wikilocal('ext'),
+ \ anchor)
+endfunction
+
+
+function! vimwiki#base#backlinks()
+ let current_filename = expand("%:p")
+ let locations = []
+ for idx in range(vimwiki#vars#number_of_wikis())
+ let syntax = vimwiki#vars#get_wikilocal('syntax', idx)
+ let wikifiles = vimwiki#base#find_files(idx, 0)
+ 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
+ if vimwiki#path#is_equal(target_file, current_filename) &&
+ \ !vimwiki#path#is_equal(target_file, source_file)
+ call add(locations, {'filename':source_file, 'lnum':lnum, 'col':col})
+ endif
+ endfor
+ endfor
+ endfor
+
+ if empty(locations)
+ echomsg 'Vimwiki: No other file links to this file'
+ else
+ call setloclist(0, locations, 'r')
+ lopen
+ endif
+endfunction
+
+
+" 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
+function! vimwiki#base#find_files(wiki_nr, directories_only)
+ let wiki_nr = a:wiki_nr
+ if wiki_nr >= 0
+ let root_directory = vimwiki#vars#get_wikilocal('path', wiki_nr)
+ else
+ let root_directory = vimwiki#vars#get_wikilocal('path') .
+ \ vimwiki#vars#get_wikilocal('diary_rel_path')
+ let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr')
+ endif
+ if a:directories_only
+ let ext = '/'
+ else
+ let ext = vimwiki#vars#get_wikilocal('ext', wiki_nr)
+ endif
+ " 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.
+ if vimwiki#vars#get_wikilocal('is_temporary_wiki', wiki_nr)
+ let pattern = '*'.ext
+ else
+ let pattern = '**/*'.ext
+ endif
+ return split(globpath(root_directory, pattern), '\n')
+endfunction
+
+
+" 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)
+ let files = vimwiki#base#find_files(a:wiki_nr, 0)
+ if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
+ let cwd = vimwiki#path#wikify_path(expand('%:p:h'))
+ elseif a:wiki_nr < 0
+ let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path')
+ else
+ let cwd = vimwiki#vars#get_wikilocal('path', a:wiki_nr)
+ endif
+ let result = []
+ for wikifile in files
+ let wikifile = fnamemodify(wikifile, ':r') " strip extension
+ let wikifile = vimwiki#path#relpath(cwd, wikifile)
+ call add(result, wikifile)
+ endfor
+ if a:also_absolute_links
+ for wikifile in files
+ if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
+ let cwd = vimwiki#vars#get_wikilocal('path')
+ elseif a:wiki_nr < 0
+ let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path')
+ endif
+ let wikifile = fnamemodify(wikifile, ':r') " strip extension
+ let wikifile = '/'.vimwiki#path#relpath(cwd, wikifile)
+ call add(result, wikifile)
+ endfor
+ endif
+ return result
+endfunction
+
+
+" Returns: a list containing the links to all directories from the current file
+function! vimwiki#base#get_wiki_directories(wiki_nr)
+ let dirs = vimwiki#base#find_files(a:wiki_nr, 1)
+ if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
+ let cwd = vimwiki#path#wikify_path(expand('%:p:h'))
+ let root_dir = vimwiki#vars#get_wikilocal('path')
+ else
+ let cwd = vimwiki#vars#get_wikilocal('path', a:wiki_nr)
+ endif
+ let result = ['./']
+ for wikidir in dirs
+ let wikidir_relative = vimwiki#path#relpath(cwd, wikidir)
+ call add(result, wikidir_relative)
+ if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr')
+ let wikidir_absolute = '/'.vimwiki#path#relpath(root_dir, wikidir)
+ call add(result, wikidir_absolute)
+ endif
+ endfor
+ return result
+endfunction
+
+
+function! vimwiki#base#get_anchors(filename, syntax)
+ if !filereadable(a:filename)
+ return []
+ endif
+
+ 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)
+
+ let anchor_level = ['', '', '', '', '', '', '']
+ let anchors = []
+ let current_complete_anchor = ''
+ 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])
+ call add(anchors, header)
+ let anchor_level[level-1] = header
+ for l in range(level, 6)
+ let anchor_level[l] = ''
+ endfor
+ 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
+ endif
+
+ " collect bold text (there can be several in one line)
+ let bold_count = 1
+ while 1
+ let bold_text = matchstr(line, rxbold, 0, bold_count)
+ if bold_text == ''
+ break
+ endif
+ call add(anchors, bold_text)
+ if current_complete_anchor != ''
+ call add(anchors, current_complete_anchor.'#'.bold_text)
+ endif
+ let bold_count += 1
+ endwhile
+
+ " collect tags text (there can be several in one line)
+ let tag_count = 1
+ while 1
+ let tag_group_text = matchstr(line, rxtag, 0, tag_count)
+ if tag_group_text == ''
+ break
+ endif
+ 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
+ let tag_count += 1
+ endwhile
+
+ endfor
+
+ return anchors
+endfunction
+
+
+function! s:jump_to_anchor(anchor)
+ let oldpos = getpos('.')
+ call cursor(1, 1)
+
+ let anchor = vimwiki#u#escape(a:anchor)
+
+ let segments = split(anchor, '#', 0)
+
+ for segment in segments
+
+ let anchor_header = s:safesubstitute(
+ \ vimwiki#vars#get_syntaxlocal('header_match'),
+ \ '__Header__', segment, '')
+ let anchor_bold = s:safesubstitute(
+ \ vimwiki#vars#get_syntaxlocal('bold_match'),
+ \ '__Text__', segment, '')
+ let anchor_tag = s:safesubstitute(
+ \ vimwiki#vars#get_syntaxlocal('tag_match'),
+ \ '__Tag__', segment, '')
+
+ if !search(anchor_tag, 'Wc') && !search(anchor_header, 'Wc') && !search(anchor_bold, 'Wc')
+ call setpos('.', oldpos)
+ break
+ endif
+ let oldpos = getpos('.')
+ endfor
+endfunction
+
+
+" 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]
+function! s:get_links(wikifile, idx)
+ if !filereadable(a:wikifile)
+ return []
+ endif
+
+ let syntax = vimwiki#vars#get_wikilocal('syntax', a:idx)
+ let rx_link = vimwiki#vars#get_syntaxlocal('wikilink', syntax)
+ let links = []
+ let lnum = 0
+
+ for line in readfile(a:wikifile)
+ let lnum += 1
+
+ let link_count = 1
+ while 1
+ let col = match(line, rx_link, 0, link_count)+1
+ let link_text = matchstr(line, rx_link, 0, link_count)
+ if link_text == ''
+ break
+ endif
+ let link_count += 1
+ let target = vimwiki#base#resolve_link(link_text, a:wikifile)
+ if target.filename != '' && target.scheme =~# '\mwiki\d\+\|diary\|file\|local'
+ call add(links, [target.filename, target.anchor, lnum, col])
+ endif
+ endwhile
+ endfor
+
+ return links
+endfunction
+
+
+function! vimwiki#base#check_links()
+ let anchors_of_files = {}
+ let links_of_files = {}
+ let errors = []
+ for idx in range(vimwiki#vars#number_of_wikis())
+ let syntax = vimwiki#vars#get_wikilocal('syntax', idx)
+ let wikifiles = vimwiki#base#find_files(idx, 0)
+ for wikifile in wikifiles
+ let links_of_files[wikifile] = s:get_links(wikifile, idx)
+ 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
+ if target_file =~ '\m/$' " maybe it's a link to a directory
+ if !isdirectory(target_file)
+ call add(errors, {'filename':wikifile, 'lnum':lnum, 'col':col,
+ \'text': "there is no such directory: ".target_file})
+ endif
+ else " maybe it's a non-wiki file
+ if filereadable(target_file)
+ 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
+ endif
+ endif
+ endfor
+ endfor
+
+
+ " 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.
+ let reachable_wikifiles = {}
+
+ " first, all files are considered not reachable
+ for wikifile in keys(links_of_files)
+ let reachable_wikifiles[wikifile] = 0
+ endfor
+
+ " mark every index file as reachable
+ for idx in range(vimwiki#vars#number_of_wikis())
+ let index_file = vimwiki#vars#get_wikilocal('path', idx) .
+ \ vimwiki#vars#get_wikilocal('index', idx) . vimwiki#vars#get_wikilocal('ext', idx)
+ if filereadable(index_file)
+ let reachable_wikifiles[index_file] = 1
+ endif
+ endfor
+
+ while 1
+ let next_unvisited_wikifile = ''
+ for wf in keys(reachable_wikifiles)
+ if reachable_wikifiles[wf] == 1
+ let next_unvisited_wikifile = wf
+ let reachable_wikifiles[wf] = 2
+ break
+ endif
+ endfor
+ if next_unvisited_wikifile == ''
+ break
+ endif
+ for [target_file, target_anchor, lnum, col] in links_of_files[next_unvisited_wikifile]
+ if has_key(reachable_wikifiles, target_file) && reachable_wikifiles[target_file] == 0
+ let reachable_wikifiles[target_file] = 1
+ endif
+ endfor
+ endwhile
+
+ 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)
+ echomsg 'Vimwiki: All links are OK'
+ else
+ call setqflist(errors, 'r')
+ copen
+ endif
+endfunction
+
+
+function! vimwiki#base#edit_file(command, filename, anchor, ...)
+ let fname = escape(a:filename, '% *|#`')
+ let dir = fnamemodify(a:filename, ":p:h")
+
+ let ok = vimwiki#path#mkdir(dir, 1)
+
+ if !ok
+ echomsg ' '
+ echomsg 'Vimwiki Error: Unable to edit file in non-existent directory: '.dir
+ return
+ endif
+
+ " Check if the file we want to open is already the current file
+ " 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.
+ if !(a:command ==# ':e ' && vimwiki#path#is_equal(a:filename, expand('%:p')))
+ 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
+ execute a:command fname
+ catch /E37:/
+ echomsg 'Vimwiki: Can''t leave the current buffer, because it is modified. Hint: Take a look at'
+ \ ''':h g:vimwiki_autowriteall'' to see how to save automatically.'
+ return
+ catch /E325:/
+ echom 'Vimwiki: Vim couldn''t open the file, probably because a swapfile already exists. See :h E325.'
+ return
+ endtry
+ endif
+
+ " If the opened file was not already loaded by Vim, an autocommand is
+ " triggered at this point
+
+ " 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/$'
+ setfiletype vimwiki
+ endif
+ endif
+ if a:anchor != ''
+ call s:jump_to_anchor(a:anchor)
+ endif
+
+ " 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
+ call vimwiki#vars#set_bufferlocal('prev_link', a:1)
+ endif
+endfunction
+
+
+function! vimwiki#base#search_word(wikiRx, cmd)
+ let match_line = search(a:wikiRx, 's'.a:cmd)
+ if match_line == 0
+ echomsg 'Vimwiki: Wiki link not found'
+ endif
+endfunction
+
+
+" Returns part of the line that matches wikiRX at cursor
+function! vimwiki#base#matchstr_at_cursor(wikiRX)
+ let col = col('.') - 1
+ let line = getline('.')
+ let ebeg = -1
+ 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
+endfunction
+
+
+function! vimwiki#base#replacestr_at_cursor(wikiRX, sub)
+ let col = col('.') - 1
+ let line = getline('.')
+ let ebeg = -1
+ let cont = match(line, a:wikiRX, 0)
+ while (ebeg >= 0 || (0 <= cont) && (cont <= col))
+ let contn = matchend(line, a:wikiRX, cont)
+ if (cont <= col) && (col < contn)
+ let ebeg = match(line, a:wikiRX, cont)
+ let elen = contn - ebeg
+ break
+ else
+ let cont = match(line, a:wikiRX, contn)
+ endif
+ endwh
+ if ebeg >= 0
+ " TODO: There might be problems with Unicode chars...
+ let newline = strpart(line, 0, ebeg).a:sub.strpart(line, ebeg+elen)
+ call setline(line('.'), newline)
+ endif
+endfunction
+
+
+function! s:print_wiki_list()
+ let idx = 0
+ while idx < vimwiki#vars#number_of_wikis()
+ if idx == vimwiki#vars#get_bufferlocal('wiki_nr')
+ let sep = ' * '
+ echohl PmenuSel
+ else
+ let sep = ' '
+ echohl None
+ endif
+ echo (idx + 1) . sep . vimwiki#vars#get_wikilocal('path', idx)
+ let idx += 1
+ endwhile
+ echohl None
+endfunction
+
+
+function! s:update_wiki_link(fname, old, new)
+ 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
+ " XXX: any other characters to escape!?
+ 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
+endfunction
+
+
+function! s:update_wiki_links_dir(wiki_nr, dir, old_fname, new_fname)
+ let old_fname = substitute(a:old_fname, '[/\\]', '[/\\\\]', 'g')
+ let new_fname = a:new_fname
+
+ let old_fname_r = vimwiki#base#apply_template(
+ \ vimwiki#vars#get_syntaxlocal('WikiLinkMatchUrlTemplate',
+ \ vimwiki#vars#get_wikilocal('syntax', a:wiki_nr)), old_fname, '', '')
+
+ let files = split(glob(vimwiki#vars#get_wikilocal('path', a:wiki_nr).a:dir.'*'.
+ \ vimwiki#vars#get_wikilocal('ext', a:wiki_nr)), '\n')
+ for fname in l:files
+ call s:update_wiki_link(fname, old_fname_r, new_fname)
+ endfor
+endfunction
+
+
+function! s:tail_name(fname)
+ let result = substitute(a:fname, ":", "__colon__", "g")
+ let result = fnamemodify(result, ":t:r")
+ let result = substitute(result, "__colon__", ":", "g")
+ return result
+endfunction
+
+
+function! s:update_wiki_links(wiki_nr, old_fname, new_fname,old_fname_relpath)
+ let old_fname = a:old_fname
+ let new_fname = a:new_fname
+
+ let subdirs = split(a:old_fname_relpath, '[/\\]')[: -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]
+ call s:update_wiki_links_dir(a:wiki_nr, dir, new_dir.old_fname, new_dir.new_fname)
+ let idx = idx + 1
+ endwhile
+endfunction
+
+
+function! s:get_wiki_buffers()
+ let blist = []
+ let bcount = 1
+ while bcount<=bufnr("$")
+ if bufexists(bcount)
+ let bname = fnamemodify(bufname(bcount), ":p")
+ " this may find buffers that are not part of the current wiki, but that
+ " doesn't hurt
+ if bname =~# vimwiki#vars#get_wikilocal('ext')."$"
+ let bitem = [bname, vimwiki#vars#get_bufferlocal('prev_link', bcount)]
+ call add(blist, bitem)
+ endif
+ endif
+ let bcount = bcount + 1
+ endwhile
+ return blist
+endfunction
+
+
+function! s:open_wiki_buffer(item)
+ call vimwiki#base#edit_file(':e', a:item[0], '')
+ if !empty(a:item[1])
+ call vimwiki#vars#set_bufferlocal('prev_link', a:item[1], a:item[0])
+ endif
+endfunction
+
+
+function! vimwiki#base#nested_syntax(filetype, start, end, textSnipHl) abort
+" 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
+ " keep going even if syntax file is not found
+ execute 'syntax include @'.group.' syntax/'.a:filetype.'.vim'
+ 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
+
+ " 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
+
+ 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
+ " included as 'contained' into specific group.
+ " 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!
+ if ft =~? 'perl'
+ syntax clear perlFunctionName
+ endif
+endfunction
+
+
+" 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,
+ \ content_regex, default_lnum, create)
+ " Vim behaves strangely when files change while in diff mode
+ if &diff || &readonly
+ return
+ endif
+
+ " check if the listing is already there
+ let already_there = 0
+
+ let header_rx = '\m^\s*'.substitute(vimwiki#vars#get_syntaxlocal('rxH1_Template'),
+ \ '__Header__', a:start_header, '') .'\s*$'
+
+ 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
+
+ let winview_save = winsaveview()
+ let cursor_line = winview_save.lnum
+ let is_cursor_after_listing = 0
+
+ let is_fold_closed = 1
+
+ let lines_diff = 0
+
+ if already_there
+ let is_fold_closed = ( foldclosed(start_lnum) > -1 )
+ " 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
+ 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
+ setlocal nofoldenable
+ silent exe 'keepjumps ' . start_lnum.','.string(end_lnum - 1).'delete _'
+ let &l:foldenable = foldenable_save
+ let lines_diff = 0 - (end_lnum - start_lnum)
+ else
+ let start_lnum = a:default_lnum
+ let is_cursor_after_listing = ( cursor_line > a:default_lnum )
+ let whitespaces_in_first_line = ''
+ endif
+
+ let start_of_listing = start_lnum
+
+ " write new listing
+ let new_header = whitespaces_in_first_line
+ \ . s:safesubstitute(vimwiki#vars#get_syntaxlocal('rxH1_Template'),
+ \ '__Header__', a:start_header, '')
+ keepjumps call append(start_lnum - 1, new_header)
+ let start_lnum += 1
+ let lines_diff += 1 + len(a:strings)
+ for string in a:strings
+ keepjumps 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*$'
+ keepjumps call append(start_lnum - 1, '')
+ let lines_diff += 1
+ endif
+
+ " Open fold, if needed
+ if !is_fold_closed && ( foldclosed(start_of_listing) > -1 )
+ exe start_of_listing
+ norm! zo
+ endif
+
+ if is_cursor_after_listing
+ let winview_save.lnum += lines_diff
+ endif
+ call winrestview(winview_save)
+endfunction
+
+
+function! vimwiki#base#find_next_link()
+ call vimwiki#base#search_word(vimwiki#vars#get_syntaxlocal('rxAnyLink'), '')
+endfunction
+
+
+function! vimwiki#base#find_prev_link()
+ "Jump 2 times if the cursor is in the middle of a link
+ if synIDattr(synID(line('.'), col('.'), 0), "name") =~# "VimwikiLink.*" &&
+ \ synIDattr(synID(line('.'), col('.')-1, 0), "name") =~# "VimwikiLink.*"
+ call vimwiki#base#search_word(vimwiki#vars#get_syntaxlocal('rxAnyLink'), 'b')
+ endif
+ call vimwiki#base#search_word(vimwiki#vars#get_syntaxlocal('rxAnyLink'), 'b')
+endfunction
+
+
+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
+
+ " 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 == ""
+ let lnk = matchstr(vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWikiIncl')),
+ \ vimwiki#vars#get_global('rxWikiInclMatchUrl'))
+ 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
+ endif
+
+ if a:split ==# "hsplit"
+ let cmd = ":split "
+ elseif a:split ==# "vsplit"
+ let cmd = ":vsplit "
+ elseif a:split ==# "tab"
+ let cmd = ":tabnew "
+ else
+ let cmd = ":e "
+ endif
+
+ " if we want to and can reuse a split window, jump to that window and open
+ " the new file there
+ if (a:split ==# 'hsplit' || a:split ==# 'vsplit') && reuse_other_split_window
+ let previous_window_nr = winnr('#')
+ if previous_window_nr > 0 && previous_window_nr != winnr()
+ execute previous_window_nr . 'wincmd w'
+ let cmd = ':e'
+ endif
+ endif
+
+
+ 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
+ let lnk = substitute(lnk, '\'.vimwiki#vars#get_wikilocal('ext').'$', '', '')
+ endif
+
+ let current_tab_page = tabpagenr()
+
+ call vimwiki#base#open_link(cmd, lnk)
+
+ if !move_cursor_to_new_window
+ if (a:split ==# 'hsplit' || a:split ==# 'vsplit')
+ execute 'wincmd p'
+ elseif a:split ==# 'tab'
+ execute 'tabnext ' . current_tab_page
+ endif
+ endif
+
+ else
+ if a:0 >= 3
+ execute "normal! ".a:3
+ else
+ call vimwiki#base#normalize_link(0)
+ endif
+ endif
+endfunction
+
+
+function! vimwiki#base#go_back_link()
+ let prev_link = vimwiki#vars#get_bufferlocal('prev_link')
+ if !empty(prev_link)
+ " go back to saved wiki link
+ call vimwiki#base#edit_file(':e ', prev_link[0], '')
+ call setpos('.', prev_link[1])
+ else
+ " maybe we came here by jumping to a tag -> pop from the tag stack
+ silent! pop!
+ endif
+endfunction
+
+
+function! vimwiki#base#goto_index(wnum, ...)
+ if a:wnum > vimwiki#vars#number_of_wikis()
+ echomsg 'Vimwiki Error: Wiki '.a:wnum.' is not registered in your Vimwiki settings!'
+ return
+ endif
+
+ " usually a:wnum is greater then 0 but with the following command it is == 0:
+ " vim -n -c ":VimwikiIndex"
+ if a:wnum > 0
+ let idx = a:wnum - 1
+ else
+ let idx = 0
+ endif
+
+ if a:0
+ if a:1 == 1
+ let cmd = 'tabedit'
+ elseif a:1 == 2
+ let cmd = 'split'
+ elseif a:1 == 3
+ let cmd = 'vsplit'
+ endif
+ else
+ let cmd = 'edit'
+ endif
+
+ 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, '')
+endfunction
+
+
+function! vimwiki#base#delete_link()
+ " Delete wiki file you are in from filesystem
+ let val = input('Delete "'.expand('%').'" [y]es/[N]o? ')
+ if val !~? '^y'
+ return
+ endif
+ let fname = expand('%:p')
+ try
+ call delete(fname)
+ catch /.*/
+ echomsg 'Vimwiki Error: Cannot delete "'.expand('%:t:r').'"!'
+ return
+ endtry
+
+ call vimwiki#base#go_back_link()
+ execute "bdelete! ".escape(fname, " ")
+
+ " reread buffer => deleted wiki link should appear as non-existent
+ if expand('%:p') != ""
+ execute "e"
+ endif
+endfunction
+
+
+" Rename current file, update all links to it
+function! vimwiki#base#rename_link()
+ let subdir = vimwiki#vars#get_bufferlocal('subdir')
+ let old_fname = subdir.expand('%:t')
+
+ " there is no file (new one maybe)
+ if glob(expand('%:p')) == ''
+ echomsg 'Vimwiki Error: Cannot rename "'.expand('%:p').
+ \'". It does not exist! (New file? Save it before renaming.)'
+ return
+ endif
+
+ let val = input('Rename "'.expand('%:t:r').'" [y]es/[N]o? ')
+ if val !~? '^y'
+ return
+ endif
+
+ let new_link = input('Enter new name: ')
+
+ if new_link =~# '[/\\]'
+ echomsg 'Vimwiki Error: Cannot rename to a filename with path!'
+ return
+ endif
+
+ if substitute(new_link, '\s', '', 'g') == ''
+ echomsg 'Vimwiki Error: Cannot rename to an empty filename!'
+ return
+ endif
+
+ let url = matchstr(new_link, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'))
+ if url != ''
+ let new_link = url
+ endif
+
+ let new_link = subdir.new_link
+ let wiki_nr = vimwiki#vars#get_bufferlocal("wiki_nr")
+ let new_fname = vimwiki#vars#get_wikilocal('path') . new_link . vimwiki#vars#get_wikilocal('ext')
+
+ " do not rename if file with such name exists
+ let fname = glob(new_fname)
+ if fname != ''
+ echomsg 'Vimwiki Error: Cannot rename to "'.new_fname.'". File with that name exist!'
+ return
+ endif
+ " rename wiki link file
+ try
+ echomsg 'Vimwiki: Renaming '.vimwiki#vars#get_wikilocal('path').old_fname.' to '.new_fname
+ let res = rename(expand('%:p'), expand(new_fname))
+ if res != 0
+ throw "Cannot rename!"
+ end
+ catch /.*/
+ echomsg 'Vimwiki Error: Cannot rename "'.expand('%:t:r').'" to "'.new_fname.'"'
+ return
+ endtry
+
+ let &buftype="nofile"
+
+ let cur_buffer = [expand('%:p'), vimwiki#vars#get_bufferlocal('prev_link')]
+
+ 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
+ call s:update_wiki_links(wiki_nr, s:tail_name(old_fname), s:tail_name(new_link),old_fname)
+
+ " restore wiki buffers
+ for bitem in blist
+ if !vimwiki#path#is_equal(bitem[0], cur_buffer[0])
+ call s:open_wiki_buffer(bitem)
+ endif
+ endfor
+
+ call s:open_wiki_buffer([new_fname, cur_buffer[1]])
+ " execute 'bwipeout '.escape(cur_buffer[0], ' ')
+
+ echomsg 'Vimwiki: '.old_fname.' is renamed to '.new_fname
+
+ let &more = setting_more
+endfunction
+
+
+function! vimwiki#base#ui_select()
+ call s:print_wiki_list()
+ let idx = input("Select Wiki (specify number): ")
+ if idx == ""
+ return
+ endif
+ call vimwiki#base#goto_index(idx)
+endfunction
+
+
+function! vimwiki#base#TO_header(inner, including_subheaders, count)
+ let headers = s:collect_headers()
+ if empty(headers)
+ return
+ endif
+
+ let current_line = line('.')
+
+ let current_header_index = s:current_header(headers, current_line)
+
+ if current_header_index < 0
+ return
+ endif
+
+ " 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, '<=')
+
+ let first_line = headers[first_header_index][0]
+ let last_line =
+ \ next_sibling_or_higher >= 0 ? headers[next_sibling_or_higher][0] - 1 : line('$')
+ endif
+
+ if a:inner
+ let first_line += 1
+ let last_line = prevnonblank(last_line)
+ endif
+
+ 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
+ endif
+
+ call cursor(first_line, 1)
+ normal! V
+ call cursor(last_line, 1)
+endfunction
+
+
+function! vimwiki#base#TO_table_cell(inner, visual)
+ if col('.') == col('$')-1
+ return
+ endif
+
+ if a:visual
+ normal! `>
+ let sel_end = getpos('.')
+ normal! `<
+ let sel_start = getpos('.')
+
+ let firsttime = sel_start == sel_end
+
+ if firsttime
+ if !search('|\|\(-+-\)', 'cb', line('.'))
+ return
+ endif
+ if getline('.')[virtcol('.')] == '+'
+ normal! l
+ endif
+ if a:inner
+ normal! 2l
+ endif
+ let sel_start = getpos('.')
+ endif
+
+ normal! `>
+ call search('|\|\(-+-\)', '', line('.'))
+ if getline('.')[virtcol('.')] == '+'
+ normal! l
+ endif
+ if a:inner
+ if firsttime || abs(sel_end[2] - getpos('.')[2]) != 2
+ normal! 2h
+ endif
+ endif
+ let sel_end = getpos('.')
+
+ call setpos('.', sel_start)
+ exe "normal! \<C-v>"
+ call setpos('.', sel_end)
+
+ " XXX: WORKAROUND.
+ " if blockwise selection is ended at | character then pressing j to extend
+ " selection further fails. But if we shake the cursor left and right then
+ " it works.
+ normal! hl
+ else
+ if !search('|\|\(-+-\)', 'cb', line('.'))
+ return
+ endif
+ if a:inner
+ normal! 2l
+ endif
+ normal! v
+ call search('|\|\(-+-\)', '', line('.'))
+ if !a:inner && getline('.')[virtcol('.')-1] == '|'
+ normal! h
+ elseif a:inner
+ normal! 2h
+ endif
+ endif
+endfunction
+
+
+function! vimwiki#base#TO_table_col(inner, visual)
+ let t_rows = vimwiki#tbl#get_rows(line('.'))
+ if empty(t_rows)
+ return
+ endif
+
+ " TODO: refactor it!
+ if a:visual
+ normal! `>
+ let sel_end = getpos('.')
+ normal! `<
+ let sel_start = getpos('.')
+
+ let firsttime = sel_start == sel_end
+
+ if firsttime
+ " place cursor to the top row of the table
+ call vimwiki#u#cursor(t_rows[0][0], virtcol('.'))
+ " do not accept the match at cursor position if cursor is next to column
+ " separator of the table separator (^ is a cursor):
+ " |-----^-+-------|
+ " | bla | bla |
+ " |-------+-------|
+ " or it will select wrong column.
+ if strpart(getline('.'), virtcol('.')-1) =~# '^-+'
+ let s_flag = 'b'
+ else
+ let s_flag = 'cb'
+ endif
+ " search the column separator backwards
+ if !search('|\|\(-+-\)', s_flag, line('.'))
+ return
+ endif
+ " -+- column separator is matched --> move cursor to the + sign
+ if getline('.')[virtcol('.')] == '+'
+ normal! l
+ endif
+ " inner selection --> reduce selection
+ if a:inner
+ normal! 2l
+ endif
+ let sel_start = getpos('.')
+ endif
+
+ normal! `>
+ if !firsttime && getline('.')[virtcol('.')] == '|'
+ normal! l
+ elseif a:inner && getline('.')[virtcol('.')+1] =~# '[|+]'
+ normal! 2l
+ endif
+ " search for the next column separator
+ call search('|\|\(-+-\)', '', line('.'))
+ " Outer selection selects a column without border on the right. So we move
+ " our cursor left if the previous search finds | border, not -+-.
+ if getline('.')[virtcol('.')] != '+'
+ normal! h
+ endif
+ if a:inner
+ " reduce selection a bit more if inner.
+ normal! h
+ endif
+ " expand selection to the bottom line of the table
+ call vimwiki#u#cursor(t_rows[-1][0], virtcol('.'))
+ let sel_end = getpos('.')
+
+ call setpos('.', sel_start)
+ exe "normal! \<C-v>"
+ call setpos('.', sel_end)
+
+ else
+ " place cursor to the top row of the table
+ call vimwiki#u#cursor(t_rows[0][0], virtcol('.'))
+ " do not accept the match at cursor position if cursor is next to column
+ " separator of the table separator (^ is a cursor):
+ " |-----^-+-------|
+ " | bla | bla |
+ " |-------+-------|
+ " or it will select wrong column.
+ if strpart(getline('.'), virtcol('.')-1) =~# '^-+'
+ let s_flag = 'b'
+ else
+ let s_flag = 'cb'
+ endif
+ " search the column separator backwards
+ if !search('|\|\(-+-\)', s_flag, line('.'))
+ return
+ endif
+ " -+- column separator is matched --> move cursor to the + sign
+ if getline('.')[virtcol('.')] == '+'
+ normal! l
+ endif
+ " inner selection --> reduce selection
+ if a:inner
+ normal! 2l
+ endif
+
+ exe "normal! \<C-V>"
+
+ " search for the next column separator
+ call search('|\|\(-+-\)', '', line('.'))
+ " Outer selection selects a column without border on the right. So we move
+ " our cursor left if the previous search finds | border, not -+-.
+ if getline('.')[virtcol('.')] != '+'
+ normal! h
+ endif
+ " reduce selection a bit more if inner.
+ if a:inner
+ normal! h
+ endif
+ " expand selection to the bottom line of the table
+ call vimwiki#u#cursor(t_rows[-1][0], virtcol('.'))
+ endif
+endfunction
+
+
+function! vimwiki#base#AddHeaderLevel()
+ let lnum = line('.')
+ let line = getline(lnum)
+ let rxHdr = vimwiki#vars#get_syntaxlocal('rxH')
+ if line =~# '^\s*$'
+ return
+ endif
+
+ if line =~# vimwiki#vars#get_syntaxlocal('rxHeader')
+ let level = vimwiki#u#count_first_sym(line)
+ if level < 6
+ if vimwiki#vars#get_syntaxlocal('symH')
+ let line = substitute(line, '\('.rxHdr.'\+\).\+\1', rxHdr.'&'.rxHdr, '')
+ else
+ let line = substitute(line, '\('.rxHdr.'\+\).\+', rxHdr.'&', '')
+ endif
+ call setline(lnum, line)
+ endif
+ else
+ let line = substitute(line, '^\s*', '&'.rxHdr.' ', '')
+ if vimwiki#vars#get_syntaxlocal('symH')
+ let line = substitute(line, '\s*$', ' '.rxHdr.'&', '')
+ endif
+ call setline(lnum, line)
+ endif
+endfunction
+
+
+function! vimwiki#base#RemoveHeaderLevel()
+ let lnum = line('.')
+ let line = getline(lnum)
+ let rxHdr = vimwiki#vars#get_syntaxlocal('rxH')
+ if line =~# '^\s*$'
+ return
+ endif
+
+ if line =~# vimwiki#vars#get_syntaxlocal('rxHeader')
+ let level = vimwiki#u#count_first_sym(line)
+ let old = repeat(rxHdr, level)
+ let new = repeat(rxHdr, level - 1)
+
+ let chomp = line =~# rxHdr.'\s'
+
+ if vimwiki#vars#get_syntaxlocal('symH')
+ let line = substitute(line, old, new, 'g')
+ else
+ let line = substitute(line, old, new, '')
+ endif
+
+ if level == 1 && chomp
+ let line = substitute(line, '^\s', '', 'g')
+ let line = substitute(line, '\s$', '', 'g')
+ endif
+
+ let line = substitute(line, '\s*$', '', '')
+
+ call setline(lnum, line)
+ endif
+endfunction
+
+
+
+" 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)
+ let header_text =
+ \ vimwiki#u#trim(matchstr(line_content, vimwiki#vars#get_syntaxlocal('rxHeader')))
+ call add(headers, [lnum, header_level, header_text])
+ endfor
+
+ return headers
+endfunction
+
+
+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)
+ elseif current_header_index < 0 && !empty(headers) " we're above the first header
+ call cursor(headers[0][0], 1)
+ 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
+ echo 'Vimwiki: no previous header found'
+ endif
+endfunction
+
+
+function! vimwiki#base#goto_sibling(direction)
+ let headers = s:collect_headers()
+ let current_header_index = s:current_header(headers, line('.'))
+ let next_potential_sibling =
+ \ s:get_another_header(headers, current_header_index, a:direction, '<=')
+ 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
+
+
+" a:create == 1: creates or updates TOC in current file
+" a:create == 0: update if TOC exists
+function! vimwiki#base#table_of_contents(create)
+ let headers = s:collect_headers()
+ let toc_header_text = vimwiki#vars#get_global('toc_header')
+
+ if !a:create
+ " Do nothing if there is no TOC to update. (This is a small performance optimization -- if
+ " auto_toc == 1, but the current buffer has no TOC but is long, saving the buffer could
+ " otherwise take a few seconds for nothing.)
+ let toc_already_present = 0
+ for entry in headers
+ if entry[2] ==# toc_header_text
+ let toc_already_present = 1
+ break
+ endif
+ endfor
+ if !toc_already_present
+ return
+ endif
+ endif
+
+ let numbering = vimwiki#vars#get_global('html_header_numbering')
+ let headers_levels = [['', 0], ['', 0], ['', 0], ['', 0], ['', 0], ['', 0]]
+ let complete_header_infos = []
+ for header in headers
+ let h_text = header[2]
+ let h_level = header[1]
+ if h_text ==# toc_header_text " don't include the TOC's header itself
+ continue
+ endif
+ 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]
+
+ if numbering > 0 && numbering <= h_level
+ let h_number = join(map(copy(headers_levels[numbering-1 : h_level-1]), 'v:val[1]'), '.')
+ let h_number .= vimwiki#vars#get_global('html_header_numbering_sym')
+ let h_text = h_number.' '.h_text
+ endif
+
+ call add(complete_header_infos, [h_level, h_complete_id, h_text])
+ endfor
+
+ let lines = []
+ let startindent = repeat(' ', vimwiki#lst#get_list_margin())
+ let indentstring = repeat(' ', vimwiki#u#sw())
+ let bullet = vimwiki#lst#default_symbol().' '
+ for [lvl, link, desc] in complete_header_infos
+ if vimwiki#vars#get_wikilocal('syntax') == 'markdown'
+ let link_tpl = vimwiki#vars#get_syntaxlocal('Weblink1Template')
+ else
+ let link_tpl = vimwiki#vars#get_global('WikiLinkTemplate2')
+ endif
+ let link = s:safesubstitute(link_tpl, '__LinkUrl__',
+ \ '#'.link, '')
+ let link = s:safesubstitute(link, '__LinkDescription__', desc, '')
+ call add(lines, startindent.repeat(indentstring, lvl-1).bullet.link)
+ endfor
+
+ let links_rx = '\m^\s*'.vimwiki#u#escape(vimwiki#lst#default_symbol()).' '
+
+ call vimwiki#base#update_listing_in_buffer(lines, toc_header_text, links_rx, 1, a:create)
+endfunction
+
+
+" Construct a regular expression matching from template (with special
+" characters properly escaped), by substituting rxUrl for __LinkUrl__, rxDesc
+" for __LinkDescription__, and rxStyle for __LinkStyle__. The three
+" arguments rxUrl, rxDesc, and rxStyle are copied verbatim, without any
+" special character escapes or substitutions.
+function! vimwiki#base#apply_template(template, rxUrl, rxDesc, rxStyle)
+ let lnk = a:template
+ if a:rxUrl != ""
+ let lnk = s:safesubstitute(lnk, '__LinkUrl__', a:rxUrl, 'g')
+ endif
+ if a:rxDesc != ""
+ let lnk = s:safesubstitute(lnk, '__LinkDescription__', a:rxDesc, 'g')
+ endif
+ if a:rxStyle != ""
+ let lnk = s:safesubstitute(lnk, '__LinkStyle__', a:rxStyle, 'g')
+ endif
+ return lnk
+endfunction
+
+
+function! s:clean_url(url)
+ " remove protocol and tld
+ let url = substitute(a:url, '^\a\+\d*:', '', '')
+ let url = substitute(url, '^//', '', '')
+ let url = substitute(url, '^\([^/]\+\)\.\a\{2,4}/', '\1/', '')
+ let url = split(url, '/\|=\|-\|&\|?\|\.')
+ let url = filter(url, 'v:val !=# ""')
+ if url[0] == "www"
+ let url = url[1:]
+ endif
+ if url[-1] =~ '^\(htm\|html\|php\)$'
+ let url = url[0:-2]
+ endif
+ " 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"')
+ return join(url, " ")
+endfunction
+
+
+function! s:is_diary_file(filename)
+ let file_path = vimwiki#path#path_norm(a:filename)
+ let rel_path = vimwiki#vars#get_wikilocal('diary_rel_path')
+ let diary_path = vimwiki#path#path_norm(vimwiki#vars#get_wikilocal('path') . rel_path)
+ return rel_path != '' && file_path =~# '^'.vimwiki#u#escape(diary_path)
+endfunction
+
+
+function! vimwiki#base#normalize_link_helper(str, rxUrl, rxDesc, template)
+ let url = matchstr(a:str, a:rxUrl)
+ let descr = matchstr(a:str, a:rxDesc)
+ if descr == ""
+ let descr = s:clean_url(url)
+ endif
+ let lnk = s:safesubstitute(a:template, '__LinkDescription__', descr, '')
+ let lnk = s:safesubstitute(lnk, '__LinkUrl__', url, '')
+ return lnk
+endfunction
+
+
+function! vimwiki#base#normalize_imagelink_helper(str, rxUrl, rxDesc, rxStyle, template)
+ let lnk = vimwiki#base#normalize_link_helper(a:str, a:rxUrl, a:rxDesc, a:template)
+ let style = matchstr(a:str, a:rxStyle)
+ let lnk = s:safesubstitute(lnk, '__LinkStyle__', style, '')
+ return lnk
+endfunction
+
+
+function! s:normalize_link_in_diary(lnk)
+ let link = a:lnk . vimwiki#vars#get_wikilocal('ext')
+ let link_wiki = vimwiki#vars#get_wikilocal('path') . '/' . link
+ let link_diary = vimwiki#vars#get_wikilocal('path') . '/'
+ \ . vimwiki#vars#get_wikilocal('diary_rel_path') . '/' . link
+ 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_diary || link_is_date
+ let str = a:lnk
+ let rxUrl = vimwiki#vars#get_global('rxWord')
+ let rxDesc = ''
+ let template = vimwiki#vars#get_global('WikiLinkTemplate1')
+ elseif link_exists_in_wiki
+ let depth = len(split(vimwiki#vars#get_wikilocal('diary_rel_path'), '/'))
+ let str = repeat('../', depth) . a:lnk . '|' . a:lnk
+ let rxUrl = '^.*\ze|'
+ let rxDesc = '|\zs.*$'
+ let template = vimwiki#vars#get_global('WikiLinkTemplate2')
+ else
+ let str = a:lnk
+ let rxUrl = '.*'
+ let rxDesc = ''
+ let template = vimwiki#vars#get_global('WikiLinkTemplate1')
+ endif
+
+ return vimwiki#base#normalize_link_helper(str, rxUrl, rxDesc, template)
+endfunction
+
+
+function! s:normalize_link_syntax_n()
+
+ " try WikiLink
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink'))
+ if !empty(lnk)
+ let sub = vimwiki#base#normalize_link_helper(lnk,
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'),
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr'),
+ \ vimwiki#vars#get_global('WikiLinkTemplate2'))
+ call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink'), sub)
+ return
+ endif
+
+ " try WikiIncl
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWikiIncl'))
+ if !empty(lnk)
+ " NO-OP !!
+ return
+ endif
+
+ " try Weblink
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'))
+ if !empty(lnk)
+ let sub = vimwiki#base#normalize_link_helper(lnk,
+ \ lnk, '', vimwiki#vars#get_global('WikiLinkTemplate2'))
+ call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'), sub)
+ return
+ endif
+
+ " try Word (any characters except separators)
+ " rxWord is less permissive than rxWikiLinkUrl which is used in
+ " normalize_link_syntax_v
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWord'))
+ if !empty(lnk)
+ if s:is_diary_file(expand("%:p"))
+ let sub = s:normalize_link_in_diary(lnk)
+ else
+ let sub = s:safesubstitute(
+ \ vimwiki#vars#get_global('WikiLinkTemplate1'), '__LinkUrl__', lnk, '')
+ endif
+ call vimwiki#base#replacestr_at_cursor('\V'.lnk, sub)
+ return
+ endif
+
+endfunction
+
+
+function! s:normalize_link_syntax_v()
+ let sel_save = &selection
+ let &selection = "old"
+ let default_register_save = @"
+ let registertype_save = getregtype('"')
+
+ try
+ " Save selected text to register "
+ normal! gv""y
+
+ " Set substitution
+ if s:is_diary_file(expand("%:p"))
+ let sub = s:normalize_link_in_diary(@")
+ else
+ let sub = s:safesubstitute(vimwiki#vars#get_global('WikiLinkTemplate1'),
+ \ '__LinkUrl__', @", '')
+ endif
+
+ " Put substitution in register " and change text
+ call setreg('"', substitute(sub, '\n', '', ''), visualmode())
+ normal! `>""pgvd
+ finally
+ call setreg('"', default_register_save, registertype_save)
+ let &selection = sel_save
+ endtry
+endfunction
+
+
+function! vimwiki#base#normalize_link(is_visual_mode)
+ if exists('*vimwiki#'.vimwiki#vars#get_wikilocal('syntax').'_base#normalize_link')
+ " Syntax-specific links
+ call vimwiki#{vimwiki#vars#get_wikilocal('syntax')}_base#normalize_link(a:is_visual_mode)
+ else
+ if !a:is_visual_mode
+ call s:normalize_link_syntax_n()
+ elseif line("'<") == line("'>")
+ " action undefined for multi-line visual mode selections
+ call s:normalize_link_syntax_v()
+ endif
+ endif
+endfunction
+
+
+function! vimwiki#base#detect_nested_syntax()
+ let last_word = '\v.*<(\w+)\s*$'
+ let lines = map(filter(getline(1, "$"), 'v:val =~ "\\%({{{\\|```\\)" && v:val =~ last_word'),
+ \ 'substitute(v:val, last_word, "\\=submatch(1)", "")')
+ let dict = {}
+ for elem in lines
+ let dict[elem] = elem
+ endfor
+ return dict
+endfunction
+
+
+function! vimwiki#base#complete_links_escaped(ArgLead, CmdLine, CursorPos) abort
+ " 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()
+endfunction
+
+
+" -------------------------------------------------------------------------
+" Load syntax-specific Wiki functionality
+for s:syn in s:vimwiki_get_known_syntaxes()
+ execute 'runtime! autoload/vimwiki/'.s:syn.'_base.vim'
+endfor
+" -------------------------------------------------------------------------
+
diff --git a/.config/nvim/autoload/vimwiki/customwiki2html.sh b/.config/nvim/autoload/vimwiki/customwiki2html.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+#
+# This script converts markdown into html, to be used with vimwiki's
+# "customwiki2html" option. Experiment with the two proposed methods by
+# commenting / uncommenting the relevant lines below.
+#
+# NEW! An alternative converter was developed by Jason6Anderson, and can
+# be located at https://github.com/vimwiki-backup/vimwiki/issues/384
+#
+#
+# To use this script, you must have the Discount converter installed.
+#
+# http://www.pell.portland.or.us/~orc/Code/discount/
+#
+# To verify your installation, check that the commands markdown and mkd2text,
+# are on your path.
+#
+# Also verify that this file is executable.
+#
+# Then, in your .vimrc file, set:
+#
+# g:vimwiki_customwiki2html=$HOME.'/.vim/autoload/vimwiki/customwiki2html.sh'
+#
+# On your next restart, Vimwiki will run this script instead of using the
+# internal wiki2html converter.
+#
+
+MARKDOWN=markdown
+MKD2HTML=mkd2html
+
+
+FORCE="$1"
+SYNTAX="$2"
+EXTENSION="$3"
+OUTPUTDIR="$4"
+INPUT="$5"
+CSSFILE="$6"
+
+FORCEFLAG=
+
+[ $FORCE -eq 0 ] || { FORCEFLAG="-f"; };
+[ $SYNTAX = "markdown" ] || { echo "Error: Unsupported syntax"; exit -2; };
+
+OUTPUT="$OUTPUTDIR"/$(basename "$INPUT" .$EXTENSION).html
+
+# # Method 1:
+# # markdown [-d] [-T] [-V] [-b url-base] [-C prefix] [-F bitmap] [-f flags] [-o file] [-s text] [-t text] [textfile]
+#
+# URLBASE=http://example.com
+# $MARKDOWN -T -b $URLBASE -o $OUTPUT $INPUT
+
+
+# Method 2:
+# mkd2html [-css file] [-header string] [-footer string] [file]
+
+$MKD2HTML -css "$CSSFILE" "$INPUT"
+OUTPUTTMP=$(dirname "$INPUT")/$(basename "$INPUT" ."$EXTENSION").html
+mv -f "$OUTPUTTMP" "$OUTPUT"
+
+
+
diff --git a/.config/nvim/autoload/vimwiki/default.tpl b/.config/nvim/autoload/vimwiki/default.tpl
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="Stylesheet" type="text/css" href="%root_path%%css%">
+<title>%title%</title>
+<meta http-equiv="Content-Type" content="text/html; charset=%encoding%">
+</head>
+<body>
+%content%
+</body>
+</html>
diff --git a/.config/nvim/autoload/vimwiki/diary.vim b/.config/nvim/autoload/vimwiki/diary.vim
@@ -0,0 +1,327 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Description: Handle diary notes
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+if exists("g:loaded_vimwiki_diary_auto") || &cp
+ finish
+endif
+let g:loaded_vimwiki_diary_auto = 1
+
+
+let s:vimwiki_max_scan_for_caption = 5
+
+
+function! s:prefix_zero(num)
+ if a:num < 10
+ return '0'.a:num
+ endif
+ return a:num
+endfunction
+
+
+function! s:diary_path(...)
+ let idx = a:0 == 0 ? vimwiki#vars#get_bufferlocal('wiki_nr') : a:1
+ return vimwiki#vars#get_wikilocal('path', idx).vimwiki#vars#get_wikilocal('diary_rel_path', idx)
+endfunction
+
+
+function! s:diary_index(...)
+ let idx = a:0 == 0 ? vimwiki#vars#get_bufferlocal('wiki_nr') : a:1
+ return s:diary_path(idx).vimwiki#vars#get_wikilocal('diary_index', idx).
+ \ vimwiki#vars#get_wikilocal('ext', idx)
+endfunction
+
+
+function! vimwiki#diary#diary_date_link(...)
+ if a:0
+ return strftime('%Y-%m-%d', a:1)
+ else
+ return strftime('%Y-%m-%d')
+ endif
+endfunction
+
+
+function! s:get_position_links(link)
+ let idx = -1
+ let links = []
+ if a:link =~# '^\d\{4}-\d\d-\d\d'
+ let links = map(s:get_diary_files(), 'fnamemodify(v:val, ":t:r")')
+ " include 'today' into links
+ if index(links, vimwiki#diary#diary_date_link()) == -1
+ call add(links, vimwiki#diary#diary_date_link())
+ endif
+ call sort(links)
+ let idx = index(links, a:link)
+ endif
+ return [idx, links]
+endfunction
+
+
+function! s:get_month_name(month)
+ return vimwiki#vars#get_global('diary_months')[str2nr(a:month)]
+endfunction
+
+
+function! s:read_captions(files)
+ let result = {}
+ let rx_header = vimwiki#vars#get_syntaxlocal('rxHeader')
+ for fl in a:files
+ " remove paths and extensions
+ let fl_key = substitute(fnamemodify(fl, ':t'), vimwiki#vars#get_wikilocal('ext').'$', '', '')
+
+ if filereadable(fl)
+ for line in readfile(fl, '', s:vimwiki_max_scan_for_caption)
+ if line =~# rx_header && !has_key(result, fl_key)
+ let result[fl_key] = vimwiki#u#trim(matchstr(line, rx_header))
+ endif
+ endfor
+ endif
+
+ if !has_key(result, fl_key)
+ let result[fl_key] = ''
+ endif
+
+ endfor
+ return result
+endfunction
+
+
+function! s:get_diary_files()
+ let rx = '^\d\{4}-\d\d-\d\d'
+ let s_files = glob(vimwiki#vars#get_wikilocal('path').
+ \ vimwiki#vars#get_wikilocal('diary_rel_path').'*'.vimwiki#vars#get_wikilocal('ext'))
+ let files = split(s_files, '\n')
+ call filter(files, 'fnamemodify(v:val, ":t") =~# "'.escape(rx, '\').'"')
+
+ " remove backup files (.wiki~)
+ call filter(files, 'v:val !~# ''.*\~$''')
+
+ return files
+endfunction
+
+
+function! s:group_links(links)
+ let result = {}
+ let p_year = 0
+ let p_month = 0
+ for fl in sort(keys(a:links))
+ let year = strpart(fl, 0, 4)
+ let month = strpart(fl, 5, 2)
+ if p_year != year
+ let result[year] = {}
+ let p_month = 0
+ endif
+ if p_month != month
+ let result[year][month] = {}
+ endif
+ let result[year][month][fl] = a:links[fl]
+ let p_year = year
+ let p_month = month
+ endfor
+ return result
+endfunction
+
+
+function! s:sort(lst)
+ if vimwiki#vars#get_wikilocal('diary_sort') ==? 'desc'
+ return reverse(sort(a:lst))
+ else
+ return sort(a:lst)
+ endif
+endfunction
+
+
+function! s:format_diary()
+ let result = []
+
+ let links_with_captions = s:read_captions(s:get_diary_files())
+ let g_files = s:group_links(links_with_captions)
+
+ for year in s:sort(keys(g_files))
+ call add(result, '')
+ call add(result,
+ \ substitute(vimwiki#vars#get_syntaxlocal('rxH2_Template'), '__Header__', year , ''))
+
+ for month in s:sort(keys(g_files[year]))
+ call add(result, '')
+ call add(result, substitute(vimwiki#vars#get_syntaxlocal('rxH3_Template'),
+ \ '__Header__', s:get_month_name(month), ''))
+
+ for [fl, cap] in s:sort(items(g_files[year][month]))
+ let link_tpl = vimwiki#vars#get_global('WikiLinkTemplate2')
+
+ if vimwiki#vars#get_wikilocal('syntax') == 'markdown'
+ let link_tpl = vimwiki#vars#get_syntaxlocal('Weblink1Template')
+
+ if empty(cap) " When using markdown syntax, we should ensure we always have a link description.
+ let cap = fl
+ endif
+ elseif empty(cap)
+ let link_tpl = vimwiki#vars#get_global('WikiLinkTemplate1')
+ endif
+
+ let entry = substitute(link_tpl, '__LinkUrl__', fl, '')
+ let entry = substitute(entry, '__LinkDescription__', cap, '')
+ call add(result, repeat(' ', vimwiki#lst#get_list_margin()).'* '.entry)
+ endfor
+
+ endfor
+ endfor
+
+ return result
+endfunction
+
+
+" The given wiki number a:wnum is 1 for the first wiki, 2 for the second and so on. This is in
+" contrast to most other places, where counting starts with 0. When a:wnum is 0, the current wiki
+" is used.
+function! vimwiki#diary#make_note(wnum, ...)
+ if a:wnum == 0
+ let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr')
+ if wiki_nr < 0 " this happens when e.g. VimwikiMakeDiaryNote was called outside a wiki buffer
+ let wiki_nr = 0
+ endif
+ else
+ let wiki_nr = a:wnum - 1
+ endif
+
+ if wiki_nr >= vimwiki#vars#number_of_wikis()
+ echomsg 'Vimwiki Error: Wiki '.wiki_nr.' is not registered in g:vimwiki_list!'
+ return
+ endif
+
+ " TODO: refactor it. base#goto_index uses the same
+
+ call vimwiki#path#mkdir(vimwiki#vars#get_wikilocal('path', wiki_nr).
+ \ vimwiki#vars#get_wikilocal('diary_rel_path', wiki_nr))
+
+ let cmd = 'edit'
+ if a:0
+ if a:1 == 1
+ let cmd = 'tabedit'
+ elseif a:1 == 2
+ let cmd = 'split'
+ elseif a:1 == 3
+ let cmd = 'vsplit'
+ endif
+ endif
+ if a:0>1
+ let link = 'diary:'.a:2
+ else
+ let link = 'diary:'.vimwiki#diary#diary_date_link()
+ endif
+
+ call vimwiki#base#open_link(cmd, link, s:diary_index(wiki_nr))
+endfunction
+
+
+function! vimwiki#diary#goto_diary_index(wnum)
+ if a:wnum > vimwiki#vars#number_of_wikis()
+ echomsg 'Vimwiki Error: Wiki '.a:wnum.' is not registered in g:vimwiki_list!'
+ return
+ endif
+
+ " TODO: refactor it. base#goto_index uses the same
+ if a:wnum > 0
+ let idx = a:wnum - 1
+ else
+ let idx = 0
+ endif
+
+ call vimwiki#base#edit_file('e', s:diary_index(idx), '')
+
+ if vimwiki#vars#get_wikilocal('auto_diary_index')
+ call vimwiki#diary#generate_diary_section()
+ write! " save changes
+ endif
+endfunction
+
+
+function! vimwiki#diary#goto_next_day()
+ let link = ''
+ let [idx, links] = s:get_position_links(expand('%:t:r'))
+
+ if idx == (len(links) - 1)
+ return
+ endif
+
+ if idx != -1 && idx < len(links) - 1
+ let link = 'diary:'.links[idx+1]
+ else
+ " goto today
+ let link = 'diary:'.vimwiki#diary#diary_date_link()
+ endif
+
+ if len(link)
+ call vimwiki#base#open_link(':e ', link)
+ endif
+endfunction
+
+
+function! vimwiki#diary#goto_prev_day()
+ let link = ''
+ let [idx, links] = s:get_position_links(expand('%:t:r'))
+
+ if idx == 0
+ return
+ endif
+
+ if idx > 0
+ let link = 'diary:'.links[idx-1]
+ else
+ " goto today
+ let link = 'diary:'.vimwiki#diary#diary_date_link()
+ endif
+
+ if len(link)
+ call vimwiki#base#open_link(':e ', link)
+ endif
+endfunction
+
+
+function! vimwiki#diary#generate_diary_section()
+ let current_file = vimwiki#path#path_norm(expand("%:p"))
+ let diary_file = vimwiki#path#path_norm(s:diary_index())
+ if vimwiki#path#is_equal(current_file, diary_file)
+ let content_rx = '^\%(\s*\* \)\|\%(^\s*$\)\|\%('.vimwiki#vars#get_syntaxlocal('rxHeader').'\)'
+ call vimwiki#base#update_listing_in_buffer(s:format_diary(),
+ \ vimwiki#vars#get_wikilocal('diary_header'), content_rx, line('$')+1, 1)
+ else
+ echomsg 'Vimwiki Error: You can generate diary links only in a diary index page!'
+ endif
+endfunction
+
+
+" Callback function for Calendar.vim
+function! vimwiki#diary#calendar_action(day, month, year, week, dir)
+ let day = s:prefix_zero(a:day)
+ let month = s:prefix_zero(a:month)
+
+ let link = a:year.'-'.month.'-'.day
+ if winnr('#') == 0
+ if a:dir ==? 'V'
+ vsplit
+ else
+ split
+ endif
+ else
+ wincmd p
+ if !&hidden && &modified
+ new
+ endif
+ endif
+
+ call vimwiki#diary#make_note(0, 0, link)
+endfunction
+
+
+function vimwiki#diary#calendar_sign(day, month, year)
+ let day = s:prefix_zero(a:day)
+ let month = s:prefix_zero(a:month)
+ let sfile = vimwiki#vars#get_wikilocal('path').vimwiki#vars#get_wikilocal('diary_rel_path').
+ \ a:year.'-'.month.'-'.day.vimwiki#vars#get_wikilocal('ext')
+ return filereadable(expand(sfile))
+endfunction
+
diff --git a/.config/nvim/autoload/vimwiki/html.vim b/.config/nvim/autoload/vimwiki/html.vim
@@ -0,0 +1,1664 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Description: HTML export
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+if exists("g:loaded_vimwiki_html_auto") || &cp
+ finish
+endif
+let g:loaded_vimwiki_html_auto = 1
+
+
+function! s:root_path(subdir)
+ return repeat('../', len(split(a:subdir, '[/\\]')))
+endfunction
+
+
+function! s:syntax_supported()
+ return vimwiki#vars#get_wikilocal('syntax') ==? "default"
+endfunction
+
+
+function! s:remove_blank_lines(lines)
+ while !empty(a:lines) && a:lines[-1] =~# '^\s*$'
+ call remove(a:lines, -1)
+ endwhile
+endfunction
+
+
+function! s:is_web_link(lnk)
+ if a:lnk =~# '^\%(https://\|http://\|www.\|ftp://\|file://\|mailto:\)'
+ return 1
+ endif
+ return 0
+endfunction
+
+
+function! s:is_img_link(lnk)
+ if tolower(a:lnk) =~# '\.\%(png\|jpg\|gif\|jpeg\)$'
+ return 1
+ endif
+ return 0
+endfunction
+
+
+function! s:has_abs_path(fname)
+ if a:fname =~# '\(^.:\)\|\(^/\)'
+ return 1
+ endif
+ return 0
+endfunction
+
+
+function! s:find_autoload_file(name)
+ for path in split(&runtimepath, ',')
+ let fname = path.'/autoload/vimwiki/'.a:name
+ if glob(fname) != ''
+ return fname
+ endif
+ endfor
+ return ''
+endfunction
+
+
+function! s:default_CSS_full_name(path)
+ let path = expand(a:path)
+ let css_full_name = path . vimwiki#vars#get_wikilocal('css_name')
+ return css_full_name
+endfunction
+
+
+function! s:create_default_CSS(path)
+ let css_full_name = s:default_CSS_full_name(a:path)
+ if glob(css_full_name) == ""
+ call vimwiki#path#mkdir(fnamemodify(css_full_name, ':p:h'))
+ let default_css = s:find_autoload_file('style.css')
+ if default_css != ''
+ let lines = readfile(default_css)
+ call writefile(lines, css_full_name)
+ return 1
+ endif
+ endif
+ return 0
+endfunction
+
+
+function! s:template_full_name(name)
+ if a:name == ''
+ let name = vimwiki#vars#get_wikilocal('template_default')
+ else
+ let name = a:name
+ endif
+
+ let fname = expand(vimwiki#vars#get_wikilocal('template_path').
+ \ name . vimwiki#vars#get_wikilocal('template_ext'))
+
+ if filereadable(fname)
+ return fname
+ else
+ return ''
+ endif
+endfunction
+
+
+function! s:get_html_template(template)
+ " TODO: refactor it!!!
+ let lines=[]
+
+ if a:template != ''
+ let template_name = s:template_full_name(a:template)
+ try
+ let lines = readfile(template_name)
+ return lines
+ catch /E484/
+ echomsg 'Vimwiki: HTML template '.template_name. ' does not exist!'
+ endtry
+ endif
+
+ let default_tpl = s:template_full_name('')
+
+ if default_tpl == ''
+ let default_tpl = s:find_autoload_file('default.tpl')
+ endif
+
+ let lines = readfile(default_tpl)
+ return lines
+endfunction
+
+
+function! s:safe_html_preformatted(line)
+ let line = substitute(a:line,'<','\<', 'g')
+ let line = substitute(line,'>','\>', 'g')
+ return line
+endfunction
+
+
+function! s:escape_html_attribute(string)
+ return substitute(a:string, '"', '\"', 'g')
+endfunction
+
+
+function! s:safe_html_line(line)
+ " escape & < > when producing HTML text
+ " s:lt_pattern, s:gt_pattern depend on g:vimwiki_valid_html_tags
+ " and are set in vimwiki#html#Wiki2HTML()
+ let line = substitute(a:line, '&', '\&', 'g')
+ let line = substitute(line,s:lt_pattern,'\<', 'g')
+ let line = substitute(line,s:gt_pattern,'\>', 'g')
+
+ return line
+endfunction
+
+
+function! s:delete_html_files(path)
+ let htmlfiles = split(glob(a:path.'**/*.html'), '\n')
+ for fname in htmlfiles
+ " ignore user html files, e.g. search.html,404.html
+ if stridx(vimwiki#vars#get_global('user_htmls'), fnamemodify(fname, ":t")) >= 0
+ continue
+ endif
+
+ " delete if there is no corresponding wiki file
+ let subdir = vimwiki#base#subdir(vimwiki#vars#get_wikilocal('path_html'), fname)
+ let wikifile = vimwiki#vars#get_wikilocal('path').subdir.
+ \fnamemodify(fname, ":t:r").vimwiki#vars#get_wikilocal('ext')
+ if filereadable(wikifile)
+ continue
+ endif
+
+ try
+ call delete(fname)
+ catch
+ echomsg 'Vimwiki Error: Cannot delete '.fname
+ endtry
+ endfor
+endfunction
+
+
+function! s:mid(value, cnt)
+ return strpart(a:value, a:cnt, len(a:value) - 2 * a:cnt)
+endfunction
+
+
+function! s:subst_func(line, regexp, func, ...)
+ " Substitute text found by regexp with result of
+ " func(matched) function.
+
+ let pos = 0
+ let lines = split(a:line, a:regexp, 1)
+ let res_line = ""
+ for line in lines
+ let res_line = res_line.line
+ let matched = matchstr(a:line, a:regexp, pos)
+ if matched != ""
+ if a:0
+ let res_line = res_line.{a:func}(matched, a:1)
+ else
+ let res_line = res_line.{a:func}(matched)
+ endif
+ endif
+ let pos = matchend(a:line, a:regexp, pos)
+ endfor
+ return res_line
+endfunction
+
+
+function! s:process_date(placeholders, default_date)
+ if !empty(a:placeholders)
+ for [placeholder, row, idx] in a:placeholders
+ let [type, param] = placeholder
+ if type ==# 'date' && !empty(param)
+ return param
+ endif
+ endfor
+ endif
+ return a:default_date
+endfunction
+
+
+function! s:process_title(placeholders, default_title)
+ if !empty(a:placeholders)
+ for [placeholder, row, idx] in a:placeholders
+ let [type, param] = placeholder
+ if type ==# 'title' && !empty(param)
+ return param
+ endif
+ endfor
+ endif
+ return a:default_title
+endfunction
+
+
+function! s:is_html_uptodate(wikifile)
+ let tpl_time = -1
+
+ let tpl_file = s:template_full_name('')
+ if tpl_file != ''
+ let tpl_time = getftime(tpl_file)
+ endif
+
+ let wikifile = fnamemodify(a:wikifile, ":p")
+ let htmlfile = expand(vimwiki#vars#get_wikilocal('path_html') .
+ \ vimwiki#vars#get_bufferlocal('subdir') . fnamemodify(wikifile, ":t:r").".html")
+
+ if getftime(wikifile) <= getftime(htmlfile) && tpl_time <= getftime(htmlfile)
+ return 1
+ endif
+ return 0
+endfunction
+
+
+function! s:html_insert_contents(html_lines, content)
+ let lines = []
+ for line in a:html_lines
+ if line =~# '%content%'
+ let parts = split(line, '%content%', 1)
+ if empty(parts)
+ call extend(lines, a:content)
+ else
+ for idx in range(len(parts))
+ call add(lines, parts[idx])
+ if idx < len(parts) - 1
+ call extend(lines, a:content)
+ endif
+ endfor
+ endif
+ else
+ call add(lines, line)
+ endif
+ endfor
+ return lines
+endfunction
+
+
+function! s:tag_eqin(value)
+ " mathJAX wants \( \) for inline maths
+ return '\('.s:mid(a:value, 1).'\)'
+endfunction
+
+
+function! s:tag_em(value)
+ return '<em>'.s:mid(a:value, 1).'</em>'
+endfunction
+
+
+function! s:tag_strong(value, header_ids)
+ let text = s:mid(a:value, 1)
+ let id = s:escape_html_attribute(text)
+ let complete_id = ''
+ for l in range(6)
+ if a:header_ids[l][0] != ''
+ let complete_id .= a:header_ids[l][0].'-'
+ endif
+ endfor
+ if a:header_ids[5][0] == ''
+ let complete_id = complete_id[:-2]
+ endif
+ let complete_id .= '-'.id
+ return '<span id="'.s:escape_html_attribute(complete_id).'"></span><strong id="'
+ \ .id.'">'.text.'</strong>'
+endfunction
+
+
+function! s:tag_tags(value, header_ids)
+ let complete_id = ''
+ for level in range(6)
+ if a:header_ids[level][0] != ''
+ let complete_id .= a:header_ids[level][0].'-'
+ endif
+ endfor
+ if a:header_ids[5][0] == ''
+ let complete_id = complete_id[:-2]
+ endif
+ let complete_id = s:escape_html_attribute(complete_id)
+
+ let result = []
+ for tag in split(a:value, ':')
+ let id = s:escape_html_attribute(tag)
+ call add(result, '<span id="'.complete_id.'-'.id.'"></span><span class="tag" id="'
+ \ .id.'">'.tag.'</span>')
+ endfor
+ return join(result)
+endfunction
+
+
+function! s:tag_todo(value)
+ return '<span class="todo">'.a:value.'</span>'
+endfunction
+
+
+function! s:tag_strike(value)
+ return '<del>'.s:mid(a:value, 2).'</del>'
+endfunction
+
+
+function! s:tag_super(value)
+ return '<sup><small>'.s:mid(a:value, 1).'</small></sup>'
+endfunction
+
+
+function! s:tag_sub(value)
+ return '<sub><small>'.s:mid(a:value, 2).'</small></sub>'
+endfunction
+
+
+function! s:tag_code(value)
+ return '<code>'.s:safe_html_preformatted(s:mid(a:value, 1)).'</code>'
+endfunction
+
+
+" match n-th ARG within {{URL[|ARG1|ARG2|...]}}
+" *c,d,e),...
+function! s:incl_match_arg(nn_index)
+ let rx = vimwiki#vars#get_global('rxWikiInclPrefix'). vimwiki#vars#get_global('rxWikiInclUrl')
+ let rx = rx . repeat(vimwiki#vars#get_global('rxWikiInclSeparator') .
+ \ vimwiki#vars#get_global('rxWikiInclArg'), a:nn_index-1)
+ if a:nn_index > 0
+ let rx = rx. vimwiki#vars#get_global('rxWikiInclSeparator'). '\zs' .
+ \ vimwiki#vars#get_global('rxWikiInclArg') . '\ze'
+ endif
+ let rx = rx . vimwiki#vars#get_global('rxWikiInclArgs') .
+ \ vimwiki#vars#get_global('rxWikiInclSuffix')
+ return rx
+endfunction
+
+
+function! s:linkify_link(src, descr)
+ let src_str = ' href="'.s:escape_html_attribute(a:src).'"'
+ let descr = vimwiki#u#trim(a:descr)
+ let descr = (descr == "" ? a:src : descr)
+ let descr_str = (descr =~# vimwiki#vars#get_global('rxWikiIncl')
+ \ ? s:tag_wikiincl(descr)
+ \ : descr)
+ return '<a'.src_str.'>'.descr_str.'</a>'
+endfunction
+
+
+function! s:linkify_image(src, descr, verbatim_str)
+ let src_str = ' src="'.a:src.'"'
+ let descr_str = (a:descr != '' ? ' alt="'.a:descr.'"' : '')
+ let verbatim_str = (a:verbatim_str != '' ? ' '.a:verbatim_str : '')
+ return '<img'.src_str.descr_str.verbatim_str.' />'
+endfunction
+
+
+function! s:tag_weblink(value)
+ " Weblink Template -> <a href="url">descr</a>
+ let str = a:value
+ let url = matchstr(str, vimwiki#vars#get_syntaxlocal('rxWeblinkMatchUrl'))
+ let descr = matchstr(str, vimwiki#vars#get_syntaxlocal('rxWeblinkMatchDescr'))
+ let line = s:linkify_link(url, descr)
+ return line
+endfunction
+
+
+function! s:tag_wikiincl(value)
+ " {{imgurl|arg1|arg2}} -> ???
+ " {{imgurl}} -> <img src="imgurl"/>
+ " {{imgurl|descr|style="A"}} -> <img src="imgurl" alt="descr" style="A" />
+ " {{imgurl|descr|class="B"}} -> <img src="imgurl" alt="descr" class="B" />
+ let str = a:value
+ " custom transclusions
+ let line = VimwikiWikiIncludeHandler(str)
+ " otherwise, assume image transclusion
+ if line == ''
+ let url_0 = matchstr(str, vimwiki#vars#get_global('rxWikiInclMatchUrl'))
+ let descr = matchstr(str, s:incl_match_arg(1))
+ let verbatim_str = matchstr(str, s:incl_match_arg(2))
+
+ let link_infos = vimwiki#base#resolve_link(url_0)
+
+ if link_infos.scheme =~# '\mlocal\|wiki\d\+\|diary'
+ let url = vimwiki#path#relpath(fnamemodify(s:current_html_file, ':h'), link_infos.filename)
+ " strip the .html extension when we have wiki links, so that the user can
+ " simply write {{image.png}} to include an image from the wiki directory
+ if link_infos.scheme =~# '\mwiki\d\+\|diary'
+ let url = fnamemodify(url, ':r')
+ endif
+ else
+ let url = link_infos.filename
+ endif
+
+ let url = escape(url, '#')
+ let line = s:linkify_image(url, descr, verbatim_str)
+ endif
+ return line
+endfunction
+
+
+function! s:tag_wikilink(value)
+ " [[url]] -> <a href="url.html">url</a>
+ " [[url|descr]] -> <a href="url.html">descr</a>
+ " [[url|{{...}}]] -> <a href="url.html"> ... </a>
+ " [[fileurl.ext|descr]] -> <a href="fileurl.ext">descr</a>
+ " [[dirurl/|descr]] -> <a href="dirurl/index.html">descr</a>
+ " [[url#a1#a2]] -> <a href="url.html#a1-a2">url#a1#a2</a>
+ " [[#a1#a2]] -> <a href="#a1-a2">#a1#a2</a>
+ let str = a:value
+ let url = matchstr(str, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'))
+ let descr = matchstr(str, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr'))
+ let descr = vimwiki#u#trim(descr)
+ let descr = (descr != '' ? descr : url)
+
+ let line = VimwikiLinkConverter(url, s:current_wiki_file, s:current_html_file)
+ if line == ''
+ let link_infos = vimwiki#base#resolve_link(url, s:current_wiki_file)
+
+ if link_infos.scheme ==# 'file'
+ " external file links are always absolute
+ let html_link = link_infos.filename
+ elseif link_infos.scheme ==# 'local'
+ let html_link = vimwiki#path#relpath(fnamemodify(s:current_html_file, ':h'),
+ \ link_infos.filename)
+ elseif link_infos.scheme =~# '\mwiki\d\+\|diary'
+ " wiki links are always relative to the current file
+ let html_link = vimwiki#path#relpath(
+ \ fnamemodify(s:current_wiki_file, ':h'),
+ \ fnamemodify(link_infos.filename, ':r'))
+ if html_link !~ '\m/$'
+ let html_link .= '.html'
+ endif
+ else " other schemes, like http, are left untouched
+ let html_link = link_infos.filename
+ endif
+
+ if link_infos.anchor != ''
+ let anchor = substitute(link_infos.anchor, '#', '-', 'g')
+ let html_link .= '#'.anchor
+ endif
+ let line = html_link
+ endif
+
+ let line = s:linkify_link(line, descr)
+ return line
+endfunction
+
+
+function! s:tag_remove_internal_link(value)
+ let value = s:mid(a:value, 2)
+
+ let line = ''
+ if value =~# '|'
+ let link_parts = split(value, "|", 1)
+ else
+ let link_parts = split(value, "][", 1)
+ endif
+
+ if len(link_parts) > 1
+ if len(link_parts) < 3
+ let style = ""
+ else
+ let style = link_parts[2]
+ endif
+ let line = link_parts[1]
+ else
+ let line = value
+ endif
+ return line
+endfunction
+
+
+function! s:tag_remove_external_link(value)
+ let value = s:mid(a:value, 1)
+
+ let line = ''
+ if s:is_web_link(value)
+ let lnkElements = split(value)
+ let head = lnkElements[0]
+ let rest = join(lnkElements[1:])
+ if rest == ""
+ let rest = head
+ endif
+ let line = rest
+ elseif s:is_img_link(value)
+ let line = '<img src="'.value.'" />'
+ else
+ " [alskfj sfsf] shouldn't be a link. So return it as it was --
+ " enclosed in [...]
+ let line = '['.value.']'
+ endif
+ return line
+endfunction
+
+
+function! s:make_tag(line, regexp, func, ...)
+ " Make tags for a given matched regexp.
+ " Exclude preformatted text and href links.
+ " FIXME
+ let patt_splitter = '\(`[^`]\+`\)\|'.
+ \ '\('.vimwiki#vars#get_syntaxlocal('rxPreStart').'.\+'.
+ \ vimwiki#vars#get_syntaxlocal('rxPreEnd').'\)\|'.
+ \ '\(<a href.\{-}</a>\)\|'.
+ \ '\(<img src.\{-}/>\)\|'.
+ \ '\(<pre.\{-}</pre>\)\|'.
+ \ '\('.vimwiki#vars#get_syntaxlocal('rxEqIn').'\)'
+
+ "FIXME FIXME !!! these can easily occur on the same line!
+ "XXX {{{ }}} ??? obsolete
+ if '`[^`]\+`' ==# a:regexp || '{{{.\+}}}' ==# a:regexp ||
+ \ vimwiki#vars#get_syntaxlocal('rxEqIn') ==# a:regexp
+ let res_line = s:subst_func(a:line, a:regexp, a:func)
+ else
+ let pos = 0
+ " split line with patt_splitter to have parts of line before and after
+ " href links, preformatted text
+ " ie:
+ " hello world `is just a` simple <a href="link.html">type of</a> prg.
+ " result:
+ " ['hello world ', ' simple ', 'type of', ' prg']
+ let lines = split(a:line, patt_splitter, 1)
+ let res_line = ""
+ for line in lines
+ if a:0
+ let res_line = res_line.s:subst_func(line, a:regexp, a:func, a:1)
+ else
+ let res_line = res_line.s:subst_func(line, a:regexp, a:func)
+ endif
+ let res_line = res_line.matchstr(a:line, patt_splitter, pos)
+ let pos = matchend(a:line, patt_splitter, pos)
+ endfor
+ endif
+ return res_line
+endfunction
+
+
+function! s:process_tags_remove_links(line)
+ let line = a:line
+ let line = s:make_tag(line, '\[\[.\{-}\]\]', 's:tag_remove_internal_link')
+ let line = s:make_tag(line, '\[.\{-}\]', 's:tag_remove_external_link')
+ return line
+endfunction
+
+
+function! s:process_tags_typefaces(line, header_ids)
+ let line = a:line
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxItalic'), 's:tag_em')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxBold'), 's:tag_strong', a:header_ids)
+ let line = s:make_tag(line, vimwiki#vars#get_global('rxTodo'), 's:tag_todo')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxDelText'), 's:tag_strike')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxSuperScript'), 's:tag_super')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxSubScript'), 's:tag_sub')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxCode'), 's:tag_code')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxEqIn'), 's:tag_eqin')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxTags'), 's:tag_tags', a:header_ids)
+ return line
+endfunction
+
+
+function! s:process_tags_links(line)
+ let line = a:line
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxWikiLink'), 's:tag_wikilink')
+ let line = s:make_tag(line, vimwiki#vars#get_global('rxWikiIncl'), 's:tag_wikiincl')
+ let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxWeblink'), 's:tag_weblink')
+ return line
+endfunction
+
+
+function! s:process_inline_tags(line, header_ids)
+ let line = s:process_tags_links(a:line)
+ let line = s:process_tags_typefaces(line, a:header_ids)
+ return line
+endfunction
+
+
+function! s:close_tag_pre(pre, ldest)
+ if a:pre[0]
+ call insert(a:ldest, "</pre>")
+ return 0
+ endif
+ return a:pre
+endfunction
+
+
+function! s:close_tag_math(math, ldest)
+ if a:math[0]
+ call insert(a:ldest, "\\\]")
+ return 0
+ endif
+ return a:math
+endfunction
+
+
+function! s:close_tag_quote(quote, ldest)
+ if a:quote
+ call insert(a:ldest, "</blockquote>")
+ return 0
+ endif
+ return a:quote
+endfunction
+
+
+function! s:close_tag_para(para, ldest)
+ if a:para
+ call insert(a:ldest, "</p>")
+ return 0
+ endif
+ return a:para
+endfunction
+
+
+function! s:close_tag_table(table, ldest, header_ids)
+ " The first element of table list is a string which tells us if table should be centered.
+ " The rest elements are rows which are lists of columns:
+ " ['center',
+ " [ CELL1, CELL2, CELL3 ],
+ " [ CELL1, CELL2, CELL3 ],
+ " [ CELL1, CELL2, CELL3 ],
+ " ]
+ " And CELLx is: { 'body': 'col_x', 'rowspan': r, 'colspan': c }
+
+ function! s:sum_rowspan(table)
+ let table = a:table
+
+ " Get max cells
+ let max_cells = 0
+ for row in table[1:]
+ let n_cells = len(row)
+ if n_cells > max_cells
+ let max_cells = n_cells
+ end
+ endfor
+
+ " Sum rowspan
+ for cell_idx in range(max_cells)
+ let rows = 1
+
+ for row_idx in range(len(table)-1, 1, -1)
+ if cell_idx >= len(table[row_idx])
+ let rows = 1
+ continue
+ endif
+
+ if table[row_idx][cell_idx].rowspan == 0
+ let rows += 1
+ else " table[row_idx][cell_idx].rowspan == 1
+ let table[row_idx][cell_idx].rowspan = rows
+ let rows = 1
+ endif
+ endfor
+ endfor
+ endfunction
+
+ function! s:sum_colspan(table)
+ for row in a:table[1:]
+ let cols = 1
+
+ for cell_idx in range(len(row)-1, 0, -1)
+ if row[cell_idx].colspan == 0
+ let cols += 1
+ else "row[cell_idx].colspan == 1
+ let row[cell_idx].colspan = cols
+ let cols = 1
+ endif
+ endfor
+ endfor
+ endfunction
+
+ function! s:close_tag_row(row, header, ldest, header_ids)
+ call add(a:ldest, '<tr>')
+
+ " Set tag element of columns
+ if a:header
+ let tag_name = 'th'
+ else
+ let tag_name = 'td'
+ end
+
+ " Close tag of columns
+ for cell in a:row
+ if cell.rowspan == 0 || cell.colspan == 0
+ continue
+ endif
+
+ if cell.rowspan > 1
+ let rowspan_attr = ' rowspan="' . cell.rowspan . '"'
+ else "cell.rowspan == 1
+ let rowspan_attr = ''
+ endif
+ if cell.colspan > 1
+ let colspan_attr = ' colspan="' . cell.colspan . '"'
+ else "cell.colspan == 1
+ let colspan_attr = ''
+ endif
+
+ call add(a:ldest, '<' . tag_name . rowspan_attr . colspan_attr .'>')
+ call add(a:ldest, s:process_inline_tags(cell.body, a:header_ids))
+ call add(a:ldest, '</'. tag_name . '>')
+ endfor
+
+ call add(a:ldest, '</tr>')
+ endfunction
+
+ let table = a:table
+ let ldest = a:ldest
+ if len(table)
+ call s:sum_rowspan(table)
+ call s:sum_colspan(table)
+
+ if table[0] ==# 'center'
+ call add(ldest, "<table class='center'>")
+ else
+ call add(ldest, "<table>")
+ endif
+
+ " Empty lists are table separators.
+ " Search for the last empty list. All the above rows would be a table header.
+ " We should exclude the first element of the table list as it is a text tag
+ " that shows if table should be centered or not.
+ let head = 0
+ for idx in range(len(table)-1, 1, -1)
+ if empty(table[idx])
+ let head = idx
+ break
+ endif
+ endfor
+ if head > 0
+ for row in table[1 : head-1]
+ if !empty(filter(row, '!empty(v:val)'))
+ call s:close_tag_row(row, 1, ldest, a:header_ids)
+ endif
+ endfor
+ for row in table[head+1 :]
+ call s:close_tag_row(row, 0, ldest, a:header_ids)
+ endfor
+ else
+ for row in table[1 :]
+ call s:close_tag_row(row, 0, ldest, a:header_ids)
+ endfor
+ endif
+ call add(ldest, "</table>")
+ let table = []
+ endif
+ return table
+endfunction
+
+
+function! s:close_tag_list(lists, ldest)
+ while len(a:lists)
+ let item = remove(a:lists, 0)
+ call insert(a:ldest, item[0])
+ endwhile
+endfunction
+
+
+function! s:close_tag_def_list(deflist, ldest)
+ if a:deflist
+ call insert(a:ldest, "</dl>")
+ return 0
+ endif
+ return a:deflist
+endfunction
+
+
+function! s:process_tag_pre(line, pre)
+ " pre is the list of [is_in_pre, indent_of_pre]
+ "XXX always outputs a single line or empty list!
+ let lines = []
+ let pre = a:pre
+ let processed = 0
+ "XXX huh?
+ "if !pre[0] && a:line =~# '^\s*{{{[^\(}}}\)]*\s*$'
+ if !pre[0] && a:line =~# '^\s*{{{'
+ let class = matchstr(a:line, '{{{\zs.*$')
+ "FIXME class cannot contain arbitrary strings
+ let class = substitute(class, '\s\+$', '', 'g')
+ if class != ""
+ call add(lines, "<pre ".class.">")
+ else
+ call add(lines, "<pre>")
+ endif
+ let pre = [1, len(matchstr(a:line, '^\s*\ze{{{'))]
+ let processed = 1
+ elseif pre[0] && a:line =~# '^\s*}}}\s*$'
+ let pre = [0, 0]
+ call add(lines, "</pre>")
+ let processed = 1
+ elseif pre[0]
+ let processed = 1
+ "XXX destroys indent in general!
+ "call add(lines, substitute(a:line, '^\s\{'.pre[1].'}', '', ''))
+ call add(lines, s:safe_html_preformatted(a:line))
+ endif
+ return [processed, lines, pre]
+endfunction
+
+
+function! s:process_tag_math(line, math)
+ " math is the list of [is_in_math, indent_of_math]
+ let lines = []
+ let math = a:math
+ let processed = 0
+ if !math[0] && a:line =~# '^\s*{{\$[^\(}}$\)]*\s*$'
+ let class = matchstr(a:line, '{{$\zs.*$')
+ "FIXME class cannot be any string!
+ let class = substitute(class, '\s\+$', '', 'g')
+ " store the environment name in a global variable in order to close the
+ " environment properly
+ let s:current_math_env = matchstr(class, '^%\zs\S\+\ze%')
+ if s:current_math_env != ""
+ call add(lines, substitute(class, '^%\(\S\+\)%', '\\begin{\1}', ''))
+ elseif class != ""
+ call add(lines, "\\\[".class)
+ else
+ call add(lines, "\\\[")
+ endif
+ let math = [1, len(matchstr(a:line, '^\s*\ze{{\$'))]
+ let processed = 1
+ elseif math[0] && a:line =~# '^\s*}}\$\s*$'
+ let math = [0, 0]
+ if s:current_math_env != ""
+ call add(lines, "\\end{".s:current_math_env."}")
+ else
+ call add(lines, "\\\]")
+ endif
+ let processed = 1
+ elseif math[0]
+ let processed = 1
+ call add(lines, substitute(a:line, '^\s\{'.math[1].'}', '', ''))
+ endif
+ return [processed, lines, math]
+endfunction
+
+
+function! s:process_tag_quote(line, quote)
+ let lines = []
+ let quote = a:quote
+ let processed = 0
+ if a:line =~# '^\s\{4,}\S'
+ if !quote
+ call add(lines, "<blockquote>")
+ let quote = 1
+ endif
+ let processed = 1
+ call add(lines, substitute(a:line, '^\s*', '', ''))
+ elseif quote
+ call add(lines, "</blockquote>")
+ let quote = 0
+ endif
+ return [processed, lines, quote]
+endfunction
+
+
+function! s:process_tag_list(line, lists)
+
+ function! s:add_checkbox(line, rx_list)
+ let st_tag = '<li>'
+ let chk = matchlist(a:line, a:rx_list)
+ if !empty(chk) && len(chk[1]) > 0
+ let completion = index(vimwiki#vars#get_syntaxlocal('listsyms_list'), chk[1])
+ let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list'))
+ if completion == 0
+ let st_tag = '<li class="done0">'
+ elseif completion == -1 && chk[1] == vimwiki#vars#get_global('listsym_rejected')
+ let st_tag = '<li class="rejected">'
+ elseif completion > 0 && completion < n
+ let completion = float2nr(round(completion / (n-1.0) * 3.0 + 0.5 ))
+ let st_tag = '<li class="done'.completion.'">'
+ endif
+ endif
+ return [st_tag, '']
+ endfunction
+
+
+ let in_list = (len(a:lists) > 0)
+
+ " If it is not list yet then do not process line that starts from *bold*
+ " text.
+ " XXX necessary? in *bold* text, no space must follow the first *
+ if !in_list
+ let pos = match(a:line, '^\s*'.vimwiki#vars#get_syntaxlocal('rxBold'))
+ if pos != -1
+ return [0, []]
+ endif
+ endif
+
+ let lines = []
+ let processed = 0
+
+ if a:line =~# '^\s*'.s:bullets.'\s'
+ let lstSym = matchstr(a:line, s:bullets)
+ let lstTagOpen = '<ul>'
+ let lstTagClose = '</ul>'
+ let lstRegExp = '^\s*'.s:bullets.'\s'
+ elseif a:line =~# '^\s*'.s:numbers.'\s'
+ let lstSym = matchstr(a:line, s:numbers)
+ let lstTagOpen = '<ol>'
+ let lstTagClose = '</ol>'
+ let lstRegExp = '^\s*'.s:numbers.'\s'
+ else
+ let lstSym = ''
+ let lstTagOpen = ''
+ let lstTagClose = ''
+ let lstRegExp = ''
+ endif
+
+ if lstSym != ''
+ " To get proper indent level 'retab' the line -- change all tabs
+ " to spaces*tabstop
+ let line = substitute(a:line, '\t', repeat(' ', &tabstop), 'g')
+ let indent = stridx(line, lstSym)
+
+ let checkbox = '\s*\[\(.\)\]\s*'
+ let [st_tag, en_tag] = s:add_checkbox(line, lstRegExp.checkbox)
+
+ if !in_list
+ call add(a:lists, [lstTagClose, indent])
+ call add(lines, lstTagOpen)
+ elseif (in_list && indent > a:lists[-1][1])
+ let item = remove(a:lists, -1)
+ call add(lines, item[0])
+
+ call add(a:lists, [lstTagClose, indent])
+ call add(lines, lstTagOpen)
+ elseif (in_list && indent < a:lists[-1][1])
+ while len(a:lists) && indent < a:lists[-1][1]
+ let item = remove(a:lists, -1)
+ call add(lines, item[0])
+ endwhile
+ elseif in_list
+ let item = remove(a:lists, -1)
+ call add(lines, item[0])
+ endif
+
+ call add(a:lists, [en_tag, indent])
+ call add(lines, st_tag)
+ call add(lines, substitute(a:line, lstRegExp.'\%('.checkbox.'\)\?', '', ''))
+ let processed = 1
+ elseif in_list && a:line =~# '^\s\+\S\+'
+ if vimwiki#vars#get_global('list_ignore_newline')
+ call add(lines, a:line)
+ else
+ call add(lines, '<br />'.a:line)
+ endif
+ let processed = 1
+ else
+ call s:close_tag_list(a:lists, lines)
+ endif
+ return [processed, lines]
+endfunction
+
+
+function! s:process_tag_def_list(line, deflist)
+ let lines = []
+ let deflist = a:deflist
+ let processed = 0
+ let matches = matchlist(a:line, '\(^.*\)::\%(\s\|$\)\(.*\)')
+ if !deflist && len(matches) > 0
+ call add(lines, "<dl>")
+ let deflist = 1
+ endif
+ if deflist && len(matches) > 0
+ if matches[1] != ''
+ call add(lines, "<dt>".matches[1]."</dt>")
+ endif
+ if matches[2] != ''
+ call add(lines, "<dd>".matches[2]."</dd>")
+ endif
+ let processed = 1
+ elseif deflist
+ let deflist = 0
+ call add(lines, "</dl>")
+ endif
+ return [processed, lines, deflist]
+endfunction
+
+
+function! s:process_tag_para(line, para)
+ let lines = []
+ let para = a:para
+ let processed = 0
+ if a:line =~# '^\s\{,3}\S'
+ if !para
+ call add(lines, "<p>")
+ let para = 1
+ endif
+ let processed = 1
+ if vimwiki#vars#get_global('text_ignore_newline')
+ call add(lines, a:line)
+ else
+ call add(lines, a:line."<br />")
+ endif
+ elseif para && a:line =~# '^\s*$'
+ call add(lines, "</p>")
+ let para = 0
+ endif
+ return [processed, lines, para]
+endfunction
+
+
+function! s:process_tag_h(line, id)
+ let line = a:line
+ let processed = 0
+ let h_level = 0
+ let h_text = ''
+ let h_id = ''
+
+ if a:line =~# vimwiki#vars#get_syntaxlocal('rxHeader')
+ let h_level = vimwiki#u#count_first_sym(a:line)
+ endif
+ if h_level > 0
+
+ let h_text = vimwiki#u#trim(matchstr(line, vimwiki#vars#get_syntaxlocal('rxHeader')))
+ let h_number = ''
+ let h_complete_id = ''
+ let h_id = s:escape_html_attribute(h_text)
+ let centered = (a:line =~# '^\s')
+
+ if h_text !=# vimwiki#vars#get_global('toc_header')
+
+ let a:id[h_level-1] = [h_text, a:id[h_level-1][1]+1]
+
+ " reset higher level ids
+ for level in range(h_level, 5)
+ let a:id[level] = ['', 0]
+ endfor
+
+ for l in range(h_level-1)
+ let h_number .= a:id[l][1].'.'
+ if a:id[l][0] != ''
+ let h_complete_id .= a:id[l][0].'-'
+ endif
+ endfor
+ let h_number .= a:id[h_level-1][1]
+ let h_complete_id .= a:id[h_level-1][0]
+
+ if vimwiki#vars#get_global('html_header_numbering')
+ let num = matchstr(h_number,
+ \ '^\(\d.\)\{'.(vimwiki#vars#get_global('html_header_numbering')-1).'}\zs.*')
+ if !empty(num)
+ let num .= vimwiki#vars#get_global('html_header_numbering_sym')
+ endif
+ let h_text = num.' '.h_text
+ endif
+ let h_complete_id = s:escape_html_attribute(h_complete_id)
+ let h_part = '<div id="'.h_complete_id.'">'
+ let h_part .= '<h'.h_level.' id="'.h_id.'" class="header">'
+ let h_part .= '<a href="#'.h_complete_id.'"'
+
+ else
+
+ let h_part = '<div id="'.h_id.'" class="toc"><h1 id="'.h_id.'"'
+
+ endif
+
+ if centered
+ let h_part .= ' class="justcenter">'
+ else
+ let h_part .= '>'
+ endif
+
+ let h_text = s:process_inline_tags(h_text, a:id)
+
+ let line = h_part.h_text.'</a></h'.h_level.'></div>'
+
+ let processed = 1
+ endif
+ return [processed, line]
+endfunction
+
+
+function! s:process_tag_hr(line)
+ let line = a:line
+ let processed = 0
+ if a:line =~# '^-----*$'
+ let line = '<hr />'
+ let processed = 1
+ endif
+ return [processed, line]
+endfunction
+
+
+function! s:process_tag_table(line, table, header_ids)
+ function! s:table_empty_cell(value)
+ let cell = {}
+
+ if a:value =~# '^\s*\\/\s*$'
+ let cell.body = ''
+ let cell.rowspan = 0
+ let cell.colspan = 1
+ elseif a:value =~# '^\s*>\s*$'
+ let cell.body = ''
+ let cell.rowspan = 1
+ let cell.colspan = 0
+ elseif a:value =~# '^\s*$'
+ let cell.body = ' '
+ let cell.rowspan = 1
+ let cell.colspan = 1
+ else
+ let cell.body = a:value
+ let cell.rowspan = 1
+ let cell.colspan = 1
+ endif
+
+ return cell
+ endfunction
+
+ function! s:table_add_row(table, line)
+ if empty(a:table)
+ if a:line =~# '^\s\+'
+ let row = ['center', []]
+ else
+ let row = ['normal', []]
+ endif
+ else
+ let row = [[]]
+ endif
+ return row
+ endfunction
+
+ let table = a:table
+ let lines = []
+ let processed = 0
+
+ if vimwiki#tbl#is_separator(a:line)
+ call extend(table, s:table_add_row(a:table, a:line))
+ let processed = 1
+ elseif vimwiki#tbl#is_table(a:line)
+ call extend(table, s:table_add_row(a:table, a:line))
+
+ let processed = 1
+ " let cells = split(a:line, vimwiki#tbl#cell_splitter(), 1)[1: -2]
+ let cells = vimwiki#tbl#get_cells(a:line)
+ call map(cells, 's:table_empty_cell(v:val)')
+ call extend(table[-1], cells)
+ else
+ let table = s:close_tag_table(table, lines, a:header_ids)
+ endif
+ return [processed, lines, table]
+endfunction
+
+
+function! s:parse_line(line, state)
+ let state = {}
+ let state.para = a:state.para
+ let state.quote = a:state.quote
+ let state.pre = a:state.pre[:]
+ let state.math = a:state.math[:]
+ let state.table = a:state.table[:]
+ let state.lists = a:state.lists[:]
+ let state.deflist = a:state.deflist
+ let state.placeholder = a:state.placeholder
+ let state.header_ids = a:state.header_ids
+
+ let res_lines = []
+
+ let line = s:safe_html_line(a:line)
+
+ let processed = 0
+
+ " pres
+ if !processed
+ let [processed, lines, state.pre] = s:process_tag_pre(line, state.pre)
+ " pre is just fine to be in the list -- do not close list item here.
+ " if processed && len(state.lists)
+ " call s:close_tag_list(state.lists, lines)
+ " endif
+ if !processed
+ let [processed, lines, state.math] = s:process_tag_math(line, state.math)
+ endif
+ if processed && len(state.table)
+ let state.table = s:close_tag_table(state.table, lines, state.header_ids)
+ endif
+ if processed && state.deflist
+ let state.deflist = s:close_tag_def_list(state.deflist, lines)
+ endif
+ if processed && state.quote
+ let state.quote = s:close_tag_quote(state.quote, lines)
+ endif
+ if processed && state.para
+ let state.para = s:close_tag_para(state.para, lines)
+ endif
+ call extend(res_lines, lines)
+ endif
+
+
+ if !processed
+ if line =~# vimwiki#vars#get_syntaxlocal('rxComment')
+ let processed = 1
+ endif
+ endif
+
+ " nohtml -- placeholder
+ if !processed
+ if line =~# '\m^\s*%nohtml\s*$'
+ let processed = 1
+ let state.placeholder = ['nohtml']
+ endif
+ endif
+
+ " title -- placeholder
+ if !processed
+ if line =~# '\m^\s*%title\%(\s.*\)\?$'
+ let processed = 1
+ let param = matchstr(line, '\m^\s*%title\s\+\zs.*')
+ let state.placeholder = ['title', param]
+ endif
+ endif
+
+ " date -- placeholder
+ if !processed
+ if line =~# '\m^\s*%date\%(\s.*\)\?$'
+ let processed = 1
+ let param = matchstr(line, '\m^\s*%date\s\+\zs.*')
+ let state.placeholder = ['date', param]
+ endif
+ endif
+
+ " html template -- placeholder
+ if !processed
+ if line =~# '\m^\s*%template\%(\s.*\)\?$'
+ let processed = 1
+ let param = matchstr(line, '\m^\s*%template\s\+\zs.*')
+ let state.placeholder = ['template', param]
+ endif
+ endif
+
+
+ " tables
+ if !processed
+ let [processed, lines, state.table] = s:process_tag_table(line, state.table, state.header_ids)
+ call extend(res_lines, lines)
+ endif
+
+
+ " lists
+ if !processed
+ let [processed, lines] = s:process_tag_list(line, state.lists)
+ if processed && state.quote
+ let state.quote = s:close_tag_quote(state.quote, lines)
+ endif
+ if processed && state.pre[0]
+ let state.pre = s:close_tag_pre(state.pre, lines)
+ endif
+ if processed && state.math[0]
+ let state.math = s:close_tag_math(state.math, lines)
+ endif
+ if processed && len(state.table)
+ let state.table = s:close_tag_table(state.table, lines, state.header_ids)
+ endif
+ if processed && state.deflist
+ let state.deflist = s:close_tag_def_list(state.deflist, lines)
+ endif
+ if processed && state.para
+ let state.para = s:close_tag_para(state.para, lines)
+ endif
+
+ call map(lines, 's:process_inline_tags(v:val, state.header_ids)')
+
+ call extend(res_lines, lines)
+ endif
+
+
+ " headers
+ if !processed
+ let [processed, line] = s:process_tag_h(line, state.header_ids)
+ if processed
+ call s:close_tag_list(state.lists, res_lines)
+ let state.table = s:close_tag_table(state.table, res_lines, state.header_ids)
+ let state.pre = s:close_tag_pre(state.pre, res_lines)
+ let state.math = s:close_tag_math(state.math, res_lines)
+ let state.quote = s:close_tag_quote(state.quote, res_lines)
+ let state.para = s:close_tag_para(state.para, res_lines)
+
+ call add(res_lines, line)
+ endif
+ endif
+
+
+ " quotes
+ if !processed
+ let [processed, lines, state.quote] = s:process_tag_quote(line, state.quote)
+ if processed && len(state.lists)
+ call s:close_tag_list(state.lists, lines)
+ endif
+ if processed && state.deflist
+ let state.deflist = s:close_tag_def_list(state.deflist, lines)
+ endif
+ if processed && len(state.table)
+ let state.table = s:close_tag_table(state.table, lines, state.header_ids)
+ endif
+ if processed && state.pre[0]
+ let state.pre = s:close_tag_pre(state.pre, lines)
+ endif
+ if processed && state.math[0]
+ let state.math = s:close_tag_math(state.math, lines)
+ endif
+ if processed && state.para
+ let state.para = s:close_tag_para(state.para, lines)
+ endif
+
+ call map(lines, 's:process_inline_tags(v:val, state.header_ids)')
+
+ call extend(res_lines, lines)
+ endif
+
+
+ " horizontal rules
+ if !processed
+ let [processed, line] = s:process_tag_hr(line)
+ if processed
+ call s:close_tag_list(state.lists, res_lines)
+ let state.table = s:close_tag_table(state.table, res_lines, state.header_ids)
+ let state.pre = s:close_tag_pre(state.pre, res_lines)
+ let state.math = s:close_tag_math(state.math, res_lines)
+ call add(res_lines, line)
+ endif
+ endif
+
+
+ " definition lists
+ if !processed
+ let [processed, lines, state.deflist] = s:process_tag_def_list(line, state.deflist)
+
+ call map(lines, 's:process_inline_tags(v:val, state.header_ids)')
+
+ call extend(res_lines, lines)
+ endif
+
+
+ "" P
+ if !processed
+ let [processed, lines, state.para] = s:process_tag_para(line, state.para)
+ if processed && len(state.lists)
+ call s:close_tag_list(state.lists, lines)
+ endif
+ if processed && state.quote
+ let state.quote = s:close_tag_quote(state.quote, res_lines)
+ endif
+ if processed && state.pre[0]
+ let state.pre = s:close_tag_pre(state.pre, res_lines)
+ endif
+ if processed && state.math[0]
+ let state.math = s:close_tag_math(state.math, res_lines)
+ endif
+ if processed && len(state.table)
+ let state.table = s:close_tag_table(state.table, res_lines, state.header_ids)
+ endif
+
+ call map(lines, 's:process_inline_tags(v:val, state.header_ids)')
+
+ call extend(res_lines, lines)
+ endif
+
+
+ "" add the rest
+ if !processed
+ call add(res_lines, line)
+ endif
+
+ return [res_lines, state]
+
+endfunction
+
+
+function! s:use_custom_wiki2html()
+ let custom_wiki2html = vimwiki#vars#get_wikilocal('custom_wiki2html')
+ return !empty(custom_wiki2html) &&
+ \ (s:file_exists(custom_wiki2html) || s:binary_exists(custom_wiki2html))
+endfunction
+
+
+function! vimwiki#html#CustomWiki2HTML(path, wikifile, force)
+ call vimwiki#path#mkdir(a:path)
+ echomsg system(vimwiki#vars#get_wikilocal('custom_wiki2html'). ' '.
+ \ a:force. ' '.
+ \ vimwiki#vars#get_wikilocal('syntax'). ' '.
+ \ strpart(vimwiki#vars#get_wikilocal('ext'), 1). ' '.
+ \ shellescape(a:path). ' '.
+ \ shellescape(a:wikifile). ' '.
+ \ shellescape(s:default_CSS_full_name(a:path)). ' '.
+ \ (len(vimwiki#vars#get_wikilocal('template_path')) > 1 ?
+ \ shellescape(expand(vimwiki#vars#get_wikilocal('template_path'))) : '-'). ' '.
+ \ (len(vimwiki#vars#get_wikilocal('template_default')) > 0 ?
+ \ vimwiki#vars#get_wikilocal('template_default') : '-'). ' '.
+ \ (len(vimwiki#vars#get_wikilocal('template_ext')) > 0 ?
+ \ vimwiki#vars#get_wikilocal('template_ext') : '-'). ' '.
+ \ (len(vimwiki#vars#get_bufferlocal('subdir')) > 0 ?
+ \ shellescape(s:root_path(vimwiki#vars#get_bufferlocal('subdir'))) : '-'). ' '.
+ \ (len(vimwiki#vars#get_wikilocal('custom_wiki2html_args')) > 0 ?
+ \ vimwiki#vars#get_wikilocal('custom_wiki2html_args') : '-'))
+endfunction
+
+
+function! s:convert_file(path_html, wikifile)
+ let done = 0
+
+ let wikifile = fnamemodify(a:wikifile, ":p")
+
+ let path_html = expand(a:path_html).vimwiki#vars#get_bufferlocal('subdir')
+ let htmlfile = fnamemodify(wikifile, ":t:r").'.html'
+
+ " the currently processed file name is needed when processing links
+ " yeah yeah, shame on me for using (quasi-) global variables
+ let s:current_wiki_file = wikifile
+ let s:current_html_file = path_html . htmlfile
+
+ if s:use_custom_wiki2html()
+ let force = 1
+ call vimwiki#html#CustomWiki2HTML(path_html, wikifile, force)
+ let done = 1
+ endif
+
+ if s:syntax_supported() && done == 0
+ let lsource = readfile(wikifile)
+ let ldest = []
+
+ call vimwiki#path#mkdir(path_html)
+
+ " nohtml placeholder -- to skip html generation.
+ let nohtml = 0
+
+ " template placeholder
+ let template_name = ''
+
+ " for table of contents placeholders.
+ let placeholders = []
+
+ " current state of converter
+ let state = {}
+ let state.para = 0
+ let state.quote = 0
+ let state.pre = [0, 0] " [in_pre, indent_pre]
+ let state.math = [0, 0] " [in_math, indent_math]
+ let state.table = []
+ let state.deflist = 0
+ let state.lists = []
+ let state.placeholder = []
+ let state.header_ids = [['', 0], ['', 0], ['', 0], ['', 0], ['', 0], ['', 0]]
+ " [last seen header text in this level, number]
+
+ " prepare constants for s:safe_html_line()
+ let s:lt_pattern = '<'
+ let s:gt_pattern = '>'
+ if vimwiki#vars#get_global('valid_html_tags') != ''
+ let tags = join(split(vimwiki#vars#get_global('valid_html_tags'), '\s*,\s*'), '\|')
+ let s:lt_pattern = '\c<\%(/\?\%('.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?>\)\@!'
+ let s:gt_pattern = '\c\%(</\?\%('.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?\)\@<!>'
+ endif
+
+ " prepare regexps for lists
+ let s:bullets = '[*-]'
+ let s:numbers = '\C\%(#\|\d\+)\|\d\+\.\|[ivxlcdm]\+)\|[IVXLCDM]\+)\|\l\{1,2})\|\u\{1,2})\)'
+
+ for line in lsource
+ let oldquote = state.quote
+ let [lines, state] = s:parse_line(line, state)
+
+ " Hack: There could be a lot of empty strings before s:process_tag_quote
+ " find out `quote` is over. So we should delete them all. Think of the way
+ " to refactor it out.
+ if oldquote != state.quote
+ call s:remove_blank_lines(ldest)
+ endif
+
+ if !empty(state.placeholder)
+ if state.placeholder[0] ==# 'nohtml'
+ let nohtml = 1
+ break
+ elseif state.placeholder[0] ==# 'template'
+ let template_name = state.placeholder[1]
+ else
+ call add(placeholders, [state.placeholder, len(ldest), len(placeholders)])
+ endif
+ let state.placeholder = []
+ endif
+
+ call extend(ldest, lines)
+ endfor
+
+
+ if nohtml
+ echon "\r"."%nohtml placeholder found"
+ return ''
+ endif
+
+ call s:remove_blank_lines(ldest)
+
+ " process end of file
+ " close opened tags if any
+ let lines = []
+ call s:close_tag_quote(state.quote, lines)
+ call s:close_tag_para(state.para, lines)
+ call s:close_tag_pre(state.pre, lines)
+ call s:close_tag_math(state.math, lines)
+ call s:close_tag_list(state.lists, lines)
+ call s:close_tag_def_list(state.deflist, lines)
+ call s:close_tag_table(state.table, lines, state.header_ids)
+ call extend(ldest, lines)
+
+ let title = s:process_title(placeholders, fnamemodify(a:wikifile, ":t:r"))
+ let date = s:process_date(placeholders, strftime('%Y-%m-%d'))
+
+ let html_lines = s:get_html_template(template_name)
+
+ " processing template variables (refactor to a function)
+ call map(html_lines, 'substitute(v:val, "%title%", "'. title .'", "g")')
+ call map(html_lines, 'substitute(v:val, "%date%", "'. date .'", "g")')
+ call map(html_lines, 'substitute(v:val, "%root_path%", "'.
+ \ s:root_path(vimwiki#vars#get_bufferlocal('subdir')) .'", "g")')
+
+ let css_name = expand(vimwiki#vars#get_wikilocal('css_name'))
+ let css_name = substitute(css_name, '\', '/', 'g')
+ call map(html_lines, 'substitute(v:val, "%css%", "'. css_name .'", "g")')
+
+ let enc = &fileencoding
+ if enc == ''
+ let enc = &encoding
+ endif
+ call map(html_lines, 'substitute(v:val, "%encoding%", "'. enc .'", "g")')
+
+ let html_lines = s:html_insert_contents(html_lines, ldest) " %contents%
+
+ call writefile(html_lines, path_html.htmlfile)
+ let done = 1
+
+ endif
+
+ if done == 0
+ echomsg 'Vimwiki Error: Conversion to HTML is not supported for this syntax'
+ return ''
+ endif
+
+ return path_html.htmlfile
+endfunction
+
+
+function! vimwiki#html#Wiki2HTML(path_html, wikifile)
+ let result = s:convert_file(a:path_html, a:wikifile)
+ if result != ''
+ call s:create_default_CSS(a:path_html)
+ endif
+ return result
+endfunction
+
+
+function! vimwiki#html#WikiAll2HTML(path_html)
+ if !s:syntax_supported() && !s:use_custom_wiki2html()
+ echomsg 'Vimwiki Error: Conversion to HTML is not supported for this syntax'
+ return
+ endif
+
+ echomsg 'Vimwiki: Saving Vimwiki files ...'
+ let save_eventignore = &eventignore
+ let &eventignore = "all"
+ try
+ wall
+ catch
+ " just ignore errors
+ endtry
+ let &eventignore = save_eventignore
+
+ let path_html = expand(a:path_html)
+ call vimwiki#path#mkdir(path_html)
+
+ echomsg 'Vimwiki: Deleting non-wiki html files ...'
+ call s:delete_html_files(path_html)
+
+ echomsg 'Vimwiki: Converting wiki to html files ...'
+ let setting_more = &more
+ setlocal nomore
+
+ " temporarily adjust current_subdir global state variable
+ let current_subdir = vimwiki#vars#get_bufferlocal('subdir')
+ let current_invsubdir = vimwiki#vars#get_bufferlocal('invsubdir')
+
+ let wikifiles = split(glob(vimwiki#vars#get_wikilocal('path').'**/*'.
+ \ vimwiki#vars#get_wikilocal('ext')), '\n')
+ for wikifile in wikifiles
+ let wikifile = fnamemodify(wikifile, ":p")
+
+ " temporarily adjust 'subdir' and 'invsubdir' state variables
+ let subdir = vimwiki#base#subdir(vimwiki#vars#get_wikilocal('path'), wikifile)
+ call vimwiki#vars#set_bufferlocal('subdir', subdir)
+ call vimwiki#vars#set_bufferlocal('invsubdir', vimwiki#base#invsubdir(subdir))
+
+ if !s:is_html_uptodate(wikifile)
+ echomsg 'Vimwiki: Processing '.wikifile
+
+ call s:convert_file(path_html, wikifile)
+ else
+ echomsg 'Vimwiki: Skipping '.wikifile
+ endif
+ endfor
+ " reset 'subdir' state variable
+ call vimwiki#vars#set_bufferlocal('subdir', current_subdir)
+ call vimwiki#vars#set_bufferlocal('invsubdir', current_invsubdir)
+
+ let created = s:create_default_CSS(path_html)
+ if created
+ echomsg 'Vimwiki: Default style.css has been created'
+ endif
+ echomsg 'Vimwiki: HTML exported to '.path_html
+ echomsg 'Vimwiki: Done!'
+
+ let &more = setting_more
+endfunction
+
+
+function! s:file_exists(fname)
+ return !empty(getftype(expand(a:fname)))
+endfunction
+
+
+function! s:binary_exists(fname)
+ return executable(expand(a:fname))
+endfunction
+
+
+function! s:get_wikifile_url(wikifile)
+ return vimwiki#vars#get_wikilocal('path_html') .
+ \ vimwiki#base#subdir(vimwiki#vars#get_wikilocal('path'), a:wikifile).
+ \ fnamemodify(a:wikifile, ":t:r").'.html'
+endfunction
+
+
+function! vimwiki#html#PasteUrl(wikifile)
+ execute 'r !echo file://'.s:get_wikifile_url(a:wikifile)
+endfunction
+
+
+function! vimwiki#html#CatUrl(wikifile)
+ execute '!echo file://'.s:get_wikifile_url(a:wikifile)
+endfunction
+
diff --git a/.config/nvim/autoload/vimwiki/lst.vim b/.config/nvim/autoload/vimwiki/lst.vim
@@ -0,0 +1,1697 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Description: Everything concerning lists and checkboxes
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+if exists("g:loaded_vimwiki_list_auto") || &cp
+ finish
+endif
+let g:loaded_vimwiki_list_auto = 1
+
+
+" ---------------------------------------------------------
+" incrementation functions for the various kinds of numbers
+" ---------------------------------------------------------
+
+function! s:increment_1(value)
+ return eval(a:value) + 1
+endfunction
+
+
+function! s:increment_A(value)
+ let list_of_chars = split(a:value, '.\zs')
+ let done = 0
+ for idx in reverse(range(len(list_of_chars)))
+ let cur_num = char2nr(list_of_chars[idx])
+ if cur_num < 90
+ let list_of_chars[idx] = nr2char(cur_num + 1)
+ let done = 1
+ break
+ else
+ let list_of_chars[idx] = 'A'
+ endif
+ endfor
+ if !done
+ call insert(list_of_chars, 'A')
+ endif
+ return join(list_of_chars, '')
+endfunction
+
+
+function! s:increment_a(value)
+ let list_of_chars = split(a:value, '.\zs')
+ let done = 0
+ for idx in reverse(range(len(list_of_chars)))
+ let cur_num = char2nr(list_of_chars[idx])
+ if cur_num < 122
+ let list_of_chars[idx] = nr2char(cur_num + 1)
+ let done = 1
+ break
+ else
+ let list_of_chars[idx] = 'a'
+ endif
+ endfor
+ if !done
+ call insert(list_of_chars, 'a')
+ endif
+ return join(list_of_chars, '')
+endfunction
+
+
+function! s:increment_I(value)
+ let subst_list = [ ['XLVIII$', 'IL'], ['VIII$', 'IX'], ['III$', 'IV'],
+ \ ['DCCCXCIX$', 'CM'], ['CCCXCIX$', 'CD'], ['LXXXIX$', 'XC'],
+ \ ['XXXIX$', 'XL'], ['\(I\{1,2\}\)$', '\1I'], ['CDXCIX$', 'D'],
+ \ ['CMXCIX$', 'M'], ['XCIX$', 'C'], ['I\([VXLCDM]\)$', '\1'],
+ \ ['\([VXLCDM]\)$', '\1I'] ]
+ for [regex, subst] in subst_list
+ if a:value =~# regex
+ return substitute(a:value, regex, subst, '')
+ endif
+ endfor
+ return ''
+endfunction
+
+
+function! s:increment_i(value)
+ let subst_list = [ ['xlviii$', 'il'], ['viii$', 'ix'], ['iii$', 'iv'],
+ \ ['dcccxcix$', 'cm'], ['cccxcix$', 'cd'], ['lxxxix$', 'xc'],
+ \ ['xxxix$', 'xl'], ['\(i\{1,2\}\)$', '\1i'], ['cdxcix$', 'd'],
+ \ ['cmxcix$', 'm'], ['xcix$', 'c'], ['i\([vxlcdm]\)$', '\1'],
+ \ ['\([vxlcdm]\)$', '\1i'] ]
+ for [regex, subst] in subst_list
+ if a:value =~# regex
+ return substitute(a:value, regex, subst, '')
+ endif
+ endfor
+ return ''
+endfunction
+
+
+" ---------------------------------------------------------
+" utility functions
+" ---------------------------------------------------------
+
+function! s:substitute_rx_in_line(lnum, pattern, new_string)
+ call setline(a:lnum, substitute(getline(a:lnum), a:pattern, a:new_string, ''))
+endfunction
+
+
+function! s:substitute_string_in_line(lnum, old_string, new_string)
+ call s:substitute_rx_in_line(a:lnum, vimwiki#u#escape(a:old_string), a:new_string)
+endfunction
+
+
+function! s:first_char(string)
+ return matchstr(a:string, '^.')
+endfunction
+
+
+if exists("*strdisplaywidth")
+ function! s:string_length(str)
+ return strdisplaywidth(a:str)
+ endfunction
+else
+ function! s:string_length(str)
+ return strlen(substitute(a:str, '.', 'x', 'g'))
+ endfunction
+endif
+
+
+function! vimwiki#lst#default_symbol()
+ return vimwiki#vars#get_syntaxlocal('list_markers')[0]
+endfunction
+
+
+function! vimwiki#lst#get_list_margin()
+ let list_margin = vimwiki#vars#get_wikilocal('list_margin')
+ if list_margin < 0
+ return &sw
+ else
+ return list_margin
+ endif
+endfunction
+
+
+"Returns: the column where the text of a line starts (possible list item
+"markers and checkboxes are skipped)
+function! s:text_begin(lnum)
+ return s:string_length(matchstr(getline(a:lnum), vimwiki#vars#get_syntaxlocal('rxListItem')))
+endfunction
+
+
+"Returns: 2 if there is a marker and text
+" 1 for a marker and no text
+" 0 for no marker at all (empty line or only text)
+function! s:line_has_marker(lnum)
+ if getline(a:lnum) =~# vimwiki#vars#get_syntaxlocal('rxListItem').'\s*$'
+ return 1
+ elseif getline(a:lnum) =~# vimwiki#vars#get_syntaxlocal('rxListItem').'\s*\S'
+ return 2
+ else
+ return 0
+ endif
+endfunction
+
+
+" ---------------------------------------------------------
+" get properties of a list item
+" ---------------------------------------------------------
+
+"Returns: the mainly used data structure in this file
+"An item represents a single list item and is a dictionary with the keys
+"lnum - the line number of the list item
+"type - 1 for bulleted item, 2 for numbered item, 0 for a regular line
+"mrkr - the concrete marker, e.g. '**' or 'b)'
+"cb - the char in the checkbox or '' if there is no checkbox
+function! s:get_item(lnum)
+ let item = {'lnum': a:lnum}
+ if a:lnum == 0 || a:lnum > line('$')
+ let item.type = 0
+ return item
+ endif
+
+ let matches = matchlist(getline(a:lnum), vimwiki#vars#get_syntaxlocal('rxListItem'))
+ if matches == [] ||
+ \ (matches[1] == '' && matches[2] == '') ||
+ \ (matches[1] != '' && matches[2] != '')
+ let item.type = 0
+ return item
+ endif
+
+ let item.cb = matches[3]
+
+ if matches[1] != ''
+ let item.type = 1
+ let item.mrkr = matches[1]
+ else
+ let item.type = 2
+ let item.mrkr = matches[2]
+ endif
+
+ return item
+endfunction
+
+
+function! s:empty_item()
+ return {'type': 0}
+endfunction
+
+
+"Returns: level of the line
+"0 is the 'highest' level
+function! s:get_level(lnum)
+ if getline(a:lnum) =~# '^\s*$'
+ return 0
+ endif
+ if !vimwiki#vars#get_syntaxlocal('recurring_bullets')
+ let level = indent(a:lnum)
+ else
+ let level = s:string_length(matchstr(getline(a:lnum),
+ \ vimwiki#vars#get_syntaxlocal(rx_bullet_chars)))-1
+ if level < 0
+ let level = (indent(a:lnum) == 0) ? 0 : 9999
+ endif
+ endif
+ return level
+endfunction
+
+
+"Returns: 1, a, i, A, I or ''
+"If in doubt if alphanumeric character or romanian
+"numeral, peek in the previous line
+function! s:guess_kind_of_numbered_item(item)
+ if a:item.type != 2 | return '' | endif
+ let number_chars = a:item.mrkr[:-2]
+ let divisor = a:item.mrkr[-1:]
+
+ let number_kinds = vimwiki#vars#get_syntaxlocal('number_kinds')
+
+ if number_chars =~# '\d\+'
+ return '1'
+ endif
+ if number_chars =~# '\l\+'
+ if number_chars !~# '^[ivxlcdm]\+' || index(number_kinds, 'i') == -1
+ return 'a'
+ else
+
+ let item_above = s:get_prev_list_item(a:item, 0)
+ if item_above.type != 0
+ if index(number_kinds, 'a') == -1 ||
+ \ (item_above.mrkr[-1:] !=# divisor && number_chars =~# 'i\+') ||
+ \ s:increment_i(item_above.mrkr[:-2]) ==# number_chars
+ return 'i'
+ else
+ return 'a'
+ endif
+ else
+ if number_chars =~# 'i\+' || index(number_kinds, 'a') == -1
+ return 'i'
+ else
+ return 'a'
+ endif
+ endif
+
+ endif
+ endif
+ if number_chars =~# '\u\+'
+ if number_chars !~# '^[IVXLCDM]\+' || index(number_kinds, 'I') == -1
+ return 'A'
+ else
+
+ let item_above = s:get_prev_list_item(a:item, 0)
+ if item_above.type != 0
+ if index(number_kinds, 'A') == -1 ||
+ \ (item_above.mrkr[-1:] !=# divisor && number_chars =~# 'I\+') ||
+ \ s:increment_I(item_above.mrkr[:-2]) ==# number_chars
+ return 'I'
+ else
+ return 'A'
+ endif
+ else
+ if number_chars =~# 'I\+' || index(number_kinds, 'A') == -1
+ return 'I'
+ else
+ return 'A'
+ endif
+ endif
+
+ endif
+ endif
+endfunction
+
+
+function! s:regexp_of_marker(item)
+ if a:item.type == 1
+ return vimwiki#u#escape(a:item.mrkr)
+ elseif a:item.type == 2
+ let number_divisors = vimwiki#vars#get_syntaxlocal('number_divisors')
+ for ki in ['d', 'u', 'l']
+ let match = matchstr(a:item.mrkr, '\'.ki.'\+['.number_divisors.']')
+ if match != ''
+ return '\'.ki.'\+'.vimwiki#u#escape(match[-1:])
+ endif
+ endfor
+ else
+ return ''
+ endif
+endfunction
+
+
+" Returns: Whether or not the checkbox of a list item is [X] or [-]
+function! s:is_closed(item)
+ let state = a:item.cb
+ return state ==# vimwiki#vars#get_syntaxlocal('listsyms_list')[-1]
+ \ || state ==# vimwiki#vars#get_global('listsym_rejected')
+endfunction
+
+" ---------------------------------------------------------
+" functions for navigating between items
+" ---------------------------------------------------------
+
+"Returns: the list item after a:item or an empty item
+"If a:ignore_kind is 1, the markers can differ
+function! s:get_next_list_item(item, ignore_kind)
+ let org_lvl = s:get_level(a:item.lnum)
+ if !a:ignore_kind
+ let org_regex = s:regexp_of_marker(a:item)
+ endif
+
+ let cur_ln = s:get_next_line(a:item.lnum)
+ while cur_ln <= line('$')
+ let cur_lvl = s:get_level(cur_ln)
+ if cur_lvl <= org_lvl
+ if a:ignore_kind
+ return s:get_any_item_of_level(cur_ln, cur_lvl, org_lvl)
+ else
+ return s:get_item_of_level(cur_ln, cur_lvl, org_lvl, org_regex)
+ endif
+ endif
+ let cur_ln = s:get_next_line(cur_ln)
+ endwhile
+ return s:empty_item()
+endfunction
+
+
+"Returns: the list item before a:item or an empty item
+"If a:ignore_kind is 1, the markers can differ
+function! s:get_prev_list_item(item, ignore_kind)
+ let org_lvl = s:get_level(a:item.lnum)
+ if !a:ignore_kind
+ let org_regex = s:regexp_of_marker(a:item)
+ endif
+
+ let cur_ln = s:get_prev_line(a:item.lnum)
+ while cur_ln >= 1
+ let cur_lvl = s:get_level(cur_ln)
+ if cur_lvl <= org_lvl
+ if a:ignore_kind
+ return s:get_any_item_of_level(cur_ln, cur_lvl, org_lvl)
+ else
+ return s:get_item_of_level(cur_ln, cur_lvl, org_lvl, org_regex)
+ endif
+ endif
+ let cur_ln = s:get_prev_line(cur_ln)
+ endwhile
+ return s:empty_item()
+endfunction
+
+
+function! s:get_item_of_level(cur_ln, cur_lvl, org_lvl, org_regex)
+ let cur_linecontent = getline(a:cur_ln)
+ if a:cur_lvl == a:org_lvl
+ if cur_linecontent =~# '^\s*'.a:org_regex.'\s'
+ return s:get_item(a:cur_ln)
+ else
+ return s:empty_item()
+ endif
+ elseif a:cur_lvl < a:org_lvl
+ return s:empty_item()
+ endif
+endfunction
+
+
+function! s:get_any_item_of_level(cur_ln, cur_lvl, org_lvl)
+ if a:cur_lvl == a:org_lvl
+ return s:get_item(a:cur_ln)
+ elseif a:cur_lvl < a:org_lvl
+ return s:empty_item()
+ endif
+endfunction
+
+
+function! s:get_first_item_in_list(item, ignore_kind)
+ let cur_item = a:item
+ while 1
+ let prev_item = s:get_prev_list_item(cur_item, a:ignore_kind)
+ if prev_item.type == 0
+ break
+ else
+ let cur_item = prev_item
+ endif
+ endwhile
+ return cur_item
+endfunction
+
+
+function! s:get_last_item_in_list(item, ignore_kind)
+ let cur_item = a:item
+ while 1
+ let next_item = s:get_next_list_item(cur_item, a:ignore_kind)
+ if next_item.type == 0
+ break
+ else
+ let cur_item = next_item
+ endif
+ endwhile
+ return cur_item
+endfunction
+
+
+"Returns: lnum+1 in most cases, but skips blank lines and preformatted text,
+"0 in case of nonvalid line.
+"If there is no second argument, 0 is returned at a header, otherwise the
+"header is skipped
+function! s:get_next_line(lnum, ...)
+ if getline(a:lnum) =~# vimwiki#vars#get_syntaxlocal('rxPreStart')
+ let cur_ln = a:lnum + 1
+ while cur_ln <= line('$') && getline(cur_ln) !~# vimwiki#vars#get_syntaxlocal('rxPreEnd')
+ let cur_ln += 1
+ endwhile
+ let next_line = cur_ln
+ else
+ let next_line = nextnonblank(a:lnum+1)
+ endif
+
+ if a:0 > 0 && getline(next_line) =~# vimwiki#vars#get_syntaxlocal('rxHeader')
+ let next_line = s:get_next_line(next_line, 1)
+ endif
+
+ if next_line < 0 || next_line > line('$') ||
+ \ (getline(next_line) =~# vimwiki#vars#get_syntaxlocal('rxHeader') && a:0 == 0)
+ return 0
+ endif
+
+ return next_line
+endfunction
+
+
+"Returns: lnum-1 in most cases, but skips blank lines and preformatted text
+"0 in case of nonvalid line and a header, because a header ends every list
+function! s:get_prev_line(lnum)
+ let prev_line = prevnonblank(a:lnum-1)
+
+ if getline(prev_line) =~# vimwiki#vars#get_syntaxlocal('rxPreEnd')
+ let cur_ln = a:lnum - 1
+ while 1
+ if cur_ln == 0 || getline(cur_ln) =~# vimwiki#vars#get_syntaxlocal('rxPreStart')
+ break
+ endif
+ let cur_ln -= 1
+ endwhile
+ let prev_line = cur_ln
+ endif
+
+ if prev_line < 0 || prev_line > line('$') ||
+ \ getline(prev_line) =~# vimwiki#vars#get_syntaxlocal('rxHeader')
+ return 0
+ endif
+
+ return prev_line
+endfunction
+
+
+function! s:get_first_child(item)
+ if a:item.lnum >= line('$')
+ return s:empty_item()
+ endif
+ let org_lvl = s:get_level(a:item.lnum)
+ let cur_item = s:get_item(s:get_next_line(a:item.lnum))
+ while 1
+ if cur_item.type != 0 && s:get_level(cur_item.lnum) > org_lvl
+ return cur_item
+ endif
+ if cur_item.lnum > line('$') || cur_item.lnum <= 0 || s:get_level(cur_item.lnum) <= org_lvl
+ return s:empty_item()
+ endif
+ let cur_item = s:get_item(s:get_next_line(cur_item.lnum))
+ endwhile
+endfunction
+
+
+"Returns: the next sibling of a:child, given the parent item
+"Used for iterating over children
+"Note: child items do not necessarily have the same indent, i.e. level
+function! s:get_next_child_item(parent, child)
+ if a:parent.type == 0 | return s:empty_item() | endif
+ let parent_lvl = s:get_level(a:parent.lnum)
+ let cur_ln = s:get_last_line_of_item_incl_children(a:child)
+ while 1
+ let next_line = s:get_next_line(cur_ln)
+ if next_line == 0 || s:get_level(next_line) <= parent_lvl
+ break
+ endif
+ let cur_ln = next_line
+ let cur_item = s:get_item(cur_ln)
+ if cur_item.type > 0
+ return cur_item
+ endif
+ endwhile
+ return s:empty_item()
+endfunction
+
+
+function! s:get_parent(item)
+ let parent_line = 0
+
+ let cur_ln = prevnonblank(a:item.lnum)
+ let child_lvl = s:get_level(cur_ln)
+ if child_lvl == 0
+ return s:empty_item()
+ endif
+
+ while 1
+ let cur_ln = s:get_prev_line(cur_ln)
+ if cur_ln == 0 | break | endif
+ let cur_lvl = s:get_level(cur_ln)
+ if cur_lvl < child_lvl
+ let cur_item = s:get_item(cur_ln)
+ if cur_item.type == 0
+ let child_lvl = cur_lvl
+ continue
+ endif
+ let parent_line = cur_ln
+ break
+ endif
+ endwhile
+ return s:get_item(parent_line)
+endfunction
+
+
+"Returns: the item above or the item below or an empty item
+function! s:get_a_neighbor_item(item)
+ let prev_item = s:get_prev_list_item(a:item, 1)
+ if prev_item.type != 0
+ return prev_item
+ else
+ let next_item = s:get_next_list_item(a:item, 1)
+ if next_item.type != 0
+ return next_item
+ endif
+ endif
+ return s:empty_item()
+endfunction
+
+
+function! s:get_a_neighbor_item_in_column(lnum, column)
+ let cur_ln = s:get_prev_line(a:lnum)
+ while cur_ln >= 1
+ if s:get_level(cur_ln) <= a:column
+ return s:get_corresponding_item(cur_ln)
+ endif
+ let cur_ln = s:get_prev_line(cur_ln)
+ endwhile
+ return s:empty_item()
+endfunction
+
+
+"Returns: the item if there is one in a:lnum
+"else the multiline item a:lnum belongs to
+function! s:get_corresponding_item(lnum)
+ let item = s:get_item(a:lnum)
+ if item.type != 0
+ return item
+ endif
+ let org_lvl = s:get_level(a:lnum)
+ let cur_ln = a:lnum
+ while cur_ln > 0
+ let cur_lvl = s:get_level(cur_ln)
+ let cur_item = s:get_item(cur_ln)
+ if cur_lvl < org_lvl && cur_item.type != 0
+ return cur_item
+ endif
+ if cur_lvl < org_lvl
+ let org_lvl = cur_lvl
+ endif
+ let cur_ln = s:get_prev_line(cur_ln)
+ endwhile
+ return s:empty_item()
+endfunction
+
+
+"Returns: the last line of a (possibly multiline) item, including all children
+function! s:get_last_line_of_item_incl_children(item)
+ let cur_ln = a:item.lnum
+ let org_lvl = s:get_level(a:item.lnum)
+ while 1
+ let next_line = s:get_next_line(cur_ln)
+ if next_line == 0 || s:get_level(next_line) <= org_lvl
+ return cur_ln
+ endif
+ let cur_ln = next_line
+ endwhile
+endfunction
+
+
+"Returns: the last line of a (possibly multiline) item
+"Note: there can be other list items between the first and last line
+function! s:get_last_line_of_item(item)
+ if a:item.type == 0 | return 0 | endif
+ let org_lvl = s:get_level(a:item.lnum)
+ let last_corresponding_line = a:item.lnum
+
+ let cur_ln = s:get_next_line(a:item.lnum)
+ while 1
+ if cur_ln == 0 || s:get_level(cur_ln) <= org_lvl
+ break
+ endif
+ let cur_item = s:get_item(cur_ln)
+ if cur_item.type == 0
+ let last_corresponding_line = cur_ln
+ let cur_ln = s:get_next_line(cur_ln)
+ else
+ let cur_ln = s:get_next_line(s:get_last_line_of_item_incl_children(cur_item))
+ endif
+ endwhile
+
+ return last_corresponding_line
+endfunction
+
+
+" ---------------------------------------------------------
+" renumber list items
+" ---------------------------------------------------------
+
+"Renumbers the current list from a:item on downwards
+"Returns: the last item that was adjusted
+function! s:adjust_numbered_list_below(item, recursive)
+ if !(a:item.type == 2 || (a:item.type == 1 && a:recursive))
+ return a:item
+ endif
+
+ let kind = s:guess_kind_of_numbered_item(a:item)
+
+ let cur_item = a:item
+ while 1
+ if a:recursive
+ call s:adjust_items_recursively(cur_item)
+ endif
+
+ let next_item = s:get_next_list_item(cur_item, 0)
+ if next_item.type == 0
+ break
+ endif
+
+ if cur_item.type == 2
+ let new_val = s:increment_{kind}(cur_item.mrkr[:-2]) . cur_item.mrkr[-1:]
+ call s:substitute_string_in_line(next_item.lnum, next_item.mrkr, new_val)
+ let next_item.mrkr = new_val
+ endif
+
+ let cur_item = next_item
+ endwhile
+ return cur_item
+endfunction
+
+
+function! s:adjust_items_recursively(parent)
+ if a:parent.type == 0
+ return s:empty_item()
+ end
+
+ let child_item = s:get_first_child(a:parent)
+ if child_item.type == 0
+ return child_item
+ endif
+ while 1
+ let last_item = s:adjust_numbered_list(child_item, 1, 1)
+
+ let child_item = s:get_next_child_item(a:parent, last_item)
+ if child_item.type == 0
+ return last_item
+ endif
+ endwhile
+endfunction
+
+
+"Renumbers the list a:item is in.
+"If a:ignore_kind == 0, only the items which have the same kind of marker as
+"a:item are considered, otherwise all items.
+"Returns: the last item that was adjusted
+function! s:adjust_numbered_list(item, ignore_kind, recursive)
+ if !(a:item.type == 2 || (a:item.type == 1 && (a:ignore_kind || a:recursive)))
+ return s:empty_item()
+ end
+
+ let first_item = s:get_first_item_in_list(a:item, a:ignore_kind)
+
+ while 1
+ if first_item.type == 2
+ let new_mrkr = s:guess_kind_of_numbered_item(first_item) . first_item.mrkr[-1:]
+ call s:substitute_string_in_line(first_item.lnum, first_item.mrkr, new_mrkr)
+ let first_item.mrkr = new_mrkr
+ endif
+
+ let last_item = s:adjust_numbered_list_below(first_item, a:recursive)
+
+ let next_first_item = s:get_next_list_item(last_item, 1)
+ if a:ignore_kind == 0 || next_first_item.type == 0
+ return last_item
+ endif
+ let first_item = next_first_item
+ endwhile
+endfunction
+
+
+"Renumbers the list the cursor is in
+"also update its parents checkbox state
+function! vimwiki#lst#adjust_numbered_list()
+ let cur_item = s:get_corresponding_item(line('.'))
+ if cur_item.type == 0 | return | endif
+ call s:adjust_numbered_list(cur_item, 1, 0)
+ call s:update_state(s:get_parent(cur_item))
+endfunction
+
+
+"Renumbers all lists of the buffer
+"of course, this might take some seconds
+function! vimwiki#lst#adjust_whole_buffer()
+ let cur_ln = 1
+ while 1
+ let cur_item = s:get_item(cur_ln)
+ if cur_item.type != 0
+ let cur_item = s:adjust_numbered_list(cur_item, 0, 1)
+ endif
+ let cur_ln = s:get_next_line(cur_item.lnum, 1)
+ if cur_ln <= 0 || cur_ln > line('$')
+ return
+ endif
+ endwhile
+endfunction
+
+
+" ---------------------------------------------------------
+" checkbox stuff
+" ---------------------------------------------------------
+
+"Returns: the rate of checkboxed list item in percent
+function! s:get_rate(item)
+ if a:item.type == 0 || a:item.cb == ''
+ return -1
+ endif
+ let state = a:item.cb
+ if state == vimwiki#vars#get_global('listsym_rejected')
+ return -1
+ endif
+ let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list'))
+ return index(vimwiki#vars#get_syntaxlocal('listsyms_list'), state) * 100/(n-1)
+endfunction
+
+
+"Set state of the list item to [ ] or [o] or whatever
+"Returns: 1 if the state changed, 0 otherwise
+function! s:set_state(item, new_rate)
+ let new_state = s:rate_to_state(a:new_rate)
+ let old_state = s:rate_to_state(s:get_rate(a:item))
+ if new_state !=# old_state
+ call s:substitute_rx_in_line(a:item.lnum, '\[.]', '['.new_state.']')
+ return 1
+ else
+ return 0
+ endif
+endfunction
+
+
+" Sets the state of the list item to [ ] or [o] or whatever. Updates the states of its child items.
+" If the new state should be [X] or [-], the state of the current list item is changed to this
+" state, but if a child item already has [X] or [-] it is left alone.
+function! s:set_state_plus_children(item, new_rate, ...)
+ let retain_state_if_closed = a:0 > 0 && a:1 > 0
+
+ if !(retain_state_if_closed && (a:new_rate == 100 || a:new_rate == -1) && s:is_closed(a:item))
+ call s:set_state(a:item, a:new_rate)
+ endif
+
+ let all_children_are_done = 1
+ let all_children_are_rejected = 1
+
+ let child_item = s:get_first_child(a:item)
+ while 1
+ if child_item.type == 0
+ break
+ endif
+ if child_item.cb != vimwiki#vars#get_global('listsym_rejected')
+ let all_children_are_rejected = 0
+ endif
+ if child_item.cb != vimwiki#vars#get_syntaxlocal('listsyms_list')[-1]
+ let all_children_are_done = 0
+ endif
+ if !all_children_are_done && !all_children_are_rejected
+ break
+ endif
+ let child_item = s:get_next_child_item(a:item, child_item)
+ endwhile
+
+ if (a:new_rate == 100 && all_children_are_done) ||
+ \ (a:new_rate == -1) && all_children_are_rejected
+ return
+ endif
+
+ if (a:new_rate == -1 && all_children_are_done) ||
+ \ (a:new_rate == 100 && all_children_are_rejected)
+ let retain_closed_children = 0
+ else
+ let retain_closed_children = 1
+ endif
+
+ let child_item = s:get_first_child(a:item)
+ while 1
+ if child_item.type == 0
+ break
+ endif
+ if child_item.cb != ''
+ call s:set_state_plus_children(child_item, a:new_rate, retain_closed_children)
+ endif
+ let child_item = s:get_next_child_item(a:item, child_item)
+ endwhile
+endfunction
+
+
+"Returns: the appropriate symbol for a given percent rate
+function! s:rate_to_state(rate)
+ let listsyms_list = vimwiki#vars#get_syntaxlocal('listsyms_list')
+ let state = ''
+ let n = len(listsyms_list)
+ if a:rate == 100
+ let state = listsyms_list[n-1]
+ elseif a:rate == 0
+ let state = listsyms_list[0]
+ elseif a:rate == -1
+ let state = vimwiki#vars#get_global('listsym_rejected')
+ else
+ let index = float2nr(ceil(a:rate/100.0*(n-2)))
+ let state = listsyms_list[index]
+ endif
+ return state
+endfunction
+
+
+"updates the symbol of a checkboxed item according to the symbols of its
+"children
+function! s:update_state(item)
+ if a:item.type == 0 || a:item.cb == ''
+ return
+ endif
+
+ let sum_children_rate = 0
+ let count_children_with_cb = 0
+ let count_rejected_children = 0
+
+ let child_item = s:get_first_child(a:item)
+
+ while 1
+ if child_item.type == 0
+ break
+ endif
+ if child_item.cb != ''
+ let rate = s:get_rate(child_item)
+ if rate == -1
+ " for calculating the parent rate, a [-] item counts as much as a [X] item ...
+ let rate = 100
+ " ... with the exception that a parent with *only* [-] items will be [-] too
+ let count_rejected_children += 1
+ endif
+ let count_children_with_cb += 1
+ let sum_children_rate += rate
+ endif
+ let child_item = s:get_next_child_item(a:item, child_item)
+ endwhile
+
+ if count_children_with_cb > 0
+ if count_rejected_children == count_children_with_cb
+ let new_rate = -1
+ else
+ let new_rate = sum_children_rate / count_children_with_cb
+ endif
+ call s:set_state_recursively(a:item, new_rate)
+ else
+ let rate = s:get_rate(a:item)
+ if rate > 0 && rate < 100
+ call s:set_state_recursively(a:item, 0)
+ endif
+ endif
+endfunction
+
+
+function! s:set_state_recursively(item, new_rate)
+ let state_changed = s:set_state(a:item, a:new_rate)
+ if state_changed
+ call s:update_state(s:get_parent(a:item))
+ endif
+endfunction
+
+
+"Creates checkbox in a list item.
+"Returns: 1 if successful
+function! s:create_cb(item, start_rate)
+ if a:item.type == 0 || a:item.cb != ''
+ return 0
+ endif
+
+ let new_item = a:item
+ let new_item.cb = s:rate_to_state(a:start_rate)
+ call s:substitute_rx_in_line(new_item.lnum,
+ \ vimwiki#u#escape(new_item.mrkr) . '\zs\ze', ' [' . new_item.cb . ']')
+
+ call s:update_state(new_item)
+ return 1
+endfunction
+
+
+function! s:remove_cb(item)
+ let item = a:item
+ if item.type != 0 && item.cb != ''
+ let item.cb = ''
+ call s:substitute_rx_in_line(item.lnum, '\s\+\[.\]', '')
+ endif
+ return item
+endfunction
+
+
+" Change state of the checkboxes in the lines of the given range
+function! s:change_cb(from_line, to_line, new_rate)
+ let from_item = s:get_corresponding_item(a:from_line)
+ if from_item.type == 0
+ return
+ endif
+
+ let parent_items_of_lines = []
+
+ for cur_ln in range(from_item.lnum, a:to_line)
+ let cur_item = s:get_item(cur_ln)
+ if cur_item.type != 0 && cur_item.cb != ''
+ call s:set_state_plus_children(cur_item, a:new_rate)
+ let cur_parent_item = s:get_parent(cur_item)
+ if index(parent_items_of_lines, cur_parent_item) == -1
+ call insert(parent_items_of_lines, cur_parent_item)
+ endif
+ endif
+ endfor
+
+ for parent_item in parent_items_of_lines
+ call s:update_state(parent_item)
+ endfor
+
+endfunction
+
+
+" Toggles checkbox between two states in the lines of the given range, creates checkboxes (with
+" a:start_rate as state) if there aren't any.
+function! s:toggle_create_cb(from_line, to_line, state1, state2, start_rate)
+ let from_item = s:get_corresponding_item(a:from_line)
+ if from_item.type == 0
+ return
+ endif
+
+ if from_item.cb == ''
+
+ "if from_line has no CB, make a CB in every selected line
+ let parent_items_of_lines = []
+ for cur_ln in range(from_item.lnum, a:to_line)
+ let cur_item = s:get_item(cur_ln)
+ let success = s:create_cb(cur_item, a:start_rate)
+
+ if success
+ let cur_parent_item = s:get_parent(cur_item)
+ if index(parent_items_of_lines, cur_parent_item) == -1
+ call insert(parent_items_of_lines, cur_parent_item)
+ endif
+ endif
+ endfor
+
+ for parent_item in parent_items_of_lines
+ call s:update_state(parent_item)
+ endfor
+
+ else
+
+ "if from_line has CB, toggle it and set all siblings to the same new state
+ let rate_first_line = s:get_rate(from_item)
+ let new_rate = rate_first_line == a:state1 ? a:state2 : a:state1
+
+ call s:change_cb(a:from_line, a:to_line, new_rate)
+
+ endif
+
+endfunction
+
+
+"Decrement checkbox between [ ] and [X]
+"in the lines of the given range
+function! vimwiki#lst#decrement_cb(from_line, to_line)
+ let from_item = s:get_corresponding_item(a:from_line)
+ if from_item.type == 0
+ return
+ endif
+
+ "if from_line has CB, decrement it and set all siblings to the same new state
+ let rate_first_line = s:get_rate(from_item)
+ let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list'))
+ let new_rate = max([rate_first_line - 100/(n-1)-1, 0])
+
+ call s:change_cb(a:from_line, a:to_line, new_rate)
+
+endfunction
+
+
+"Increment checkbox between [ ] and [X]
+"in the lines of the given range
+function! vimwiki#lst#increment_cb(from_line, to_line)
+ let from_item = s:get_corresponding_item(a:from_line)
+ if from_item.type == 0
+ return
+ endif
+
+ "if from_line has CB, increment it and set all siblings to the same new state
+ let rate_first_line = s:get_rate(from_item)
+ let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list'))
+ let new_rate = min([rate_first_line + 100/(n-1)+1, 100])
+
+ call s:change_cb(a:from_line, a:to_line, new_rate)
+
+endfunction
+
+
+"Toggles checkbox between [ ] and [X] or creates one
+"in the lines of the given range
+function! vimwiki#lst#toggle_cb(from_line, to_line)
+ return s:toggle_create_cb(a:from_line, a:to_line, 100, 0, 0)
+endfunction
+
+
+"Toggles checkbox between [ ] and [-] or creates one
+"in the lines of the given range
+function! vimwiki#lst#toggle_rejected_cb(from_line, to_line)
+ return s:toggle_create_cb(a:from_line, a:to_line, -1, 0, -1)
+endfunction
+
+
+function! vimwiki#lst#remove_cb(first_line, last_line)
+ let first_item = s:get_corresponding_item(a:first_line)
+ let last_item = s:get_corresponding_item(a:last_line)
+
+ if first_item.type == 0 || last_item.type == 0
+ return
+ endif
+
+ let parent_items_of_lines = []
+ let cur_ln = first_item.lnum
+ while 1
+ if cur_ln <= 0 || cur_ln > last_item.lnum | break | endif
+ let cur_item = s:get_item(cur_ln)
+ if cur_item.type != 0
+ let cur_item = s:remove_cb(cur_item)
+ let cur_parent_item = s:get_parent(cur_item)
+ if index(parent_items_of_lines, cur_parent_item) == -1
+ call insert(parent_items_of_lines, cur_parent_item)
+ endif
+ endif
+ let cur_ln = s:get_next_line(cur_ln)
+ endwhile
+ for parent_item in parent_items_of_lines
+ call s:update_state(parent_item)
+ endfor
+endfunction
+
+
+function! vimwiki#lst#remove_cb_in_list()
+ let first_item = s:get_first_item_in_list(s:get_corresponding_item(line('.')), 0)
+
+ let cur_item = first_item
+ while 1
+ let next_item = s:get_next_list_item(cur_item, 0)
+ let cur_item = s:remove_cb(cur_item)
+ if next_item.type == 0
+ break
+ else
+ let cur_item = next_item
+ endif
+ endwhile
+
+ call s:update_state(s:get_parent(first_item))
+endfunction
+
+
+
+" ---------------------------------------------------------
+" change the level of list items
+" ---------------------------------------------------------
+
+function! s:set_indent(lnum, new_indent)
+ if &expandtab
+ let indentstring = repeat(' ', a:new_indent)
+ else
+ let indentstring = repeat('\t', a:new_indent / &tabstop) . repeat(' ', a:new_indent % &tabstop)
+ endif
+ call s:substitute_rx_in_line(a:lnum, '^\s*', indentstring)
+endfunction
+
+
+function! s:decrease_level(item)
+ let removed_indent = 0
+ if vimwiki#vars#get_syntaxlocal('recurring_bullets') && a:item.type == 1 &&
+ \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'),
+ \ s:first_char(a:item.mrkr)) > -1
+ if s:string_length(a:item.mrkr) >= 2
+ call s:substitute_string_in_line(a:item.lnum, s:first_char(a:item.mrkr), '')
+ let removed_indent = -1
+ endif
+ else
+ let old_indent = indent(a:item.lnum)
+ if &shiftround
+ let new_indent = (old_indent - 1) / vimwiki#u#sw() * vimwiki#u#sw()
+ else
+ let new_indent = old_indent - vimwiki#u#sw()
+ endif
+ call s:set_indent(a:item.lnum, new_indent)
+ let removed_indent = new_indent - old_indent
+ endif
+ return removed_indent
+endfunction
+
+
+function! s:increase_level(item)
+ let additional_indent = 0
+ if vimwiki#vars#get_syntaxlocal('recurring_bullets') && a:item.type == 1 &&
+ \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'),
+ \ s:first_char(a:item.mrkr)) > -1
+ call s:substitute_string_in_line(a:item.lnum, a:item.mrkr, a:item.mrkr .
+ \ s:first_char(a:item.mrkr))
+ let additional_indent = 1
+ else
+ let old_indent = indent(a:item.lnum)
+ if &shiftround
+ let new_indent = (old_indent / vimwiki#u#sw() + 1) * vimwiki#u#sw()
+ else
+ let new_indent = old_indent + vimwiki#u#sw()
+ endif
+ call s:set_indent(a:item.lnum, new_indent)
+ let additional_indent = new_indent - old_indent
+ endif
+ return additional_indent
+endfunction
+
+
+"adds a:indent_by to the current indent
+"a:indent_by can be negative
+function! s:indent_line_by(lnum, indent_by)
+ let item = s:get_item(a:lnum)
+ if vimwiki#vars#get_syntaxlocal('recurring_bullets') && item.type == 1 &&
+ \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'),
+ \ s:first_char(item.mrkr)) > -1
+ if a:indent_by > 0
+ call s:substitute_string_in_line(a:lnum, item.mrkr, item.mrkr . s:first_char(item.mrkr))
+ elseif a:indent_by < 0
+ call s:substitute_string_in_line(a:lnum, s:first_char(item.mrkr), '')
+ endif
+ else
+ call s:set_indent(a:lnum, indent(a:lnum) + a:indent_by)
+ endif
+endfunction
+
+
+"changes lvl of lines in selection
+function! s:change_level(from_line, to_line, direction, plus_children)
+ let from_item = s:get_corresponding_item(a:from_line)
+ if from_item.type == 0
+ if a:direction ==# 'increase' && a:from_line == a:to_line && empty(getline(a:from_line))
+ "that's because :> doesn't work on an empty line
+ normal! gi
+ else
+ execute a:from_line.','.a:to_line.(a:direction ==# 'increase' ? '>' : '<')
+ endif
+ return
+ endif
+
+ if a:direction ==# 'decrease' && s:get_level(from_item.lnum) == 0
+ return
+ endif
+
+ if a:from_line == a:to_line
+ if a:plus_children
+ let to_line = s:get_last_line_of_item_incl_children(from_item)
+ else
+ let to_line = s:get_last_line_of_item(from_item)
+ endif
+ else
+ let to_item = s:get_corresponding_item(a:to_line)
+ if to_item.type == 0
+ let to_line = a:to_line
+ else
+ if a:plus_children
+ let to_line = s:get_last_line_of_item_incl_children(to_item)
+ else
+ let to_line = s:get_last_line_of_item(to_item)
+ endif
+ endif
+ endif
+
+ if to_line == 0
+ return
+ endif
+
+ let to_be_adjusted = s:get_a_neighbor_item(from_item)
+ let old_parent = s:get_parent(from_item)
+ let first_line_level = s:get_level(from_item.lnum)
+ let more_than_one_level_concerned = 0
+
+ let first_line_indented_by = (a:direction ==# 'increase') ?
+ \ s:increase_level(from_item) : s:decrease_level(from_item)
+
+ let cur_ln = s:get_next_line(from_item.lnum)
+ while cur_ln > 0 && cur_ln <= to_line
+ if !more_than_one_level_concerned &&
+ \ s:get_level(cur_ln) != first_line_level &&
+ \ s:get_item(cur_ln).type != 0
+ let more_than_one_level_concerned = 1
+ endif
+ call s:indent_line_by(cur_ln, first_line_indented_by)
+ let cur_ln = s:get_next_line(cur_ln, 1)
+ endwhile
+
+ if a:from_line == a:to_line
+ call s:adjust_mrkr(from_item)
+ endif
+ call s:update_state(old_parent)
+ let from_item = s:get_item(from_item.lnum)
+ if from_item.cb != ''
+ call s:update_state(from_item)
+ call s:update_state(s:get_parent(from_item))
+ endif
+
+ if more_than_one_level_concerned
+ call vimwiki#lst#adjust_whole_buffer()
+ else
+ call s:adjust_numbered_list(from_item, 0, 0)
+ call s:adjust_numbered_list(to_be_adjusted, 0, 0)
+ endif
+endfunction
+
+
+function! vimwiki#lst#change_level(from_line, to_line, direction, plus_children)
+ let cur_col = col('$') - col('.')
+ call s:change_level(a:from_line, a:to_line, a:direction, a:plus_children)
+ call cursor('.', col('$') - cur_col)
+endfunction
+
+
+"indent line a:lnum to be the continuation of a:prev_item
+function! s:indent_multiline(prev_item, lnum)
+ if a:prev_item.type != 0
+ call s:set_indent(a:lnum, s:text_begin(a:prev_item.lnum))
+ endif
+endfunction
+
+
+" ---------------------------------------------------------
+" change markers of list items
+" ---------------------------------------------------------
+
+"Returns: the position of a marker in g:vimwiki_list_markers
+function! s:get_idx_list_markers(item)
+ if a:item.type == 1
+ let m = s:first_char(a:item.mrkr)
+ else
+ let m = s:guess_kind_of_numbered_item(a:item) . a:item.mrkr[-1:]
+ endif
+ return index(vimwiki#vars#get_syntaxlocal('list_markers'), m)
+endfunction
+
+
+"changes the marker of the given item to the next in g:vimwiki_list_markers
+function! s:get_next_mrkr(item)
+ let markers = vimwiki#vars#get_syntaxlocal('list_markers')
+ if a:item.type == 0
+ let new_mrkr = markers[0]
+ else
+ let idx = s:get_idx_list_markers(a:item)
+ let new_mrkr = markers[(idx+1) % len(markers)]
+ endif
+ return new_mrkr
+endfunction
+
+
+"changes the marker of the given item to the previous in g:vimwiki_list_markers
+function! s:get_prev_mrkr(item)
+ let markers = vimwiki#vars#get_syntaxlocal('list_markers')
+ if a:item.type == 0
+ return markers[-1]
+ endif
+ let idx = s:get_idx_list_markers(a:item)
+ if idx == -1
+ return markers[-1]
+ else
+ return markers[(idx - 1 + len(markers)) % len(markers)]
+ endif
+endfunction
+
+
+function! s:set_new_mrkr(item, new_mrkr)
+ if a:item.type == 0
+ call s:substitute_rx_in_line(a:item.lnum, '^\s*\zs\ze', a:new_mrkr.' ')
+ if indent(a:item.lnum) == 0 && !vimwiki#vars#get_syntaxlocal('recurring_bullets')
+ call s:set_indent(a:item.lnum, vimwiki#lst#get_list_margin())
+ endif
+ else
+ call s:substitute_string_in_line(a:item.lnum, a:item.mrkr, a:new_mrkr)
+ endif
+endfunction
+
+
+function! vimwiki#lst#change_marker(from_line, to_line, new_mrkr, mode)
+ let cur_col_from_eol = col("$") - (a:mode ==# "i" ? col("'^") : col('.'))
+ let new_mrkr = a:new_mrkr
+ let cur_ln = a:from_line
+ while 1
+ let cur_item = s:get_item(cur_ln)
+
+ if new_mrkr ==# "next"
+ let new_mrkr = s:get_next_mrkr(cur_item)
+ elseif new_mrkr ==# "prev"
+ let new_mrkr = s:get_prev_mrkr(cur_item)
+ endif
+
+ "handle markers like ***
+ if index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'), s:first_char(new_mrkr)) > -1
+ "use *** if the item above has *** too
+ let item_above = s:get_prev_list_item(cur_item, 1)
+ if item_above.type == 1 && s:first_char(item_above.mrkr) ==# s:first_char(new_mrkr)
+ let new_mrkr = item_above.mrkr
+ else
+ "use *** if the item below has *** too
+ let item_below = s:get_next_list_item(cur_item, 1)
+ if item_below.type == 1 && s:first_char(item_below.mrkr) ==# s:first_char(new_mrkr)
+ let new_mrkr = item_below.mrkr
+ else
+ "if the old is ### and the new is * use ***
+ if cur_item.type == 1 &&
+ \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'),
+ \ s:first_char(cur_item.mrkr))>-1
+ let new_mrkr = repeat(new_mrkr, s:string_length(cur_item.mrkr))
+ else
+ "use *** if the parent item has **
+ let parent_item = s:get_parent(cur_item)
+ if parent_item.type == 1 && s:first_char(parent_item.mrkr) ==# s:first_char(new_mrkr)
+ let new_mrkr = repeat(s:first_char(parent_item.mrkr),
+ \ s:string_length(parent_item.mrkr)+1)
+ endif
+ endif
+ endif
+ endif
+
+ endif
+
+ call s:set_new_mrkr(cur_item, new_mrkr)
+ call s:adjust_numbered_list(s:get_item(cur_ln), 1, 0)
+
+ if cur_ln >= a:to_line | break | endif
+ let cur_ln = s:get_next_line(cur_ln, 1)
+ endwhile
+
+ call cursor('.', col('$') - cur_col_from_eol)
+endfunction
+
+
+function! vimwiki#lst#change_marker_in_list(new_mrkr)
+ let cur_item = s:get_corresponding_item(line('.'))
+ let first_item = s:get_first_item_in_list(cur_item, 0)
+ let last_item = s:get_last_item_in_list(cur_item, 0)
+ if first_item.type == 0 || last_item.type == 0 | return | endif
+ let first_item_line = first_item.lnum
+
+ let cur_item = first_item
+ while cur_item.type != 0 && cur_item.lnum <= last_item.lnum
+ call s:set_new_mrkr(cur_item, a:new_mrkr)
+ let cur_item = s:get_next_list_item(cur_item, 1)
+ endwhile
+
+ call s:adjust_numbered_list(s:get_item(first_item_line), 0, 0)
+endfunction
+
+
+"sets kind of the item depending on neighbor items and the parent item
+function! s:adjust_mrkr(item)
+ if a:item.type == 0 || vimwiki#vars#get_syntaxlocal('recurring_bullets')
+ return
+ endif
+
+ let new_mrkr = a:item.mrkr
+ let neighbor_item = s:get_a_neighbor_item(a:item)
+ if neighbor_item.type != 0
+ let new_mrkr = neighbor_item.mrkr
+ endif
+
+ "if possible, set e.g. *** if parent has ** as marker
+ if neighbor_item.type == 0 && a:item.type == 1 &&
+ \ index(vimwiki#vars#get_syntaxlocal('multiple_bullet_chars'),
+ \ s:first_char(a:item.mrkr)) > -1
+ let parent_item = s:get_parent(a:item)
+ if parent_item.type == 1 && s:first_char(parent_item.mrkr) ==# s:first_char(a:item.mrkr)
+ let new_mrkr = repeat(s:first_char(parent_item.mrkr), s:string_length(parent_item.mrkr)+1)
+ endif
+ endif
+
+ call s:substitute_string_in_line(a:item.lnum, a:item.mrkr, new_mrkr)
+ call s:adjust_numbered_list(a:item, 0, 1)
+endfunction
+
+
+function! s:clone_marker_from_to(from, to)
+ let item_from = s:get_item(a:from)
+ if item_from.type == 0 | return | endif
+ let new_mrkr = item_from.mrkr . ' '
+ call s:substitute_rx_in_line(a:to, '^\s*', new_mrkr)
+ let new_indent = ( vimwiki#vars#get_syntaxlocal('recurring_bullets') ? 0 : indent(a:from) )
+ call s:set_indent(a:to, new_indent)
+ if item_from.cb != ''
+ call s:create_cb(s:get_item(a:to), 0)
+ call s:update_state(s:get_parent(s:get_item(a:to)))
+ endif
+ if item_from.type == 2
+ let adjust_from = ( a:from < a:to ? a:from : a:to )
+ call s:adjust_numbered_list_below(s:get_item(adjust_from), 0)
+ endif
+endfunction
+
+
+function! s:remove_mrkr(item)
+ let item = a:item
+ if item.cb != ''
+ let item = s:remove_cb(item)
+ let parent_item = s:get_parent(item)
+ else
+ let parent_item = s:empty_item()
+ endif
+ call s:substitute_rx_in_line(item.lnum, vimwiki#u#escape(item.mrkr).'\s*', '')
+ call remove(item, 'mrkr')
+ call remove(item, 'cb')
+ let item.type = 0
+ call s:update_state(parent_item)
+ return item
+endfunction
+
+
+function! s:create_marker(lnum)
+ let new_sibling = s:get_corresponding_item(a:lnum)
+ if new_sibling.type == 0
+ let new_sibling = s:get_a_neighbor_item_in_column(a:lnum, virtcol('.'))
+ endif
+ if new_sibling.type != 0
+ call s:clone_marker_from_to(new_sibling.lnum, a:lnum)
+ else
+ let cur_item = s:get_item(a:lnum)
+ call s:set_new_mrkr(cur_item, vimwiki#vars#get_syntaxlocal('list_markers')[0])
+ call s:adjust_numbered_list(cur_item, 0, 0)
+ endif
+endfunction
+
+
+" ---------------------------------------------------------
+" handle keys
+" ---------------------------------------------------------
+
+function! vimwiki#lst#kbd_o()
+ let fold_end = foldclosedend('.')
+ let lnum = (fold_end == -1) ? line('.') : fold_end
+ let cur_item = s:get_item(lnum)
+ "inserting and deleting the x is necessary
+ "because otherwise the indent is lost
+ normal! ox
+ if cur_item.lnum < s:get_last_line_of_item(cur_item)
+ call s:indent_multiline(cur_item, cur_item.lnum+1)
+ else
+ call s:clone_marker_from_to(cur_item.lnum, cur_item.lnum+1)
+ endif
+ startinsert!
+endfunction
+
+
+function! vimwiki#lst#kbd_O()
+ normal! Ox
+ let cur_ln = line('.')
+ if getline(cur_ln+1) !~# '^\s*$'
+ call s:clone_marker_from_to(cur_ln+1, cur_ln)
+ else
+ call s:clone_marker_from_to(cur_ln-1, cur_ln)
+ endif
+ startinsert!
+endfunction
+
+
+function! s:cr_on_empty_list_item(lnum, behavior)
+ if a:behavior == 1
+ "just make a new list item
+ normal! gi
+ call s:clone_marker_from_to(a:lnum, a:lnum+1)
+ startinsert!
+ return
+ elseif a:behavior == 2
+ "insert new marker but remove marker in old line
+ call append(a:lnum-1, '')
+ startinsert!
+ return
+ elseif a:behavior == 3
+ "list is finished, but cursor stays in current line
+ let item = s:get_item(a:lnum)
+ let neighbor_item = s:get_a_neighbor_item(item)
+ let child_item = s:get_first_child(item)
+ let parent_item = (item.cb != '') ? s:get_parent(item) : s:empty_item()
+ normal! "_cc
+ call s:adjust_numbered_list(neighbor_item, 0, 0)
+ call s:adjust_numbered_list(child_item, 0, 0)
+ call s:update_state(parent_item)
+ startinsert
+ return
+ elseif a:behavior == 4
+ "list is finished, but cursor goes to next line
+ let item = s:get_item(a:lnum)
+ let neighbor_item = s:get_a_neighbor_item(item)
+ let child_item = s:get_first_child(item)
+ let parent_item = (item.cb != '') ? s:get_parent(item) : s:empty_item()
+ normal! "_cc
+ call s:adjust_numbered_list(neighbor_item, 0, 0)
+ call s:adjust_numbered_list(child_item, 0, 0)
+ call s:update_state(parent_item)
+ startinsert
+ return
+ elseif a:behavior == 5
+ "successively decrease level
+ if s:get_level(a:lnum) > 0
+ call s:change_level(a:lnum, a:lnum, 'decrease', 0)
+ startinsert!
+ else
+ let item = s:get_item(a:lnum)
+ let neighbor_item = s:get_a_neighbor_item(item)
+ let child_item = s:get_first_child(item)
+ let parent_item = (item.cb != '') ? s:get_parent(item) : s:empty_item()
+ normal! "_cc
+ call s:adjust_numbered_list(neighbor_item, 0, 0)
+ call s:adjust_numbered_list(child_item, 0, 0)
+ call s:update_state(parent_item)
+ startinsert
+ endif
+ return
+ endif
+endfunction
+
+
+function! s:cr_on_empty_line(lnum, behavior)
+ "inserting and deleting the x is necessary
+ "because otherwise the indent is lost
+ normal! gix
+ if a:behavior == 2 || a:behavior == 3
+ call s:create_marker(a:lnum+1)
+ endif
+endfunction
+
+
+function! s:cr_on_list_item(lnum, insert_new_marker, not_at_eol)
+ if a:insert_new_marker
+ "the ultimate feature of this script: make new marker on <CR>
+ normal! gi
+ call s:clone_marker_from_to(a:lnum, a:lnum+1)
+ "tiny sweet extra feature: indent next line if current line ends with :
+ if !a:not_at_eol && getline(a:lnum) =~# ':$'
+ call s:change_level(a:lnum+1, a:lnum+1, 'increase', 0)
+ endif
+ else
+ " || (cur_item.lnum < s:get_last_line_of_item(cur_item))
+ "indent this line so that it becomes the continuation of the line above
+ normal! gi
+ let prev_line = s:get_corresponding_item(s:get_prev_line(a:lnum+1))
+ call s:indent_multiline(prev_line, a:lnum+1)
+ endif
+endfunction
+
+
+function! vimwiki#lst#kbd_cr(normal, just_mrkr)
+ let lnum = line('.')
+ let has_bp = s:line_has_marker(lnum)
+
+ if has_bp != 0 && virtcol('.') < s:text_begin(lnum)
+ call append(lnum-1, '')
+ startinsert!
+ return
+ endif
+
+ if has_bp == 1
+ call s:cr_on_empty_list_item(lnum, a:just_mrkr)
+ return
+ endif
+
+ let insert_new_marker = (a:normal == 1 || a:normal == 3)
+ if getline('.')[col("'^")-1:] =~# '^\s\+$'
+ let cur_col = 0
+ else
+ let cur_col = col("$") - col("'^")
+ if getline('.')[col("'^")-1] =~# '\s' && exists("*strdisplaywidth")
+ let ws_behind_cursor =
+ \ strdisplaywidth(matchstr(getline('.')[col("'^")-1:], '\s\+'),
+ \ virtcol("'^")-1)
+ let cur_col -= ws_behind_cursor
+ endif
+ if insert_new_marker && cur_col == 0 && getline(lnum) =~# '\s$'
+ let insert_new_marker = 0
+ endif
+ endif
+
+ if has_bp == 0
+ call s:cr_on_empty_line(lnum, a:normal)
+ endif
+
+ if has_bp == 2
+ call s:cr_on_list_item(lnum, insert_new_marker, cur_col)
+ endif
+
+ call cursor(lnum+1, col("$") - cur_col)
+ if cur_col == 0
+ startinsert!
+ else
+ startinsert
+ endif
+
+endfunction
+
+
+"creates a list item in the current line or removes it
+function! vimwiki#lst#toggle_list_item()
+ let cur_col_from_eol = col("$") - col("'^")
+ let cur_item = s:get_item(line('.'))
+
+ if cur_item.type == 0
+ call s:create_marker(cur_item.lnum)
+ else
+ let prev_item = s:get_prev_list_item(cur_item, 1)
+ if prev_item.type == 0
+ let prev_item = s:get_corresponding_item(s:get_prev_line(cur_item.lnum))
+ endif
+ let cur_item = s:remove_mrkr(cur_item)
+ let adjust_prev_item = (prev_item.type == 2 &&
+ \ s:get_level(cur_item.lnum) <= s:get_level(prev_item.lnum)) ? 1 : 0
+ call s:indent_multiline(prev_item, cur_item.lnum)
+ if adjust_prev_item
+ call s:adjust_numbered_list_below(prev_item, 0)
+ endif
+ endif
+
+ "set cursor position s.t. it's on the same char as before
+ let new_cur_col = col("$") - cur_col_from_eol
+ call cursor(cur_item.lnum, new_cur_col >= 1 ? new_cur_col : 1)
+
+ if cur_col_from_eol == 0 || getline(cur_item.lnum) =~# '^\s*$'
+ startinsert!
+ else
+ startinsert
+ endif
+endfunction
+
+
+" ---------------------------------------------------------
+" misc stuff
+" ---------------------------------------------------------
+
+function! vimwiki#lst#TO_list_item(inner, visual)
+ let lnum = prevnonblank('.')
+ let item = s:get_corresponding_item(lnum)
+ if item.type == 0
+ return
+ endif
+ let from_line = item.lnum
+ if a:inner
+ let to_line = s:get_last_line_of_item(item)
+ else
+ let to_line = s:get_last_line_of_item_incl_children(item)
+ endif
+ normal! V
+ call cursor(to_line, 0)
+ normal! o
+ call cursor(from_line, 0)
+endfunction
+
+
+function! vimwiki#lst#fold_level(lnum)
+ let cur_item = s:get_item(a:lnum)
+ if cur_item.type != 0
+ let parent_item = s:get_parent(cur_item)
+ let child_item = s:get_first_child(cur_item)
+ let next_item = s:get_next_child_item(parent_item, cur_item)
+ if child_item.type != 0
+ return 'a1'
+ elseif next_item.type == 0
+ return 's1'
+ endif
+ endif
+ return '='
+endfunction
+
diff --git a/.config/nvim/autoload/vimwiki/markdown_base.vim b/.config/nvim/autoload/vimwiki/markdown_base.vim
@@ -0,0 +1,150 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Description: Link functions for markdown syntax
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+function! s:safesubstitute(text, search, replace, mode)
+ " Substitute regexp but do not interpret replace
+ let escaped = escape(a:replace, '\&')
+ return substitute(a:text, a:search, escaped, a:mode)
+endfunction
+
+
+function! vimwiki#markdown_base#scan_reflinks()
+ let mkd_refs = {}
+ " construct list of references using vimgrep
+ try
+ " Why noautocmd? Because https://github.com/vimwiki/vimwiki/issues/121
+ noautocmd execute 'vimgrep #'.vimwiki#vars#get_syntaxlocal('rxMkdRef').'#j %'
+ catch /^Vim\%((\a\+)\)\=:E480/ " No Match
+ "Ignore it, and move on to the next file
+ endtry
+
+ for d in getqflist()
+ let matchline = join(getline(d.lnum, min([d.lnum+1, line('$')])), ' ')
+ let descr = matchstr(matchline, vimwiki#vars#get_syntaxlocal('rxMkdRefMatchDescr'))
+ let url = matchstr(matchline, vimwiki#vars#get_syntaxlocal('rxMkdRefMatchUrl'))
+ if descr != '' && url != ''
+ let mkd_refs[descr] = url
+ endif
+ endfor
+ call vimwiki#vars#set_bufferlocal('markdown_refs', mkd_refs)
+ return mkd_refs
+endfunction
+
+
+" try markdown reference links
+function! vimwiki#markdown_base#open_reflink(link)
+ " echom "vimwiki#markdown_base#open_reflink"
+ let link = a:link
+ let mkd_refs = vimwiki#vars#get_bufferlocal('markdown_refs')
+ if has_key(mkd_refs, link)
+ let url = mkd_refs[link]
+ call vimwiki#base#system_open_link(url)
+ return 1
+ else
+ return 0
+ endif
+endfunction
+
+
+function! s:normalize_link_syntax_n()
+ let lnum = line('.')
+
+ " try WikiIncl
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWikiIncl'))
+ if !empty(lnk)
+ " NO-OP !!
+ return
+ endif
+
+ " try WikiLink0: replace with WikiLink1
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink0'))
+ if !empty(lnk)
+ let sub = vimwiki#base#normalize_link_helper(lnk,
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'),
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr'),
+ \ vimwiki#vars#get_syntaxlocal('WikiLink1Template2'))
+ call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink0'), sub)
+ return
+ endif
+
+ " try WikiLink1: replace with WikiLink0
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink1'))
+ if !empty(lnk)
+ let sub = vimwiki#base#normalize_link_helper(lnk,
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'),
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr'),
+ \ vimwiki#vars#get_global('WikiLinkTemplate2'))
+ call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink1'), sub)
+ return
+ endif
+
+ " try Weblink
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'))
+ if !empty(lnk)
+ let sub = vimwiki#base#normalize_link_helper(lnk,
+ \ vimwiki#vars#get_syntaxlocal('rxWeblinkMatchUrl'),
+ \ vimwiki#vars#get_syntaxlocal('rxWeblinkMatchDescr'),
+ \ vimwiki#vars#get_syntaxlocal('Weblink1Template'))
+ call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'), sub)
+ return
+ endif
+
+ " try Word (any characters except separators)
+ " rxWord is less permissive than rxWikiLinkUrl which is used in
+ " normalize_link_syntax_v
+ let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWord'))
+ if !empty(lnk)
+ let sub = vimwiki#base#normalize_link_helper(lnk,
+ \ vimwiki#vars#get_global('rxWord'), '',
+ \ vimwiki#vars#get_syntaxlocal('Weblink1Template'))
+ call vimwiki#base#replacestr_at_cursor('\V'.lnk, sub)
+ return
+ endif
+
+endfunction
+
+
+function! s:normalize_link_syntax_v()
+ let lnum = line('.')
+ let sel_save = &selection
+ let &selection = "old"
+ let rv = @"
+ let rt = getregtype('"')
+ let done = 0
+
+ try
+ norm! gvy
+ let visual_selection = @"
+ let link = s:safesubstitute(vimwiki#vars#get_syntaxlocal('Weblink1Template'),
+ \ '__LinkUrl__', visual_selection, '')
+ let link = s:safesubstitute(link, '__LinkDescription__', visual_selection, '')
+
+ call setreg('"', substitute(link, '\n', '', ''), visualmode())
+
+ " paste result
+ norm! `>""pgvd
+
+ finally
+ call setreg('"', rv, rt)
+ let &selection = sel_save
+ endtry
+
+endfunction
+
+
+function! vimwiki#markdown_base#normalize_link(is_visual_mode)
+ if 0
+ " Syntax-specific links
+ else
+ if !a:is_visual_mode
+ call s:normalize_link_syntax_n()
+ elseif line("'<") == line("'>")
+ " action undefined for multi-line visual mode selections
+ call s:normalize_link_syntax_v()
+ endif
+ endif
+endfunction
+
diff --git a/.config/nvim/autoload/vimwiki/path.vim b/.config/nvim/autoload/vimwiki/path.vim
@@ -0,0 +1,183 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Description: Path manipulation functions
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+function! vimwiki#path#chomp_slash(str)
+ return substitute(a:str, '[/\\]\+$', '', '')
+endfunction
+
+
+" Define path-compare function, either case-sensitive or not, depending on OS.
+if vimwiki#u#is_windows()
+ function! vimwiki#path#is_equal(p1, p2)
+ return a:p1 ==? a:p2
+ endfunction
+else
+ function! vimwiki#path#is_equal(p1, p2)
+ return a:p1 ==# a:p2
+ endfunction
+endif
+
+
+" collapse sections like /a/b/../c to /a/c
+function! vimwiki#path#normalize(path)
+ let path = a:path
+ while 1
+ let result = substitute(path, '/[^/]\+/\.\.', '', '')
+ if result ==# path
+ break
+ endif
+ let path = result
+ endwhile
+ return result
+endfunction
+
+
+function! vimwiki#path#path_norm(path)
+ " /-slashes
+ if a:path !~# '^scp:'
+ let path = substitute(a:path, '\', '/', 'g')
+ " treat multiple consecutive slashes as one path separator
+ let path = substitute(path, '/\+', '/', 'g')
+ " ensure that we are not fooled by a symbolic link
+ return resolve(path)
+ else
+ return a:path
+ endif
+endfunction
+
+
+function! vimwiki#path#is_link_to_dir(link)
+ " Check if link is to a directory.
+ " It should be ended with \ or /.
+ return a:link =~# '\m[/\\]$'
+endfunction
+
+
+function! vimwiki#path#abs_path_of_link(link)
+ return vimwiki#path#normalize(expand("%:p:h").'/'.a:link)
+endfunction
+
+
+" return longest common path prefix of 2 given paths.
+" '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki'
+function! vimwiki#path#path_common_pfx(path1, path2)
+ let p1 = split(a:path1, '[/\\]', 1)
+ let p2 = split(a:path2, '[/\\]', 1)
+
+ let idx = 0
+ let minlen = min([len(p1), len(p2)])
+ while (idx < minlen) && vimwiki#path#is_equal(p1[idx], p2[idx])
+ let idx = idx + 1
+ endwhile
+ if idx == 0
+ return ''
+ else
+ return join(p1[: idx-1], '/')
+ endif
+endfunction
+
+
+function! vimwiki#path#wikify_path(path)
+ let result = resolve(fnamemodify(a:path, ':p'))
+ if vimwiki#u#is_windows()
+ let result = substitute(result, '\\', '/', 'g')
+ endif
+ let result = vimwiki#path#chomp_slash(result)
+ return result
+endfunction
+
+
+function! vimwiki#path#current_wiki_file()
+ return vimwiki#path#wikify_path(expand('%:p'))
+endfunction
+
+
+" Returns: the relative path from a:dir to a:file
+function! vimwiki#path#relpath(dir, file)
+ let result = []
+ let dir = split(a:dir, '/')
+ let file = split(a:file, '/')
+ while (len(dir) > 0 && len(file) > 0) && vimwiki#path#is_equal(dir[0], file[0])
+ call remove(dir, 0)
+ call remove(file, 0)
+ endwhile
+ if empty(dir) && empty(file)
+ return './'
+ endif
+ for segment in dir
+ let result += ['..']
+ endfor
+ for segment in file
+ let result += [segment]
+ endfor
+ let result_path = join(result, '/')
+ if a:file =~ '\m/$'
+ let result_path .= '/'
+ endif
+ return result_path
+endfunction
+
+
+" If the optional argument provided and nonzero,
+" it will ask before creating a directory
+" Returns: 1 iff directory exists or successfully created
+function! vimwiki#path#mkdir(path, ...)
+ let path = expand(a:path)
+
+ if path =~# '^scp:'
+ " we can not do much, so let's pretend everything is ok
+ return 1
+ endif
+
+ if isdirectory(path)
+ return 1
+ else
+ if !exists("*mkdir")
+ return 0
+ endif
+
+ let path = vimwiki#path#chomp_slash(path)
+ if vimwiki#u#is_windows() && !empty(vimwiki#vars#get_global('w32_dir_enc'))
+ let path = iconv(path, &enc, vimwiki#vars#get_global('w32_dir_enc'))
+ endif
+
+ if a:0 && a:1 && input("Vimwiki: Make new directory: ".path."\n [y]es/[N]o? ") !~? '^y'
+ return 0
+ endif
+
+ call mkdir(path, "p")
+ return 1
+ endif
+endfunction
+
+
+function! vimwiki#path#is_absolute(path)
+ if vimwiki#u#is_windows()
+ return a:path =~? '\m^\a:'
+ else
+ return a:path =~# '\m^/\|\~/'
+ endif
+endfunction
+
+
+" Combine a directory and a file into one path, doesn't generate duplicate
+" path separator in case the directory is also having an ending / or \. This
+" is because on windows ~\vimwiki//.tags is invalid but ~\vimwiki/.tags is a
+" valid path.
+if vimwiki#u#is_windows()
+ function! vimwiki#path#join_path(directory, file)
+ let directory = vimwiki#path#chomp_slash(a:directory)
+ let file = substitute(a:file, '\m^[\\/]\+', '', '')
+ return directory . '/' . file
+ endfunction
+else
+ function! vimwiki#path#join_path(directory, file)
+ let directory = substitute(a:directory, '\m/\+$', '', '')
+ let file = substitute(a:file, '\m^/\+', '', '')
+ return directory . '/' . file
+ endfunction
+endif
+
diff --git a/.config/nvim/autoload/vimwiki/style.css b/.config/nvim/autoload/vimwiki/style.css
@@ -0,0 +1,83 @@
+body {font-family: Tahoma, Geneva, sans-serif; margin: 1em 2em 1em 2em; font-size: 100%; line-height: 130%;}
+h1, h2, h3, h4, h5, h6 {font-family: Trebuchet MS, Helvetica, sans-serif; font-weight: bold; line-height:100%; margin-top: 1.5em; margin-bottom: 0.5em;}
+h1 {font-size: 2.6em; color: #000000;}
+h2 {font-size: 2.2em; color: #404040;}
+h3 {font-size: 1.8em; color: #707070;}
+h4 {font-size: 1.4em; color: #909090;}
+h5 {font-size: 1.3em; color: #989898;}
+h6 {font-size: 1.2em; color: #9c9c9c;}
+p, pre, blockquote, table, ul, ol, dl {margin-top: 1em; margin-bottom: 1em;}
+ul ul, ul ol, ol ol, ol ul {margin-top: 0.5em; margin-bottom: 0.5em;}
+li {margin: 0.3em auto;}
+ul {margin-left: 2em; padding-left: 0.5em;}
+dt {font-weight: bold;}
+img {border: none;}
+pre {border-left: 1px solid #ccc; margin-left: 2em; padding-left: 0.5em;}
+blockquote {padding: 0.4em; background-color: #f6f5eb;}
+th, td {border: 1px solid #ccc; padding: 0.3em;}
+th {background-color: #f0f0f0;}
+hr {border: none; border-top: 1px solid #ccc; width: 100%;}
+del {text-decoration: line-through; color: #777777;}
+.toc li {list-style-type: none;}
+.todo {font-weight: bold; background-color: #f0ece8; color: #a03020;}
+.justleft {text-align: left;}
+.justright {text-align: right;}
+.justcenter {text-align: center;}
+.center {margin-left: auto; margin-right: auto;}
+.tag {background-color: #eeeeee; font-family: monospace; padding: 2px;}
+.header a {text-decoration: none; color: inherit;}
+
+/* classes for items of todo lists */
+.rejected {
+ /* list-style: none; */
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAAACXBIWXMAAADFAAAAxQEdzbqoAAAAB3RJTUUH4QgEFhAtuWgv9wAAAPZQTFRFmpqam5iYnJaWnJeXnpSUn5OTopCQpoqKpouLp4iIqIiIrYCAt3V1vW1tv2xsmZmZmpeXnpKS/x4e/x8f/yAg/yIi/yQk/yUl/yYm/ygo/ykp/yws/zAw/zIy/zMz/zQ0/zU1/zY2/zw8/0BA/0ZG/0pK/1FR/1JS/1NT/1RU/1VV/1ZW/1dX/1pa/15e/19f/2Zm/2lp/21t/25u/3R0/3p6/4CA/4GB/4SE/4iI/46O/4+P/52d/6am/6ur/66u/7Oz/7S0/7e3/87O/9fX/9zc/93d/+Dg/+vr/+3t/+/v//Dw//Ly//X1//f3//n5//z8////gzaKowAAAA90Uk5T/Pz8/Pz8/Pz8/Pz8/f39ppQKWQAAAAFiS0dEEnu8bAAAAACuSURBVAhbPY9ZF4FQFEZPSKbIMmWep4gMGTKLkIv6/3/GPbfF97b3w17rA0kQOPgvAeHW6uJ6+5h7HqLdwowgOzejXRXBdx6UdSru216xuOMBHHNU0clTzeSUA6EhF8V8kqroluMiU6HKcuf4phGPr1o2q9kYZWwNq1qfRRmTaXpqsyjj17KkWCxKBUBgXWueHIyiAIg18gsse4KHkLF5IKIY10WQgv7fOy4ST34BRiopZ8WLNrgAAAAASUVORK5CYII=);
+ background-repeat: no-repeat;
+ background-position: 0 .2em;
+ padding-left: 1.5em;
+}
+.done0 {
+ /* list-style: none; */
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAA7SURBVCiR7dMxEgAgCANBI3yVRzF5KxNbW6wsuH7LQ2YKQK1mkswBVERYF5Os3UV3gwd/jF2SkXy66gAZkxS6BniubAAAAABJRU5ErkJggg==);
+ background-repeat: no-repeat;
+ background-position: 0 .2em;
+ padding-left: 1.5em;
+}
+.done1 {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABtSURBVCiR1ZO7DYAwDER9BDmTeZQMFXmUbGYpOjrEryA0wOvO8itOslFrJYAug5BMM4BeSkmjsrv3aVTa8p48Xw1JSkSsWVUFwD05IqS1tmYzk5zzae9jnVVVzGyXb8sALjse+euRkEzu/uirFomVIdDGOLjuAAAAAElFTkSuQmCC);
+ background-repeat: no-repeat;
+ background-position: 0 .15em;
+ padding-left: 1.5em;
+}
+.done2 {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAB1SURBVCiRzdO5DcAgDAVQGxjAYgTvxlDIu1FTIRYAp8qlFISkSH7l5kk+ZIwxKiI2mIyqWoeILYRgZ7GINDOLjnmF3VqklKCUMgTee2DmM661Qs55iI3Zm/1u5h9sm4ig9z4ERHTFzLyd4G4+nFlVrYg8+qoF/c0kdpeMsmcAAAAASUVORK5CYII=);
+ background-repeat: no-repeat;
+ background-position: 0 .15em;
+ padding-left: 1.5em;
+}
+.done3 {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABoSURBVCiR7dOxDcAgDATA/0DtUdiKoZC3YhLkHjkVKF3idJHiztKfvrHZWnOSE8Fx95RJzlprimJVnXktvXeY2S0SEZRSAAAbmxnGGKH2I5T+8VfxPhIReQSuuY3XyYWa3T2p6quvOgGrvSFGlewuUAAAAABJRU5ErkJggg==);
+ background-repeat: no-repeat;
+ background-position: 0 .15em;
+ padding-left: 1.5em;
+}
+.done4 {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAzgAAAM4BlP6ToAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIISURBVDiNnZQ9SFtRFMd/773kpTaGJoQk1im4VDpWQcTNODhkFBcVTCNCF0NWyeDiIIiCm82QoIMIUkHUxcFBg1SEQoZszSat6cdTn1qNue92CMbEr9Sey+XC/Z/zu+f8h6ukUil3sVg0+M+4cFxk42/jH2wAqqqKSCSiPQdwcHHAnDHH9s/tN1h8V28ETdP+eU8fT9Nt62ancYdIPvJNtsu87bmjrJlrTDVM4RROJs1JrHPrD4Bar7A6cpc54iKOaTdJXCUI2UMVrQZ0Js7YPN18ECKkYNQcJe/OE/4dZsw7VqNXQMvHy3QZXQypQ6ycrtwDjf8aJ+PNEDSCzLpn7+m2pD8ZKHlKarYhy6XjEoCYGcN95qansQeA3fNdki+SaJZGTMQIOoL3W/Z89rxv+tokubNajlvk/vm+LFpF2XnUKZHI0I+QrI7Dw0OZTqdzUkpsM7mZTyfy5OPGyw1tK7AFSvmB/Ks8w8YwbUYbe6/3QEKv0vugfxWPnMLJun+d/kI/WLdizpNjMbAIKrhMF4OuwadBALqqs+RfInwUvuNi+fBd+wjogfogAFVRmffO02q01mZZ0HHdgXIzdz0QQLPezIQygX6llxNKKgOFARYCC49CqhoHIUTlss/Vx2phlYwjw8j1CAlfAiwQiJpiy7o1VHnsG5FISkoJu7Q/2YmmaV+i0ei7v38L2CBguSi5AAAAAElFTkSuQmCC);
+ background-repeat: no-repeat;
+ background-position: 0 .15em;
+ padding-left: 1.5em;
+}
+
+code {
+ font-family: Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ border-radius: 1px;
+ -moz-background-clip: padding;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ padding: 0px 3px;
+ display: inline-block;
+ color: #52595d;
+ border: 1px solid #ccc;
+ background-color: #f9f9f9;
+}
diff --git a/.config/nvim/autoload/vimwiki/tags.vim b/.config/nvim/autoload/vimwiki/tags.vim
@@ -0,0 +1,342 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+
+
+let s:TAGS_METADATA_FILE_NAME = '.tags'
+
+
+
+" Tags metadata in-memory format:
+" metadata := { 'pagename': [entries, ...] }
+" entry := { 'tagname':..., 'lineno':..., 'link':... }
+
+" Tags metadata in-file format:
+"
+" Is based on CTags format (see |tags-file-format|).
+"
+" {tagaddress} is set to lineno. We'll let vim search by exact line number; we
+" can afford that, we assume metadata file is always updated before use.
+"
+" Pagename and link are not saved in standard ctags fields, so we'll add
+" an optional field, "vimwiki:". In this field, we encode tab-separated values
+" of missing parameters -- "pagename" and "link".
+
+
+
+" Update tags metadata.
+" a:full_rebuild == 1: re-scan entire wiki
+" a:full_rebuild == 0: only re-scan current page
+" a:all_files == '': only if the file is newer than .tags
+function! vimwiki#tags#update_tags(full_rebuild, all_files)
+ let all_files = a:all_files != ''
+ if !a:full_rebuild
+ " Updating for one page (current)
+ let page_name = vimwiki#vars#get_bufferlocal('subdir') . expand('%:t:r')
+ " Collect tags in current file
+ let tags = s:scan_tags(getline(1, '$'), page_name)
+ " Load metadata file
+ let metadata = s:load_tags_metadata()
+ " Drop old tags
+ let metadata = s:remove_page_from_tags(metadata, page_name)
+ " Merge in the new ones
+ let metadata = s:merge_tags(metadata, page_name, tags)
+ " Save
+ call s:write_tags_metadata(metadata)
+ else " full rebuild
+ let files = vimwiki#base#find_files(vimwiki#vars#get_bufferlocal('wiki_nr'), 0)
+ let wiki_base_dir = vimwiki#vars#get_wikilocal('path')
+ let tags_file_last_modification = getftime(vimwiki#tags#metadata_file_path())
+ let metadata = s:load_tags_metadata()
+ for file in files
+ if all_files || getftime(file) >= tags_file_last_modification
+ let subdir = vimwiki#base#subdir(wiki_base_dir, file)
+ let page_name = subdir . fnamemodify(file, ':t:r')
+ let tags = s:scan_tags(readfile(file), page_name)
+ let metadata = s:remove_page_from_tags(metadata, page_name)
+ let metadata = s:merge_tags(metadata, page_name, tags)
+ endif
+ endfor
+ call s:write_tags_metadata(metadata)
+ endif
+endfunction
+
+
+" Scans the list of text lines (argument) and produces tags metadata as a list of tag entries.
+function! s:scan_tags(lines, page_name)
+
+ let entries = []
+
+ " Code wireframe to scan for headers -- borrowed from
+ " vimwiki#base#get_anchors(), with minor modifications.
+
+ let rxheader = vimwiki#vars#get_syntaxlocal('header_search')
+ let rxtag = vimwiki#vars#get_syntaxlocal('tag_search')
+
+ let anchor_level = ['', '', '', '', '', '', '']
+ let current_complete_anchor = ''
+
+ let PROXIMITY_LINES_NR = 2
+ let header_line_nr = - (2 * PROXIMITY_LINES_NR)
+
+ for line_nr in range(1, len(a:lines))
+ let line = a:lines[line_nr - 1]
+
+ " process headers
+ let h_match = matchlist(line, rxheader)
+ if !empty(h_match) " got a header
+ let header_line_nr = line_nr
+ let header = vimwiki#u#trim(h_match[2])
+ let level = len(h_match[1])
+ let anchor_level[level-1] = header
+ for l in range(level, 6)
+ let anchor_level[l] = ''
+ endfor
+ 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
+ endif
+ continue " tags are not allowed in headers
+ endif
+
+ " TODO ignore verbatim blocks
+
+ " Scan line for tags. There can be many of them.
+ let str = line
+ while 1
+ let tag_group = matchstr(str, rxtag)
+ if tag_group == ''
+ break
+ endif
+ let tagend = matchend(str, rxtag)
+ let str = str[(tagend):]
+ for tag in split(tag_group, ':')
+ " Create metadata entry
+ let entry = {}
+ let entry.tagname = tag
+ let entry.lineno = line_nr
+ if line_nr <= PROXIMITY_LINES_NR && header_line_nr < 0
+ " Tag appeared at the top of the file
+ let entry.link = a:page_name
+ elseif line_nr <= (header_line_nr + PROXIMITY_LINES_NR)
+ " Tag appeared right below a header
+ let entry.link = a:page_name . '#' . current_complete_anchor
+ else
+ " Tag stands on its own
+ let entry.link = a:page_name . '#' . tag
+ endif
+ call add(entries, entry)
+ endfor
+ endwhile
+
+ endfor " loop over lines
+ return entries
+endfunction
+
+
+" Returns tags metadata file path
+function! vimwiki#tags#metadata_file_path() abort
+ return fnamemodify(vimwiki#path#join_path(vimwiki#vars#get_wikilocal('path'),
+ \ s:TAGS_METADATA_FILE_NAME), ':p')
+endfunction
+
+
+" Loads tags metadata from file, returns a dictionary
+function! s:load_tags_metadata() abort
+ let metadata_path = vimwiki#tags#metadata_file_path()
+ if !filereadable(metadata_path)
+ return {}
+ endif
+ let metadata = {}
+ for line in readfile(metadata_path)
+ if line =~ '^!_TAG_FILE_'
+ continue
+ endif
+ let parts = matchlist(line, '^\(.\{-}\);"\(.*\)$')
+ if parts[0] == '' || parts[1] == '' || parts[2] == ''
+ throw 'VimwikiTags1: Metadata file corrupted'
+ endif
+ let std_fields = split(parts[1], '\t')
+ if len(std_fields) != 3
+ throw 'VimwikiTags2: Metadata file corrupted'
+ endif
+ let vw_part = parts[2]
+ if vw_part[0] != "\t"
+ throw 'VimwikiTags3: Metadata file corrupted'
+ endif
+ let vw_fields = split(vw_part[1:], "\t")
+ if len(vw_fields) != 1 || vw_fields[0] !~ '^vimwiki:'
+ throw 'VimwikiTags4: Metadata file corrupted'
+ endif
+ let vw_data = substitute(vw_fields[0], '^vimwiki:', '', '')
+ let vw_data = substitute(vw_data, '\\n', "\n", 'g')
+ let vw_data = substitute(vw_data, '\\r', "\r", 'g')
+ let vw_data = substitute(vw_data, '\\t', "\t", 'g')
+ let vw_data = substitute(vw_data, '\\\\', "\\", 'g')
+ let vw_fields = split(vw_data, "\t")
+ if len(vw_fields) != 2
+ throw 'VimwikiTags5: Metadata file corrupted'
+ endif
+ let pagename = vw_fields[0]
+ let entry = {}
+ let entry.tagname = std_fields[0]
+ let entry.lineno = std_fields[2]
+ let entry.link = vw_fields[1]
+ if has_key(metadata, pagename)
+ call add(metadata[pagename], entry)
+ else
+ let metadata[pagename] = [entry]
+ endif
+ endfor
+ return metadata
+endfunction
+
+
+" Removes all entries for given page from metadata in-place. Returns updated
+" metadata (just in case).
+function! s:remove_page_from_tags(metadata, page_name)
+ if has_key(a:metadata, a:page_name)
+ call remove(a:metadata, a:page_name)
+ return a:metadata
+ else
+ return a:metadata
+ endif
+endfunction
+
+
+" Merges metadata of one file into a:metadata
+function! s:merge_tags(metadata, pagename, file_metadata)
+ let metadata = a:metadata
+ let metadata[a:pagename] = a:file_metadata
+ return metadata
+endfunction
+
+
+" Compares two actual lines from tags file. Return value is in strcmp style.
+" See help on sort() -- that's what this function is going to be used for.
+" See also s:write_tags_metadata below -- that's where we compose these tags
+" file lines.
+"
+" This function is needed for tags sorting, since plain sort() compares line
+" numbers as strings, not integers, and so, for example, tag at line 14
+" preceeds the same tag on the same page at line 9. (Because string "14" is
+" alphabetically 'less than' string "9".)
+function! s:tags_entry_cmp(i1, i2)
+ let items = []
+ for orig_item in [a:i1, a:i2]
+ let fields = split(orig_item, "\t")
+ let item = {}
+ let item.text = fields[0]."\t".fields[1]
+ let item.lineno = 0 + matchstr(fields[2], '\m\d\+')
+ call add(items, item)
+ endfor
+ if items[0].text ># items[1].text
+ return 1
+ elseif items[0].text <# items[1].text
+ return -1
+ elseif items[0].lineno > items[1].lineno
+ return 1
+ elseif items[0].lineno < items[1].lineno
+ return -1
+ else
+ return 0
+ endif
+endfunction
+
+
+" Saves metadata object into a file. Throws exceptions in case of problems.
+function! s:write_tags_metadata(metadata)
+ let metadata_path = vimwiki#tags#metadata_file_path()
+ let tags = []
+ for pagename in keys(a:metadata)
+ for entry in a:metadata[pagename]
+ let entry_data = pagename . "\t" . entry.link
+ let entry_data = substitute(entry_data, "\\", '\\\\', 'g')
+ let entry_data = substitute(entry_data, "\t", '\\t', 'g')
+ let entry_data = substitute(entry_data, "\r", '\\r', 'g')
+ let entry_data = substitute(entry_data, "\n", '\\n', 'g')
+ call add(tags,
+ \ entry.tagname . "\t"
+ \ . pagename . vimwiki#vars#get_wikilocal('ext') . "\t"
+ \ . entry.lineno
+ \ . ';"'
+ \ . "\t" . "vimwiki:" . entry_data
+ \)
+ endfor
+ endfor
+ call sort(tags, "s:tags_entry_cmp")
+ call insert(tags, "!_TAG_FILE_SORTED\t1\t")
+ call writefile(tags, metadata_path)
+endfunction
+
+
+" Returns list of unique tags found in the .tags file
+function! vimwiki#tags#get_tags()
+ let metadata = s:load_tags_metadata()
+ let tags = {}
+ for entries in values(metadata)
+ for entry in entries
+ let tags[entry.tagname] = 1
+ endfor
+ endfor
+ return keys(tags)
+endfunction
+
+
+" Similar to vimwiki#base#generate_links. In the current buffer, appends
+" tags and references to all their instances. If no arguments (tags) are
+" specified, outputs all tags.
+function! vimwiki#tags#generate_tags(...) abort
+ let need_all_tags = (a:0 == 0)
+ let specific_tags = a:000
+
+ let metadata = s:load_tags_metadata()
+
+ " make a dictionary { tag_name: [tag_links, ...] }
+ let tags_entries = {}
+ for entries in values(metadata)
+ for entry in entries
+ if has_key(tags_entries, entry.tagname)
+ call add(tags_entries[entry.tagname], entry.link)
+ else
+ let tags_entries[entry.tagname] = [entry.link]
+ endif
+ endfor
+ endfor
+
+ let lines = []
+ let bullet = repeat(' ', vimwiki#lst#get_list_margin()).vimwiki#lst#default_symbol().' '
+ for tagname in sort(keys(tags_entries))
+ if need_all_tags || index(specific_tags, tagname) != -1
+ call extend(lines, [
+ \ '',
+ \ substitute(vimwiki#vars#get_syntaxlocal('rxH2_Template'), '__Header__', tagname, ''),
+ \ '' ])
+ for taglink in sort(tags_entries[tagname])
+ call add(lines, bullet . substitute(vimwiki#vars#get_global('WikiLinkTemplate1'),
+ \ '__LinkUrl__', taglink, ''))
+ endfor
+ endif
+ endfor
+
+ let links_rx = '\m\%(^\s*$\)\|\%('.vimwiki#vars#get_syntaxlocal('rxH2').'\)\|\%(^\s*'
+ \ .vimwiki#u#escape(vimwiki#lst#default_symbol()).' '
+ \ .vimwiki#vars#get_syntaxlocal('rxWikiLink').'$\)'
+
+ call vimwiki#base#update_listing_in_buffer(lines, 'Generated Tags', links_rx, line('$')+1, 1)
+endfunction
+
+
+function! vimwiki#tags#complete_tags(ArgLead, CmdLine, CursorPos) abort
+ " We can safely ignore args if we use -custom=complete option, Vim engine
+ " will do the job of filtering.
+ let taglist = vimwiki#tags#get_tags()
+ return join(taglist, "\n")
+endfunction
+
diff --git a/.config/nvim/autoload/vimwiki/tbl.vim b/.config/nvim/autoload/vimwiki/tbl.vim
@@ -0,0 +1,703 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Description: Tables
+" | Easily | manageable | text | tables | ! |
+" |--------|------------|-------|--------|---------|
+" | Have | fun! | Drink | tea | Period. |
+"
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+
+if exists("g:loaded_vimwiki_tbl_auto") || &cp
+ finish
+endif
+let g:loaded_vimwiki_tbl_auto = 1
+
+
+let s:textwidth = &tw
+
+
+function! s:rxSep()
+ return vimwiki#vars#get_syntaxlocal('rxTableSep')
+endfunction
+
+
+function! s:wide_len(str)
+ " vim73 has new function that gives correct string width.
+ if exists("*strdisplaywidth")
+ return strdisplaywidth(a:str)
+ endif
+
+ " get str display width in vim ver < 7.2
+ if !vimwiki#vars#get_global('CJK_length')
+ let ret = strlen(substitute(a:str, '.', 'x', 'g'))
+ else
+ let savemodified = &modified
+ let save_cursor = getpos('.')
+ exe "norm! o\<esc>"
+ call setline(line("."), a:str)
+ let ret = virtcol("$") - 1
+ d
+ call setpos('.', save_cursor)
+ let &modified = savemodified
+ endif
+ return ret
+endfunction
+
+
+function! s:cell_splitter()
+ return '\s*'.s:rxSep().'\s*'
+endfunction
+
+
+function! s:sep_splitter()
+ return '-'.s:rxSep().'-'
+endfunction
+
+
+function! s:is_table(line)
+ return s:is_separator(a:line) ||
+ \ (a:line !~# s:rxSep().s:rxSep() && a:line =~# '^\s*'.s:rxSep().'.\+'.s:rxSep().'\s*$')
+endfunction
+
+
+function! s:is_separator(line)
+ return a:line =~# '^\s*'.s:rxSep().'\(--\+'.s:rxSep().'\)\+\s*$'
+endfunction
+
+
+function! s:is_separator_tail(line)
+ return a:line =~# '^\{-1}\%(\s*\|-*\)\%('.s:rxSep().'-\+\)\+'.s:rxSep().'\s*$'
+endfunction
+
+
+function! s:is_last_column(lnum, cnum)
+ let line = strpart(getline(a:lnum), a:cnum - 1)
+ return line =~# s:rxSep().'\s*$' && line !~# s:rxSep().'.*'.s:rxSep().'\s*$'
+endfunction
+
+
+function! s:is_first_column(lnum, cnum)
+ let line = strpart(getline(a:lnum), 0, a:cnum - 1)
+ return line =~# '^\s*$' ||
+ \ (line =~# '^\s*'.s:rxSep() && line !~# '^\s*'.s:rxSep().'.*'.s:rxSep())
+endfunction
+
+
+function! s:count_separators_up(lnum)
+ let lnum = a:lnum - 1
+ while lnum > 1
+ if !s:is_separator(getline(lnum))
+ break
+ endif
+ let lnum -= 1
+ endwhile
+
+ return (a:lnum-lnum)
+endfunction
+
+
+function! s:count_separators_down(lnum)
+ let lnum = a:lnum + 1
+ while lnum < line('$')
+ if !s:is_separator(getline(lnum))
+ break
+ endif
+ let lnum += 1
+ endwhile
+
+ return (lnum-a:lnum)
+endfunction
+
+
+function! s:create_empty_row(cols)
+ let row = s:rxSep()
+ let cell = " ".s:rxSep()
+
+ for c in range(a:cols)
+ let row .= cell
+ endfor
+
+ return row
+endfunction
+
+
+function! s:create_row_sep(cols)
+ let row = s:rxSep()
+ let cell = "---".s:rxSep()
+
+ for c in range(a:cols)
+ let row .= cell
+ endfor
+
+ return row
+endfunction
+
+
+function! vimwiki#tbl#get_cells(line)
+ let result = []
+ let cell = ''
+ let quote = ''
+ let state = 'NONE'
+
+ " 'Simple' FSM
+ for idx in range(strlen(a:line))
+ " The only way I know Vim can do Unicode...
+ let ch = a:line[idx]
+ if state ==# 'NONE'
+ if ch == '|'
+ let state = 'CELL'
+ endif
+ elseif state ==# 'CELL'
+ if ch == '[' || ch == '{'
+ let state = 'BEFORE_QUOTE_START'
+ let quote = ch
+ elseif ch == '|'
+ call add(result, vimwiki#u#trim(cell))
+ let cell = ""
+ else
+ let cell .= ch
+ endif
+ elseif state ==# 'BEFORE_QUOTE_START'
+ if ch == '[' || ch == '{'
+ let state = 'QUOTE'
+ let quote .= ch
+ else
+ let state = 'CELL'
+ let cell .= quote.ch
+ let quote = ''
+ endif
+ elseif state ==# 'QUOTE'
+ if ch == ']' || ch == '}'
+ let state = 'BEFORE_QUOTE_END'
+ endif
+ let quote .= ch
+ elseif state ==# 'BEFORE_QUOTE_END'
+ if ch == ']' || ch == '}'
+ let state = 'CELL'
+ endif
+ let cell .= quote.ch
+ let quote = ''
+ endif
+ endfor
+
+ if cell.quote != ''
+ call add(result, vimwiki#u#trim(cell.quote, '|'))
+ endif
+ return result
+endfunction
+
+
+function! s:col_count(lnum)
+ return len(vimwiki#tbl#get_cells(getline(a:lnum)))
+endfunction
+
+
+function! s:get_indent(lnum)
+ if !s:is_table(getline(a:lnum))
+ return
+ endif
+
+ let indent = 0
+
+ let lnum = a:lnum - 1
+ while lnum > 1
+ let line = getline(lnum)
+ if !s:is_table(line)
+ let indent = indent(lnum+1)
+ break
+ endif
+ let lnum -= 1
+ endwhile
+
+ return indent
+endfunction
+
+
+function! s:get_rows(lnum)
+ if !s:is_table(getline(a:lnum))
+ return
+ endif
+
+ let upper_rows = []
+ let lower_rows = []
+
+ let lnum = a:lnum - 1
+ while lnum >= 1
+ let line = getline(lnum)
+ if s:is_table(line)
+ call add(upper_rows, [lnum, line])
+ else
+ break
+ endif
+ let lnum -= 1
+ endwhile
+ call reverse(upper_rows)
+
+ let lnum = a:lnum
+ while lnum <= line('$')
+ let line = getline(lnum)
+ if s:is_table(line)
+ call add(lower_rows, [lnum, line])
+ else
+ break
+ endif
+ let lnum += 1
+ endwhile
+
+ return upper_rows + lower_rows
+endfunction
+
+
+function! s:get_cell_max_lens(lnum, ...)
+ let max_lens = {}
+ for [lnum, row] in s:get_rows(a:lnum)
+ if s:is_separator(row)
+ continue
+ endif
+ let cells = a:0 > 1 ? a:1[lnum - a:2] : vimwiki#tbl#get_cells(row)
+ for idx in range(len(cells))
+ let value = cells[idx]
+ if has_key(max_lens, idx)
+ let max_lens[idx] = max([s:wide_len(value), max_lens[idx]])
+ else
+ let max_lens[idx] = s:wide_len(value)
+ endif
+ endfor
+ endfor
+ return max_lens
+endfunction
+
+
+function! s:get_aligned_rows(lnum, col1, col2)
+ let rows = s:get_rows(a:lnum)
+ let startlnum = rows[0][0]
+ let cells = []
+ for [lnum, row] in rows
+ call add(cells, vimwiki#tbl#get_cells(row))
+ endfor
+ let max_lens = s:get_cell_max_lens(a:lnum, cells, startlnum)
+ let result = []
+ for [lnum, row] in rows
+ if s:is_separator(row)
+ let new_row = s:fmt_sep(max_lens, a:col1, a:col2)
+ else
+ let new_row = s:fmt_row(cells[lnum - startlnum], max_lens, a:col1, a:col2)
+ endif
+ call add(result, [lnum, new_row])
+ endfor
+ return result
+endfunction
+
+
+" Number of the current column. Starts from 0.
+function! s:cur_column()
+ let line = getline('.')
+ if !s:is_table(line)
+ return -1
+ endif
+ " TODO: do we need conditional: if s:is_separator(line)
+
+ let curs_pos = col('.')
+ let mpos = match(line, s:rxSep(), 0)
+ let col = -1
+ while mpos < curs_pos && mpos != -1
+ let mpos = match(line, s:rxSep(), mpos+1)
+ if mpos != -1
+ let col += 1
+ endif
+ endwhile
+ return col
+endfunction
+
+
+function! s:fmt_cell(cell, max_len)
+ let cell = ' '.a:cell.' '
+
+ let diff = a:max_len - s:wide_len(a:cell)
+ if diff == 0 && empty(a:cell)
+ let diff = 1
+ endif
+
+ let cell .= repeat(' ', diff)
+ return cell
+endfunction
+
+
+function! s:fmt_row(cells, max_lens, col1, col2)
+ let new_line = s:rxSep()
+ for idx in range(len(a:cells))
+ if idx == a:col1
+ let idx = a:col2
+ elseif idx == a:col2
+ let idx = a:col1
+ endif
+ let value = a:cells[idx]
+ let new_line .= s:fmt_cell(value, a:max_lens[idx]).s:rxSep()
+ endfor
+
+ let idx = len(a:cells)
+ while idx < len(a:max_lens)
+ let new_line .= s:fmt_cell('', a:max_lens[idx]).s:rxSep()
+ let idx += 1
+ endwhile
+ return new_line
+endfunction
+
+
+function! s:fmt_cell_sep(max_len)
+ if a:max_len == 0
+ return repeat('-', 3)
+ else
+ return repeat('-', a:max_len+2)
+ endif
+endfunction
+
+
+function! s:fmt_sep(max_lens, col1, col2)
+ let new_line = s:rxSep()
+ for idx in range(len(a:max_lens))
+ if idx == a:col1
+ let idx = a:col2
+ elseif idx == a:col2
+ let idx = a:col1
+ endif
+ let new_line .= s:fmt_cell_sep(a:max_lens[idx]).s:rxSep()
+ endfor
+ return new_line
+endfunction
+
+
+function! s:kbd_create_new_row(cols, goto_first)
+ let cmd = "\<ESC>o".s:create_empty_row(a:cols)
+ let cmd .= "\<ESC>:call vimwiki#tbl#format(line('.'))\<CR>"
+ let cmd .= "\<ESC>0"
+ if a:goto_first
+ let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'c', line('.'))\<CR>"
+ else
+ let cmd .= (col('.')-1)."l"
+ let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\<CR>"
+ endif
+ let cmd .= "a"
+
+ return cmd
+endfunction
+
+
+function! s:kbd_goto_next_row()
+ let cmd = "\<ESC>j"
+ let cmd .= ":call search('.\\(".s:rxSep()."\\)', 'c', line('.'))\<CR>"
+ let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\<CR>"
+ let cmd .= "a"
+ return cmd
+endfunction
+
+
+function! s:kbd_goto_prev_row()
+ let cmd = "\<ESC>k"
+ let cmd .= ":call search('.\\(".s:rxSep()."\\)', 'c', line('.'))\<CR>"
+ let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\<CR>"
+ let cmd .= "a"
+ return cmd
+endfunction
+
+
+" Used in s:kbd_goto_next_col
+function! vimwiki#tbl#goto_next_col()
+ let curcol = virtcol('.')
+ let lnum = line('.')
+ let newcol = s:get_indent(lnum)
+ let max_lens = s:get_cell_max_lens(lnum)
+ for cell_len in values(max_lens)
+ if newcol >= curcol-1
+ break
+ endif
+ let newcol += cell_len + 3 " +3 == 2 spaces + 1 separator |<space>...<space>
+ endfor
+ let newcol += 2 " +2 == 1 separator + 1 space |<space
+ call vimwiki#u#cursor(lnum, newcol)
+endfunction
+
+
+function! s:kbd_goto_next_col(jumpdown)
+ let cmd = "\<ESC>"
+ if a:jumpdown
+ let seps = s:count_separators_down(line('.'))
+ let cmd .= seps."j0"
+ endif
+ let cmd .= ":call vimwiki#tbl#goto_next_col()\<CR>a"
+ return cmd
+endfunction
+
+
+" Used in s:kbd_goto_prev_col
+function! vimwiki#tbl#goto_prev_col()
+ let curcol = virtcol('.')
+ let lnum = line('.')
+ let newcol = s:get_indent(lnum)
+ let max_lens = s:get_cell_max_lens(lnum)
+ let prev_cell_len = 0
+ for cell_len in values(max_lens)
+ let delta = cell_len + 3 " +3 == 2 spaces + 1 separator |<space>...<space>
+ if newcol + delta > curcol-1
+ let newcol -= (prev_cell_len + 3) " +3 == 2 spaces + 1 separator |<space>...<space>
+ break
+ elseif newcol + delta == curcol-1
+ break
+ endif
+ let prev_cell_len = cell_len
+ let newcol += delta
+ endfor
+ let newcol += 2 " +2 == 1 separator + 1 space |<space
+ call vimwiki#u#cursor(lnum, newcol)
+endfunction
+
+
+function! s:kbd_goto_prev_col(jumpup)
+ let cmd = "\<ESC>"
+ if a:jumpup
+ let seps = s:count_separators_up(line('.'))
+ let cmd .= seps."k"
+ let cmd .= "$"
+ endif
+ let cmd .= ":call vimwiki#tbl#goto_prev_col()\<CR>a"
+ " let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'b', line('.'))\<CR>"
+ " let cmd .= "a"
+ "echomsg "DEBUG kbd_goto_prev_col> ".cmd
+ return cmd
+endfunction
+
+
+function! vimwiki#tbl#kbd_cr()
+ let lnum = line('.')
+ if !s:is_table(getline(lnum))
+ return ""
+ endif
+
+ if s:is_separator(getline(lnum+1)) || !s:is_table(getline(lnum+1))
+ let cols = len(vimwiki#tbl#get_cells(getline(lnum)))
+ return s:kbd_create_new_row(cols, 0)
+ else
+ return s:kbd_goto_next_row()
+ endif
+endfunction
+
+
+function! vimwiki#tbl#kbd_tab()
+ let lnum = line('.')
+ if !s:is_table(getline(lnum))
+ return "\<Tab>"
+ endif
+
+ let last = s:is_last_column(lnum, col('.'))
+ let is_sep = s:is_separator_tail(getline(lnum))
+ "echomsg "DEBUG kbd_tab> last=".last.", is_sep=".is_sep
+ if (is_sep || last) && !s:is_table(getline(lnum+1))
+ let cols = len(vimwiki#tbl#get_cells(getline(lnum)))
+ return s:kbd_create_new_row(cols, 1)
+ endif
+ return s:kbd_goto_next_col(is_sep || last)
+endfunction
+
+
+function! vimwiki#tbl#kbd_shift_tab()
+ let lnum = line('.')
+ if !s:is_table(getline(lnum))
+ return "\<S-Tab>"
+ endif
+
+ let first = s:is_first_column(lnum, col('.'))
+ let is_sep = s:is_separator_tail(getline(lnum))
+ "echomsg "DEBUG kbd_tab> ".first
+ if (is_sep || first) && !s:is_table(getline(lnum-1))
+ return ""
+ endif
+ return s:kbd_goto_prev_col(is_sep || first)
+endfunction
+
+
+function! vimwiki#tbl#format(lnum, ...)
+ if !(&filetype ==? 'vimwiki')
+ return
+ endif
+ let line = getline(a:lnum)
+ if !s:is_table(line)
+ return
+ endif
+
+ if a:0 == 2
+ let col1 = a:1
+ let col2 = a:2
+ else
+ let col1 = 0
+ let col2 = 0
+ endif
+
+ let indent = s:get_indent(a:lnum)
+ if &expandtab
+ let indentstring = repeat(' ', indent)
+ else
+ let indentstring = repeat(' ', indent / &tabstop) . repeat(' ', indent % &tabstop)
+ endif
+
+ for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2)
+ let row = indentstring.row
+ call setline(lnum, row)
+ endfor
+
+ let &tw = s:textwidth
+endfunction
+
+
+function! vimwiki#tbl#create(...)
+ if a:0 > 1
+ let cols = a:1
+ let rows = a:2
+ elseif a:0 == 1
+ let cols = a:1
+ let rows = 2
+ elseif a:0 == 0
+ let cols = 5
+ let rows = 2
+ endif
+
+ if cols < 1
+ let cols = 5
+ endif
+
+ if rows < 1
+ let rows = 2
+ endif
+
+ let lines = []
+ let row = s:create_empty_row(cols)
+
+ call add(lines, row)
+ if rows > 1
+ call add(lines, s:create_row_sep(cols))
+ endif
+
+ for r in range(rows - 1)
+ call add(lines, row)
+ endfor
+
+ call append(line('.'), lines)
+endfunction
+
+
+function! vimwiki#tbl#align_or_cmd(cmd)
+ if s:is_table(getline('.'))
+ call vimwiki#tbl#format(line('.'))
+ else
+ exe 'normal! '.a:cmd
+ endif
+endfunction
+
+
+function! vimwiki#tbl#reset_tw(lnum)
+ if !(&filetype ==? 'vimwiki')
+ return
+ endif
+ let line = getline(a:lnum)
+ if !s:is_table(line)
+ return
+ endif
+
+ let s:textwidth = &tw
+ let &tw = 0
+endfunction
+
+
+" TODO: move_column_left and move_column_right are good candidates to be refactored.
+function! vimwiki#tbl#move_column_left()
+
+ "echomsg "DEBUG move_column_left: "
+
+ let line = getline('.')
+
+ if !s:is_table(line)
+ return
+ endif
+
+ let cur_col = s:cur_column()
+ if cur_col == -1
+ return
+ endif
+
+ if cur_col > 0
+ call vimwiki#tbl#format(line('.'), cur_col-1, cur_col)
+ call cursor(line('.'), 1)
+
+ let sep = '\('.s:rxSep().'\).\zs'
+ let mpos = -1
+ let col = -1
+ while col < cur_col-1
+ let mpos = match(line, sep, mpos+1)
+ if mpos != -1
+ let col += 1
+ else
+ break
+ endif
+ endwhile
+
+ endif
+endfunction
+
+
+function! vimwiki#tbl#move_column_right()
+
+ let line = getline('.')
+
+ if !s:is_table(line)
+ return
+ endif
+
+ let cur_col = s:cur_column()
+ if cur_col == -1
+ return
+ endif
+
+ if cur_col < s:col_count(line('.'))-1
+ call vimwiki#tbl#format(line('.'), cur_col, cur_col+1)
+ call cursor(line('.'), 1)
+
+ let sep = '\('.s:rxSep().'\).\zs'
+ let mpos = -1
+ let col = -1
+ while col < cur_col+1
+ let mpos = match(line, sep, mpos+1)
+ if mpos != -1
+ let col += 1
+ else
+ break
+ endif
+ endwhile
+ endif
+endfunction
+
+
+function! vimwiki#tbl#get_rows(lnum)
+ return s:get_rows(a:lnum)
+endfunction
+
+
+function! vimwiki#tbl#is_table(line)
+ return s:is_table(a:line)
+endfunction
+
+
+function! vimwiki#tbl#is_separator(line)
+ return s:is_separator(a:line)
+endfunction
+
+
+function! vimwiki#tbl#cell_splitter()
+ return s:cell_splitter()
+endfunction
+
+
+function! vimwiki#tbl#sep_splitter()
+ return s:sep_splitter()
+endfunction
+
diff --git a/.config/nvim/autoload/vimwiki/u.vim b/.config/nvim/autoload/vimwiki/u.vim
@@ -0,0 +1,72 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Description: Utility functions
+" Home: https://github.com/vimwiki/vimwiki/
+
+function! vimwiki#u#trim(string, ...)
+ let chars = ''
+ if a:0 > 0
+ let chars = a:1
+ endif
+ let res = substitute(a:string, '^[[:space:]'.chars.']\+', '', '')
+ let res = substitute(res, '[[:space:]'.chars.']\+$', '', '')
+ return res
+endfunction
+
+
+" Builtin cursor doesn't work right with unicode characters.
+function! vimwiki#u#cursor(lnum, cnum)
+ exe a:lnum
+ exe 'normal! 0'.a:cnum.'|'
+endfunction
+
+
+function! vimwiki#u#is_windows()
+ return has("win32") || has("win64") || has("win95") || has("win16")
+endfunction
+
+
+function! vimwiki#u#is_macos()
+ if has("mac") || has("macunix") || has("gui_mac")
+ return 1
+ endif
+ " that still doesn't mean we are not on Mac OS
+ let os = substitute(system('uname'), '\n', '', '')
+ return os == 'Darwin' || os == 'Mac'
+endfunction
+
+
+function! vimwiki#u#count_first_sym(line)
+ let first_sym = matchstr(a:line, '\S')
+ return len(matchstr(a:line, first_sym.'\+'))
+endfunction
+
+
+function! vimwiki#u#escape(string)
+ return escape(a:string, '~.*[]\^$')
+endfunction
+
+
+" Load concrete Wiki syntax: sets regexes and templates for headers and links
+function vimwiki#u#reload_regexes()
+ execute 'runtime! syntax/vimwiki_'.vimwiki#vars#get_wikilocal('syntax').'.vim'
+endfunction
+
+
+" Load syntax-specific functionality
+function vimwiki#u#reload_regexes_custom()
+ execute 'runtime! syntax/vimwiki_'.vimwiki#vars#get_wikilocal('syntax').'_custom.vim'
+endfunction
+
+
+" Backward compatible version of the built-in function shiftwidth()
+if exists('*shiftwidth')
+ func vimwiki#u#sw()
+ return shiftwidth()
+ endfunc
+else
+ func vimwiki#u#sw()
+ return &sw
+ endfunc
+endif
+
diff --git a/.config/nvim/autoload/vimwiki/vars.vim b/.config/nvim/autoload/vimwiki/vars.vim
@@ -0,0 +1,850 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki autoload plugin file
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+
+" ------------------------------------------------------------------------------------------------
+" This file provides functions to manage the various state variables which are needed during a
+" Vimwiki session.
+" They consist of:
+"
+" - global variables. These are stored in the dict g:vimwiki_global_vars. They consist mainly of
+" global user variables and syntax stuff which is the same for every syntax.
+"
+" - wiki-local variables. They are stored in g:vimwiki_wikilocal_vars which is a list of
+" dictionaries, one dict for every registered wiki. The last dictionary contains default values
+" (used for temporary wikis).
+"
+" - syntax variables. Stored in the dict g:vimwiki_syntax_variables which holds all the regexes and
+" other stuff which is needed for highlighting.
+"
+" - buffer-local variables. They are stored as buffer variables directly (b:foo)
+
+" As a developer, you should, if possible, only use the get_ and set_ functions for these types of
+" variables, not the underlying dicts!
+" ------------------------------------------------------------------------------------------------
+
+
+function! s:populate_global_variables()
+
+ let g:vimwiki_global_vars = {}
+
+ call s:read_global_settings_from_user()
+ call s:normalize_global_settings()
+
+ " non-configurable global variables:
+
+ " Scheme regexes must be defined even if syntax file is not loaded yet cause users should be
+ " able to <leader>w<leader>w without opening any vimwiki file first
+ let g:vimwiki_global_vars.schemes = join(['wiki\d\+', 'diary', 'local'], '\|')
+ let g:vimwiki_global_vars.web_schemes1 = join(['http', 'https', 'file', 'ftp', 'gopher',
+ \ 'telnet', 'nntp', 'ldap', 'rsync', 'imap', 'pop', 'irc', 'ircs', 'cvs', 'svn', 'svn+ssh',
+ \ 'git', 'ssh', 'fish', 'sftp'], '\|')
+ let web_schemes2 =
+ \ join(['mailto', 'news', 'xmpp', 'sip', 'sips', 'doi', 'urn', 'tel', 'data'], '\|')
+
+ let g:vimwiki_global_vars.rxSchemes = '\%('.
+ \ g:vimwiki_global_vars.schemes . '\|'.
+ \ g:vimwiki_global_vars.web_schemes1 . '\|'.
+ \ web_schemes2 .
+ \ '\)'
+
+ " match URL for common protocols; see http://en.wikipedia.org/wiki/URI_scheme
+ " http://tools.ietf.org/html/rfc3986
+ let rxWebProtocols =
+ \ '\%('.
+ \ '\%('.
+ \ '\%('.g:vimwiki_global_vars.web_schemes1 . '\):'.
+ \ '\%(//\)'.
+ \ '\)'.
+ \ '\|'.
+ \ '\%('.web_schemes2.'\):'.
+ \ '\)'
+
+ let g:vimwiki_global_vars.rxWeblinkUrl = rxWebProtocols . '\S\{-1,}'. '\%(([^ \t()]*)\)\='
+
+ let wikilink_prefix = '[['
+ let wikilink_suffix = ']]'
+ let wikilink_separator = '|'
+ let g:vimwiki_global_vars.rx_wikilink_prefix = vimwiki#u#escape(wikilink_prefix)
+ let g:vimwiki_global_vars.rx_wikilink_suffix = vimwiki#u#escape(wikilink_suffix)
+ let g:vimwiki_global_vars.rx_wikilink_separator = vimwiki#u#escape(wikilink_separator)
+
+ " templates for the creation of wiki links
+ " [[URL]]
+ let g:vimwiki_global_vars.WikiLinkTemplate1 = wikilink_prefix . '__LinkUrl__'. wikilink_suffix
+ " [[URL|DESCRIPTION]]
+ let g:vimwiki_global_vars.WikiLinkTemplate2 = wikilink_prefix . '__LinkUrl__'. wikilink_separator
+ \ . '__LinkDescription__' . wikilink_suffix
+
+ let valid_chars = '[^\\\]]'
+ let g:vimwiki_global_vars.rxWikiLinkUrl = valid_chars.'\{-}'
+ let g:vimwiki_global_vars.rxWikiLinkDescr = valid_chars.'\{-}'
+
+ " this regexp defines what can form a link when the user presses <CR> in the
+ " buffer (and not on a link) to create a link
+ " basically, it's Ascii alphanumeric characters plus #|./@-_~ plus all
+ " non-Ascii characters, except that . is not accepted as the last character
+ let g:vimwiki_global_vars.rxWord = '[^[:blank:]!"$%&''()*+,:;<=>?\[\]\\^`{}]*[^[:blank:]!"$%&''()*+.,:;<=>?\[\]\\^`{}]'
+
+ let g:vimwiki_global_vars.rx_wikilink_prefix1 = g:vimwiki_global_vars.rx_wikilink_prefix .
+ \ g:vimwiki_global_vars.rxWikiLinkUrl . g:vimwiki_global_vars.rx_wikilink_separator
+ let g:vimwiki_global_vars.rx_wikilink_suffix1 = g:vimwiki_global_vars.rx_wikilink_suffix
+
+ let g:vimwiki_global_vars.rxWikiInclPrefix = '{{'
+ let g:vimwiki_global_vars.rxWikiInclSuffix = '}}'
+ let g:vimwiki_global_vars.rxWikiInclSeparator = '|'
+ " '{{__LinkUrl__}}'
+ let g:vimwiki_global_vars.WikiInclTemplate1 = g:vimwiki_global_vars.rxWikiInclPrefix
+ \ .'__LinkUrl__'. g:vimwiki_global_vars.rxWikiInclSuffix
+ " '{{__LinkUrl____LinkDescription__}}'
+ let g:vimwiki_global_vars.WikiInclTemplate2 = g:vimwiki_global_vars.rxWikiInclPrefix
+ \ . '__LinkUrl__' . g:vimwiki_global_vars.rxWikiInclSeparator . '__LinkDescription__'
+ \ . g:vimwiki_global_vars.rxWikiInclSuffix
+
+ let valid_chars = '[^\\\}]'
+ let g:vimwiki_global_vars.rxWikiInclUrl = valid_chars.'\{-}'
+ let g:vimwiki_global_vars.rxWikiInclArg = valid_chars.'\{-}'
+ let g:vimwiki_global_vars.rxWikiInclArgs = '\%('. g:vimwiki_global_vars.rxWikiInclSeparator.
+ \ g:vimwiki_global_vars.rxWikiInclArg. '\)'.'\{-}'
+
+ " *. {{URL}[{...}]} - i.e. {{URL}}, {{URL|ARG1}}, {{URL|ARG1|ARG2}}, etc.
+ " *a) match {{URL}[{...}]}
+ let g:vimwiki_global_vars.rxWikiIncl = g:vimwiki_global_vars.rxWikiInclPrefix.
+ \ g:vimwiki_global_vars.rxWikiInclUrl.
+ \ g:vimwiki_global_vars.rxWikiInclArgs. g:vimwiki_global_vars.rxWikiInclSuffix
+ " *b) match URL within {{URL}[{...}]}
+ let g:vimwiki_global_vars.rxWikiInclMatchUrl = g:vimwiki_global_vars.rxWikiInclPrefix.
+ \ '\zs'. g:vimwiki_global_vars.rxWikiInclUrl . '\ze'.
+ \ g:vimwiki_global_vars.rxWikiInclArgs . g:vimwiki_global_vars.rxWikiInclSuffix
+
+ let g:vimwiki_global_vars.rxWikiInclPrefix1 = g:vimwiki_global_vars.rxWikiInclPrefix.
+ \ g:vimwiki_global_vars.rxWikiInclUrl . g:vimwiki_global_vars.rxWikiInclSeparator
+ let g:vimwiki_global_vars.rxWikiInclSuffix1 = g:vimwiki_global_vars.rxWikiInclArgs.
+ \ g:vimwiki_global_vars.rxWikiInclSuffix
+
+ let g:vimwiki_global_vars.rxTodo = '\C\<\%(TODO\|DONE\|STARTED\|FIXME\|FIXED\|XXX\)\>'
+
+ " default colors when headers of different levels are highlighted differently
+ " not making it yet another option; needed by ColorScheme autocommand
+ let g:vimwiki_global_vars.hcolor_guifg_light = ['#aa5858', '#507030', '#1030a0', '#103040'
+ \ , '#505050', '#636363']
+ let g:vimwiki_global_vars.hcolor_ctermfg_light = ['DarkRed', 'DarkGreen', 'DarkBlue', 'Black'
+ \ , 'Black', 'Black']
+ let g:vimwiki_global_vars.hcolor_guifg_dark = ['#e08090', '#80e090', '#6090e0', '#c0c0f0'
+ \ , '#e0e0f0', '#f0f0f0']
+ let g:vimwiki_global_vars.hcolor_ctermfg_dark = ['Red', 'Green', 'Blue', 'White', 'White'
+ \ , 'White']
+endfunction
+
+
+function! s:read_global_settings_from_user()
+ let global_settings = {
+ \ 'CJK_length': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'auto_chdir': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'autowriteall': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'conceallevel': {'type': type(0), 'default': 2, 'min': 0, 'max': 3},
+ \ 'diary_months': {'type': type({}), 'default':
+ \ {
+ \ 1: 'January', 2: 'February', 3: 'March',
+ \ 4: 'April', 5: 'May', 6: 'June',
+ \ 7: 'July', 8: 'August', 9: 'September',
+ \ 10: 'October', 11: 'November', 12: 'December'
+ \ }},
+ \ 'dir_link': {'type': type(''), 'default': ''},
+ \ 'ext2syntax': {'type': type({}), 'default': {}},
+ \ 'folding': {'type': type(''), 'default': '', 'possible_values': ['', 'expr', 'syntax',
+ \ 'list', 'custom', ':quick', 'expr:quick', 'syntax:quick', 'list:quick',
+ \ 'custom:quick']},
+ \ 'global_ext': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'hl_cb_checked': {'type': type(0), 'default': 0, 'min': 0, 'max': 2},
+ \ 'hl_headers': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'html_header_numbering': {'type': type(0), 'default': 0, 'min': 0, 'max': 6},
+ \ 'html_header_numbering_sym': {'type': type(''), 'default': ''},
+ \ 'list_ignore_newline': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'text_ignore_newline': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'listsyms': {'type': type(''), 'default': ' .oOX', 'min_length': 2},
+ \ 'listsym_rejected': {'type': type(''), 'default': '-', 'length': 1},
+ \ 'map_prefix': {'type': type(''), 'default': '<Leader>w'},
+ \ 'menu': {'type': type(''), 'default': 'Vimwiki'},
+ \ 'table_auto_fmt': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'table_mappings': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'toc_header': {'type': type(''), 'default': 'Contents', 'min_length': 1},
+ \ 'url_maxsave': {'type': type(0), 'default': 15, 'min': 0},
+ \ 'use_calendar': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'use_mouse': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'user_htmls': {'type': type(''), 'default': ''},
+ \ 'valid_html_tags': {'type': type(''), 'default':
+ \ 'b,i,s,u,sub,sup,kbd,br,hr,div,center,strong,em'},
+ \ 'w32_dir_enc': {'type': type(''), 'default': ''},
+ \ }
+
+ " copy the user's settings from variables of the form g:vimwiki_<option> into the dict
+ " g:vimwiki_global_vars (or set a default value)
+ for key in keys(global_settings)
+ if exists('g:vimwiki_'.key)
+ let users_value = g:vimwiki_{key}
+ let value_infos = global_settings[key]
+
+ call s:check_users_value(key, users_value, value_infos, 1)
+
+ let g:vimwiki_global_vars[key] = users_value
+ else
+ let g:vimwiki_global_vars[key] = global_settings[key].default
+ endif
+ endfor
+
+ " validate some settings individually
+
+ let key = 'diary_months'
+ let users_value = g:vimwiki_global_vars[key]
+ for month in range(1, 12)
+ if !has_key(users_value, month) || type(users_value[month]) != type('') ||
+ \ empty(users_value[month])
+ echom printf('Vimwiki Error: The provided value ''%s'' of the option ''g:vimwiki_%s'' is'
+ \ . ' invalid. See '':h g:vimwiki_%s''.', string(users_value), key, key)
+ break
+ endif
+ endfor
+
+ let key = 'ext2syntax'
+ let users_value = g:vimwiki_global_vars[key]
+ for ext in keys(users_value)
+ if empty(ext) || index(['markdown', 'media', 'mediawiki', 'default'], users_value[ext]) == -1
+ echom printf('Vimwiki Error: The provided value ''%s'' of the option ''g:vimwiki_%s'' is'
+ \ . ' invalid. See '':h g:vimwiki_%s''.', string(users_value), key, key)
+ break
+ endif
+ endfor
+
+endfunction
+
+
+function! s:normalize_global_settings()
+ let keys = keys(g:vimwiki_global_vars.ext2syntax)
+ for ext in keys
+ " ensure the file extensions in ext2syntax start with a dot
+ if ext[0] != '.'
+ let new_ext = '.' . ext
+ let g:vimwiki_global_vars.ext2syntax[new_ext] = g:vimwiki_global_vars.ext2syntax[ext]
+ call remove(g:vimwiki_global_vars.ext2syntax, ext)
+ endif
+ " for convenience, we also allow the term 'mediawiki'
+ if g:vimwiki_global_vars.ext2syntax[ext] ==# 'mediawiki'
+ let g:vimwiki_global_vars.ext2syntax[ext] = 'media'
+ endif
+ endfor
+endfunction
+
+
+function! s:populate_wikilocal_options()
+ let default_values = {
+ \ 'auto_diary_index': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'auto_export': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'auto_tags': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'auto_toc': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'automatic_nested_syntaxes': {'type': type(0), 'default': 1, 'min': 0, 'max': 1},
+ \ 'css_name': {'type': type(''), 'default': 'style.css', 'min_length': 1},
+ \ 'custom_wiki2html': {'type': type(''), 'default': ''},
+ \ 'custom_wiki2html_args': {'type': type(''), 'default': ''},
+ \ 'diary_header': {'type': type(''), 'default': 'Diary', 'min_length': 1},
+ \ 'diary_index': {'type': type(''), 'default': 'diary', 'min_length': 1},
+ \ 'diary_rel_path': {'type': type(''), 'default': 'diary/', 'min_length': 1},
+ \ 'diary_sort': {'type': type(''), 'default': 'desc', 'possible_values': ['asc', 'desc']},
+ \ 'ext': {'type': type(''), 'default': '.wiki', 'min_length': 1},
+ \ 'index': {'type': type(''), 'default': 'index', 'min_length': 1},
+ \ 'list_margin': {'type': type(0), 'default': -1, 'min': -1},
+ \ 'maxhi': {'type': type(0), 'default': 0, 'min': 0, 'max': 1},
+ \ 'nested_syntaxes': {'type': type({}), 'default': {}},
+ \ 'path': {'type': type(''), 'default': $HOME . '/vimwiki/', 'min_length': 1},
+ \ 'path_html': {'type': type(''), 'default': ''},
+ \ 'syntax': {'type': type(''), 'default': 'default',
+ \ 'possible_values': ['default', 'markdown', 'media', 'mediawiki']},
+ \ 'template_default': {'type': type(''), 'default': 'default', 'min_length': 1},
+ \ 'template_ext': {'type': type(''), 'default': '.tpl'},
+ \ 'template_path': {'type': type(''), 'default': $HOME . '/vimwiki/templates/'},
+ \ }
+
+ let g:vimwiki_wikilocal_vars = []
+
+ let default_wiki_settings = {}
+ for key in keys(default_values)
+ if exists('g:vimwiki_'.key)
+ call s:check_users_value(key, g:vimwiki_{key}, default_values[key], 1)
+ let default_wiki_settings[key] = g:vimwiki_{key}
+ else
+ let default_wiki_settings[key] = default_values[key].default
+ endif
+ endfor
+
+ " set the wiki-local variables according to g:vimwiki_list (or the default settings)
+ if exists('g:vimwiki_list')
+ for users_wiki_settings in g:vimwiki_list
+ let new_wiki_settings = {}
+ for key in keys(default_values)
+ if has_key(users_wiki_settings, key)
+ call s:check_users_value(key, users_wiki_settings[key], default_values[key], 0)
+ let new_wiki_settings[key] = users_wiki_settings[key]
+ else
+ let new_wiki_settings[key] = default_wiki_settings[key]
+ endif
+ endfor
+
+ let new_wiki_settings.is_temporary_wiki = 0
+
+ call add(g:vimwiki_wikilocal_vars, new_wiki_settings)
+ endfor
+ else
+ " if the user hasn't registered any wiki, we register one wiki using the default values
+ let new_wiki_settings = deepcopy(default_wiki_settings)
+ let new_wiki_settings.is_temporary_wiki = 0
+ call add(g:vimwiki_wikilocal_vars, new_wiki_settings)
+ endif
+
+ " default values for temporary wikis
+ let temporary_wiki_settings = deepcopy(default_wiki_settings)
+ let temporary_wiki_settings.is_temporary_wiki = 1
+ call add(g:vimwiki_wikilocal_vars, temporary_wiki_settings)
+
+ " check some values individually
+ let key = 'nested_syntaxes'
+ for wiki_settings in g:vimwiki_wikilocal_vars
+ let users_value = wiki_settings[key]
+ for keyword in keys(users_value)
+ if type(keyword) != type('') || empty(keyword) || type(users_value[keyword]) != type('') ||
+ \ empty(users_value[keyword])
+ echom printf('Vimwiki Error: The provided value ''%s'' of the option ''g:vimwiki_%s'' is'
+ \ . ' invalid. See '':h g:vimwiki_%s''.', string(users_value), key, key)
+ break
+ endif
+ endfor
+ endfor
+
+ call s:normalize_wikilocal_settings()
+endfunction
+
+
+function! s:check_users_value(key, users_value, value_infos, comes_from_global_variable)
+ let type_code_to_name = {
+ \ type(0): 'number',
+ \ type(''): 'string',
+ \ type([]): 'list',
+ \ type({}): 'dictionary'}
+
+ let setting_origin = a:comes_from_global_variable ?
+ \ printf('''g:vimwiki_%s''', a:key) :
+ \ printf('''%s'' in g:vimwiki_list', a:key)
+
+ if has_key(a:value_infos, 'type') && type(a:users_value) != a:value_infos.type
+ echom printf('Vimwiki Error: The provided value of the option %s is a %s, ' .
+ \ 'but expected is a %s. See '':h g:vimwiki_%s''.', setting_origin,
+ \ type_code_to_name[type(a:users_value)], type_code_to_name[a:value_infos.type], a:key)
+ endif
+
+ if a:value_infos.type == type(0) && has_key(a:value_infos, 'min') &&
+ \ a:users_value < a:value_infos.min
+ echom printf('Vimwiki Error: The provided value ''%i'' of the option %s is'
+ \ . ' too small. The minimum value is %i. See '':h g:vimwiki_%s''.', a:users_value,
+ \ setting_origin, a:value_infos.min, a:key)
+ endif
+
+ if a:value_infos.type == type(0) && has_key(a:value_infos, 'max') &&
+ \ a:users_value > a:value_infos.max
+ echom printf('Vimwiki Error: The provided value ''%i'' of the option %s is'
+ \ . ' too large. The maximum value is %i. See '':h g:vimwiki_%s''.', a:users_value,
+ \ setting_origin, a:value_infos.max, a:key)
+ endif
+
+ if has_key(a:value_infos, 'possible_values') &&
+ \ index(a:value_infos.possible_values, a:users_value) == -1
+ echom printf('Vimwiki Error: The provided value ''%s'' of the option %s is'
+ \ . ' invalid. Allowed values are %s. See ''g:vimwiki_%s''.', a:users_value,
+ \ setting_origin, string(a:value_infos.possible_values), a:key)
+ endif
+
+ if a:value_infos.type == type('') && has_key(a:value_infos, 'length') &&
+ \ strwidth(a:users_value) != a:value_infos.length
+ echom printf('Vimwiki Error: The provided value ''%s'' of the option %s must'
+ \ . ' contain exactly %i character(s) but has %i. See '':h g:vimwiki_%s''.',
+ \ a:users_value, setting_origin, a:value_infos.length, strwidth(a:users_value), a:key)
+ endif
+
+ if a:value_infos.type == type('') && has_key(a:value_infos, 'min_length') &&
+ \ strwidth(a:users_value) < a:value_infos.min_length
+ echom printf('Vimwiki Error: The provided value ''%s'' of the option %s must'
+ \ . ' have at least %d character(s) but has %d. See '':h g:vimwiki_%s''.', a:users_value,
+ \ setting_origin, a:value_infos.min_length, strwidth(a:users_value), a:key)
+ endif
+endfunction
+
+
+function! s:normalize_wikilocal_settings()
+ for wiki_settings in g:vimwiki_wikilocal_vars
+ let wiki_settings['path'] = s:normalize_path(wiki_settings['path'])
+
+ let path_html = wiki_settings['path_html']
+ if !empty(path_html)
+ let wiki_settings['path_html'] = s:normalize_path(path_html)
+ else
+ let wiki_settings['path_html'] = s:normalize_path(
+ \ substitute(wiki_settings['path'], '[/\\]\+$', '', '').'_html/')
+ endif
+
+ let wiki_settings['template_path'] = s:normalize_path(wiki_settings['template_path'])
+ let wiki_settings['diary_rel_path'] = s:normalize_path(wiki_settings['diary_rel_path'])
+
+ let ext = wiki_settings['ext']
+ if !empty(ext) && ext[0] != '.'
+ let wiki_settings['ext'] = '.' . ext
+ endif
+
+ " for convenience, we also allow the term 'mediawiki'
+ if wiki_settings.syntax ==# 'mediawiki'
+ let wiki_settings.syntax = 'media'
+ endif
+ endfor
+endfunction
+
+
+function! s:normalize_path(path)
+ " trim trailing / and \ because otherwise resolve() doesn't work quite right
+ let path = substitute(a:path, '[/\\]\+$', '', '')
+ if path !~# '^scp:'
+ return resolve(expand(path)).'/'
+ else
+ return path.'/'
+ endif
+endfunction
+
+
+function! vimwiki#vars#populate_syntax_vars(syntax)
+ if !exists('g:vimwiki_syntax_variables')
+ let g:vimwiki_syntax_variables = {}
+ endif
+
+ if has_key(g:vimwiki_syntax_variables, a:syntax)
+ return
+ endif
+
+ let g:vimwiki_syntax_variables[a:syntax] = {}
+
+ execute 'runtime! syntax/vimwiki_'.a:syntax.'.vim'
+
+ " generic stuff
+ let header_symbol = g:vimwiki_syntax_variables[a:syntax].rxH
+ if g:vimwiki_syntax_variables[a:syntax].symH
+ " symmetric headers
+ for i in range(1,6)
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i.'_Template'] =
+ \ repeat(header_symbol, i).' __Header__ '.repeat(header_symbol, i)
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i] =
+ \ '^\s*'.header_symbol.'\{'.i.'}[^'.header_symbol.'].*[^'.header_symbol.']'
+ \ .header_symbol.'\{'.i.'}\s*$'
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i.'_Start'] =
+ \ '^\s*'.header_symbol.'\{'.i.'}[^'.header_symbol.'].*[^'.header_symbol.']'
+ \ .header_symbol.'\{'.i.'}\s*$'
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i.'_End'] =
+ \ '^\s*'.header_symbol.'\{1,'.i.'}[^'.header_symbol.'].*[^'.header_symbol.']'
+ \ .header_symbol.'\{1,'.i.'}\s*$'
+ endfor
+ let g:vimwiki_syntax_variables[a:syntax].rxHeader =
+ \ '^\s*\('.header_symbol.'\{1,6}\)\zs[^'.header_symbol.'].*[^'.header_symbol.']\ze\1\s*$'
+ else
+ " asymmetric
+ for i in range(1,6)
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i.'_Template'] =
+ \ repeat(header_symbol, i).' __Header__'
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i] =
+ \ '^\s*'.header_symbol.'\{'.i.'}[^'.header_symbol.'].*$'
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i.'_Start'] =
+ \ '^\s*'.header_symbol.'\{'.i.'}[^'.header_symbol.'].*$'
+ let g:vimwiki_syntax_variables[a:syntax]['rxH'.i.'_End'] =
+ \ '^\s*'.header_symbol.'\{1,'.i.'}[^'.header_symbol.'].*$'
+ endfor
+ let g:vimwiki_syntax_variables[a:syntax].rxHeader =
+ \ '^\s*\('.header_symbol.'\{1,6}\)\zs[^'.header_symbol.'].*\ze$'
+ endif
+
+ let g:vimwiki_syntax_variables[a:syntax].rxPreStart =
+ \ '^\s*'.g:vimwiki_syntax_variables[a:syntax].rxPreStart
+ let g:vimwiki_syntax_variables[a:syntax].rxPreEnd =
+ \ '^\s*'.g:vimwiki_syntax_variables[a:syntax].rxPreEnd.'\s*$'
+
+ let g:vimwiki_syntax_variables[a:syntax].rxMathStart =
+ \ '^\s*'.g:vimwiki_syntax_variables[a:syntax].rxMathStart
+ let g:vimwiki_syntax_variables[a:syntax].rxMathEnd =
+ \ '^\s*'.g:vimwiki_syntax_variables[a:syntax].rxMathEnd.'\s*$'
+
+ " list stuff
+ let g:vimwiki_syntax_variables[a:syntax].rx_bullet_chars =
+ \ '['.join(g:vimwiki_syntax_variables[a:syntax].bullet_types, '').']\+'
+
+ let g:vimwiki_syntax_variables[a:syntax].multiple_bullet_chars =
+ \ g:vimwiki_syntax_variables[a:syntax].recurring_bullets
+ \ ? g:vimwiki_syntax_variables[a:syntax].bullet_types : []
+
+ let g:vimwiki_syntax_variables[a:syntax].number_kinds = []
+ let g:vimwiki_syntax_variables[a:syntax].number_divisors = ''
+ for i in g:vimwiki_syntax_variables[a:syntax].number_types
+ call add(g:vimwiki_syntax_variables[a:syntax].number_kinds, i[0])
+ let g:vimwiki_syntax_variables[a:syntax].number_divisors .= vimwiki#u#escape(i[1])
+ endfor
+
+ let char_to_rx = {'1': '\d\+', 'i': '[ivxlcdm]\+', 'I': '[IVXLCDM]\+',
+ \ 'a': '\l\{1,2}', 'A': '\u\{1,2}'}
+
+ "create regexp for bulleted list items
+ if !empty(g:vimwiki_syntax_variables[a:syntax].bullet_types)
+ let g:vimwiki_syntax_variables[a:syntax].rxListBullet =
+ \ join( map(copy(g:vimwiki_syntax_variables[a:syntax].bullet_types),
+ \'vimwiki#u#escape(v:val).'
+ \ .'repeat("\\+", g:vimwiki_syntax_variables[a:syntax].recurring_bullets)'
+ \ ) , '\|')
+ else
+ "regex that matches nothing
+ let g:vimwiki_syntax_variables[a:syntax].rxListBullet = '$^'
+ endif
+
+ "create regex for numbered list items
+ if !empty(g:vimwiki_syntax_variables[a:syntax].number_types)
+ let g:vimwiki_syntax_variables[a:syntax].rxListNumber = '\C\%('
+ for type in g:vimwiki_syntax_variables[a:syntax].number_types[:-2]
+ let g:vimwiki_syntax_variables[a:syntax].rxListNumber .= char_to_rx[type[0]] .
+ \ vimwiki#u#escape(type[1]) . '\|'
+ endfor
+ let g:vimwiki_syntax_variables[a:syntax].rxListNumber .=
+ \ char_to_rx[g:vimwiki_syntax_variables[a:syntax].number_types[-1][0]].
+ \ vimwiki#u#escape(g:vimwiki_syntax_variables[a:syntax].number_types[-1][1]) . '\)'
+ else
+ "regex that matches nothing
+ let g:vimwiki_syntax_variables[a:syntax].rxListNumber = '$^'
+ endif
+
+ "the user can set the listsyms as string, but vimwiki needs a list
+ let g:vimwiki_syntax_variables[a:syntax].listsyms_list =
+ \ split(vimwiki#vars#get_global('listsyms'), '\zs')
+ if match(vimwiki#vars#get_global('listsyms'), vimwiki#vars#get_global('listsym_rejected')) != -1
+ echomsg 'Vimwiki Warning: the value of g:vimwiki_listsym_rejected ('''
+ \ . vimwiki#vars#get_global('listsym_rejected')
+ \ . ''') must not be a part of g:vimwiki_listsyms (''' .
+ \ . vimwiki#vars#get_global('listsyms') . ''')'
+ endif
+ let g:vimwiki_syntax_variables[a:syntax].rxListItemWithoutCB =
+ \ '^\s*\%(\('.g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\)\|\('
+ \ .g:vimwiki_syntax_variables[a:syntax].rxListNumber.'\)\)\s'
+ let g:vimwiki_syntax_variables[a:syntax].rxListItem =
+ \ g:vimwiki_syntax_variables[a:syntax].rxListItemWithoutCB
+ \ . '\+\%(\[\(['.vimwiki#vars#get_global('listsyms')
+ \ . vimwiki#vars#get_global('listsym_rejected').']\)\]\s\)\?'
+ if g:vimwiki_syntax_variables[a:syntax].recurring_bullets
+ let g:vimwiki_syntax_variables[a:syntax].rxListItemAndChildren =
+ \ '^\('.g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\)\s\+\[['
+ \ . g:vimwiki_syntax_variables[a:syntax].listsyms_list[-1]
+ \ . vimwiki#vars#get_global('listsym_rejected') . ']\]\s.*\%(\n\%(\1\%('
+ \ .g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\).*\|^$\|\s.*\)\)*'
+ else
+ let g:vimwiki_syntax_variables[a:syntax].rxListItemAndChildren =
+ \ '^\(\s*\)\%('.g:vimwiki_syntax_variables[a:syntax].rxListBullet.'\|'
+ \ . g:vimwiki_syntax_variables[a:syntax].rxListNumber.'\)\s\+\[['
+ \ . g:vimwiki_syntax_variables[a:syntax].listsyms_list[-1]
+ \ . vimwiki#vars#get_global('listsym_rejected') . ']\]\s.*\%(\n\%(\1\s.*\|^$\)\)*'
+ endif
+
+ " 0. URL : free-standing links: keep URL UR(L) strip trailing punct: URL; URL) UR(L))
+ " let g:vimwiki_rxWeblink = '[\["(|]\@<!'. g:vimwiki_rxWeblinkUrl .
+ " \ '\%([),:;.!?]\=\%([ \t]\|$\)\)\@='
+ let g:vimwiki_syntax_variables[a:syntax].rxWeblink =
+ \ '\<'. g:vimwiki_global_vars.rxWeblinkUrl . '\S*'
+ " 0a) match URL within URL
+ let g:vimwiki_syntax_variables[a:syntax].rxWeblinkMatchUrl =
+ \ g:vimwiki_syntax_variables[a:syntax].rxWeblink
+ " 0b) match DESCRIPTION within URL
+ let g:vimwiki_syntax_variables[a:syntax].rxWeblinkMatchDescr = ''
+
+ " template for matching all wiki links with a given target file
+ let g:vimwiki_syntax_variables[a:syntax].WikiLinkMatchUrlTemplate =
+ \ g:vimwiki_global_vars.rx_wikilink_prefix .
+ \ '\zs__LinkUrl__\ze\%(#.*\)\?' .
+ \ g:vimwiki_global_vars.rx_wikilink_suffix .
+ \ '\|' .
+ \ g:vimwiki_global_vars.rx_wikilink_prefix .
+ \ '\zs__LinkUrl__\ze\%(#.*\)\?' .
+ \ g:vimwiki_global_vars.rx_wikilink_separator .
+ \ '.*' .
+ \ g:vimwiki_global_vars.rx_wikilink_suffix
+
+ " a) match [[URL|DESCRIPTION]]
+ let g:vimwiki_syntax_variables[a:syntax].rxWikiLink = g:vimwiki_global_vars.rx_wikilink_prefix.
+ \ g:vimwiki_global_vars.rxWikiLinkUrl.'\%('.g:vimwiki_global_vars.rx_wikilink_separator.
+ \ g:vimwiki_global_vars.rxWikiLinkDescr.'\)\?'.g:vimwiki_global_vars.rx_wikilink_suffix
+ let g:vimwiki_syntax_variables[a:syntax].rxAnyLink =
+ \ g:vimwiki_syntax_variables[a:syntax].rxWikiLink.'\|'.
+ \ g:vimwiki_global_vars.rxWikiIncl.'\|'.g:vimwiki_syntax_variables[a:syntax].rxWeblink
+ " b) match URL within [[URL|DESCRIPTION]]
+ let g:vimwiki_syntax_variables[a:syntax].rxWikiLinkMatchUrl =
+ \ g:vimwiki_global_vars.rx_wikilink_prefix . '\zs'. g:vimwiki_global_vars.rxWikiLinkUrl
+ \ .'\ze\%('. g:vimwiki_global_vars.rx_wikilink_separator
+ \ . g:vimwiki_global_vars.rxWikiLinkDescr.'\)\?'.g:vimwiki_global_vars.rx_wikilink_suffix
+ " c) match DESCRIPTION within [[URL|DESCRIPTION]]
+ let g:vimwiki_syntax_variables[a:syntax].rxWikiLinkMatchDescr =
+ \ g:vimwiki_global_vars.rx_wikilink_prefix . g:vimwiki_global_vars.rxWikiLinkUrl
+ \ . g:vimwiki_global_vars.rx_wikilink_separator.'\%(\zs'
+ \ . g:vimwiki_global_vars.rxWikiLinkDescr. '\ze\)\?'
+ \ . g:vimwiki_global_vars.rx_wikilink_suffix
+
+ if a:syntax ==# 'markdown'
+ call s:populate_extra_markdown_vars()
+ endif
+endfunction
+
+
+function! s:populate_extra_markdown_vars()
+ let mkd_syntax = g:vimwiki_syntax_variables['markdown']
+
+ " 0a) match [[URL|DESCRIPTION]]
+ let mkd_syntax.rxWikiLink0 = mkd_syntax.rxWikiLink
+ " 0b) match URL within [[URL|DESCRIPTION]]
+ let mkd_syntax.rxWikiLink0MatchUrl = mkd_syntax.rxWikiLinkMatchUrl
+ " 0c) match DESCRIPTION within [[URL|DESCRIPTION]]
+ let mkd_syntax.rxWikiLink0MatchDescr = mkd_syntax.rxWikiLinkMatchDescr
+
+ let wikilink_md_prefix = '['
+ let wikilink_md_suffix = ']'
+ let wikilink_md_separator = ']['
+ let rx_wikilink_md_separator = vimwiki#u#escape(wikilink_md_separator)
+ let mkd_syntax.rx_wikilink_md_prefix = vimwiki#u#escape(wikilink_md_prefix)
+ let mkd_syntax.rx_wikilink_md_suffix = vimwiki#u#escape(wikilink_md_suffix)
+
+ " [URL][]
+ let mkd_syntax.WikiLink1Template1 = wikilink_md_prefix . '__LinkUrl__'.
+ \ wikilink_md_separator. wikilink_md_suffix
+ " [DESCRIPTION][URL]
+ let mkd_syntax.WikiLink1Template2 = wikilink_md_prefix. '__LinkDescription__'.
+ \ wikilink_md_separator. '__LinkUrl__'. wikilink_md_suffix
+ let mkd_syntax.WikiLinkMatchUrlTemplate .=
+ \ '\|' .
+ \ mkd_syntax.rx_wikilink_md_prefix .
+ \ '.*' .
+ \ rx_wikilink_md_separator .
+ \ '\zs__LinkUrl__\ze\%(#.*\)\?' .
+ \ mkd_syntax.rx_wikilink_md_suffix .
+ \ '\|' .
+ \ mkd_syntax.rx_wikilink_md_prefix .
+ \ '\zs__LinkUrl__\ze\%(#.*\)\?' .
+ \ rx_wikilink_md_separator .
+ \ mkd_syntax.rx_wikilink_md_suffix
+
+ let valid_chars = '[^\\\[\]]'
+ let mkd_syntax.rxWikiLink1Url = valid_chars.'\{-}'
+ let mkd_syntax.rxWikiLink1Descr = valid_chars.'\{-}'
+ let mkd_syntax.rxWikiLink1InvalidPrefix = '[\]\[]\@<!'
+ let mkd_syntax.rxWikiLink1InvalidSuffix = '[\]\[]\@!'
+ let mkd_syntax.rx_wikilink_md_prefix = mkd_syntax.rxWikiLink1InvalidPrefix.
+ \ mkd_syntax.rx_wikilink_md_prefix
+ let mkd_syntax.rx_wikilink_md_suffix = mkd_syntax.rx_wikilink_md_suffix.
+ \ mkd_syntax.rxWikiLink1InvalidSuffix
+
+ " 1. match [URL][], [DESCRIPTION][URL]
+ let mkd_syntax.rxWikiLink1 = mkd_syntax.rx_wikilink_md_prefix.
+ \ mkd_syntax.rxWikiLink1Url. rx_wikilink_md_separator.
+ \ mkd_syntax.rx_wikilink_md_suffix.
+ \ '\|'. mkd_syntax.rx_wikilink_md_prefix.
+ \ mkd_syntax.rxWikiLink1Descr . rx_wikilink_md_separator.
+ \ mkd_syntax.rxWikiLink1Url . mkd_syntax.rx_wikilink_md_suffix
+ " 2. match URL within [URL][], [DESCRIPTION][URL]
+ let mkd_syntax.rxWikiLink1MatchUrl = mkd_syntax.rx_wikilink_md_prefix.
+ \ '\zs'. mkd_syntax.rxWikiLink1Url. '\ze'. rx_wikilink_md_separator.
+ \ mkd_syntax.rx_wikilink_md_suffix.
+ \ '\|'. mkd_syntax.rx_wikilink_md_prefix.
+ \ mkd_syntax.rxWikiLink1Descr. rx_wikilink_md_separator.
+ \ '\zs'. mkd_syntax.rxWikiLink1Url. '\ze'. mkd_syntax.rx_wikilink_md_suffix
+ " 3. match DESCRIPTION within [DESCRIPTION][URL]
+ let mkd_syntax.rxWikiLink1MatchDescr = mkd_syntax.rx_wikilink_md_prefix.
+ \ '\zs'. mkd_syntax.rxWikiLink1Descr.'\ze'. rx_wikilink_md_separator.
+ \ mkd_syntax.rxWikiLink1Url . mkd_syntax.rx_wikilink_md_suffix
+
+ let mkd_syntax.rxWikiLink1Prefix1 = mkd_syntax.rx_wikilink_md_prefix
+ let mkd_syntax.rxWikiLink1Suffix1 = rx_wikilink_md_separator.
+ \ mkd_syntax.rxWikiLink1Url . mkd_syntax.rx_wikilink_md_suffix
+
+ " 1. match ANY wikilink
+ let mkd_syntax.rxWikiLink = mkd_syntax.rxWikiLink0 . '\|' . mkd_syntax.rxWikiLink1
+ " 2. match URL within ANY wikilink
+ let mkd_syntax.rxWikiLinkMatchUrl = mkd_syntax.rxWikiLink0MatchUrl . '\|' .
+ \ mkd_syntax.rxWikiLink1MatchUrl
+ " 3. match DESCRIPTION within ANY wikilink
+ let mkd_syntax.rxWikiLinkMatchDescr = mkd_syntax.rxWikiLink0MatchDescr . '\|' .
+ \ mkd_syntax.rxWikiLink1MatchDescr
+
+ " 0. URL : free-standing links: keep URL UR(L) strip trailing punct: URL; URL) UR(L))
+ let mkd_syntax.rxWeblink0 = mkd_syntax.rxWeblink
+ " 0a) match URL within URL
+ let mkd_syntax.rxWeblinkMatchUrl0 = mkd_syntax.rxWeblinkMatchUrl
+ " 0b) match DESCRIPTION within URL
+ let mkd_syntax.rxWeblinkMatchDescr0 = mkd_syntax.rxWeblinkMatchDescr
+
+ let mkd_syntax.rxWeblink1Prefix = '['
+ let mkd_syntax.rxWeblink1Suffix = ')'
+ let mkd_syntax.rxWeblink1Separator = ']('
+ " [DESCRIPTION](URL)
+ let mkd_syntax.Weblink1Template = mkd_syntax.rxWeblink1Prefix . '__LinkDescription__'.
+ \ mkd_syntax.rxWeblink1Separator. '__LinkUrl__'.
+ \ mkd_syntax.rxWeblink1Suffix
+
+ let valid_chars = '[^\\]'
+
+ let mkd_syntax.rxWeblink1Prefix = vimwiki#u#escape(mkd_syntax.rxWeblink1Prefix)
+ let mkd_syntax.rxWeblink1Suffix = vimwiki#u#escape(mkd_syntax.rxWeblink1Suffix)
+ let mkd_syntax.rxWeblink1Separator = vimwiki#u#escape(mkd_syntax.rxWeblink1Separator)
+ let mkd_syntax.rxWeblink1Url = valid_chars.'\{-}'
+ let mkd_syntax.rxWeblink1Descr = valid_chars.'\{-}'
+
+ " 1. [DESCRIPTION](URL)
+ " 1a) match [DESCRIPTION](URL)
+ let mkd_syntax.rxWeblink1 = mkd_syntax.rxWeblink1Prefix.
+ \ mkd_syntax.rxWeblink1Url . mkd_syntax.rxWeblink1Separator.
+ \ mkd_syntax.rxWeblink1Descr . mkd_syntax.rxWeblink1Suffix
+ " 1b) match URL within [DESCRIPTION](URL)
+ let mkd_syntax.rxWeblink1MatchUrl = mkd_syntax.rxWeblink1Prefix.
+ \ mkd_syntax.rxWeblink1Descr. mkd_syntax.rxWeblink1Separator.
+ \ '\zs' . mkd_syntax.rxWeblink1Url . '\ze' . mkd_syntax.rxWeblink1Suffix
+ " 1c) match DESCRIPTION within [DESCRIPTION](URL)
+ let mkd_syntax.rxWeblink1MatchDescr = mkd_syntax.rxWeblink1Prefix.
+ \ '\zs'.mkd_syntax.rxWeblink1Descr.'\ze'. mkd_syntax.rxWeblink1Separator.
+ \ mkd_syntax.rxWeblink1Url. mkd_syntax.rxWeblink1Suffix
+
+ " TODO: image links too !!
+ let mkd_syntax.rxWeblink1Prefix1 = mkd_syntax.rxWeblink1Prefix
+ let mkd_syntax.rxWeblink1Suffix1 = mkd_syntax.rxWeblink1Separator.
+ \ mkd_syntax.rxWeblink1Url . mkd_syntax.rxWeblink1Suffix
+
+ " *a) match ANY weblink
+ let mkd_syntax.rxWeblink = ''.
+ \ mkd_syntax.rxWeblink1.'\|'.
+ \ mkd_syntax.rxWeblink0
+ " *b) match URL within ANY weblink
+ let mkd_syntax.rxWeblinkMatchUrl = ''.
+ \ mkd_syntax.rxWeblink1MatchUrl.'\|'.
+ \ mkd_syntax.rxWeblinkMatchUrl0
+ " *c) match DESCRIPTION within ANY weblink
+ let mkd_syntax.rxWeblinkMatchDescr = ''.
+ \ mkd_syntax.rxWeblink1MatchDescr.'\|'.
+ \ mkd_syntax.rxWeblinkMatchDescr0
+
+ let mkd_syntax.rxAnyLink = mkd_syntax.rxWikiLink.'\|'.
+ \ g:vimwiki_global_vars.rxWikiIncl.'\|'.mkd_syntax.rxWeblink
+
+ let mkd_syntax.rxMkdRef = '\['.g:vimwiki_global_vars.rxWikiLinkDescr.']:\%(\s\+\|\n\)'.
+ \ mkd_syntax.rxWeblink0
+ let mkd_syntax.rxMkdRefMatchDescr =
+ \ '\[\zs'.g:vimwiki_global_vars.rxWikiLinkDescr.'\ze]:\%(\s\+\|\n\)'. mkd_syntax.rxWeblink0
+ let mkd_syntax.rxMkdRefMatchUrl =
+ \ '\['.g:vimwiki_global_vars.rxWikiLinkDescr.']:\%(\s\+\|\n\)\zs'.
+ \ mkd_syntax.rxWeblink0.'\ze'
+endfunction
+
+
+function! vimwiki#vars#init()
+ call s:populate_global_variables()
+ call s:populate_wikilocal_options()
+endfunction
+
+
+function! vimwiki#vars#get_syntaxlocal(key, ...)
+ if a:0
+ let syntax = a:1
+ else
+ let syntax = vimwiki#vars#get_wikilocal('syntax')
+ endif
+ if !exists('g:vimwiki_syntax_variables') || !has_key(g:vimwiki_syntax_variables, syntax)
+ call vimwiki#vars#populate_syntax_vars(syntax)
+ endif
+
+ return g:vimwiki_syntax_variables[syntax][a:key]
+endfunction
+
+
+" Get a variable for the buffer we are currently in or for the given buffer (number or name).
+" Populate the variable, if it doesn't exist.
+function! vimwiki#vars#get_bufferlocal(key, ...)
+ let buffer = a:0 ? a:1 : '%'
+
+ let value = getbufvar(buffer, 'vimwiki_'.a:key, '/\/\')
+ if type(value) != 1 || value !=# '/\/\'
+ return value
+ elseif a:key ==# 'wiki_nr'
+ call setbufvar(buffer, 'vimwiki_wiki_nr', vimwiki#base#find_wiki(expand('%:p')))
+ elseif a:key ==# 'subdir'
+ call setbufvar(buffer, 'vimwiki_subdir', vimwiki#base#current_subdir())
+ elseif a:key ==# 'invsubdir'
+ let subdir = vimwiki#vars#get_bufferlocal('subdir')
+ call setbufvar(buffer, 'vimwiki_invsubdir', vimwiki#base#invsubdir(subdir))
+ elseif a:key ==# 'existing_wikifiles'
+ call setbufvar(buffer, 'vimwiki_existing_wikifiles',
+ \ vimwiki#base#get_wikilinks(vimwiki#vars#get_bufferlocal('wiki_nr'), 1))
+ elseif a:key ==# 'existing_wikidirs'
+ call setbufvar(buffer, 'vimwiki_existing_wikidirs',
+ \ vimwiki#base#get_wiki_directories(vimwiki#vars#get_bufferlocal('wiki_nr')))
+ elseif a:key ==# 'prev_link'
+ call setbufvar(buffer, 'vimwiki_prev_link', [])
+ elseif a:key ==# 'markdown_refs'
+ call setbufvar(buffer, 'vimwiki_markdown_refs', vimwiki#markdown_base#scan_reflinks())
+ else
+ echoerr 'Vimwiki Error: unknown buffer variable ' . string(a:key)
+ endif
+
+ return getbufvar(buffer, 'vimwiki_'.a:key)
+endfunction
+
+
+function! vimwiki#vars#set_bufferlocal(key, value, ...)
+ let buffer = a:0 ? a:1 : '%'
+ call setbufvar(buffer, 'vimwiki_' . a:key, a:value)
+endfunction
+
+
+function! vimwiki#vars#get_global(key)
+ return g:vimwiki_global_vars[a:key]
+endfunction
+
+
+" the second argument can be a wiki number. When absent, the wiki of the currently active buffer is
+" used
+function! vimwiki#vars#get_wikilocal(key, ...)
+ if a:0
+ return g:vimwiki_wikilocal_vars[a:1][a:key]
+ else
+ return g:vimwiki_wikilocal_vars[vimwiki#vars#get_bufferlocal('wiki_nr')][a:key]
+ endif
+endfunction
+
+
+function! vimwiki#vars#get_wikilocal_default(key)
+ return g:vimwiki_wikilocal_vars[-1][a:key]
+endfunction
+
+
+function! vimwiki#vars#set_wikilocal(key, value, wiki_nr)
+ if a:wiki_nr == len(g:vimwiki_wikilocal_vars) - 1
+ call insert(g:vimwiki_wikilocal_vars, {}, -1)
+ endif
+ let g:vimwiki_wikilocal_vars[a:wiki_nr][a:key] = a:value
+endfunction
+
+
+function! vimwiki#vars#add_temporary_wiki(settings)
+ let new_temp_wiki_settings = copy(g:vimwiki_wikilocal_vars[-1])
+ for [key, value] in items(a:settings)
+ let new_temp_wiki_settings[key] = value
+ endfor
+ call insert(g:vimwiki_wikilocal_vars, new_temp_wiki_settings, -1)
+ call s:normalize_wikilocal_settings()
+endfunction
+
+
+" number of registered wikis + temporary
+function! vimwiki#vars#number_of_wikis()
+ return len(g:vimwiki_wikilocal_vars) - 1
+endfunction
+
diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim
@@ -13,7 +13,7 @@
" repeat - repeat things
" vimling (ipa, deadkeys) - deadkeys
" vimagit - git in vim
-" v(org)im (written by me) - emulating org mode in vim
+" vimwiki - wiki program (can view my wiki)
"Leader
let mapleader=","
@@ -40,21 +40,25 @@ set relativenumber
set number
set hlsearch
filetype plugin on
+set noshowmode
"Leader keys
-noremap <leader>ve :vsplit ~/.config/nvim/init.vim<CR>
+noremap <leader>vv :edit ~/.config/nvim/init.vim<CR>
+noremap <leader>vz :vsplit ~/.config/nvim/init.vim<CR>
+noremap <leader>vZ :split ~/.config/nvim/init.vim<CR>
noremap <leader>vs :source ~/.config/nvim/init.vim<CR>
map <leader><leader><leader> <leader>vs
noremap <leader>g :Goyo \| set linebreak<CR>
-noremap <leader>c :!sudo make all install clean \| set linebreak<CR>
+noremap <leader>cd :chdir
+noremap <leader>C :!sudo make all install clean<CR>
noremap <leader>oc :!groff -T pdf % - > /tmp/grff \| zathura -<Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left><Left>
-noremap <Leader>sv :!sent % \| set linebreak<CR>
+noremap <leader>sv :!sent % \| set linebreak<CR>
noremap <leader>sc :setlocal spell! spelllang=en_us \| set linebreak<CR>
noremap <leader>sf mm[s1z=`m<CR>
-noremap <leader>ssf z=<CR>
-noremap <leader>ff :r !find \| set linebreak<CR>
-noremap <leader>fl :r !ls \| set linebreak<CR>
+noremap <leader>ssf mm[sz=`m
+noremap <leader>Ff :r !find \| set linebreak<CR>
+noremap <leader>Fl :r !ls \| set linebreak<CR>
noremap <leader>bd :bdelete \| set linebreak<CR>
noremap <leader>bn :bn \| set linebreak<CR>
noremap <leader>bp :bp \| set linebreak<CR>
@@ -63,12 +67,15 @@ noremap <leader>mvd :w! /tmp/bmv-edit \| set linebreak<CR>:!sh /tmp/bmv-edit \|
noremap <leader>ss :set syntax=
inoremap <leader><leader>ss <Esc>:set syntax=
noremap <leader>w :w \| set linebreak<CR>
-noremap <leader>W :w !sudo tee %<CR>
+noremap <leader>w! :w !sudo tee %<CR>
+noremap <leader>wq :x!<CR>
noremap <leader>" ea"<esc>bi"<esc>
noremap <leader>u" ds"
noremap <leader>' ea'<esc>bi'<esc>
noremap <leader>u' ds'
noremap <leader>sp o<esc>pi
+noremap <leader>Ee :edit
+noremap <leader>yv :reg<CR>
noremap <leader>nn :set number! relativenumber!<CR>
noremap <leader><leader>nn :setlocal number! relativenumber!<CR>
@@ -99,16 +106,16 @@ noremap cw ciw
noremap md ddp
noremap mu ddkkp
noremap <c-U> viwU
-noremap <c-u> viwu
+noremap <c-i> viwu
"Insert mode
inoremap <c-d> <esc>ddi
inoremap <c-c> <esc>cci
-inoremap <c-r> <esc>r
-inoremap <c-R> <esc>R
-inoremap <c-v> <esc>v
-inoremap <c-p> <esc>pi
-inoremap <c-P> <esc>Pi
+inoremap <c-r> <esc>lr
+inoremap <c-R> <esc>lR
+inoremap <c-v> <esc>lv
+inoremap <c-p> <esc>lpli
+inoremap <c-P> <esc>lPli
"Folds
nnoremap <silent> <Space> @=(foldlevel('.')?'za':"\<Space>")<CR>
@@ -127,7 +134,7 @@ inoremap <leader>li <esc>:call ToggleIPA()<CR>a
"An erotic file-browser
noremap <leader>eh :Sex \| set linebreak<CR>
noremap <leader>ev :Vex \| set linebreak<CR>
-noremap <leader>ee :Explore \| set linebreak<CR>
+noremap <leader>ee :Explore
noremap <leader>eo :browse oldfiles \| set linebreak<CR>
noremap <leader>eb 100j
let g:netrw_liststyle=3
@@ -161,13 +168,19 @@ source ~/.config/nvim/modules/theme.vim
source ~/.config/nvim/modules/abbrs.vim
source ~/.config/nvim/modules/statusline.vim
source ~/.config/nvim/modules/splits.vim
-source ~/.config/nvim/modules/buffs.vim
source ~/.config/nvim/modules/netrw.vim
source ~/.config/nvim/modules/term.vim
source ~/.config/nvim/modules/tabs.vim
+source ~/.config/nvim/modules/wiki.vim
+source ~/.config/nvim/modules/edit.vim
+source ~/.config/nvim/modules/window.vim
+source ~/.config/nvim/modules/message.vim
+source ~/.config/nvim/modules/openc.vim
"Automatic commands
augroup autocmd
+ "greet
+ autocmd BufRead *.greet set syntax=greet
"netrw
autocmd FileType,WinEnter,BufEnter netrw call Configurenetrw()
diff --git a/.config/nvim/modules/abbrs.vim b/.config/nvim/modules/abbrs.vim
@@ -2,3 +2,5 @@ iabbrev eemail hayden@haydenvh.com
iabbrev <email> <hayden@haydenvh.com>
iabbrev wweb haydenvh.com
iabbrev ccopy Copyright (c) Hayden Hamilton <hayden@haydenvh.com>
+iabbrev ssig -- Hayden
+iabbrev nname Hayden Hamilton
diff --git a/.config/nvim/modules/buffs.vim b/.config/nvim/modules/buffs.vim
@@ -1,3 +0,0 @@
-hi TabLine cterm=none ctermfg=256 ctermbg=0
-hi TabLineSel cterm=bold ctermfg=252 ctermbg=1
-hi TabLineFill cterm=none ctermfg=none ctermbg=none
diff --git a/.config/nvim/modules/edit.vim b/.config/nvim/modules/edit.vim
@@ -0,0 +1,28 @@
+function! Sedrun(args)
+ write
+ let cmd="sed -i '" . a:args . "' %"
+ execute ":!" . cmd | redraw
+ silent! edit!
+endfunction
+
+function! Grepwin(args, vert)
+ if a:vert == '1'
+ let split="vsplit"
+ else
+ let split="split"
+ endif
+
+ write
+ let ftsave=&filetype
+ let tmpfile=fnameescape(tempname())
+ let cmd="grep '" . a:args . "' % > " . tmpfile
+ execute ":!" . cmd | redraw
+
+ silent! execute ":" . split . " " . tmpfile
+
+ execute ":set filetype=" . ftsave
+endfunction
+
+nnoremap <leader>S :call Sedrun("")<left><left>
+nnoremap <leader>Gh :call Grepwin("", 0)<left><left><left><left><left>
+nnoremap <leader>Gv :call Grepwin("", 1)<left><left><left><left><left>
diff --git a/.config/nvim/modules/message.vim b/.config/nvim/modules/message.vim
@@ -0,0 +1,116 @@
+set shortmess+=I
+
+augroup EnterMessage
+ autocmd VimEnter * if !argc() && (line2byte('$') == -1) && (v:progname =~? '^[-gmnq]\=vim\=x\=\%[\.exe]$')
+ \ | call VimEnterDisplay()
+ \ | endif
+augroup END
+
+function! VimEnterDisplay()
+ edit ~/.config/nvim/startup.greet
+ set syntax=greet
+ call SpawnLauncher()
+endfunction
+
+function! SpawnLauncher()
+ call Winmsg()
+ call LauncherRecent()
+ call Winset()
+endfunction
+
+function! FzfLauncher()
+ call Winmsg()
+ " fzf
+ call Winset()
+endfunction
+
+function! LauncherRecent()
+ rshada!
+ let olist=v:oldfiles
+ let i=0
+
+ redir! >/tmp/vim-recent | silent! echo ' Press "q" to open empty buffer, "Q" to quit, or any key below:' | silent! echo '' | silent! echo ' Recent files:' | redir END
+ redir! >/tmp/vim-recent.1 | silent! echo '' | silent! echo '' | silent! echo 'Config files:' | redir END
+ redir! >/tmp/vim-recent.2 | silent! echo '' | silent! echo '' | silent! echo 'Recent files (cwd):' | redir END
+ redir! >/tmp/vim-recentcmd.vim | silent! echo ':silent! unmap <buffer> q' | silent! echo 'nnoremap <buffer> q :q<CR>:new<CR>:only<CR>' | silent! echo ':silent! unmap <buffer>Q' | silent! echo ':nnoremap <buffer> Q :qa!<CR>' | silent! echo ':nnoremap <buffer> :q :qa!<CR>' | redir END
+ for string in olist
+ if i=='10'
+ break
+ endif
+ redir >>/tmp/vim-recent | silent! echo ' [' . i . '] ' . string | redir END
+ redir >>/tmp/vim-recentcmd.vim | silent! echo ':silent! unmap <buffer> ' . i | silent! echo ':nnoremap <buffer> ' . i . ' :q<CR>:edit ' . string '<CR>' | redir END
+ let i+=1
+ endfor
+ let dir=getcwd()
+ let i=10
+ for string in olist
+ if i=='20'
+ break
+ endif
+ if stridx(string, dir) != '-1'
+ redir >>/tmp/vim-recent.2 | silent! echo ' [' . i . '] ' . string | redir END
+ redir >>/tmp/vim-recentcmd.vim | silent! echo ':silent! unmap <buffer> ' . i | silent! echo ':nnoremap <buffer> ' . i . ' :q<CR>:edit ' . string '<CR>' | redir END
+ else
+ continue
+ endif
+ let i+=1
+ endfor
+ call LauncherConfig()
+ call LauncherFileMerge()
+ edit /tmp/vim-recent
+ source /tmp/vim-recentcmd.vim
+ setlocal syntax=recent nomodifiable
+endfunction
+
+function! LauncherFileMerge()
+ let w=&columns
+ execute ':silent !pr -mtw ' . w . ' /tmp/vim-recent /tmp/vim-recent.* > /tmp/vim-recent-concat'
+ execute ':silent !mv /tmp/vim-recent-concat /tmp/vim-recent'
+endfunction
+
+function! LauncherConfig()
+ let configs=[
+ \":edit ~/.config/nvim/init.vim",
+ \":Explore ~/.config/nvim/modules"
+ \]
+
+ let i=1
+ for config in configs
+ let a=Itoa(i)
+ redir! >/tmp/vim-config-dict | silent! echo config | redir END
+ let string=system("awk '{$1=\"\";print $0}' < /tmp/vim-config-dict | tr -d '\n\r'")
+
+ redir >>/tmp/vim-recent.1 | silent! echo ' [' . a . '] ' . string | redir END
+ redir >>/tmp/vim-recentcmd.vim | silent! echo ':silent! unmap <buffer> ' . a | silent! echo ':nnoremap <buffer> ' . a . ' :q<CR>' . config . '<CR>' | redir END
+ let i+=1
+ endfor
+
+endfunction
+
+function Itoa(i)
+ let i=a:i
+ let a=''
+ if i=='1'
+ let a='a'
+ elseif i=='2'
+ let a='b'
+ elseif i=='3'
+ let a='c'
+ elseif i=='4'
+ let a='d'
+ elseif i=='5'
+ let a='e'
+ elseif i=='6'
+ let a='f'
+ elseif i=='7'
+ let a='g'
+ elseif i=='8'
+ let a='h'
+ elseif i=='9'
+ let a='i'
+ elseif i=='10'
+ let a='j'
+ endif
+
+ return a
+endfunction
diff --git a/.config/nvim/modules/openc.vim b/.config/nvim/modules/openc.vim
@@ -0,0 +1,15 @@
+function! OpenC(arg)
+ let file='<cWORD>'
+ if a:arg == '0'
+ let split="vsplit"
+ elseif a:arg == '1'
+ let split="split"
+ else
+ let split="edit"
+ endif
+ execute ":" . split . " " . file
+endfunction
+
+nnoremap <leader>Ew :call OpenC(2)<CR>
+nnoremap <leader>EZ :call OpenC(1)<CR>
+nnoremap <leader>Ez :call OpenC(0)<CR>
diff --git a/.config/nvim/modules/splits.vim b/.config/nvim/modules/splits.vim
@@ -9,18 +9,8 @@ noremap <C-l> <C-w>l
noremap <C-c> <C-w>c
noremap <A-j> <C-w>+
noremap <A-k> <C-w>-
-noremap <A-h> <C-w><
-noremap <A-l> <C-w>>
-
-inoremap <C-h> <C-w>h
-inoremap <C-j> <C-w>j
-inoremap <C-k> <C-w>k
-inoremap <C-l> <C-w>l
-inoremap <C-c> <C-w>c
-inoremap <A-j> <C-w>+
-inoremap <A-k> <C-w>-
-inoremap <A-h> <C-w><
-inoremap <A-l> <C-w>>
+noremap <A-h> <C-w>>
+noremap <A-l> <C-w><
function! Netrwmap(filetype)
if a:filetype == 'netrw'
@@ -38,5 +28,5 @@ augroup Netrwstop
augroup END
set fillchars+=vert:\
-hi VertSplit ctermbg=0 ctermfg=0
-hi StatusLine ctermbg=0 ctermfg=0
+hi VertSplit ctermbg=1 ctermfg=1
+hi StatusLine ctermbg=1 ctermfg=1
diff --git a/.config/nvim/modules/statusline.vim b/.config/nvim/modules/statusline.vim
@@ -1,7 +1,7 @@
hi Statusbar ctermbg=0 ctermfg=0
hi Modecol ctermbg=10 ctermfg=254 gui=bold
-hi Basecol ctermbg=0
-hi Filecol ctermbg=2 ctermfg=7 gui=bold
+hi Basecol ctermbg=1
+hi Filecol ctermbg=3 ctermfg=7 gui=bold
hi Branchcol ctermbg=9 ctermfg=7 gui=bold
hi Positioncol ctermbg=3 ctermfg=254 gui=bold
hi Buffcol ctermbg=4 ctermfg=159
diff --git a/.config/nvim/modules/tabs.vim b/.config/nvim/modules/tabs.vim
@@ -1,3 +1,7 @@
+hi TabLine cterm=none ctermfg=252 ctermbg=1
+hi TabLineSel cterm=bold ctermfg=252 ctermbg=0
+hi TabLineFill cterm=none ctermfg=none ctermbg=1
+
nnoremap <leader>te :tabedit
nnoremap <leader>tf :tabfind
nnoremap <leader>tc :tabclose<CR>
@@ -6,7 +10,10 @@ nnoremap <leader>tb :tab ball<CR>
nnoremap <leader>th :tab help
nnoremap <leader>tz :tab split<CR>
nnoremap <leader>tZ :tab split<CR>
-nnoremap <leader>tn :tabn<CR>
+nnoremap <leader>tn :tabnew<CR>
+nnoremap <leader>tN :tabNext<CR>
nnoremap <leader>tp :tabp<CR>
nnoremap <leader>tN :tablast<CR>
nnoremap <leader>tP :tabfirst<CR>
+
+set showtabline=2
diff --git a/.config/nvim/modules/theme.vim b/.config/nvim/modules/theme.vim
@@ -4,3 +4,10 @@ hi NvimInternalError ctermbg=3 ctermfg=3
hi Float ctermfg=13 cterm=bold
hi LineNr ctermfg=11
hi CursorLineNr ctermfg=11 cterm=bold
+hi SpellBad ctermbg=1 ctermfg=10
+hi SpellCap ctermbg=1 ctermfg=13
+hi SpellRare ctermbg=1 ctermfg=256 cterm=underline
+hi SpellLocal ctermbg=1 ctermfg=255 cterm=bold
+
+hi MsgArea ctermbg=0
+hi MsgSeparator ctermbg=1
diff --git a/.config/nvim/modules/wiki.vim b/.config/nvim/modules/wiki.vim
@@ -0,0 +1,12 @@
+augroup wikimaps
+ autocmd WinNew,WinEnter,BufNew,BufEnter *.wiki :call Wikimaps()
+augroup END
+
+let g:vimwiki_listsyms='-~=X'
+
+function! Wikimaps()
+ nnoremap <buffer> <leader>Wt :VimwikiTable
+ nnoremap <buffer> <leader>W2h :Vimwiki2HTML
+ " To be continued
+endfunction
+
diff --git a/.config/nvim/modules/window.vim b/.config/nvim/modules/window.vim
@@ -0,0 +1,19 @@
+hi Float ctermbg=0 cterm=none ctermfg=256
+
+function! Winmsg()
+ let width=&columns+4
+ let height=20
+ let top=&lines-height-1
+ echo top
+ let left=-2
+ let opts = {'relative': 'editor', 'row': top, 'col': left, 'width': width, 'height': height, 'style': 'minimal'}
+ let opts.row += 1
+ let opts.height -= 2
+ let opts.col += 2
+ let opts.width -= 4
+ call nvim_open_win(nvim_create_buf(v:false, v:true), v:true, opts)
+endfunction
+
+function! Winset()
+ setlocal winhl=Normal:Float
+endfunction
diff --git a/.config/nvim/plugin/vimwiki.vim b/.config/nvim/plugin/vimwiki.vim
@@ -0,0 +1,398 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki plugin file
+" Home: https://github.com/vimwiki/vimwiki/
+" GetLatestVimScripts: 2226 1 :AutoInstall: vimwiki
+
+
+if exists("g:loaded_vimwiki") || &cp
+ finish
+endif
+let g:loaded_vimwiki = 1
+
+" Set to version number for release, otherwise -1 for dev-branch
+let s:plugin_vers = "2.4.1"
+
+" Get the directory the script is installed in
+let s:plugin_dir = expand('<sfile>:p:h:h')
+
+let s:old_cpo = &cpo
+set cpo&vim
+
+
+if exists('g:vimwiki_autowriteall')
+ let s:vimwiki_autowriteall_saved = g:vimwiki_autowriteall
+else
+ let s:vimwiki_autowriteall_saved = 1
+endif
+
+
+" this is called when the cursor leaves the buffer
+function! s:setup_buffer_leave()
+ " don't do anything if it's not managed by Vimwiki (that is, when it's not in
+ " a registered wiki and not a temporary wiki)
+ if vimwiki#vars#get_bufferlocal('wiki_nr') == -1
+ return
+ endif
+
+ let &autowriteall = s:vimwiki_autowriteall_saved
+
+ if !empty(vimwiki#vars#get_global('menu'))
+ exe 'nmenu disable '.vimwiki#vars#get_global('menu').'.Table'
+ endif
+endfunction
+
+
+" create a new temporary wiki for the current buffer
+function! s:create_temporary_wiki()
+ let path = expand('%:p:h')
+ let ext = '.'.expand('%:e')
+
+ let syntax_mapping = vimwiki#vars#get_global('ext2syntax')
+ if has_key(syntax_mapping, ext)
+ let syntax = syntax_mapping[ext]
+ else
+ let syntax = vimwiki#vars#get_wikilocal_default('syntax')
+ endif
+
+ let new_temp_wiki_settings = {'path': path,
+ \ 'ext': ext,
+ \ 'syntax': syntax,
+ \ }
+
+ call vimwiki#vars#add_temporary_wiki(new_temp_wiki_settings)
+
+ " Update the wiki number of the current buffer, because it may have changed when adding this
+ " temporary wiki.
+ call vimwiki#vars#set_bufferlocal('wiki_nr', vimwiki#base#find_wiki(expand('%:p')))
+endfunction
+
+
+" This function is called when Vim opens a new buffer with a known wiki
+" extension. Both when the buffer has never been opened in this session and
+" when it has.
+function! s:setup_new_wiki_buffer()
+ let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr')
+ if wiki_nr == -1 " it's not in a known wiki directory
+ if vimwiki#vars#get_global('global_ext')
+ call s:create_temporary_wiki()
+ else
+ " the user does not want a temporary wiki, so do nothing
+ return
+ endif
+ endif
+
+ if vimwiki#vars#get_wikilocal('maxhi')
+ call vimwiki#vars#set_bufferlocal('existing_wikifiles', vimwiki#base#get_wikilinks(wiki_nr, 1))
+ call vimwiki#vars#set_bufferlocal('existing_wikidirs',
+ \ vimwiki#base#get_wiki_directories(wiki_nr))
+ endif
+
+ " this makes that ftplugin/vimwiki.vim and afterwards syntax/vimwiki.vim are
+ " sourced
+ setfiletype vimwiki
+
+endfunction
+
+
+" this is called when the cursor enters the buffer
+function! s:setup_buffer_enter()
+ " don't do anything if it's not managed by Vimwiki (that is, when it's not in
+ " a registered wiki and not a temporary wiki)
+ if vimwiki#vars#get_bufferlocal('wiki_nr') == -1
+ return
+ endif
+
+ if &filetype != 'vimwiki'
+ setfiletype vimwiki
+ endif
+
+ call s:set_global_options()
+
+ call s:set_windowlocal_options()
+endfunction
+
+
+function! s:setup_cleared_syntax()
+ " highlight groups that get cleared
+ " on colorscheme change because they are not linked to Vim-predefined groups
+ hi def VimwikiBold term=bold cterm=bold gui=bold
+ hi def VimwikiItalic term=italic cterm=italic gui=italic
+ hi def VimwikiBoldItalic term=bold cterm=bold gui=bold,italic
+ hi def VimwikiUnderline gui=underline
+ if vimwiki#vars#get_global('hl_headers') == 1
+ for i in range(1,6)
+ execute 'hi def VimwikiHeader'.i.' guibg=bg guifg='
+ \ . vimwiki#vars#get_global('hcolor_guifg_'.&bg)[i-1]
+ \ .' gui=bold ctermfg='.vimwiki#vars#get_global('hcolor_ctermfg_'.&bg)[i-1]
+ \ .' term=bold cterm=bold'
+ endfor
+ endif
+endfunction
+
+
+function! s:vimwiki_get_known_extensions()
+ " Getting all extensions that different wikis could have
+ let extensions = {}
+ for idx in range(vimwiki#vars#number_of_wikis())
+ let ext = vimwiki#vars#get_wikilocal('ext', idx)
+ let extensions[ext] = 1
+ endfor
+ " append extensions from g:vimwiki_ext2syntax
+ for ext in keys(vimwiki#vars#get_global('ext2syntax'))
+ let extensions[ext] = 1
+ endfor
+ return keys(extensions)
+endfunction
+
+
+" Set settings which are global for Vim, but should only be executed for
+" Vimwiki buffers. So they must be set when the cursor enters a Vimwiki buffer
+" and reset when the cursor leaves the buffer.
+function! s:set_global_options()
+ let s:vimwiki_autowriteall_saved = &autowriteall
+ let &autowriteall = vimwiki#vars#get_global('autowriteall')
+
+ if !empty(vimwiki#vars#get_global('menu'))
+ exe 'nmenu enable '.vimwiki#vars#get_global('menu').'.Table'
+ endif
+endfunction
+
+
+" Set settings which are local to a window. In a new tab they would be reset to
+" Vim defaults. So we enforce our settings here when the cursor enters a
+" Vimwiki buffer.
+function! s:set_windowlocal_options()
+ if !&diff " if Vim is currently in diff mode, don't interfere with its folding
+ let foldmethod = vimwiki#vars#get_global('folding')
+ if foldmethod =~? '^expr.*'
+ setlocal foldmethod=expr
+ setlocal foldexpr=VimwikiFoldLevel(v:lnum)
+ setlocal foldtext=VimwikiFoldText()
+ elseif foldmethod =~? '^list.*' || foldmethod =~? '^lists.*'
+ setlocal foldmethod=expr
+ setlocal foldexpr=VimwikiFoldListLevel(v:lnum)
+ setlocal foldtext=VimwikiFoldText()
+ elseif foldmethod =~? '^syntax.*'
+ setlocal foldmethod=syntax
+ setlocal foldtext=VimwikiFoldText()
+ elseif foldmethod =~? '^custom.*'
+ " do nothing
+ else
+ setlocal foldmethod=manual
+ normal! zE
+ endif
+ endif
+
+ if vimwiki#vars#get_global('conceallevel') && exists("+conceallevel")
+ let &conceallevel = vimwiki#vars#get_global('conceallevel')
+ endif
+
+ if vimwiki#vars#get_global('auto_chdir')
+ exe 'lcd' vimwiki#vars#get_wikilocal('path')
+ endif
+endfunction
+
+
+function! s:get_version()
+ if s:plugin_vers != -1
+ echo "Stable version: " . string(s:plugin_vers)
+ else
+ let l:plugin_rev = system("git --git-dir " . s:plugin_dir . "/.git rev-parse --short HEAD")
+ let l:plugin_branch = system("git --git-dir " . s:plugin_dir . "/.git rev-parse --abbrev-ref HEAD")
+ let l:plugin_date = system("git --git-dir " . s:plugin_dir . "/.git show -s --format=%ci")
+ if v:shell_error == 0
+ echo "Branch: " . l:plugin_branch
+ echo "Revision: " . l:plugin_rev
+ echo "Date: " . l:plugin_date
+ else
+ echo "Unknown version"
+ endif
+ endif
+endfunction
+
+
+
+" Initialization of Vimwiki starts here. Make sure everything below does not
+" cause autoload/vimwiki/base.vim to be loaded
+
+call vimwiki#vars#init()
+
+
+" Define callback functions which the user can redefine
+if !exists("*VimwikiLinkHandler")
+ function VimwikiLinkHandler(url)
+ return 0
+ endfunction
+endif
+
+if !exists("*VimwikiLinkConverter")
+ function VimwikiLinkConverter(url, source, target)
+ " Return the empty string when unable to process link
+ return ''
+ endfunction
+endif
+
+if !exists("*VimwikiWikiIncludeHandler")
+ function! VimwikiWikiIncludeHandler(value)
+ return ''
+ endfunction
+endif
+
+
+
+" Define autocommands for all known wiki extensions
+
+let s:known_extensions = s:vimwiki_get_known_extensions()
+
+if index(s:known_extensions, '.wiki') > -1
+ augroup filetypedetect
+ " clear FlexWiki's stuff
+ au! * *.wiki
+ augroup end
+endif
+
+augroup vimwiki
+ autocmd!
+ autocmd ColorScheme * call s:setup_cleared_syntax()
+ for s:ext in s:known_extensions
+ exe 'autocmd BufNewFile,BufRead *'.s:ext.' call s:setup_new_wiki_buffer()'
+ exe 'autocmd BufEnter *'.s:ext.' call s:setup_buffer_enter()'
+ exe 'autocmd BufLeave *'.s:ext.' call s:setup_buffer_leave()'
+ " Format tables when exit from insert mode. Do not use textwidth to
+ " autowrap tables.
+ if vimwiki#vars#get_global('table_auto_fmt')
+ exe 'autocmd InsertLeave *'.s:ext.' call vimwiki#tbl#format(line("."))'
+ exe 'autocmd InsertEnter *'.s:ext.' call vimwiki#tbl#reset_tw(line("."))'
+ endif
+ if vimwiki#vars#get_global('folding') =~? ':quick$'
+ " from http://vim.wikia.com/wiki/Keep_folds_closed_while_inserting_text
+ " Don't screw up folds when inserting text that might affect them, until
+ " leaving insert mode. Foldmethod is local to the window. Protect against
+ " screwing up folding when switching between windows.
+ exe 'autocmd InsertEnter *'.s:ext.' if !exists("w:last_fdm") | let w:last_fdm=&foldmethod'.
+ \ ' | setlocal foldmethod=manual | endif'
+ exe 'autocmd InsertLeave,WinLeave *'.s:ext.' if exists("w:last_fdm") |'.
+ \ 'let &l:foldmethod=w:last_fdm | unlet w:last_fdm | endif'
+ endif
+ endfor
+augroup END
+
+
+
+command! VimwikiUISelect call vimwiki#base#ui_select()
+" why not using <count> instead of v:count1?
+" See https://github.com/vimwiki-backup/vimwiki/issues/324
+command! -count=1 VimwikiIndex
+ \ call vimwiki#base#goto_index(v:count1)
+command! -count=1 VimwikiTabIndex
+ \ call vimwiki#base#goto_index(v:count1, 1)
+
+command! -count=1 VimwikiDiaryIndex
+ \ call vimwiki#diary#goto_diary_index(v:count1)
+command! -count=1 VimwikiMakeDiaryNote
+ \ call vimwiki#diary#make_note(v:count)
+command! -count=1 VimwikiTabMakeDiaryNote
+ \ call vimwiki#diary#make_note(v:count, 1)
+command! -count=1 VimwikiMakeYesterdayDiaryNote
+ \ call vimwiki#diary#make_note(v:count, 0,
+ \ vimwiki#diary#diary_date_link(localtime() - 60*60*24))
+command! -count=1 VimwikiMakeTomorrowDiaryNote
+ \ call vimwiki#diary#make_note(v:count, 0,
+ \ vimwiki#diary#diary_date_link(localtime() + 60*60*24))
+
+command! VimwikiDiaryGenerateLinks
+ \ call vimwiki#diary#generate_diary_section()
+
+command! VimwikiShowVersion call s:get_version()
+
+
+
+let s:map_prefix = vimwiki#vars#get_global('map_prefix')
+
+if !hasmapto('<Plug>VimwikiIndex')
+ exe 'nmap <silent><unique> '.s:map_prefix.'w <Plug>VimwikiIndex'
+endif
+nnoremap <unique><script> <Plug>VimwikiIndex :VimwikiIndex<CR>
+
+if !hasmapto('<Plug>VimwikiTabIndex')
+ exe 'nmap <silent><unique> '.s:map_prefix.'t <Plug>VimwikiTabIndex'
+endif
+nnoremap <unique><script> <Plug>VimwikiTabIndex :VimwikiTabIndex<CR>
+
+if !hasmapto('<Plug>VimwikiUISelect')
+ exe 'nmap <silent><unique> '.s:map_prefix.'s <Plug>VimwikiUISelect'
+endif
+nnoremap <unique><script> <Plug>VimwikiUISelect :VimwikiUISelect<CR>
+
+if !hasmapto('<Plug>VimwikiDiaryIndex')
+ exe 'nmap <silent><unique> '.s:map_prefix.'i <Plug>VimwikiDiaryIndex'
+endif
+nnoremap <unique><script> <Plug>VimwikiDiaryIndex :VimwikiDiaryIndex<CR>
+
+if !hasmapto('<Plug>VimwikiDiaryGenerateLinks')
+ exe 'nmap <silent><unique> '.s:map_prefix.'<Leader>i <Plug>VimwikiDiaryGenerateLinks'
+endif
+nnoremap <unique><script> <Plug>VimwikiDiaryGenerateLinks :VimwikiDiaryGenerateLinks<CR>
+
+if !hasmapto('<Plug>VimwikiMakeDiaryNote')
+ exe 'nmap <silent><unique> '.s:map_prefix.'<Leader>w <Plug>VimwikiMakeDiaryNote'
+endif
+nnoremap <unique><script> <Plug>VimwikiMakeDiaryNote :VimwikiMakeDiaryNote<CR>
+
+if !hasmapto('<Plug>VimwikiTabMakeDiaryNote')
+ exe 'nmap <silent><unique> '.s:map_prefix.'<Leader>t <Plug>VimwikiTabMakeDiaryNote'
+endif
+nnoremap <unique><script> <Plug>VimwikiTabMakeDiaryNote
+ \ :VimwikiTabMakeDiaryNote<CR>
+
+if !hasmapto('<Plug>VimwikiMakeYesterdayDiaryNote')
+ exe 'nmap <silent><unique> '.s:map_prefix.'<Leader>y <Plug>VimwikiMakeYesterdayDiaryNote'
+endif
+nnoremap <unique><script> <Plug>VimwikiMakeYesterdayDiaryNote
+ \ :VimwikiMakeYesterdayDiaryNote<CR>
+
+if !hasmapto('<Plug>VimwikiMakeTomorrowDiaryNote')
+ exe 'nmap <silent><unique> '.s:map_prefix.'<Leader>m <Plug>VimwikiMakeTomorrowDiaryNote'
+endif
+nnoremap <unique><script> <Plug>VimwikiMakeTomorrowDiaryNote
+ \ :VimwikiMakeTomorrowDiaryNote<CR>
+
+
+
+
+function! s:build_menu(topmenu)
+ for idx in range(vimwiki#vars#number_of_wikis())
+ let norm_path = fnamemodify(vimwiki#vars#get_wikilocal('path', idx), ':h:t')
+ let norm_path = escape(norm_path, '\ \.')
+ execute 'menu '.a:topmenu.'.Open\ index.'.norm_path.
+ \ ' :call vimwiki#base#goto_index('.(idx+1).')<CR>'
+ execute 'menu '.a:topmenu.'.Open/Create\ diary\ note.'.norm_path.
+ \ ' :call vimwiki#diary#make_note('.(idx+1).')<CR>'
+ endfor
+endfunction
+
+function! s:build_table_menu(topmenu)
+ exe 'menu '.a:topmenu.'.-Sep- :'
+ exe 'menu '.a:topmenu.'.Table.Create\ (enter\ cols\ rows) :VimwikiTable '
+ exe 'nmenu '.a:topmenu.'.Table.Format<tab>gqq gqq'
+ exe 'nmenu '.a:topmenu.'.Table.Move\ column\ left<tab><A-Left> :VimwikiTableMoveColumnLeft<CR>'
+ exe 'nmenu '.a:topmenu.
+ \ '.Table.Move\ column\ right<tab><A-Right> :VimwikiTableMoveColumnRight<CR>'
+ exe 'nmenu disable '.a:topmenu.'.Table'
+endfunction
+
+
+if !empty(vimwiki#vars#get_global('menu'))
+ call s:build_menu(vimwiki#vars#get_global('menu'))
+ call s:build_table_menu(vimwiki#vars#get_global('menu'))
+endif
+
+
+" Hook for calendar.vim
+if vimwiki#vars#get_global('use_calendar')
+ let g:calendar_action = 'vimwiki#diary#calendar_action'
+ let g:calendar_sign = 'vimwiki#diary#calendar_sign'
+endif
+
+
+let &cpo = s:old_cpo
diff --git a/.config/nvim/startup.greet b/.config/nvim/startup.greet
@@ -0,0 +1,24 @@
+
+
+
+
+
+ |‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|
+ | _ _ _ _ |
+ | | |__ __ _ _ _ __| | ___ _ __ ( )___ __ _(_)_ __ ___ |
+ | | '_ \ / _` | | | |/ _` |/ _ \ '_ \|// __| \ \ / / | '_ ` _ \ |
+ | | | | | (_| | |_| | (_| | __/ | | | \__ \ \ V /| | | | | | | |
+ | |_| |_|\__,_|\__, |\__,_|\___|_| |_| |___/ (n)\_/ |_|_| |_| |_| |
+ | |___/ |
+ |____________________________________________________________________|
+
+ Plugins collected by Hayden Hamilton
+ init.vim created by Hayden Hamilton
+ modules/ created by Hayden Hamilton
+ Find more stuff at http://haydenvh.com
+
+ :edit ~/.config/nvim/init - Contains mappings and settings for neovim.
+
+ :Explore ~/.config/nvim/modules - Contains my modules and additions.
+
+ :help intro - introduction to the vim editor.
diff --git a/.config/nvim/syntax/greet.vim b/.config/nvim/syntax/greet.vim
@@ -0,0 +1,12 @@
+if exists("b:current_syntax")
+ finish
+endif
+
+syn match gAscii '|.*|'
+syn match gCommand ':[A-Za-z!]* [A-Za-z/~\.]*'
+syn match gText '^\s*[A-Za-z].*'
+hi gAscii cterm=none ctermbg=1 ctermfg=12
+hi gCommand cterm=none ctermbg=none ctermfg=13
+hi gText cterm=none ctermbg=none ctermfg=255
+setlocal fcs=eob:\
+set nonumber norelativenumber
diff --git a/.config/nvim/syntax/recent.vim b/.config/nvim/syntax/recent.vim
@@ -0,0 +1,10 @@
+if exists("b:current_syntax")
+ finish
+endif
+
+syn match rNum '\[[0-9]*\]'
+syn match rChar '\[[A-Za-z]*\]'
+syn match Head '^\s*[A-Za-z0-9].*'
+hi rNum cterm=none ctermfg=30
+hi rChar cterm=none ctermfg=28
+hi Head cterm=bold ctermfg=255
diff --git a/.config/nvim/syntax/vimwiki.vim b/.config/nvim/syntax/vimwiki.vim
@@ -0,0 +1,487 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki syntax file
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+" Quit if syntax file is already loaded
+if v:version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+
+let s:current_syntax = vimwiki#vars#get_wikilocal('syntax')
+
+
+call vimwiki#vars#populate_syntax_vars(s:current_syntax)
+
+
+" LINKS: highlighting is complicated due to "nonexistent" links feature
+function! s:add_target_syntax_ON(target, type)
+ let prefix0 = 'syntax match '.a:type.' `'
+ let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,'.a:type.'Char'
+ let prefix1 = 'syntax match '.a:type.'T `'
+ let suffix1 = '` display contained'
+ execute prefix0. a:target. suffix0
+ execute prefix1. a:target. suffix1
+endfunction
+
+
+function! s:add_target_syntax_OFF(target)
+ let prefix0 = 'syntax match VimwikiNoExistsLink `'
+ let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,VimwikiLinkChar'
+ let prefix1 = 'syntax match VimwikiNoExistsLinkT `'
+ let suffix1 = '` display contained'
+ execute prefix0. a:target. suffix0
+ execute prefix1. a:target. suffix1
+endfunction
+
+
+function! s:highlight_existing_links()
+ " Wikilink
+ " Conditional highlighting that depends on the existence of a wiki file or
+ " directory is only available for *schemeless* wiki links
+ " Links are set up upon BufEnter (see plugin/...)
+ let safe_links = '\%('.vimwiki#base#file_pattern(
+ \ vimwiki#vars#get_bufferlocal('existing_wikifiles')) . '\%(#[^|]*\)\?\|#[^|]*\)'
+ " Wikilink Dirs set up upon BufEnter (see plugin/...)
+ let safe_dirs = vimwiki#base#file_pattern(vimwiki#vars#get_bufferlocal('existing_wikidirs'))
+
+ " match [[URL]]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiLinkTemplate1')),
+ \ safe_links, vimwiki#vars#get_global('rxWikiLinkDescr'), '')
+ call s:add_target_syntax_ON(target, 'VimwikiLink')
+ " match [[URL|DESCRIPTION]]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiLinkTemplate2')),
+ \ safe_links, vimwiki#vars#get_global('rxWikiLinkDescr'), '')
+ call s:add_target_syntax_ON(target, 'VimwikiLink')
+
+ " match {{URL}}
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiInclTemplate1')),
+ \ safe_links, vimwiki#vars#get_global('rxWikiInclArgs'), '')
+ call s:add_target_syntax_ON(target, 'VimwikiLink')
+ " match {{URL|...}}
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiInclTemplate2')),
+ \ safe_links, vimwiki#vars#get_global('rxWikiInclArgs'), '')
+ call s:add_target_syntax_ON(target, 'VimwikiLink')
+ " match [[DIRURL]]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiLinkTemplate1')),
+ \ safe_dirs, vimwiki#vars#get_global('rxWikiLinkDescr'), '')
+ call s:add_target_syntax_ON(target, 'VimwikiLink')
+ " match [[DIRURL|DESCRIPTION]]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiLinkTemplate2')),
+ \ safe_dirs, vimwiki#vars#get_global('rxWikiLinkDescr'), '')
+ call s:add_target_syntax_ON(target, 'VimwikiLink')
+endfunction
+
+
+" use max highlighting - could be quite slow if there are too many wikifiles
+if vimwiki#vars#get_wikilocal('maxhi')
+ " WikiLink
+ call s:add_target_syntax_OFF(vimwiki#vars#get_syntaxlocal('rxWikiLink'))
+ " WikiIncl
+ call s:add_target_syntax_OFF(vimwiki#vars#get_global('rxWikiIncl'))
+
+ " Subsequently, links verified on vimwiki's path are highlighted as existing
+ call s:highlight_existing_links()
+else
+ " Wikilink
+ call s:add_target_syntax_ON(vimwiki#vars#get_syntaxlocal('rxWikiLink'), 'VimwikiLink')
+ " WikiIncl
+ call s:add_target_syntax_ON(vimwiki#vars#get_global('rxWikiIncl'), 'VimwikiLink')
+endif
+
+
+" Weblink
+call s:add_target_syntax_ON(vimwiki#vars#get_syntaxlocal('rxWeblink'), 'VimwikiLink')
+
+
+" WikiLink
+" All remaining schemes are highlighted automatically
+let s:rxSchemes = '\%('.
+ \ vimwiki#vars#get_global('schemes') . '\|'.
+ \ vimwiki#vars#get_global('web_schemes1').
+ \ '\):'
+
+" a) match [[nonwiki-scheme-URL]]
+let s:target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiLinkTemplate1')),
+ \ s:rxSchemes.vimwiki#vars#get_global('rxWikiLinkUrl'),
+ \ vimwiki#vars#get_global('rxWikiLinkDescr'), '')
+call s:add_target_syntax_ON(s:target, 'VimwikiLink')
+" b) match [[nonwiki-scheme-URL|DESCRIPTION]]
+let s:target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiLinkTemplate2')),
+ \ s:rxSchemes.vimwiki#vars#get_global('rxWikiLinkUrl'),
+ \ vimwiki#vars#get_global('rxWikiLinkDescr'), '')
+call s:add_target_syntax_ON(s:target, 'VimwikiLink')
+
+" a) match {{nonwiki-scheme-URL}}
+let s:target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiInclTemplate1')),
+ \ s:rxSchemes.vimwiki#vars#get_global('rxWikiInclUrl'),
+ \ vimwiki#vars#get_global('rxWikiInclArgs'), '')
+call s:add_target_syntax_ON(s:target, 'VimwikiLink')
+" b) match {{nonwiki-scheme-URL}[{...}]}
+let s:target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_global('WikiInclTemplate2')),
+ \ s:rxSchemes.vimwiki#vars#get_global('rxWikiInclUrl'),
+ \ vimwiki#vars#get_global('rxWikiInclArgs'), '')
+call s:add_target_syntax_ON(s:target, 'VimwikiLink')
+
+
+
+" Header levels, 1-6
+for s:i in range(1,6)
+ execute 'syntax match VimwikiHeader'.s:i
+ \ . ' /'.vimwiki#vars#get_syntaxlocal('rxH'.s:i, s:current_syntax).
+ \ '/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiCode,'.
+ \ 'VimwikiLink,@Spell'
+ execute 'syntax region VimwikiH'.s:i.'Folding start=/'.
+ \ vimwiki#vars#get_syntaxlocal('rxH'.s:i.'_Start', s:current_syntax).'/ end=/'.
+ \ vimwiki#vars#get_syntaxlocal('rxH'.s:i.'_End', s:current_syntax).
+ \ '/me=s-1 transparent fold'
+endfor
+
+
+
+" possibly concealed chars
+let s:conceal = exists("+conceallevel") ? ' conceal' : ''
+
+execute 'syn match VimwikiEqInChar contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_eqin').'/'.s:conceal
+execute 'syn match VimwikiBoldChar contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_bold').'/'.s:conceal
+execute 'syn match VimwikiItalicChar contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_italic').'/'.s:conceal
+execute 'syn match VimwikiBoldItalicChar contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_bolditalic').'/'.s:conceal
+execute 'syn match VimwikiItalicBoldChar contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_italicbold').'/'.s:conceal
+execute 'syn match VimwikiCodeChar contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_code').'/'.s:conceal
+execute 'syn match VimwikiDelTextChar contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_deltext').'/'.s:conceal
+execute 'syn match VimwikiSuperScript contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_superscript').'/'.s:conceal
+execute 'syn match VimwikiSubScript contained /'.
+ \ vimwiki#vars#get_syntaxlocal('char_subscript').'/'.s:conceal
+
+
+
+
+
+let s:options = ' contained transparent contains=NONE'
+
+" A shortener for long URLs: LinkRest (a middle part of the URL) is concealed
+" VimwikiLinkRest group is left undefined if link shortening is not desired
+if exists("+conceallevel") && vimwiki#vars#get_global('url_maxsave') > 0
+ let s:options .= s:conceal
+ execute 'syn match VimwikiLinkRest `\%(///\=[^/ \t]\+/\)\zs\S\+\ze'
+ \.'\%([/#?]\w\|\S\{'.vimwiki#vars#get_global('url_maxsave').'}\)`'.' cchar=~'.s:options
+endif
+
+" VimwikiLinkChar is for syntax markers (and also URL when a description
+" is present) and may be concealed
+
+" conceal wikilinks
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rx_wikilink_prefix').'/'.s:options
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rx_wikilink_suffix').'/'.s:options
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rx_wikilink_prefix1').'/'.s:options
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rx_wikilink_suffix1').'/'.s:options
+
+" conceal wikiincls
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rxWikiInclPrefix').'/'.s:options
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rxWikiInclSuffix').'/'.s:options
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rxWikiInclPrefix1').'/'.s:options
+execute 'syn match VimwikiLinkChar /'.vimwiki#vars#get_global('rxWikiInclSuffix1').'/'.s:options
+
+
+" non concealed chars
+execute 'syn match VimwikiHeaderChar contained /\%(^\s*'.
+ \ vimwiki#vars#get_syntaxlocal('rxH').'\+\)\|\%('.vimwiki#vars#get_syntaxlocal('rxH').
+ \ '\+\s*$\)/'
+execute 'syn match VimwikiEqInCharT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_eqin').'/'
+execute 'syn match VimwikiBoldCharT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_bold').'/'
+execute 'syn match VimwikiItalicCharT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_italic').'/'
+execute 'syn match VimwikiBoldItalicCharT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_bolditalic').'/'
+execute 'syn match VimwikiItalicBoldCharT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_italicbold').'/'
+execute 'syn match VimwikiCodeCharT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_code').'/'
+execute 'syn match VimwikiDelTextCharT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_deltext').'/'
+execute 'syn match VimwikiSuperScriptT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_superscript').'/'
+execute 'syn match VimwikiSubScriptT contained /'
+ \ .vimwiki#vars#get_syntaxlocal('char_subscript').'/'
+
+
+execute 'syntax match VimwikiTodo /'. vimwiki#vars#get_global('rxTodo') .'/'
+
+
+
+" Tables
+syntax match VimwikiTableRow /^\s*|.\+|\s*$/
+ \ transparent contains=VimwikiCellSeparator,
+ \ VimwikiLinkT,
+ \ VimwikiNoExistsLinkT,
+ \ VimwikiTodo,
+ \ VimwikiBoldT,
+ \ VimwikiItalicT,
+ \ VimwikiBoldItalicT,
+ \ VimwikiItalicBoldT,
+ \ VimwikiDelTextT,
+ \ VimwikiSuperScriptT,
+ \ VimwikiSubScriptT,
+ \ VimwikiCodeT,
+ \ VimwikiEqInT,
+ \ @Spell
+syntax match VimwikiCellSeparator
+ \ /\%(|\)\|\%(-\@<=+\-\@=\)\|\%([|+]\@<=-\+\)/ contained
+
+
+" Lists
+execute 'syntax match VimwikiList /'.vimwiki#vars#get_syntaxlocal('rxListItemWithoutCB').'/'
+execute 'syntax match VimwikiList /'.vimwiki#vars#get_syntaxlocal('rxListDefine').'/'
+execute 'syntax match VimwikiListTodo /'.vimwiki#vars#get_syntaxlocal('rxListItem').'/'
+
+if vimwiki#vars#get_global('hl_cb_checked') == 1
+ execute 'syntax match VimwikiCheckBoxDone /'.vimwiki#vars#get_syntaxlocal('rxListItemWithoutCB')
+ \ . '\s*\[['.vimwiki#vars#get_syntaxlocal('listsyms_list')[-1]
+ \ . vimwiki#vars#get_global('listsym_rejected')
+ \ . ']\]\s.*$/ contains=VimwikiNoExistsLink,VimwikiLink,@Spell'
+elseif vimwiki#vars#get_global('hl_cb_checked') == 2
+ execute 'syntax match VimwikiCheckBoxDone /'
+ \ . vimwiki#vars#get_syntaxlocal('rxListItemAndChildren')
+ \ .'/ contains=VimwikiNoExistsLink,VimwikiLink,@Spell'
+endif
+
+
+execute 'syntax match VimwikiEqIn /'.vimwiki#vars#get_syntaxlocal('rxEqIn').
+ \ '/ contains=VimwikiEqInChar'
+execute 'syntax match VimwikiEqInT /'.vimwiki#vars#get_syntaxlocal('rxEqIn').
+ \ '/ contained contains=VimwikiEqInCharT'
+
+execute 'syntax match VimwikiBold /'.vimwiki#vars#get_syntaxlocal('rxBold').
+ \ '/ contains=VimwikiBoldChar,@Spell'
+execute 'syntax match VimwikiBoldT /'.vimwiki#vars#get_syntaxlocal('rxBold').
+ \ '/ contained contains=VimwikiBoldCharT,@Spell'
+
+execute 'syntax match VimwikiItalic /'.vimwiki#vars#get_syntaxlocal('rxItalic').
+ \ '/ contains=VimwikiItalicChar,@Spell'
+execute 'syntax match VimwikiItalicT /'.vimwiki#vars#get_syntaxlocal('rxItalic').
+ \ '/ contained contains=VimwikiItalicCharT,@Spell'
+
+execute 'syntax match VimwikiBoldItalic /'.vimwiki#vars#get_syntaxlocal('rxBoldItalic').
+ \ '/ contains=VimwikiBoldItalicChar,VimwikiItalicBoldChar,@Spell'
+execute 'syntax match VimwikiBoldItalicT /'.vimwiki#vars#get_syntaxlocal('rxBoldItalic').
+ \ '/ contained contains=VimwikiBoldItalicChatT,VimwikiItalicBoldCharT,@Spell'
+
+execute 'syntax match VimwikiItalicBold /'.vimwiki#vars#get_syntaxlocal('rxItalicBold').
+ \ '/ contains=VimwikiBoldItalicChar,VimwikiItalicBoldChar,@Spell'
+execute 'syntax match VimwikiItalicBoldT /'.vimwiki#vars#get_syntaxlocal('rxItalicBold').
+ \ '/ contained contains=VimwikiBoldItalicCharT,VimsikiItalicBoldCharT,@Spell'
+
+execute 'syntax match VimwikiDelText /'.vimwiki#vars#get_syntaxlocal('rxDelText').
+ \ '/ contains=VimwikiDelTextChar,@Spell'
+execute 'syntax match VimwikiDelTextT /'.vimwiki#vars#get_syntaxlocal('rxDelText').
+ \ '/ contained contains=VimwikiDelTextCharT,@Spell'
+
+execute 'syntax match VimwikiSuperScript /'.vimwiki#vars#get_syntaxlocal('rxSuperScript').
+ \ '/ contains=VimwikiSuperScriptChar,@Spell'
+execute 'syntax match VimwikiSuperScriptT /'.vimwiki#vars#get_syntaxlocal('rxSuperScript').
+ \ '/ contained contains=VimwikiSuperScriptCharT,@Spell'
+
+execute 'syntax match VimwikiSubScript /'.vimwiki#vars#get_syntaxlocal('rxSubScript').
+ \ '/ contains=VimwikiSubScriptChar,@Spell'
+execute 'syntax match VimwikiSubScriptT /'.vimwiki#vars#get_syntaxlocal('rxSubScript').
+ \ '/ contained contains=VimwikiSubScriptCharT,@Spell'
+
+execute 'syntax match VimwikiCode /'.vimwiki#vars#get_syntaxlocal('rxCode').
+ \ '/ contains=VimwikiCodeChar'
+execute 'syntax match VimwikiCodeT /'.vimwiki#vars#get_syntaxlocal('rxCode').
+ \ '/ contained contains=VimwikiCodeCharT'
+
+
+" <hr> horizontal rule
+execute 'syntax match VimwikiHR /'.vimwiki#vars#get_syntaxlocal('rxHR').'/'
+
+execute 'syntax region VimwikiPre start=/'.vimwiki#vars#get_syntaxlocal('rxPreStart').
+ \ '/ end=/'.vimwiki#vars#get_syntaxlocal('rxPreEnd').'/ contains=@Spell'
+
+execute 'syntax region VimwikiMath start=/'.vimwiki#vars#get_syntaxlocal('rxMathStart').
+ \ '/ end=/'.vimwiki#vars#get_syntaxlocal('rxMathEnd').'/ contains=@Spell'
+
+
+" placeholders
+syntax match VimwikiPlaceholder /^\s*%nohtml\s*$/
+syntax match VimwikiPlaceholder
+ \ /^\s*%title\ze\%(\s.*\)\?$/ nextgroup=VimwikiPlaceholderParam skipwhite
+syntax match VimwikiPlaceholder
+ \ /^\s*%date\ze\%(\s.*\)\?$/ nextgroup=VimwikiPlaceholderParam skipwhite
+syntax match VimwikiPlaceholder
+ \ /^\s*%template\ze\%(\s.*\)\?$/ nextgroup=VimwikiPlaceholderParam skipwhite
+syntax match VimwikiPlaceholderParam /.*/ contained
+
+
+" html tags
+if vimwiki#vars#get_global('valid_html_tags') != ''
+ let s:html_tags = join(split(vimwiki#vars#get_global('valid_html_tags'), '\s*,\s*'), '\|')
+ exe 'syntax match VimwikiHTMLtag #\c</\?\%('.s:html_tags.'\)\%(\s\{-1}\S\{-}\)\{-}\s*/\?>#'
+ execute 'syntax match VimwikiBold #\c<b>.\{-}</b># contains=VimwikiHTMLTag'
+ execute 'syntax match VimwikiItalic #\c<i>.\{-}</i># contains=VimwikiHTMLTag'
+ execute 'syntax match VimwikiUnderline #\c<u>.\{-}</u># contains=VimwikiHTMLTag'
+
+ execute 'syntax match VimwikiComment /'.vimwiki#vars#get_syntaxlocal('rxComment').
+ \ '/ contains=@Spell,VimwikiTodo'
+endif
+
+" tags
+execute 'syntax match VimwikiTag /'.vimwiki#vars#get_syntaxlocal('rxTags').'/'
+
+
+
+" header groups highlighting
+if vimwiki#vars#get_global('hl_headers') == 0
+ " Strangely in default colorscheme Title group is not set to bold for cterm...
+ if !exists("g:colors_name")
+ hi Title cterm=bold
+ endif
+ for s:i in range(1,6)
+ execute 'hi def link VimwikiHeader'.s:i.' Title'
+ endfor
+else
+ for s:i in range(1,6)
+ execute 'hi def VimwikiHeader'.s:i.' guibg=bg guifg='
+ \ .vimwiki#vars#get_global('hcolor_guifg_'.&bg)[s:i-1].' gui=bold ctermfg='
+ \ .vimwiki#vars#get_global('hcolor_ctermfg_'.&bg)[s:i-1].' term=bold cterm=bold'
+ endfor
+endif
+
+
+
+hi def link VimwikiMarkers Normal
+
+hi def link VimwikiEqIn Number
+hi def link VimwikiEqInT VimwikiEqIn
+
+hi def VimwikiBold term=bold cterm=bold gui=bold
+hi def link VimwikiBoldT VimwikiBold
+
+hi def VimwikiItalic term=italic cterm=italic gui=italic
+hi def link VimwikiItalicT VimwikiItalic
+
+hi def VimwikiBoldItalic term=bold cterm=bold gui=bold,italic
+hi def link VimwikiItalicBold VimwikiBoldItalic
+hi def link VimwikiBoldItalicT VimwikiBoldItalic
+hi def link VimwikiItalicBoldT VimwikiBoldItalic
+
+hi def VimwikiUnderline gui=underline
+
+hi def link VimwikiCode PreProc
+hi def link VimwikiCodeT VimwikiCode
+
+hi def link VimwikiPre PreProc
+hi def link VimwikiPreT VimwikiPre
+
+hi def link VimwikiMath Number
+hi def link VimwikiMathT VimwikiMath
+
+hi def link VimwikiNoExistsLink SpellBad
+hi def link VimwikiNoExistsLinkT VimwikiNoExistsLink
+
+hi def link VimwikiLink Underlined
+hi def link VimwikiLinkT VimwikiLink
+
+hi def link VimwikiList Identifier
+hi def link VimwikiListTodo VimwikiList
+hi def link VimwikiCheckBoxDone Comment
+hi def link VimwikiHR Identifier
+hi def link VimwikiTag Keyword
+
+hi def link VimwikiDelText Constant
+hi def link VimwikiDelTextT VimwikiDelText
+
+hi def link VimwikiSuperScript Number
+hi def link VimwikiSuperScriptT VimwikiSuperScript
+
+hi def link VimwikiSubScript Number
+hi def link VimwikiSubScriptT VimwikiSubScript
+
+hi def link VimwikiTodo Todo
+hi def link VimwikiComment Comment
+
+hi def link VimwikiPlaceholder SpecialKey
+hi def link VimwikiPlaceholderParam String
+hi def link VimwikiHTMLtag SpecialKey
+
+hi def link VimwikiEqInChar VimwikiMarkers
+hi def link VimwikiCellSeparator VimwikiMarkers
+hi def link VimwikiBoldChar VimwikiMarkers
+hi def link VimwikiItalicChar VimwikiMarkers
+hi def link VimwikiBoldItalicChar VimwikiMarkers
+hi def link VimwikiItalicBoldChar VimwikiMarkers
+hi def link VimwikiDelTextChar VimwikiMarkers
+hi def link VimwikiSuperScriptChar VimwikiMarkers
+hi def link VimwikiSubScriptChar VimwikiMarkers
+hi def link VimwikiCodeChar VimwikiMarkers
+hi def link VimwikiHeaderChar VimwikiMarkers
+
+hi def link VimwikiEqInCharT VimwikiMarkers
+hi def link VimwikiBoldCharT VimwikiMarkers
+hi def link VimwikiItalicCharT VimwikiMarkers
+hi def link VimwikiBoldItalicCharT VimwikiMarkers
+hi def link VimwikiItalicBoldCharT VimwikiMarkers
+hi def link VimwikiDelTextCharT VimwikiMarkers
+hi def link VimwikiSuperScriptCharT VimwikiMarkers
+hi def link VimwikiSubScriptCharT VimwikiMarkers
+hi def link VimwikiCodeCharT VimwikiMarkers
+hi def link VimwikiHeaderCharT VimwikiMarkers
+hi def link VimwikiLinkCharT VimwikiLinkT
+hi def link VimwikiNoExistsLinkCharT VimwikiNoExistsLinkT
+
+
+" Load syntax-specific functionality
+call vimwiki#u#reload_regexes_custom()
+
+
+" FIXME it now does not make sense to pretend there is a single syntax "vimwiki"
+let b:current_syntax="vimwiki"
+
+
+" EMBEDDED syntax setup
+let s:nested = vimwiki#vars#get_wikilocal('nested_syntaxes')
+if vimwiki#vars#get_wikilocal('automatic_nested_syntaxes')
+ let s:nested = extend(s:nested, vimwiki#base#detect_nested_syntax(), "keep")
+endif
+if !empty(s:nested)
+ for [s:hl_syntax, s:vim_syntax] in items(s:nested)
+ call vimwiki#base#nested_syntax(s:vim_syntax,
+ \ vimwiki#vars#get_syntaxlocal('rxPreStart').'\%(.*[[:blank:][:punct:]]\)\?'.
+ \ s:hl_syntax.'\%([[:blank:][:punct:]].*\)\?',
+ \ vimwiki#vars#get_syntaxlocal('rxPreEnd'), 'VimwikiPre')
+ endfor
+endif
+
+
+" LaTeX
+call vimwiki#base#nested_syntax('tex',
+ \ vimwiki#vars#get_syntaxlocal('rxMathStart').'\%(.*[[:blank:][:punct:]]\)\?'.
+ \ '\%([[:blank:][:punct:]].*\)\?',
+ \ vimwiki#vars#get_syntaxlocal('rxMathEnd'), 'VimwikiMath')
+
+
+syntax spell toplevel
+
diff --git a/.config/nvim/syntax/vimwiki_default.vim b/.config/nvim/syntax/vimwiki_default.vim
@@ -0,0 +1,110 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki syntax file
+" Description: Defines default syntax
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+" s:default_syntax is kind of a reference to the dict in
+" g:vimwiki_syntax_variables['default']. It is used here simply as an
+" abbreviation for the latter.
+let s:default_syntax = g:vimwiki_syntax_variables['default']
+
+
+
+" text: $ equation_inline $
+let s:default_syntax.rxEqIn = '\$[^$`]\+\$'
+let s:default_syntax.char_eqin = '\$'
+
+" text: *strong*
+" let s:default_syntax.rxBold = '\*[^*]\+\*'
+let s:default_syntax.rxBold = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'\*'.
+ \'\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)'.
+ \'\*'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:default_syntax.char_bold = '*'
+
+" text: _emphasis_
+" let s:default_syntax.rxItalic = '_[^_]\+_'
+let s:default_syntax.rxItalic = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'_'.
+ \'\%([^_`[:space:]][^_`]*[^_`[:space:]]\|[^_`[:space:]]\)'.
+ \'_'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:default_syntax.char_italic = '_'
+
+" text: *_bold italic_* or _*italic bold*_
+let s:default_syntax.rxBoldItalic = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'\*_'.
+ \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'.
+ \'_\*'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:default_syntax.char_bolditalic = '\*_'
+
+let s:default_syntax.rxItalicBold = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'_\*'.
+ \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'.
+ \'\*_'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:default_syntax.char_italicbold = '_\*'
+
+" text: `code`
+let s:default_syntax.rxCode = '`[^`]\+`'
+let s:default_syntax.char_code = '`'
+
+" text: ~~deleted text~~
+let s:default_syntax.rxDelText = '\~\~[^~`]\+\~\~'
+let s:default_syntax.char_deltext = '\~\~'
+
+" text: ^superscript^
+let s:default_syntax.rxSuperScript = '\^[^^`]\+\^'
+let s:default_syntax.char_superscript = '^'
+
+" text: ,,subscript,,
+let s:default_syntax.rxSubScript = ',,[^,`]\+,,'
+let s:default_syntax.char_subscript = ',,'
+
+" generic headers
+let s:default_syntax.rxH = '='
+let s:default_syntax.symH = 1
+
+
+
+" <hr>, horizontal rule
+let s:default_syntax.rxHR = '^-----*$'
+
+" Tables. Each line starts and ends with '|'; each cell is separated by '|'
+let s:default_syntax.rxTableSep = '|'
+
+" Lists
+let s:default_syntax.bullet_types = ['-', '*', '#']
+" 1 means the bullets can be repeatet to indicate the level, like * ** ***
+" 0 means the bullets stand on their own and the level is indicated by the indentation
+let s:default_syntax.recurring_bullets = 0
+let s:default_syntax.number_types = ['1)', '1.', 'i)', 'I)', 'a)', 'A)']
+"this should contain at least one element
+"it is used for i_<C-L><C-J> among other things
+let s:default_syntax.list_markers = ['-', '1.', '*', 'I)', 'a)']
+let s:default_syntax.rxListDefine = '::\(\s\|$\)'
+
+" Preformatted text
+let s:default_syntax.rxPreStart = '{{{'
+let s:default_syntax.rxPreEnd = '}}}'
+
+" Math block
+let s:default_syntax.rxMathStart = '{{\$'
+let s:default_syntax.rxMathEnd = '}}\$'
+
+let s:default_syntax.rxComment = '^\s*%%.*$'
+let s:default_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:''[:space:]]\+:\)\+\%(\s\|$\)\@='
+
+let s:default_syntax.header_search = '^\s*\(=\{1,6}\)\([^=].*[^=]\)\1\s*$'
+let s:default_syntax.header_match = '^\s*\(=\{1,6}\)=\@!\s*__Header__\s*\1=\@!\s*$'
+let s:default_syntax.bold_search = '\%(^\|\s\|[[:punct:]]\)\@<=\*\zs\%([^*`[:space:]][^*`]*'.
+ \ '[^*`[:space:]]\|[^*`[:space:]]\)\ze\*\%([[:punct:]]\|\s\|$\)\@='
+let s:default_syntax.bold_match = '\%(^\|\s\|[[:punct:]]\)\@<=\*__Text__\*'.
+ \ '\%([[:punct:]]\|\s\|$\)\@='
+let s:default_syntax.wikilink = '\[\[\zs[^\\\]|]\+\ze\%(|[^\\\]]\+\)\?\]\]'
+let s:default_syntax.tag_search = '\(^\|\s\)\zs:\([^:''[:space:]]\+:\)\+\ze\(\s\|$\)'
+let s:default_syntax.tag_match = '\(^\|\s\):\([^:''[:space:]]\+:\)*__Tag__:'.
+ \ '\([^:[:space:]]\+:\)*\(\s\|$\)'
diff --git a/.config/nvim/syntax/vimwiki_markdown.vim b/.config/nvim/syntax/vimwiki_markdown.vim
@@ -0,0 +1,104 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki syntax file
+" Description: Defines markdown syntax
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+" see the comments in vimwiki_default.vim for some info about this file
+
+
+let s:markdown_syntax = g:vimwiki_syntax_variables['markdown']
+
+" text: $ equation_inline $
+let s:markdown_syntax.rxEqIn = '\$[^$`]\+\$'
+let s:markdown_syntax.char_eqin = '\$'
+
+" text: *strong*
+" let s:markdown_syntax.rxBold = '\*[^*]\+\*'
+let s:markdown_syntax.rxBold = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'\*'.
+ \'\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)'.
+ \'\*'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:markdown_syntax.char_bold = '*'
+
+" text: _emphasis_
+" let s:markdown_syntax.rxItalic = '_[^_]\+_'
+let s:markdown_syntax.rxItalic = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'_'.
+ \'\%([^_`[:space:]][^_`]*[^_`[:space:]]\|[^_`[:space:]]\)'.
+ \'_'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:markdown_syntax.char_italic = '_'
+
+" text: *_bold italic_* or _*italic bold*_
+let s:markdown_syntax.rxBoldItalic = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'\*_'.
+ \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'.
+ \'_\*'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:markdown_syntax.char_bolditalic = '\*_'
+
+let s:markdown_syntax.rxItalicBold = '\%(^\|\s\|[[:punct:]]\)\@<='.
+ \'_\*'.
+ \'\%([^*_`[:space:]][^*_`]*[^*_`[:space:]]\|[^*_`[:space:]]\)'.
+ \'\*_'.
+ \'\%([[:punct:]]\|\s\|$\)\@='
+let s:markdown_syntax.char_italicbold = '_\*'
+
+" text: `code`
+let s:markdown_syntax.rxCode = '`[^`]\+`'
+let s:markdown_syntax.char_code = '`'
+
+" text: ~~deleted text~~
+let s:markdown_syntax.rxDelText = '\~\~[^~`]\+\~\~'
+let s:markdown_syntax.char_deltext = '\~\~'
+
+" text: ^superscript^
+let s:markdown_syntax.rxSuperScript = '\^[^^`]\+\^'
+let s:markdown_syntax.char_superscript = '^'
+
+" text: ,,subscript,,
+let s:markdown_syntax.rxSubScript = ',,[^,`]\+,,'
+let s:markdown_syntax.char_subscript = ',,'
+
+" generic headers
+let s:markdown_syntax.rxH = '#'
+let s:markdown_syntax.symH = 0
+
+
+
+" <hr>, horizontal rule
+let s:markdown_syntax.rxHR = '^-----*$'
+
+" Tables. Each line starts and ends with '|'; each cell is separated by '|'
+let s:markdown_syntax.rxTableSep = '|'
+
+" Lists
+let s:markdown_syntax.bullet_types = ['-', '*', '+']
+let s:markdown_syntax.recurring_bullets = 0
+let s:markdown_syntax.number_types = ['1.']
+let s:markdown_syntax.list_markers = ['-', '*', '+', '1.']
+let s:markdown_syntax.rxListDefine = '::\%(\s\|$\)'
+
+" Preformatted text
+let s:markdown_syntax.rxPreStart = '```'
+let s:markdown_syntax.rxPreEnd = '```'
+
+" Math block
+let s:markdown_syntax.rxMathStart = '\$\$'
+let s:markdown_syntax.rxMathEnd = '\$\$'
+
+let s:markdown_syntax.rxComment = '^\s*%%.*$\|<!--[^>]*-->'
+let s:markdown_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:[:space:]]\+:\)\+\%(\s\|$\)\@='
+
+let s:markdown_syntax.header_search = '^\s*\(#\{1,6}\)\([^#].*\)$'
+let s:markdown_syntax.header_match = '^\s*\(#\{1,6}\)#\@!\s*__Header__\s*$'
+let s:markdown_syntax.bold_search = '\%(^\|\s\|[[:punct:]]\)\@<=\*\zs'.
+ \ '\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)\ze\*\%([[:punct:]]\|\s\|$\)\@='
+let s:markdown_syntax.bold_match = '\%(^\|\s\|[[:punct:]]\)\@<=\*__Text__\*'.
+ \ '\%([[:punct:]]\|\s\|$\)\@='
+let s:markdown_syntax.wikilink = '\[\[\zs[^\\\]|]\+\ze\%(|[^\\\]]\+\)\?\]\]'
+let s:markdown_syntax.tag_search = '\(^\|\s\)\zs:\([^:''[:space:]]\+:\)\+\ze\(\s\|$\)'
+let s:markdown_syntax.tag_match = '\(^\|\s\):\([^:''[:space:]]\+:\)*__Tag__:'.
+ \ '\([^:[:space:]]\+:\)*\(\s\|$\)'
diff --git a/.config/nvim/syntax/vimwiki_markdown_custom.vim b/.config/nvim/syntax/vimwiki_markdown_custom.vim
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+function! s:add_target_syntax_ON(target, type)
+ let prefix0 = 'syntax match '.a:type.' `'
+ let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,'.a:type.'Char'
+ let prefix1 = 'syntax match '.a:type.'T `'
+ let suffix1 = '` display contained'
+ execute prefix0. a:target. suffix0
+ execute prefix1. a:target. suffix1
+endfunction
+
+
+function! s:add_target_syntax_OFF(target, type)
+ let prefix0 = 'syntax match VimwikiNoExistsLink `'
+ let suffix0 = '` display contains=@NoSpell,VimwikiLinkRest,'.a:type.'Char'
+ let prefix1 = 'syntax match VimwikiNoExistsLinkT `'
+ let suffix1 = '` display contained'
+ execute prefix0. a:target. suffix0
+ execute prefix1. a:target. suffix1
+endfunction
+
+
+function! s:wrap_wikilink1_rx(target)
+ return vimwiki#vars#get_syntaxlocal('rxWikiLink1InvalidPrefix') . a:target.
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLink1InvalidSuffix')
+endfunction
+
+
+function! s:existing_mkd_refs()
+ return keys(vimwiki#markdown_base#scan_reflinks())
+endfunction
+
+
+function! s:highlight_existing_links()
+ " Wikilink1
+ " Conditional highlighting that depends on the existence of a wiki file or
+ " directory is only available for *schemeless* wiki links
+ " Links are set up upon BufEnter (see plugin/...)
+ let safe_links = '\%('.
+ \ vimwiki#base#file_pattern(vimwiki#vars#get_bufferlocal('existing_wikifiles')) .
+ \ '\%(#[^|]*\)\?\|#[^|]*\)'
+ " Wikilink1 Dirs set up upon BufEnter (see plugin/...)
+ let safe_dirs = vimwiki#base#file_pattern(vimwiki#vars#get_bufferlocal('existing_wikidirs'))
+ " Ref links are cached
+ let safe_reflinks = vimwiki#base#file_pattern(s:existing_mkd_refs())
+
+
+ " match [URL][]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template1')),
+ \ safe_links, vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+ call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1')
+ " match [DESCRIPTION][URL]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template2')),
+ \ safe_links, vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+ call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1')
+
+ " match [DIRURL][]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template1')),
+ \ safe_dirs, vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+ call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1')
+ " match [DESCRIPTION][DIRURL]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template2')),
+ \ safe_dirs, vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+ call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1')
+
+ " match [MKDREF][]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template1')),
+ \ safe_reflinks, vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+ call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1')
+ " match [DESCRIPTION][MKDREF]
+ let target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template2')),
+ \ safe_reflinks, vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+ call s:add_target_syntax_ON(s:wrap_wikilink1_rx(target), 'VimwikiWikiLink1')
+endfunction
+
+
+" use max highlighting - could be quite slow if there are too many wikifiles
+if vimwiki#vars#get_wikilocal('maxhi')
+ " WikiLink
+ call s:add_target_syntax_OFF(vimwiki#vars#get_syntaxlocal('rxWikiLink1'), 'VimwikiWikiLink1')
+
+ " Subsequently, links verified on vimwiki's path are highlighted as existing
+ call s:highlight_existing_links()
+else
+ " Wikilink
+ call s:add_target_syntax_ON(vimwiki#vars#get_syntaxlocal('rxWikiLink1'), 'VimwikiWikiLink1')
+endif
+
+
+" Weblink
+call s:add_target_syntax_ON(vimwiki#vars#get_syntaxlocal('rxWeblink1'), 'VimwikiWeblink1')
+
+
+" WikiLink
+" All remaining schemes are highlighted automatically
+let s:rxSchemes = '\%('.
+ \ vimwiki#vars#get_global('schemes') . '\|'.
+ \ vimwiki#vars#get_global('web_schemes1').
+ \ '\):'
+
+" a) match [nonwiki-scheme-URL]
+let s:target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template1')),
+ \ s:rxSchemes . vimwiki#vars#get_syntaxlocal('rxWikiLink1Url'),
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+call s:add_target_syntax_ON(s:wrap_wikilink1_rx(s:target), 'VimwikiWikiLink1')
+" b) match [DESCRIPTION][nonwiki-scheme-URL]
+let s:target = vimwiki#base#apply_template(
+ \ vimwiki#u#escape(vimwiki#vars#get_syntaxlocal('WikiLink1Template2')),
+ \ s:rxSchemes . vimwiki#vars#get_syntaxlocal('rxWikiLink1Url'),
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLink1Descr'), '')
+call s:add_target_syntax_ON(s:wrap_wikilink1_rx(s:target), 'VimwikiWikiLink1')
+
+
+
+" Header levels, 1-6
+for s:i in range(1,6)
+ execute 'syntax match VimwikiHeader'.s:i.' /'.vimwiki#vars#get_syntaxlocal('rxH'.s:i).
+ \ '/ contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiCode,'.
+ \ 'VimwikiLink,VimwikiWeblink1,VimwikiWikiLink1,@Spell'
+endfor
+
+
+
+" concealed chars
+if exists("+conceallevel")
+ syntax conceal on
+endif
+
+syntax spell toplevel
+
+" VimwikiWikiLink1Char is for syntax markers (and also URL when a description
+" is present) and may be concealed
+let s:options = ' contained transparent contains=NONE'
+" conceal wikilink1
+execute 'syn match VimwikiWikiLink1Char /'.
+ \ vimwiki#vars#get_syntaxlocal('rx_wikilink_md_prefix').'/'.s:options
+execute 'syn match VimwikiWikiLink1Char /'.
+ \ vimwiki#vars#get_syntaxlocal('rx_wikilink_md_suffix').'/'.s:options
+execute 'syn match VimwikiWikiLink1Char /'.
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLink1Prefix1').'/'.s:options
+execute 'syn match VimwikiWikiLink1Char /'.
+ \ vimwiki#vars#get_syntaxlocal('rxWikiLink1Suffix1').'/'.s:options
+
+" conceal weblink1
+execute 'syn match VimwikiWeblink1Char "'.
+ \ vimwiki#vars#get_syntaxlocal('rxWeblink1Prefix1').'"'.s:options
+execute 'syn match VimwikiWeblink1Char "'.
+ \ vimwiki#vars#get_syntaxlocal('rxWeblink1Suffix1').'"'.s:options
+
+if exists("+conceallevel")
+ syntax conceal off
+endif
+
+
+
+" Tables
+syntax match VimwikiTableRow /^\s*|.\+|\s*$/
+ \ transparent contains=VimwikiCellSeparator,
+ \ VimwikiLinkT,
+ \ VimwikiWeblink1T,
+ \ VimwikiWikiLink1T,
+ \ VimwikiNoExistsLinkT,
+ \ VimwikiTodo,
+ \ VimwikiBoldT,
+ \ VimwikiItalicT,
+ \ VimwikiBoldItalicT,
+ \ VimwikiItalicBoldT,
+ \ VimwikiDelTextT,
+ \ VimwikiSuperScriptT,
+ \ VimwikiSubScriptT,
+ \ VimwikiCodeT,
+ \ VimwikiEqInT,
+ \ @Spell
+
+
+
+" syntax group highlighting
+hi def link VimwikiWeblink1 VimwikiLink
+hi def link VimwikiWeblink1T VimwikiLink
+
+hi def link VimwikiWikiLink1 VimwikiLink
+hi def link VimwikiWikiLink1T VimwikiLink
+
diff --git a/.config/nvim/syntax/vimwiki_media.vim b/.config/nvim/syntax/vimwiki_media.vim
@@ -0,0 +1,85 @@
+" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99
+" Vimwiki syntax file
+" Description: Defines mediaWiki syntax
+" Home: https://github.com/vimwiki/vimwiki/
+
+
+" see the comments in vimwiki_default.vim for some info about this file
+
+
+let s:media_syntax = g:vimwiki_syntax_variables['media']
+
+" text: $ equation_inline $
+let s:media_syntax.rxEqIn = '\$[^$`]\+\$'
+let s:media_syntax.char_eqin = '\$'
+
+" text: '''strong'''
+let s:media_syntax.rxBold = "'''[^']\\+'''"
+let s:media_syntax.char_bold = "'''"
+
+" text: ''emphasis''
+let s:media_syntax.rxItalic = "''[^']\\+''"
+let s:media_syntax.char_italic = "''"
+
+" text: '''''strong italic'''''
+let s:media_syntax.rxBoldItalic = "'''''[^']\\+'''''"
+let s:media_syntax.rxItalicBold = s:media_syntax.rxBoldItalic
+let s:media_syntax.char_bolditalic = "'''''"
+let s:media_syntax.char_italicbold = s:media_syntax.char_bolditalic
+
+" text: `code`
+let s:media_syntax.rxCode = '`[^`]\+`'
+let s:media_syntax.char_code = '`'
+
+" text: ~~deleted text~~
+let s:media_syntax.rxDelText = '\~\~[^~]\+\~\~'
+let s:media_syntax.char_deltext = '\~\~'
+
+" text: ^superscript^
+let s:media_syntax.rxSuperScript = '\^[^^]\+\^'
+let s:media_syntax.char_superscript = '^'
+
+" text: ,,subscript,,
+let s:media_syntax.rxSubScript = ',,[^,]\+,,'
+let s:media_syntax.char_subscript = ',,'
+
+" generic headers
+let s:media_syntax.rxH = '='
+let s:media_syntax.symH = 1
+
+
+
+" <hr>, horizontal rule
+let s:media_syntax.rxHR = '^-----*$'
+
+" Tables. Each line starts and ends with '|'; each cell is separated by '|'
+let s:media_syntax.rxTableSep = '|'
+
+" Lists
+let s:media_syntax.bullet_types = ['*', '#']
+let s:media_syntax.recurring_bullets = 1
+let s:media_syntax.number_types = []
+let s:media_syntax.list_markers = ['*', '#']
+let s:media_syntax.rxListDefine = '^\%(;\|:\)\s'
+
+" Preformatted text
+let s:media_syntax.rxPreStart = '<pre>'
+let s:media_syntax.rxPreEnd = '<\/pre>'
+
+" Math block
+let s:media_syntax.rxMathStart = '{{\$'
+let s:media_syntax.rxMathEnd = '}}\$'
+
+let s:media_syntax.rxComment = '^\s*%%.*$'
+let s:media_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:[:space:]]\+:\)\+\%(\s\|$\)\@='
+
+let s:media_syntax.header_search = '^\s*\(=\{1,6}\)\([^=].*[^=]\)\1\s*$'
+let s:media_syntax.header_match = '^\s*\(=\{1,6}\)=\@!\s*__Header__\s*\1=\@!\s*$'
+let s:media_syntax.bold_search = "'''\\zs[^']\\+\\ze'''"
+let s:media_syntax.bold_match = '''''''__Text__'''''''
+" ^- this strange looking thing is equivalent to "'''__Text__'''" but since we later
+" want to call escape() on this string, we must keep it in single quotes
+let s:media_syntax.wikilink = '\[\[\zs[^\\\]|]\+\ze\%(|[^\\\]]\+\)\?\]\]'
+let s:media_syntax.tag_search = '\(^\|\s\)\zs:\([^:''[:space:]]\+:\)\+\ze\(\s\|$\)'
+let s:media_syntax.tag_match = '\(^\|\s\):\([^:''[:space:]]\+:\)*__Tag__:'.
+ \ '\([^:[:space:]]\+:\)*\(\s\|$\)'
diff --git a/.config/zsh/functions b/.config/zsh/functions
@@ -1,25 +1,27 @@
#!/bin/sh
killprog(){
for prog in $(printf "$@")
- do
- pkill $prog
- done
+ do
+ pkill $prog
+ done
}
0x0(){
for file in $(printf "$@")
- do
- name=$(curl -n -F "file=@$file" http://0x0.st)
- echo "$file has been hosted at $name"
- done
+ do
+ name=$(curl -n -F "file=@$file" http://0x0.st)
+ echo "$file has been hosted at $name"
+ echo "$name" | xclip
+ done
}
ix(){
for file in $(printf "$@")
- do
- name=$(curl -n -F "f:1=<-" http://ix.io < $file)
- echo "$file has been hosted at $name"
- done
+ do
+ name=$(curl -n -F "f:1=<-" http://ix.io < $file)
+ echo "$file has been hosted at $name"
+ echo "$name" | xclip
+ done
}
pc(){
diff --git a/.scripts/bin/misc/drefresh b/.scripts/bin/misc/drefresh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+hkill dunst
+dunst &