diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cdf8546 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2008-2010 Maxim Kim + 2013-2017 Daniel Schemala + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 5816229..a407040 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A Personal Wiki For Vim ============================================================================== ![screenshot1](doc/screenshot_1.png) -![screenshot2](doc/screenshot_2.png) +![screenshot2](doc/screenshot_2.png) * Intro ------------------------------------------------------------------------------ @@ -122,6 +122,11 @@ Make sure you have these settings in your vimrc file: Without them Vimwiki will not work properly. +Installation using [Vim packages](http://vimhelp.appspot.com/repeat.txt.html#packages) (since Vim 7.4.1528) +------------------------------------------------------------------------------ + + git clone https://github.com/vimwiki/vimwiki.git ~/.vim/pack/plugins/start/vimwiki + Installation using [Pathogen](http://www.vim.org/scripts/script.php?script_id=2332) ------------------------------------------------------------------------------ @@ -140,3 +145,7 @@ Add `Plugin 'vimwiki/vimwiki'` to your vimrc file and run Or download the [zip archive](https://github.com/vimwiki/vimwiki/archive/master.zip) and extract it in `~/.vim/bundle/` Then launch Vim, run `:Helptags` and then `:help vimwiki` to verify it was installed. + +---- +\* Screenshots made with the [solarized colorscheme](https://github.com/altercation/vim-colors-solarized) +and [lightline](https://github.com/itchyny/lightline.vim) diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim index 724b647..530dba3 100644 --- a/autoload/vimwiki/base.vim +++ b/autoload/vimwiki/base.vim @@ -1,4 +1,4 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file " Desc: Basic functionality " Home: https://github.com/vimwiki/vimwiki/ @@ -8,8 +8,15 @@ if exists("g:loaded_vimwiki_auto") || &cp endif let g:loaded_vimwiki_auto = 1 -" s:vimwiki_get_known_syntaxes -function! s:vimwiki_get_known_syntaxes() " {{{ + +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 @@ -22,21 +29,22 @@ function! s:vimwiki_get_known_syntaxes() " {{{ let syntaxes[syn] = 1 endfor return keys(syntaxes) -endfunction " }}} +endfunction -" vimwiki#base#file_pattern -function! vimwiki#base#file_pattern(files) "{{{ Get search regex from glob() + +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" + " Change / to [/\\] to allow "Windows paths" return '\V\%('.join(a:files, '\|').'\)\m' -endfunction "}}} +endfunction + -" vimwiki#base#subdir "FIXME TODO slow and faulty -function! vimwiki#base#subdir(path, filename) "{{{ +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? @@ -57,27 +65,28 @@ function! vimwiki#base#subdir(path, filename) "{{{ let res = res.'/' endif return res -endfunction "}}} +endfunction -" vimwiki#base#current_subdir -function! vimwiki#base#current_subdir()"{{{ + +function! vimwiki#base#current_subdir() return vimwiki#base#subdir(vimwiki#vars#get_wikilocal('path'), expand('%:p')) -endfunction"}}} +endfunction -" vimwiki#base#invsubdir -function! vimwiki#base#invsubdir(subdir) " {{{ + +function! vimwiki#base#invsubdir(subdir) return substitute(a:subdir, '[^/\.]\+/', '../', 'g') -endfunction " }}} +endfunction -" Returns: the number of the wiki a file belongs to -function! vimwiki#base#find_wiki(path) "{{{ +" 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 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)) - if vimwiki#path#is_equal( - \ vimwiki#path#path_common_pfx(idx_path, path), idx_path) + if vimwiki#path#is_equal(vimwiki#path#path_common_pfx(idx_path, path), idx_path) return idx endif let idx += 1 @@ -85,20 +94,20 @@ function! vimwiki#base#find_wiki(path) "{{{ " an orphan page has been detected return -1 -endfunction "}}} +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, ...) "{{{ +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 = expand('%:p') + let source_file = vimwiki#path#current_wiki_file() endif let link_text = a:link_text @@ -129,8 +138,7 @@ function! vimwiki#base#resolve_link(link_text, ...) "{{{ endif let link_text = matchstr(link_text, vimwiki#vars#get_global('rxSchemeUrlMatchUrl')) - let is_wiki_link = link_infos.scheme =~# '\mwiki\d\+' || - \ link_infos.scheme ==# 'diary' + let is_wiki_link = link_infos.scheme =~# '\mwiki\d\+' || link_infos.scheme ==# 'diary' " extract anchor if is_wiki_link @@ -188,8 +196,7 @@ function! vimwiki#base#resolve_link(link_text, ...) "{{{ \ vimwiki#vars#get_wikilocal('diary_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 + 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 @@ -201,11 +208,10 @@ function! vimwiki#base#resolve_link(link_text, ...) "{{{ let link_infos.filename = vimwiki#path#normalize(link_infos.filename) return link_infos -endfunction "}}} +endfunction -" vimwiki#base#system_open_link -function! vimwiki#base#system_open_link(url) "{{{ +function! vimwiki#base#system_open_link(url) " handlers function! s:win32_handler(url) "http://vim.wikia.com/wiki/Opening_current_Vim_file_in_your_Windows_browser @@ -220,7 +226,11 @@ function! vimwiki#base#system_open_link(url) "{{{ else let url = shellescape(a:url, 1) endif - execute 'silent ! start "Title" /B ' . url + if &l:shell ==? "powershell" + execute 'silent ! start ' . a:url + else + execute 'silent ! start "Title" /B ' . a:url + endif endfunction function! s:macunix_handler(url) call system('open ' . shellescape(a:url).' &') @@ -241,22 +251,26 @@ function! vimwiki#base#system_open_link(url) "{{{ endif endtry echomsg 'Vimwiki Error: Default Vimwiki link handler was unable to open the HTML file!' -endfunction "}}} +endfunction -" vimwiki#base#open_link -function! vimwiki#base#open_link(cmd, link, ...) "{{{ - let link_infos = vimwiki#base#resolve_link(a:link) + +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 == '' echomsg 'Vimwiki Error: Unable to resolve link!' return endif - let is_wiki_link = link_infos.scheme =~# '\mwiki\d\+' - \ || link_infos.scheme =~# 'diary' + 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, expand('%:p')) + \ !vimwiki#path#is_equal(link_infos.filename, vimwiki#path#current_wiki_file()) let vimwiki_prev_link = [] " update previous link for wiki pages @@ -264,7 +278,7 @@ function! vimwiki#base#open_link(cmd, link, ...) "{{{ if a:0 let vimwiki_prev_link = [a:1, []] elseif &ft ==# 'vimwiki' - let vimwiki_prev_link = [expand('%:p'), getpos('.')] + let vimwiki_prev_link = [vimwiki#path#current_wiki_file(), getpos('.')] endif endif @@ -275,14 +289,15 @@ function! vimwiki#base#open_link(cmd, link, ...) "{{{ else call vimwiki#base#system_open_link(link_infos.filename) endif -endfunction " }}} +endfunction -" vimwiki#base#get_globlinks_escaped -function! vimwiki#base#get_globlinks_escaped() abort "{{{only get links from the current dir + +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 + " 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') @@ -296,43 +311,42 @@ function! vimwiki#base#get_globlinks_escaped() abort "{{{only get links from the let globlinks = join(lst, "\n") " return all escaped links as a single newline-separated string return globlinks -endfunction " }}} +endfunction -" vimwiki#base#generate_links -function! vimwiki#base#generate_links() "{{{ + +function! vimwiki#base#generate_links() let lines = [] let links = vimwiki#base#get_wikilinks(vimwiki#vars#get_bufferlocal('wiki_nr'), 0, 0) call sort(links) - let bullet = repeat(' ', vimwiki#lst#get_list_margin()). - \ vimwiki#lst#default_symbol().' ' + 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. - \ substitute(vimwiki#vars#get_global('WikiLinkTemplate1'), '__LinkUrl__', '\='."'".link."'", '')) + \ 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 " }}} + call vimwiki#base#update_listing_in_buffer(lines, 'Generated Links', links_rx, line('$')+1, 1) +endfunction -" vimwiki#base#goto -function! vimwiki#base#goto(...) "{{{ + +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 "}}} +endfunction -" vimwiki#base#backlinks -function! vimwiki#base#backlinks() "{{{ + +function! vimwiki#base#backlinks() let current_filename = expand("%:p") let locations = [] for idx in range(vimwiki#vars#number_of_wikis()) @@ -356,7 +370,8 @@ function! vimwiki#base#backlinks() "{{{ call setloclist(0, locations, 'r') lopen endif -endfunction "}}} +endfunction + " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX kann das weg? @@ -379,7 +394,7 @@ function! vimwiki#base#find_files(wiki_nr, directories_only) " 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('temp', wiki_nr) + if vimwiki#vars#get_wikilocal('is_temporary_wiki', wiki_nr) let pattern = '*'.ext else let pattern = '**/*'.ext @@ -387,6 +402,7 @@ function! vimwiki#base#find_files(wiki_nr, directories_only) 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 a:diary_only is nonzero, the diary of the wiki is used. @@ -425,6 +441,7 @@ function! vimwiki#base#get_wikilinks(wiki_nr, diary_only, also_absolute_links) 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) @@ -446,7 +463,8 @@ function! vimwiki#base#get_wiki_directories(wiki_nr) return result endfunction -function! vimwiki#base#get_anchors(filename, syntax) "{{{ + +function! vimwiki#base#get_anchors(filename, syntax) if !filereadable(a:filename) return [] endif @@ -517,10 +535,10 @@ function! vimwiki#base#get_anchors(filename, syntax) "{{{ endfor return anchors -endfunction "}}} +endfunction -" s:jump_to_anchor -function! s:jump_to_anchor(anchor) "{{{ + +function! s:jump_to_anchor(anchor) let oldpos = getpos('.') call cursor(1, 1) @@ -530,31 +548,30 @@ function! s:jump_to_anchor(anchor) "{{{ for segment in segments - let anchor_header = substitute( + let anchor_header = s:safesubstitute( \ vimwiki#vars#get_syntaxlocal('header_match'), - \ '__Header__', "\\='".segment."'", '') - let anchor_bold = substitute( + \ '__Header__', segment, '') + let anchor_bold = s:safesubstitute( \ vimwiki#vars#get_syntaxlocal('bold_match'), - \ '__Text__', "\\='".segment."'", '') - let anchor_tag = substitute( + \ '__Text__', segment, '') + let anchor_tag = s:safesubstitute( \ vimwiki#vars#get_syntaxlocal('tag_match'), - \ '__Tag__', "\\='".segment."'", '') + \ '__Tag__', segment, '') - if !search(anchor_tag, 'Wc') - \ && !search(anchor_header, 'Wc') - \ && !search(anchor_bold, 'Wc') + if !search(anchor_tag, 'Wc') && !search(anchor_header, 'Wc') && !search(anchor_bold, 'Wc') call setpos('.', oldpos) break endif let oldpos = getpos('.') endfor -endfunction "}}} +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) "{{{ +function! s:get_links(wikifile, idx) if !filereadable(a:wikifile) return [] endif @@ -576,17 +593,17 @@ function! s:get_links(wikifile, idx) "{{{ 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' + 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 "}}} +endfunction -function! vimwiki#base#check_links() "{{{ + +function! vimwiki#base#check_links() let anchors_of_files = {} let links_of_files = {} let errors = [] @@ -645,8 +662,8 @@ function! vimwiki#base#check_links() "{{{ " 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) + 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 @@ -683,19 +700,11 @@ function! vimwiki#base#check_links() "{{{ call setqflist(errors, 'r') copen endif -endfunction "}}} +endfunction -" vimwiki#base#edit_file -function! vimwiki#base#edit_file(command, filename, anchor, ...) "{{{ - " XXX: Should we allow * in filenames!? - " Maxim: It is allowed, escaping here is for vim to be able to open files - " which have that symbols. - " Try to remove * from escaping and open&save : - " [[testBLAfile]]... - " then - " [[test*file]]... - " you'll have E77: Too many file names - let fname = escape(a:filename, '% *|#') + +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) @@ -706,17 +715,33 @@ function! vimwiki#base#edit_file(command, filename, anchor, ...) "{{{ return endif - " check if the file we want to open is already the current file + " 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'))) - execute a:command.' '.fname + try + 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 + execute a:command fname + endif + catch /E37:/ + echomsg 'Vimwiki: The current file is modified. Hint: Take a look at' + \ ''':h g:vimwiki_autowriteall'' to see how to save automatically.' + return + endtry + + " 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/$' - set filetype=vimwiki + setfiletype vimwiki endif endif if a:anchor != '' @@ -729,19 +754,19 @@ function! vimwiki#base#edit_file(command, filename, anchor, ...) "{{{ if a:0 && a:2 && len(a:1) > 0 call vimwiki#vars#set_bufferlocal('prev_link', a:1) endif -endfunction " }}} +endfunction -" vimwiki#base#search_word -function! vimwiki#base#search_word(wikiRx, cmd) "{{{ + +function! vimwiki#base#search_word(wikiRx, cmd) let match_line = search(a:wikiRx, 's'.a:cmd) if match_line == 0 echomsg 'Vimwiki: Wiki link not found' endif -endfunction " }}} +endfunction + -" vimwiki#base#matchstr_at_cursor " Returns part of the line that matches wikiRX at cursor -function! vimwiki#base#matchstr_at_cursor(wikiRX) "{{{ +function! vimwiki#base#matchstr_at_cursor(wikiRX) let col = col('.') - 1 let line = getline('.') let ebeg = -1 @@ -761,10 +786,10 @@ function! vimwiki#base#matchstr_at_cursor(wikiRX) "{{{ else return "" endif -endf "}}} +endfunction -" vimwiki#base#replacestr_at_cursor -function! vimwiki#base#replacestr_at_cursor(wikiRX, sub) "{{{ + +function! vimwiki#base#replacestr_at_cursor(wikiRX, sub) let col = col('.') - 1 let line = getline('.') let ebeg = -1 @@ -784,10 +809,10 @@ function! vimwiki#base#replacestr_at_cursor(wikiRX, sub) "{{{ let newline = strpart(line, 0, ebeg).a:sub.strpart(line, ebeg+elen) call setline(line('.'), newline) endif -endf "}}} +endfunction -" s:print_wiki_list -function! s:print_wiki_list() "{{{ + +function! s:print_wiki_list() let idx = 0 while idx < vimwiki#vars#number_of_wikis() if idx == vimwiki#vars#get_bufferlocal('wiki_nr') @@ -801,10 +826,10 @@ function! s:print_wiki_list() "{{{ let idx += 1 endwhile echohl None -endfunction " }}} +endfunction -" s:update_wiki_link -function! s:update_wiki_link(fname, old, new) " {{{ + +function! s:update_wiki_link(fname, old, new) echo "Updating links in ".a:fname let has_updates = 0 let dest = [] @@ -821,32 +846,33 @@ function! s:update_wiki_link(fname, old, new) " {{{ call writefile(dest, a:fname) call delete(a:fname.'#vimwiki_upd#') endif -endfunction " }}} +endfunction -" s:update_wiki_links_dir -function! s:update_wiki_links_dir(dir, old_fname, new_fname) " {{{ + +function! s:update_wiki_links_dir(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'), old_fname, '', '') - let files = split(glob(vimwiki#vars#get_wikilocal('path').a:dir.'*'.vimwiki#vars#get_wikilocal('ext')), '\n') + let files = split(glob(vimwiki#vars#get_wikilocal('path').a:dir.'*'. + \ vimwiki#vars#get_wikilocal('ext')), '\n') for fname in files call s:update_wiki_link(fname, old_fname_r, new_fname) endfor -endfunction " }}} +endfunction -" s:tail_name -function! s:tail_name(fname) "{{{ + +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 "}}} +endfunction -" s:update_wiki_links -function! s:update_wiki_links(old_fname, new_fname) " {{{ + +function! s:update_wiki_links(old_fname, new_fname) let old_fname = a:old_fname let new_fname = a:new_fname @@ -872,14 +898,13 @@ function! s:update_wiki_links(old_fname, new_fname) " {{{ while idx < len(dirs_keys) let dir = dirs_keys[idx] let new_dir = dirs_vals[idx] - call s:update_wiki_links_dir(dir, - \ new_dir.old_fname, new_dir.new_fname) + call s:update_wiki_links_dir(dir, new_dir.old_fname, new_dir.new_fname) let idx = idx + 1 endwhile -endfunction " }}} +endfunction -" s:get_wiki_buffers -function! s:get_wiki_buffers() "{{{ + +function! s:get_wiki_buffers() let blist = [] let bcount = 1 while bcount<=bufnr("$") @@ -895,18 +920,18 @@ function! s:get_wiki_buffers() "{{{ let bcount = bcount + 1 endwhile return blist -endfunction " }}} +endfunction -" s:open_wiki_buffer -function! s:open_wiki_buffer(item) "{{{ + +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 " }}} +endfunction -" vimwiki#base#nested_syntax -function! vimwiki#base#nested_syntax(filetype, start, end, textSnipHl) abort "{{{ + +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 @@ -953,14 +978,15 @@ function! vimwiki#base#nested_syntax(filetype, start, end, textSnipHl) abort "{{ " 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. + " 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 + syntax clear perlFunctionName endif -endfunction "}}} +endfunction + " creates or updates auto-generated listings in a wiki file, like TOC, diary " links, tags list etc. @@ -971,7 +997,7 @@ endfunction "}}} " - 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) "{{{ + \ content_regex, default_lnum, create) " apparently, Vim behaves strange when files change while in diff mode if &diff || &readonly return @@ -980,9 +1006,8 @@ function! vimwiki#base#update_listing_in_buffer(strings, start_header, " 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 header_rx = '\m^\s*'.substitute(vimwiki#vars#get_syntaxlocal('rxH1_Template'), + \ '__Header__', a:start_header, '') .'\s*$' let start_lnum = 1 while start_lnum <= line('$') @@ -1033,8 +1058,8 @@ function! vimwiki#base#update_listing_in_buffer(strings, start_header, " write new listing let new_header = whitespaces_in_first_line - \ . substitute(vimwiki#vars#get_syntaxlocal('rxH1_Template'), - \ '__Header__', '\='."'".a:start_header."'", '') + \ . s:safesubstitute(vimwiki#vars#get_syntaxlocal('rxH1_Template'), + \ '__Header__', a:start_header, '') call append(start_lnum - 1, new_header) let start_lnum += 1 let lines_diff += 1 + len(a:strings) @@ -1058,93 +1083,117 @@ function! vimwiki#base#update_listing_in_buffer(strings, start_header, let winview_save.lnum += lines_diff endif call winrestview(winview_save) -endfunction "}}} +endfunction -" WIKI link following functions {{{ -" vimwiki#base#find_next_link -function! vimwiki#base#find_next_link() "{{{ + +function! vimwiki#base#find_next_link() call vimwiki#base#search_word(vimwiki#vars#get_syntaxlocal('rxAnyLink'), '') -endfunction " }}} +endfunction -" vimwiki#base#find_prev_link -function! vimwiki#base#find_prev_link() "{{{ + +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 " }}} +endfunction -" vimwiki#base#follow_link -function! vimwiki#base#follow_link(split, ...) "{{{ Parse link at cursor and pass - " to VimwikiLinkHandler, or failing that, the default open_link handler - if exists('*vimwiki#'.vimwiki#vars#get_wikilocal('syntax').'_base#follow_link') - " Syntax-specific links - " XXX: @Stuart: do we still need it? - " XXX: @Maxim: most likely! I am still working on a seemless way to - " integrate regexp's without complicating syntax/vimwiki.vim - if a:0 - call vimwiki#{vimwiki#vars#get_wikilocal('syntax')}_base#follow_link(a:split, a:1) - else - call vimwiki#{vimwiki#vars#get_wikilocal('syntax')}_base#follow_link(a:split) + +" This is an API function, that is, remappable by the user. Don't change the signature. +function! vimwiki#base#follow_link(split, reuse, move_cursor, ...) + " 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 - else - if a:split ==# "split" + + if a:split ==# "hsplit" let cmd = ":split " elseif a:split ==# "vsplit" let cmd = ":vsplit " - elseif a:split ==# "tabnew" + elseif a:split ==# "tab" let cmd = ":tabnew " else let cmd = ":e " endif - " 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 != "" - if !VimwikiLinkHandler(lnk) - call vimwiki#base#open_link(cmd, lnk) + " 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') && a:reuse + let previous_window_nr = winnr('#') + if previous_window_nr > 0 && previous_window_nr != winnr() + execute previous_window_nr . 'wincmd w' + let cmd = ':e' endif - return 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 !a:move_cursor + 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 > 0 execute "normal! ".a:1 - else + else call vimwiki#base#normalize_link(0) endif endif +endfunction -endfunction " }}} -" vimwiki#base#go_back_link -function! vimwiki#base#go_back_link() "{{{ +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 - execute ":e ".substitute(prev_link[0], '\s', '\\\0', 'g') + 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 " }}} +endfunction -" vimwiki#base#goto_index -function! vimwiki#base#goto_index(wnum, ...) "{{{ + +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 @@ -1159,7 +1208,13 @@ function! vimwiki#base#goto_index(wnum, ...) "{{{ endif if a:0 - let cmd = 'tabedit' + 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 @@ -1169,12 +1224,11 @@ function! vimwiki#base#goto_index(wnum, ...) "{{{ \ vimwiki#vars#get_wikilocal('ext', idx) call vimwiki#base#edit_file(cmd, index_file, '') -endfunction "}}} +endfunction -" vimwiki#base#delete_link -function! vimwiki#base#delete_link() "{{{ - "" file system funcs - "" Delete wiki link you are in from filesystem + +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 @@ -1194,11 +1248,11 @@ function! vimwiki#base#delete_link() "{{{ if expand('%:p') != "" execute "e" endif -endfunction "}}} +endfunction + -" vimwiki#base#rename_link " Rename current file, update all links to it -function! vimwiki#base#rename_link() "{{{ +function! vimwiki#base#rename_link() let subdir = vimwiki#vars#get_bufferlocal('subdir') let old_fname = subdir.expand('%:t') @@ -1232,15 +1286,14 @@ function! vimwiki#base#rename_link() "{{{ if url != '' let new_link = url endif - + let new_link = subdir.new_link 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!' + echomsg 'Vimwiki Error: Cannot rename to "'.new_fname.'". File with that name exist!' return endif " rename wiki link file @@ -1257,8 +1310,7 @@ function! vimwiki#base#rename_link() "{{{ let &buftype="nofile" - let cur_buffer = [expand('%:p'), - \ vimwiki#vars#get_bufferlocal('prev_link')] + let cur_buffer = [expand('%:p'), vimwiki#vars#get_bufferlocal('prev_link')] let blist = s:get_wiki_buffers() @@ -1288,73 +1340,79 @@ function! vimwiki#base#rename_link() "{{{ endif endfor - call s:open_wiki_buffer([new_fname, - \ cur_buffer[1]]) + 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 " }}} +endfunction -" vimwiki#base#ui_select -function! vimwiki#base#ui_select() "{{{ + +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 "}}} -" }}} +endfunction -" TEXT OBJECTS functions {{{ -" vimwiki#base#TO_header -function! vimwiki#base#TO_header(inner, visual) "{{{ - if !search('^\(=\+\).\+\1\s*$', 'bcW') +function! vimwiki#base#TO_header(inner, including_subheaders, count) + let headers = s:collect_headers() + if empty(headers) return endif - - let sel_start = line("'<") - let sel_end = line("'>") - let block_start = line(".") - let advance = 0 - let level = vimwiki#u#count_first_sym(getline('.')) + let current_line = line('.') - let is_header_selected = sel_start == block_start - \ && sel_start != sel_end + let current_header_index = s:current_header(headers, current_line) - if a:visual && is_header_selected - if level > 1 - let level -= 1 - call search('^\(=\{'.level.'\}\).\+\1\s*$', 'bcW') - else - let advance = 1 - endif + if current_header_index < 0 + return endif - normal! V - - if a:visual && is_header_selected - call cursor(sel_end + advance, 0) - endif - - if search('^\(=\{1,'.level.'}\).\+\1\s*$', 'W') - call cursor(line('.') - 1, 0) + " 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 - call cursor(line('$'), 0) + 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 && getline(line('.')) =~# '^\s*$' - let lnum = prevnonblank(line('.') - 1) - call cursor(lnum, 0) + if a:inner + let first_line += 1 + let last_line = prevnonblank(last_line) endif -endfunction "}}} -" vimwiki#base#TO_table_cell -function! vimwiki#base#TO_table_cell(inner, visual) "{{{ + 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 @@ -1398,7 +1456,7 @@ function! vimwiki#base#TO_table_cell(inner, visual) "{{{ " XXX: WORKAROUND. " if blockwise selection is ended at | character then pressing j to extend - " selection furhter fails. But if we shake the cursor left and right then + " selection further fails. But if we shake the cursor left and right then " it works. normal! hl else @@ -1416,10 +1474,10 @@ function! vimwiki#base#TO_table_cell(inner, visual) "{{{ normal! 2h endif endif -endfunction "}}} +endfunction -" vimwiki#base#TO_table_col -function! vimwiki#base#TO_table_col(inner, visual) "{{{ + +function! vimwiki#base#TO_table_col(inner, visual) let t_rows = vimwiki#tbl#get_rows(line('.')) if empty(t_rows) return @@ -1531,12 +1589,10 @@ function! vimwiki#base#TO_table_col(inner, visual) "{{{ " expand selection to the bottom line of the table call vimwiki#u#cursor(t_rows[-1][0], virtcol('.')) endif -endfunction "}}} -" }}} +endfunction -" HEADER functions {{{ -" vimwiki#base#AddHeaderLevel -function! vimwiki#base#AddHeaderLevel() "{{{ + +function! vimwiki#base#AddHeaderLevel() let lnum = line('.') let line = getline(lnum) let rxHdr = vimwiki#vars#get_syntaxlocal('rxH') @@ -1555,16 +1611,16 @@ function! vimwiki#base#AddHeaderLevel() "{{{ call setline(lnum, line) endif else - let line = substitute(line, '^\s*', '&'.rxHdr.' ', '') + 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 "}}} +endfunction -" vimwiki#base#RemoveHeaderLevel -function! vimwiki#base#RemoveHeaderLevel() "{{{ + +function! vimwiki#base#RemoveHeaderLevel() let lnum = line('.') let line = getline(lnum) let rxHdr = vimwiki#vars#get_syntaxlocal('rxH') @@ -1594,20 +1650,19 @@ function! vimwiki#base#RemoveHeaderLevel() "{{{ call setline(lnum, line) endif -endfunction " }}} +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) - " collect new headers + + +" 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 numbering = vimwiki#vars#get_global('html_header_numbering') let headers = [] - let headers_levels = [['', 0], ['', 0], ['', 0], ['', 0], ['', 0], ['', 0]] 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')) + \ (is_inside_pre_or_math == 2 && line_content =~# vimwiki#vars#get_syntaxlocal('rxMathEnd')) let is_inside_pre_or_math = 0 continue endif @@ -1625,8 +1680,116 @@ function! vimwiki#base#table_of_contents(create) if line_content !~# vimwiki#vars#get_syntaxlocal('rxHeader') continue endif - let h_level = vimwiki#u#count_first_sym(line_content) - let h_text = vimwiki#u#trim(matchstr(line_content, vimwiki#vars#get_syntaxlocal('rxHeader'))) + 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 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 ==# vimwiki#vars#get_global('toc_header') " don't include the TOC's header itself continue endif @@ -1641,60 +1804,56 @@ function! vimwiki#base#table_of_contents(create) 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]'), '.') + 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(headers, [h_level, h_complete_id, h_text]) + 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 headers + for [lvl, link, desc] in complete_header_infos let esc_link = substitute(link, "'", "''", 'g') let esc_desc = substitute(desc, "'", "''", 'g') - let link = substitute(vimwiki#vars#get_global('WikiLinkTemplate2'), '__LinkUrl__', - \ '\='."'".'#'.esc_link."'", '') - let link = substitute(link, '__LinkDescription__', '\='."'".esc_desc."'", '') + let link = s:safesubstitute(vimwiki#vars#get_global('WikiLinkTemplate2'), '__LinkUrl__', + \ '#'.esc_link, '') + let link = s:safesubstitute(link, '__LinkDescription__', esc_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, vimwiki#vars#get_global('toc_header'), links_rx, - \ 1, a:create) + call vimwiki#base#update_listing_in_buffer(lines, + \ vimwiki#vars#get_global('toc_header'), links_rx, 1, a:create) endfunction -"}}} -" LINK functions {{{ -" vimwiki#base#apply_template + " 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) "{{{ +function! vimwiki#base#apply_template(template, rxUrl, rxDesc, rxStyle) let lnk = a:template if a:rxUrl != "" - let lnk = substitute(lnk, '__LinkUrl__', '\='."'".a:rxUrl."'", 'g') + let lnk = s:safesubstitute(lnk, '__LinkUrl__', a:rxUrl, 'g') endif if a:rxDesc != "" - let lnk = substitute(lnk, '__LinkDescription__', '\='."'".a:rxDesc."'", 'g') + let lnk = s:safesubstitute(lnk, '__LinkDescription__', a:rxDesc, 'g') endif if a:rxStyle != "" - let lnk = substitute(lnk, '__LinkStyle__', '\='."'".a:rxStyle."'", 'g') + let lnk = s:safesubstitute(lnk, '__LinkStyle__', a:rxStyle, 'g') endif return lnk -endfunction " }}} +endfunction -" s:clean_url -function! s:clean_url(url) " {{{ + +function! s:clean_url(url) let url = split(a:url, '/\|=\|-\|&\|?\|\.') let url = filter(url, 'v:val !=# ""') let url = filter(url, 'v:val !=# "www"') @@ -1707,41 +1866,38 @@ function! s:clean_url(url) " {{{ let url = filter(url, 'v:val !=# "file\:"') let url = filter(url, 'v:val !=# "xml\:"') return join(url, " ") -endfunction " }}} +endfunction -" s:is_diary_file -function! s:is_diary_file(filename) " {{{ + +function! s:is_diary_file(filename) let file_path = vimwiki#path#path_norm(a:filename) let diary_path = vimwiki#path#path_norm(vimwiki#vars#get_wikilocal('diary_path')) - return vimwiki#path#equal(vimwiki#vars#get_wikilocal('path'), + return !vimwiki#path#equal(vimwiki#vars#get_wikilocal('path'), \ vimwiki#vars#get_wikilocal('diary_path')) \ && file_path =~# '^'.vimwiki#u#escape(diary_path) endfunction " }}} -" vimwiki#base#normalize_link_helper -function! vimwiki#base#normalize_link_helper(str, rxUrl, rxDesc, template) " {{{ - let str = a:str - let url = matchstr(str, a:rxUrl) - let descr = matchstr(str, a:rxDesc) - let template = a:template +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 = substitute(template, '__LinkDescription__', '\="'.descr.'"', '') - let lnk = substitute(lnk, '__LinkUrl__', '\="'.url.'"', '') + let lnk = s:safesubstitute(a:template, '__LinkDescription__', descr, '') + let lnk = s:safesubstitute(lnk, '__LinkUrl__', url, '') return lnk -endfunction " }}} +endfunction -" vimwiki#base#normalize_imagelink_helper -function! vimwiki#base#normalize_imagelink_helper(str, rxUrl, rxDesc, rxStyle, template) "{{{ + +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 = substitute(lnk, '__LinkStyle__', '\="'.style.'"', '') + let lnk = s:safesubstitute(lnk, '__LinkStyle__', style, '') return lnk -endfunction " }}} +endfunction -" s:normalize_link_in_diary -function! s:normalize_link_in_diary(lnk) " {{{ + +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('diary_path') . '/' . link @@ -1765,21 +1921,22 @@ function! s:normalize_link_in_diary(lnk) " {{{ endif return vimwiki#base#normalize_link_helper(str, rxUrl, rxDesc, template) -endfunction " }}} +endfunction -" s:normalize_link_syntax_n -function! s:normalize_link_syntax_n() " {{{ + +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_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) @@ -1812,14 +1969,14 @@ function! s:normalize_link_syntax_n() " {{{ return endif -endfunction " }}} +endfunction -" s:normalize_link_syntax_v -function! s:normalize_link_syntax_v() " {{{ + +function! s:normalize_link_syntax_v() let sel_save = &selection let &selection = "old" - let rv = @" - let rt = getregtype('"') + let default_register_save = @" + let registertype_save = getregtype('"') try " Save selected text to register " @@ -1829,36 +1986,36 @@ function! s:normalize_link_syntax_v() " {{{ if s:is_diary_file(expand("%:p")) let sub = s:normalize_link_in_diary(@") else - let sub = substitute(vimwiki#vars#get_global('WikiLinkTemplate1'), - \ '__LinkUrl__', '\=' . "'" . @" . "'", '') + let sub = s:safesubstitute(vimwiki#vars#get_global('WikiLinkTemplate1'), + \ '__LinkUrl__', @", '') endif " Put substitution in register " and change text - call setreg('"', sub, 'v') + call setreg('"', substitute(sub, '\n', '', ''), visualmode()) normal! `>""pgvd finally - call setreg('"', rv, rt) + call setreg('"', default_register_save, registertype_save) let &selection = sel_save endtry -endfunction " }}} +endfunction -" vimwiki#base#normalize_link -function! vimwiki#base#normalize_link(is_visual_mode) "{{{ + +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 visualmode() ==# 'v' && line("'<") == line("'>") - " action undefined for 'line-wise' or 'multi-line' visual mode selections + elseif line("'<") == line("'>") + " action undefined for multi-line visual mode selections call s:normalize_link_syntax_v() endif endif -endfunction "}}} +endfunction -" vimwiki#base#detect_nested_syntax -function! vimwiki#base#detect_nested_syntax() "{{{ + +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)", "")') @@ -1867,26 +2024,20 @@ function! vimwiki#base#detect_nested_syntax() "{{{ let dict[elem] = elem endfor return dict -endfunction "}}} +endfunction -" }}} -" Command completion functions {{{ - -" vimwiki#base#complete_links_escaped -function! vimwiki#base#complete_links_escaped(ArgLead, CmdLine, CursorPos) abort " {{{ +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 " }}} +endfunction -"}}} " ------------------------------------------------------------------------- " Load syntax-specific Wiki functionality for s:syn in s:vimwiki_get_known_syntaxes() execute 'runtime! autoload/vimwiki/'.s:syn.'_base.vim' -endfor +endfor " ------------------------------------------------------------------------- - diff --git a/autoload/vimwiki/diary.vim b/autoload/vimwiki/diary.vim index 52d1b22..dd154ec 100644 --- a/autoload/vimwiki/diary.vim +++ b/autoload/vimwiki/diary.vim @@ -1,48 +1,53 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: Handle diary notes +" Description: Handle diary notes " Home: https://github.com/vimwiki/vimwiki/ -" Load only once {{{ + 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 -" Helpers {{{ -function! s:prefix_zero(num) "{{{ + +function! s:prefix_zero(num) if a:num < 10 return '0'.a:num endif return a:num -endfunction "}}} +endfunction -function! s:diary_path(...) "{{{ + +function! s:diary_path(...) let idx = a:0 == 0 ? vimwiki#vars#get_bufferlocal('wiki_nr') : a:1 return vimwiki#vars#get_wikilocal('diary_path', idx) -endfunction "}}} +endfunction -function! s:diary_index(...) "{{{ + +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 "}}} + 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(...) "{{{ + +function! vimwiki#diary#diary_date_link(...) if a:0 return strftime('%Y-%m-%d', a:1) else return strftime('%Y-%m-%d') endif -endfunction "}}} +endfunction -function! s:get_position_links(link) "{{{ + +function! s:get_position_links(link) let idx = -1 let links = [] if a:link =~# '^\d\{4}-\d\d-\d\d' - let links = keys(s:get_diary_links()) + 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()) @@ -51,21 +56,20 @@ function! s:get_position_links(link) "{{{ let idx = index(links, a:link) endif return [idx, links] -endfunction "}}} +endfunction -fun! s:get_month_name(month) "{{{ + +function! s:get_month_name(month) return vimwiki#vars#get_global('diary_months')[str2nr(a:month)] -endfun "}}} +endfunction -" Helpers }}} -" Diary index stuff {{{ -fun! s:read_captions(files) "{{{ +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 = fnamemodify(fl, ':t:r') + 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) @@ -81,9 +85,10 @@ fun! s:read_captions(files) "{{{ endfor return result -endfun "}}} +endfunction -fun! s:get_diary_links() "{{{ + +function! s:get_diary_files() let rx = '^\d\{4}-\d\d-\d\d' let s_files = glob(vimwiki#vars#get_wikilocal('diary_path') . '*' . vimwiki#vars#get_wikilocal('ext')) let files = split(s_files, '\n') @@ -92,12 +97,11 @@ fun! s:get_diary_links() "{{{ " remove backup files (.wiki~) call filter(files, 'v:val !~# ''.*\~$''') - let links_with_captions = s:read_captions(files) + return files +endfunction - return links_with_captions -endfun "}}} -fun! s:group_links(links) "{{{ +function! s:group_links(links) let result = {} let p_year = 0 let p_month = 0 @@ -116,38 +120,45 @@ fun! s:group_links(links) "{{{ let p_month = month endfor return result -endfun "}}} +endfunction -function! s:sort(lst) "{{{ + +function! s:sort(lst) if vimwiki#vars#get_wikilocal('diary_sort') ==? 'desc' return reverse(sort(a:lst)) else return sort(a:lst) endif -endfunction "}}} +endfunction -function! s:format_diary() "{{{ + +function! s:format_diary() let result = [] - let g_files = s:group_links(s:get_diary_links()) + 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 , '')) + 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), '')) + 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])) if empty(cap) - let entry = substitute(vimwiki#vars#get_global('WikiLinkTemplate1'), '__LinkUrl__', fl, '') + let entry = substitute(vimwiki#vars#get_global('WikiLinkTemplate1'), + \ '__LinkUrl__', fl, '') let entry = substitute(entry, '__LinkDescription__', cap, '') - call add(result, repeat(' ', &sw).'* '.entry) + call add(result, repeat(' ', vimwiki#lst#get_list_margin()).'* '.entry) else - let entry = substitute(vimwiki#vars#get_global('WikiLinkTemplate2'), '__LinkUrl__', fl, '') + let entry = substitute(vimwiki#vars#get_global('WikiLinkTemplate2'), + \ '__LinkUrl__', fl, '') let entry = substitute(entry, '__LinkDescription__', cap, '') - call add(result, repeat(' ', &sw).'* '.entry) + call add(result, repeat(' ', vimwiki#lst#get_list_margin()).'* '.entry) endif endfor @@ -155,11 +166,10 @@ function! s:format_diary() "{{{ endfor return result -endfunction "}}} +endfunction -" Diary index stuff }}} -function! vimwiki#diary#make_note(wnum, ...) "{{{ +function! vimwiki#diary#make_note(wnum, ...) if a:wnum > vimwiki#vars#number_of_wikis() echomsg 'Vimwiki Error: Wiki '.a:wnum.' is not registered in g:vimwiki_list!' return @@ -174,10 +184,15 @@ function! vimwiki#diary#make_note(wnum, ...) "{{{ call vimwiki#path#mkdir(vimwiki#vars#get_wikilocal('diary_path', idx)) - if a:0 && a:1 == 1 - let cmd = 'tabedit' - else - let cmd = 'edit' + 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 @@ -186,9 +201,10 @@ function! vimwiki#diary#make_note(wnum, ...) "{{{ endif call vimwiki#base#open_link(cmd, link, s:diary_index(idx)) -endfunction "}}} +endfunction -function! vimwiki#diary#goto_diary_index(wnum) "{{{ + +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 @@ -202,9 +218,10 @@ function! vimwiki#diary#goto_diary_index(wnum) "{{{ endif call vimwiki#base#edit_file('e', s:diary_index(idx), '') -endfunction "}}} +endfunction -function! vimwiki#diary#goto_next_day() "{{{ + +function! vimwiki#diary#goto_next_day() let link = '' let [idx, links] = s:get_position_links(expand('%:t:r')) @@ -222,9 +239,10 @@ function! vimwiki#diary#goto_next_day() "{{{ if len(link) call vimwiki#base#open_link(':e ', link) endif -endfunction "}}} +endfunction -function! vimwiki#diary#goto_prev_day() "{{{ + +function! vimwiki#diary#goto_prev_day() let link = '' let [idx, links] = s:get_position_links(expand('%:t:r')) @@ -242,9 +260,10 @@ function! vimwiki#diary#goto_prev_day() "{{{ if len(link) call vimwiki#base#open_link(':e ', link) endif -endfunction "}}} +endfunction -function! vimwiki#diary#generate_diary_section() "{{{ + +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) @@ -254,11 +273,11 @@ function! vimwiki#diary#generate_diary_section() "{{{ else echomsg 'Vimwiki Error: You can generate diary links only in a diary index page!' endif -endfunction "}}} +endfunction -" Calendar.vim {{{ -" Callback function. -function! vimwiki#diary#calendar_action(day, month, year, week, dir) "{{{ + +" 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) @@ -278,16 +297,14 @@ function! vimwiki#diary#calendar_action(day, month, year, week, dir) "{{{ " XXX: Well, +1 is for inconsistent index basing... call vimwiki#diary#make_note(vimwiki#vars#get_bufferlocal('wiki_nr')+1, 0, link) -endfunction "}}} +endfunction -" Sign function. -function vimwiki#diary#calendar_sign(day, month, year) "{{{ + +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('diary_path') . \ a:year.'-'.month.'-'.day.vimwiki#vars#get_wikilocal('ext') return filereadable(expand(sfile)) -endfunction "}}} - -" Calendar.vim }}} +endfunction diff --git a/autoload/vimwiki/html.vim b/autoload/vimwiki/html.vim index f2b55bb..d808e65 100644 --- a/autoload/vimwiki/html.vim +++ b/autoload/vimwiki/html.vim @@ -1,60 +1,55 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: Export to HTML +" Description: HTML export " Home: https://github.com/vimwiki/vimwiki/ -" TODO: We need vimwiki abstract syntax tree. If properly designed it wourld -" greatly symplify different syntax to HTML generation. -" -" vimwiki -- --> PDF -" \ / -" markdown -----> AST -----> HTML -" / \ -" mediawiki -- --> Latex -" -" Load only once {{{ if exists("g:loaded_vimwiki_html_auto") || &cp finish endif let g:loaded_vimwiki_html_auto = 1 -"}}} -" UTILITY "{{{ -function! s:root_path(subdir) "{{{ + +function! s:root_path(subdir) return vimwiki#path#relpath(vimwiki#vars#get_wikilocal('path'), a:subdir) -endfunction "}}} +endfunction -function! s:syntax_supported() " {{{ + +function! s:syntax_supported() return vimwiki#vars#get_wikilocal('syntax') ==? "default" -endfunction " }}} +endfunction -function! s:remove_blank_lines(lines) " {{{ + +function! s:remove_blank_lines(lines) while !empty(a:lines) && a:lines[-1] =~# '^\s*$' call remove(a:lines, -1) endwhile -endfunction "}}} +endfunction -function! s:is_web_link(lnk) "{{{ + +function! s:is_web_link(lnk) if a:lnk =~# '^\%(https://\|http://\|www.\|ftp://\|file://\|mailto:\)' return 1 endif return 0 -endfunction "}}} +endfunction -function! s:is_img_link(lnk) "{{{ + +function! s:is_img_link(lnk) if tolower(a:lnk) =~# '\.\%(png\|jpg\|gif\|jpeg\)$' return 1 endif return 0 -endfunction "}}} +endfunction -function! s:default_CSS_full_name(path) " {{{ + +function! s:default_CSS_full_name(path) return vimwiki#path#join(a:path, vimwiki#vars#get_wikilocal('css_name')) -endfunction "}}} +endfunction + " Returns: 1 if it was created, 0 if it already existed -function! s:create_default_CSS(target_dir) " {{{ +function! s:create_default_CSS(target_dir) let css_full_name = s:default_CSS_full_name(a:target_dir) if vimwiki#path#exists(css_full_name) return 0 @@ -63,9 +58,10 @@ function! s:create_default_CSS(target_dir) " {{{ call vimwiki#path#copy_file(default_css, css_full_name) return 1 endif -endfunction "}}} +endfunction -function! s:template_full_name(name) "{{{ + +function! s:template_full_name(name) if a:name == '' let name = vimwiki#vars#get_wikilocal('template_default') else @@ -81,9 +77,10 @@ function! s:template_full_name(name) "{{{ else return '' endif -endfunction "}}} +endfunction -function! s:get_html_template(template) "{{{ + +function! s:get_html_template(template) " TODO: refactor it!!! let lines=[] @@ -93,8 +90,7 @@ function! s:get_html_template(template) "{{{ let lines = readfile(template_name) return lines catch /E484/ - echomsg 'Vimwiki: HTML template ' . template_name . - \ ' does not exist!' + echomsg 'Vimwiki: HTML template '.template_name. ' does not exist!' endtry endif @@ -106,23 +102,22 @@ function! s:get_html_template(template) "{{{ let lines = readfile(default_tpl) return lines -endfunction "}}} +endfunction -function! s:safe_html_preformatted(line) "{{{ + +function! s:safe_html_preformatted(line) let line = substitute(a:line,'<','\<', 'g') let line = substitute(line,'>','\>', 'g') return line -endfunction "}}} +endfunction -function! s:safe_html_anchor(string) "{{{ - let string = substitute(a:string, '"', '\"', 'g') - let string = substitute(string, "'", '\'', 'g') - let string = substitute(string, '/', '\/', 'g') - let string = substitute(string, '\t', ' ', 'g') " doesn't work - return string -endfunction "}}} -function! s:safe_html_line(line) "{{{ +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() @@ -131,9 +126,10 @@ function! s:safe_html_line(line) "{{{ let line = substitute(line,s:gt_pattern,'\>', 'g') return line -endfunction "}}} +endfunction -function! s:delete_html_files(path) "{{{ + +function! s:delete_html_files(path) let htmlfiles = vimwiki#path#files_in_dir_recursive(a:path, 'html') for fname in htmlfiles " ignore user html files, e.g. search.html,404.html @@ -155,13 +151,15 @@ function! s:delete_html_files(path) "{{{ echomsg 'Vimwiki Error: Cannot delete '.fname endtry endfor -endfunction "}}} +endfunction -function! s:mid(value, cnt) "{{{ + +function! s:mid(value, cnt) return strpart(a:value, a:cnt, len(a:value) - 2 * a:cnt) -endfunction "}}} +endfunction -function! s:subst_func(line, regexp, func, ...) " {{{ + +function! s:subst_func(line, regexp, func, ...) " Substitute text found by regexp with result of " func(matched) function. @@ -181,16 +179,30 @@ function! s:subst_func(line, regexp, func, ...) " {{{ let pos = matchend(a:line, a:regexp, pos) endfor return res_line -endfunction " }}} +endfunction -function! s:save_vimwiki_buffer() "{{{ + +function! s:save_vimwiki_buffer() if &filetype ==? 'vimwiki' && filewritable(expand('%')) silent update endif -endfunction "}}} +endfunction -" get title. -function! s:process_title(placeholders, default_title) "{{{ + +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 @@ -200,9 +212,10 @@ function! s:process_title(placeholders, default_title) "{{{ endfor endif return a:default_title -endfunction "}}} +endfunction -function! s:is_html_uptodate(wikifile) "{{{ + +function! s:is_html_uptodate(wikifile) let tpl_time = -1 let tpl_file = s:template_full_name('') @@ -211,16 +224,17 @@ function! s:is_html_uptodate(wikifile) "{{{ 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") + 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 "}}} +endfunction -function! s:html_insert_contents(html_lines, content) "{{{ + +function! s:html_insert_contents(html_lines, content) let lines = [] for line in a:html_lines if line =~# '%content%' @@ -240,22 +254,23 @@ function! s:html_insert_contents(html_lines, content) "{{{ endif endfor return lines -endfunction "}}} -"}}} +endfunction -" INLINE TAGS "{{{ -function! s:tag_eqin(value) "{{{ + +function! s:tag_eqin(value) " mathJAX wants \( \) for inline maths return '\('.s:mid(a:value, 1).'\)' -endfunction "}}} +endfunction -function! s:tag_em(value) "{{{ + +function! s:tag_em(value) return ''.s:mid(a:value, 1).'' -endfunction "}}} +endfunction -function! s:tag_strong(value, header_ids) "{{{ + +function! s:tag_strong(value, header_ids) let text = s:mid(a:value, 1) - let id = s:safe_html_anchor(text) + let id = s:escape_html_attribute(text) let complete_id = '' for l in range(6) if a:header_ids[l][0] != '' @@ -266,11 +281,12 @@ function! s:tag_strong(value, header_ids) "{{{ let complete_id = complete_id[:-2] endif let complete_id .= '-'.id - return ''.text.'' -endfunction "}}} +endfunction -function! s:tag_tags(value, header_ids) "{{{ + +function! s:tag_tags(value, header_ids) let complete_id = '' for level in range(6) if a:header_ids[level][0] != '' @@ -280,88 +296,89 @@ function! s:tag_tags(value, header_ids) "{{{ if a:header_ids[5][0] == '' let complete_id = complete_id[:-2] endif - let complete_id = s:safe_html_anchor(complete_id) + let complete_id = s:escape_html_attribute(complete_id) let result = [] for tag in split(a:value, ':') - let id = s:safe_html_anchor(tag) + let id = s:escape_html_attribute(tag) call add(result, ''.tag.'') endfor return join(result) -endfunction "}}} +endfunction -function! s:tag_todo(value) "{{{ + +function! s:tag_todo(value) return ''.a:value.'' -endfunction "}}} +endfunction -function! s:tag_strike(value) "{{{ + +function! s:tag_strike(value) return ''.s:mid(a:value, 2).'' -endfunction "}}} +endfunction -function! s:tag_super(value) "{{{ + +function! s:tag_super(value) return ''.s:mid(a:value, 1).'' -endfunction "}}} +endfunction -function! s:tag_sub(value) "{{{ + +function! s:tag_sub(value) return ''.s:mid(a:value, 2).'' -endfunction "}}} +endfunction -function! s:tag_code(value) "{{{ + +function! s:tag_code(value) return ''.s:safe_html_preformatted(s:mid(a:value, 1)).'' -endfunction "}}} - -"function! s:tag_pre(value) "{{{ -" return ''.s:mid(a:value, 3).'' -"endfunction "}}} - -"FIXME dead code? -"function! s:tag_math(value) "{{{ -" return '\['.s:mid(a:value, 3).'\]' -"endfunction "}}} +endfunction -"{{{ v2.0 links -" match n-th ARG within {{URL[|ARG1|ARG2|...]}} " {{{ +" match n-th ARG within {{URL[|ARG1|ARG2|...]}} " *c,d,e),... -function! vimwiki#html#incl_match_arg(nn_index) +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) + 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' + 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') + let rx = rx . vimwiki#vars#get_global('rxWikiInclArgs') . + \ vimwiki#vars#get_global('rxWikiInclSuffix') return rx endfunction -"}}} -function! vimwiki#html#linkify_link(src, descr) "{{{ - let src_str = ' href="'.s:safe_html_anchor(a:src).'"' + +function! s:linkify_link(src, descr) + let src_str = ' href="'.s:escape_html_attribute(a:src).'"' let descr = substitute(a:descr,'^\s*\(.*\)\s*$','\1','') let descr = (descr == "" ? a:src : descr) let descr_str = (descr =~# vimwiki#vars#get_global('rxWikiIncl') - \ ? s:tag_wikiincl(descr) + \ ? s:tag_wikiincl(descr) \ : descr) return ''.descr_str.'' -endfunction "}}} +endfunction -function! vimwiki#html#linkify_image(src, descr, verbatim_str) "{{{ + +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 '' -endfunction "}}} +endfunction -function! s:tag_weblink(value) "{{{ + +function! s:tag_weblink(value) " Weblink Template -> descr let str = a:value let url = matchstr(str, vimwiki#vars#get_syntaxlocal('rxWeblinkMatchUrl')) let descr = matchstr(str, vimwiki#vars#get_syntaxlocal('rxWeblinkMatchDescr')) - let line = vimwiki#html#linkify_link(url, descr) + let line = s:linkify_link(url, descr) return line -endfunction "}}} +endfunction -function! s:tag_wikiincl(value) "{{{ + +function! s:tag_wikiincl(value) " {{imgurl|arg1|arg2}} -> ??? " {{imgurl}} -> " {{imgurl|descr|style="A"}} -> descr @@ -372,14 +389,13 @@ function! s:tag_wikiincl(value) "{{{ " otherwise, assume image transclusion if line == '' let url_0 = matchstr(str, vimwiki#vars#get_global('rxWikiInclMatchUrl')) - let descr = matchstr(str, vimwiki#html#incl_match_arg(1)) - let verbatim_str = matchstr(str, vimwiki#html#incl_match_arg(2)) + 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) + 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' @@ -390,12 +406,13 @@ function! s:tag_wikiincl(value) "{{{ endif let url = escape(url, '#') - let line = vimwiki#html#linkify_image(url, descr, verbatim_str) + let line = s:linkify_image(url, descr, verbatim_str) endif return line -endfunction "}}} +endfunction -function! s:tag_wikilink(value) "{{{ + +function! s:tag_wikilink(value) " [[url]] -> url " [[url|descr]] -> descr " [[url|{{...}}]] -> ... @@ -408,8 +425,7 @@ function! s:tag_wikilink(value) "{{{ let descr = matchstr(str, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr')) let descr = (substitute(descr,'^\s*\(.*\)\s*$','\1','') != '' ? descr : url) - let line = VimwikiLinkConverter(url, s:current_wiki_file, - \ s:current_html_file) + 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) @@ -417,8 +433,8 @@ function! s:tag_wikilink(value) "{{{ " 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) + 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( @@ -438,13 +454,12 @@ function! s:tag_wikilink(value) "{{{ let line = html_link endif - let line =vimwiki#html#linkify_link(line, descr) + let line = s:linkify_link(line, descr) return line -endfunction "}}} -"}}} +endfunction -function! s:tag_remove_internal_link(value) "{{{ +function! s:tag_remove_internal_link(value) let value = s:mid(a:value, 2) let line = '' @@ -465,9 +480,10 @@ function! s:tag_remove_internal_link(value) "{{{ let line = value endif return line -endfunction "}}} +endfunction -function! s:tag_remove_external_link(value) "{{{ + +function! s:tag_remove_external_link(value) let value = s:mid(a:value, 1) let line = '' @@ -487,14 +503,16 @@ function! s:tag_remove_external_link(value) "{{{ let line = '['.value.']' endif return line -endfunction "}}} +endfunction -function! s:make_tag(line, regexp, func, ...) "{{{ + +function! s:make_tag(line, regexp, func, ...) " Make tags for a given matched regexp. " Exclude preformatted text and href links. - " FIXME + " FIXME let patt_splitter = '\(`[^`]\+`\)\|'. - \ '\('.vimwiki#vars#get_syntaxlocal('rxPreStart').'.\+'.vimwiki#vars#get_syntaxlocal('rxPreEnd').'\)\|'. + \ '\('.vimwiki#vars#get_syntaxlocal('rxPreStart').'.\+'. + \ vimwiki#vars#get_syntaxlocal('rxPreEnd').'\)\|'. \ '\(\)\|'. \ '\(\)\|'. \ '\(\)\|'. @@ -526,16 +544,18 @@ function! s:make_tag(line, regexp, func, ...) "{{{ endfor endif return res_line -endfunction "}}} +endfunction -function! s:process_tags_remove_links(line) " {{{ + +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 " }}} +endfunction -function! s:process_tags_typefaces(line, header_ids) "{{{ + +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) @@ -547,71 +567,76 @@ function! s:process_tags_typefaces(line, header_ids) "{{{ 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 " }}} +endfunction -function! s:process_tags_links(line) " {{{ + +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 " }}} +endfunction -function! s:process_inline_tags(line, header_ids) "{{{ + +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 " }}} -"}}} +endfunction -" BLOCK TAGS {{{ -function! s:close_tag_pre(pre, ldest) "{{{ + +function! s:close_tag_pre(pre, ldest) if a:pre[0] call insert(a:ldest, "") return 0 endif return a:pre -endfunction "}}} +endfunction -function! s:close_tag_math(math, ldest) "{{{ + +function! s:close_tag_math(math, ldest) if a:math[0] call insert(a:ldest, "\\\]") return 0 endif return a:math -endfunction "}}} +endfunction -function! s:close_tag_quote(quote, ldest) "{{{ + +function! s:close_tag_quote(quote, ldest) if a:quote call insert(a:ldest, "") return 0 endif return a:quote -endfunction "}}} +endfunction -function! s:close_tag_para(para, ldest) "{{{ + +function! s:close_tag_para(para, ldest) if a:para call insert(a:ldest, "

") return 0 endif return a:para -endfunction "}}} +endfunction -function! s:close_tag_table(table, ldest, header_ids) "{{{ + +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', + " ['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) "{{{ + function! s:sum_rowspan(table) let table = a:table " Get max cells - let max_cells = 0 + let max_cells = 0 for row in table[1:] let n_cells = len(row) if n_cells > max_cells @@ -637,9 +662,9 @@ function! s:close_tag_table(table, ldest, header_ids) "{{{ endif endfor endfor - endfunction "}}} + endfunction - function! s:sum_colspan(table) "{{{ + function! s:sum_colspan(table) for row in a:table[1:] let cols = 1 @@ -652,19 +677,19 @@ function! s:close_tag_table(table, ldest, header_ids) "{{{ endif endfor endfor - endfunction "}}} + endfunction - function! s:close_tag_row(row, header, ldest, header_ids) "{{{ + function! s:close_tag_row(row, header, ldest, header_ids) call add(a:ldest, '') - " Set tag element of columns + " Set tag element of columns if a:header let tag_name = 'th' else let tag_name = 'td' end - " Close tag of columns + " Close tag of columns for cell in a:row if cell.rowspan == 0 || cell.colspan == 0 continue @@ -687,7 +712,7 @@ function! s:close_tag_table(table, ldest, header_ids) "{{{ endfor call add(a:ldest, '') - endfunction "}}} + endfunction let table = a:table let ldest = a:ldest @@ -730,24 +755,27 @@ function! s:close_tag_table(table, ldest, header_ids) "{{{ let table = [] endif return table -endfunction "}}} +endfunction -function! s:close_tag_list(lists, ldest) "{{{ + +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 "}}} +endfunction -function! s:close_tag_def_list(deflist, ldest) "{{{ + +function! s:close_tag_def_list(deflist, ldest) if a:deflist call insert(a:ldest, "") return 0 endif return a:deflist -endfunction "}}} +endfunction -function! s:process_tag_pre(line, pre) "{{{ + +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 = [] @@ -777,9 +805,10 @@ function! s:process_tag_pre(line, pre) "{{{ call add(lines, s:safe_html_preformatted(a:line)) endif return [processed, lines, pre] -endfunction "}}} +endfunction -function! s:process_tag_math(line, math) "{{{ + +function! s:process_tag_math(line, math) " math is the list of [is_in_math, indent_of_math] let lines = [] let math = a:math @@ -813,9 +842,10 @@ function! s:process_tag_math(line, math) "{{{ call add(lines, substitute(a:line, '^\s\{'.math[1].'}', '', '')) endif return [processed, lines, math] -endfunction "}}} +endfunction -function! s:process_tag_quote(line, quote) "{{{ + +function! s:process_tag_quote(line, quote) let lines = [] let quote = a:quote let processed = 0 @@ -831,21 +861,29 @@ function! s:process_tag_quote(line, quote) "{{{ let quote = 0 endif return [processed, lines, quote] -endfunction "}}} +endfunction -function! s:process_tag_list(line, lists) "{{{ - function! s:add_checkbox(line, rx_list) "{{{ +function! s:process_tag_list(line, lists) + + function! s:add_checkbox(line, rx_list) let st_tag = '
  • ' 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]) - if completion >= 0 && completion <=4 + let n = len(vimwiki#vars#get_syntaxlocal('listsyms_list')) + if completion == 0 + let st_tag = '
  • ' + elseif completion == -1 && chk[1] == vimwiki#vars#get_global('listsym_rejected') + let st_tag = '
  • ' + elseif completion > 0 && completion < n + let completion = float2nr(round(completion / (n-1.0) * 3.0 + 0.5 )) let st_tag = '
  • ' endif endif return [st_tag, ''] - endfunction "}}} + endfunction + let in_list = (len(a:lists) > 0) @@ -909,8 +947,7 @@ function! s:process_tag_list(line, lists) "{{{ call add(a:lists, [en_tag, indent]) call add(lines, st_tag) - call add(lines, - \ substitute(a:line, lstRegExp.'\%('.checkbox.'\)\?', '', '')) + 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') @@ -923,9 +960,10 @@ function! s:process_tag_list(line, lists) "{{{ call s:close_tag_list(a:lists, lines) endif return [processed, lines] -endfunction "}}} +endfunction -function! s:process_tag_def_list(line, deflist) "{{{ + +function! s:process_tag_def_list(line, deflist) let lines = [] let deflist = a:deflist let processed = 0 @@ -947,9 +985,10 @@ function! s:process_tag_def_list(line, deflist) "{{{ call add(lines, "") endif return [processed, lines, deflist] -endfunction "}}} +endfunction -function! s:process_tag_para(line, para) "{{{ + +function! s:process_tag_para(line, para) let lines = [] let para = a:para let processed = 0 @@ -959,15 +998,20 @@ function! s:process_tag_para(line, para) "{{{ let para = 1 endif let processed = 1 - call add(lines, a:line) + if vimwiki#vars#get_global('text_ignore_newline') + call add(lines, a:line) + else + call add(lines, a:line."
    ") + endif elseif para && a:line =~# '^\s*$' call add(lines, "

    ") let para = 0 endif return [processed, lines, para] -endfunction "}}} +endfunction -function! s:process_tag_h(line, id) "{{{ + +function! s:process_tag_h(line, id) let line = a:line let processed = 0 let h_level = 0 @@ -982,7 +1026,7 @@ function! s:process_tag_h(line, id) "{{{ let h_text = vimwiki#u#trim(matchstr(line, vimwiki#vars#get_syntaxlocal('rxHeader'))) let h_number = '' let h_complete_id = '' - let h_id = s:safe_html_anchor(h_text) + let h_id = s:escape_html_attribute(h_text) let centered = (a:line =~# '^\s') if h_text !=# vimwiki#vars#get_global('toc_header') @@ -1011,7 +1055,7 @@ function! s:process_tag_h(line, id) "{{{ endif let h_text = num.' '.h_text endif - let h_complete_id = s:safe_html_anchor(h_complete_id) + let h_complete_id = s:escape_html_attribute(h_complete_id) let h_part = '
    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'))) : '-')) -endfunction " }}} + \ (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) "{{{ + +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 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 @@ -1399,14 +1455,13 @@ function! s:convert_file(path_html, wikifile) "{{{ 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:lt_pattern = '\c<\%(/\?\%('.tags.'\)\%(\s\{-1}\S\{-}\)\{-}/\?>\)\@!' let s:gt_pattern = '\c\%(' endif " prepare regexps for lists let s:bullets = '[*-]' - let s:numbers = - \'\C\%(#\|\d\+)\|\d\+\.\|[ivxlcdm]\+)\|[IVXLCDM]\+)\|\l\{1,2})\|\u\{1,2})\)' + let s:numbers = '\C\%(#\|\d\+)\|\d\+\.\|[ivxlcdm]\+)\|[IVXLCDM]\+)\|\l\{1,2})\|\u\{1,2})\)' for line in lsource let oldquote = state.quote @@ -1455,11 +1510,13 @@ function! s:convert_file(path_html, wikifile) "{{{ 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")') @@ -1486,17 +1543,19 @@ function! s:convert_file(path_html, wikifile) "{{{ endif return path_html.htmlfile -endfunction "}}} +endfunction -function! vimwiki#html#Wiki2HTML(output_dir, wikifile) "{{{ + +function! vimwiki#html#Wiki2HTML(output_dir, wikifile) let result = s:convert_file(a:output_dir, a:wikifile) if result != '' call s:create_default_CSS(a:output_dir) endif return result -endfunction "}}} +endfunction -function! vimwiki#html#WikiAll2HTML(path_html) "{{{ + +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 @@ -1524,7 +1583,8 @@ function! vimwiki#html#WikiAll2HTML(path_html) "{{{ 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') + let wikifiles = split(glob(vimwiki#vars#get_wikilocal('path').'**/*'. + \ vimwiki#vars#get_wikilocal('ext')), '\n') for wikifile in wikifiles let wikifile = fnamemodify(wikifile, ":p") @@ -1553,27 +1613,32 @@ function! vimwiki#html#WikiAll2HTML(path_html) "{{{ echomsg 'Vimwiki: Done!' let &more = setting_more -endfunction "}}} +endfunction -function! s:file_exists(fname) "{{{ + +function! s:file_exists(fname) return !empty(getftype(expand(a:fname))) -endfunction "}}} +endfunction -function! s:binary_exists(fname) "{{{ + +function! s:binary_exists(fname) return executable(expand(a:fname)) -endfunction "}}} +endfunction -function! s:get_wikifile_url(wikifile) "{{{ + +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 "}}} +endfunction -function! vimwiki#html#PasteUrl(wikifile) "{{{ + +function! vimwiki#html#PasteUrl(wikifile) execute 'r !echo file://'.s:get_wikifile_url(a:wikifile) -endfunction "}}} +endfunction -function! vimwiki#html#CatUrl(wikifile) "{{{ + +function! vimwiki#html#CatUrl(wikifile) execute '!echo file://'.s:get_wikifile_url(a:wikifile) -endfunction "}}} -"}}} +endfunction + diff --git a/autoload/vimwiki/lst.vim b/autoload/vimwiki/lst.vim index 41ef51b..d4ccbbd 100644 --- a/autoload/vimwiki/lst.vim +++ b/autoload/vimwiki/lst.vim @@ -1,20 +1,25 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: Everything concerning lists and checkboxes +" 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) "{{{ +" --------------------------------------------------------- +" incrementation functions for the various kinds of numbers +" --------------------------------------------------------- + +function! s:increment_1(value) return eval(a:value) + 1 -endfunction "}}} +endfunction -function! s:increment_A(value) "{{{ + +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))) @@ -31,9 +36,10 @@ function! s:increment_A(value) "{{{ call insert(list_of_chars, 'A') endif return join(list_of_chars, '') -endfunction "}}} +endfunction -function! s:increment_a(value) "{{{ + +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))) @@ -50,9 +56,10 @@ function! s:increment_a(value) "{{{ call insert(list_of_chars, 'a') endif return join(list_of_chars, '') -endfunction "}}} +endfunction -function! s:increment_I(value) "{{{ + +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'], @@ -64,9 +71,10 @@ function! s:increment_I(value) "{{{ endif endfor return '' -endfunction "}}} +endfunction -function! s:increment_i(value) "{{{ + +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'], @@ -78,27 +86,29 @@ function! s:increment_i(value) "{{{ endif endfor return '' -endfunction "}}} +endfunction -"incrementation functions for the various kinds of numbers }}} -"utility functions {{{ +" --------------------------------------------------------- +" 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_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) "{{{ +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 "}}} +endfunction -if exists("*strdisplaywidth") "{{{ + +if exists("*strdisplaywidth") function! s:string_length(str) return strdisplaywidth(a:str) endfunction @@ -106,31 +116,35 @@ else function! s:string_length(str) return strlen(substitute(a:str, '.', 'x', 'g')) endfunction -endif "}}} +endif -function! vimwiki#lst#default_symbol() "{{{ + +function! vimwiki#lst#default_symbol() return vimwiki#vars#get_syntaxlocal('list_markers')[0] -endfunction "}}} +endfunction -function! vimwiki#lst#get_list_margin() "{{{ + +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 "}}} +endfunction + "Returns: the column where the text of a line starts (possible list item "markers and checkboxes are skipped) -function! s:text_begin(lnum) "{{{ +function! s:text_begin(lnum) return s:string_length(matchstr(getline(a:lnum), vimwiki#vars#get_syntaxlocal('rxListItem'))) -endfunction "}}} +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) "{{{ +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' @@ -138,11 +152,12 @@ function! s:line_has_marker(lnum) "{{{ else return 0 endif -endfunction "}}} +endfunction -"utility functions }}} -"get properties of an item {{{ +" --------------------------------------------------------- +" 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 @@ -150,7 +165,7 @@ endfunction "}}} "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) "{{{ +function! s:get_item(lnum) let item = {'lnum': a:lnum} if a:lnum == 0 || a:lnum > line('$') let item.type = 0 @@ -176,33 +191,37 @@ function! s:get_item(lnum) "{{{ endif return item -endfunction "}}} +endfunction -function! s:empty_item() "{{{ + +function! s:empty_item() return {'type': 0} -endfunction "}}} +endfunction + "Returns: level of the line "0 is the 'highest' level -function! s:get_level(lnum) "{{{ +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 + 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 "}}} +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) "{{{ +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:] @@ -260,9 +279,10 @@ function! s:guess_kind_of_numbered_item(item) "{{{ endif endif -endfunction "}}} +endfunction -function! s:regexp_of_marker(item) "{{{ + +function! s:regexp_of_marker(item) if a:item.type == 1 return vimwiki#u#escape(a:item.mrkr) elseif a:item.type == 2 @@ -276,15 +296,16 @@ function! s:regexp_of_marker(item) "{{{ else return '' endif -endfunction "}}} +endfunction -"get properties of an item }}} -"functions for navigating between items {{{ +" --------------------------------------------------------- +" 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) "{{{ +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) @@ -303,11 +324,12 @@ function! s:get_next_list_item(item, ignore_kind) "{{{ let cur_ln = s:get_next_line(cur_ln) endwhile return s:empty_item() -endfunction "}}} +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) "{{{ +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) @@ -326,9 +348,10 @@ function! s:get_prev_list_item(item, ignore_kind) "{{{ let cur_ln = s:get_prev_line(cur_ln) endwhile return s:empty_item() -endfunction "}}} +endfunction -function! s:get_item_of_level(cur_ln, cur_lvl, org_lvl, org_regex) "{{{ + +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' @@ -339,17 +362,19 @@ function! s:get_item_of_level(cur_ln, cur_lvl, org_lvl, org_regex) "{{{ elseif a:cur_lvl < a:org_lvl return s:empty_item() endif -endfunction "}}} +endfunction -function! s:get_any_item_of_level(cur_ln, cur_lvl, org_lvl) "{{{ + +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 "}}} +endfunction -function! s:get_first_item_in_list(item, ignore_kind) "{{{ + +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) @@ -360,9 +385,10 @@ function! s:get_first_item_in_list(item, ignore_kind) "{{{ endif endwhile return cur_item -endfunction "}}} +endfunction -function! s:get_last_item_in_list(item, ignore_kind) "{{{ + +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) @@ -373,17 +399,17 @@ function! s:get_last_item_in_list(item, ignore_kind) "{{{ endif endwhile return cur_item -endfunction "}}} +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, ...) "{{{ +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') + while cur_ln <= line('$') && getline(cur_ln) !~# vimwiki#vars#get_syntaxlocal('rxPreEnd') let cur_ln += 1 endwhile let next_line = cur_ln @@ -401,11 +427,12 @@ function! s:get_next_line(lnum, ...) "{{{ endif return next_line -endfunction "}}} +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) "{{{ +function! s:get_prev_line(lnum) let prev_line = prevnonblank(a:lnum-1) if getline(prev_line) =~# vimwiki#vars#get_syntaxlocal('rxPreEnd') @@ -425,9 +452,10 @@ function! s:get_prev_line(lnum) "{{{ endif return prev_line -endfunction "}}} +endfunction -function! s:get_first_child(item) "{{{ + +function! s:get_first_child(item) if a:item.lnum >= line('$') return s:empty_item() endif @@ -437,19 +465,18 @@ function! s:get_first_child(item) "{{{ 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 + 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 "}}} +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) "{{{ +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) @@ -465,9 +492,10 @@ function! s:get_next_child_item(parent, child) "{{{ endif endwhile return s:empty_item() -endfunction "}}} +endfunction -function! s:get_parent(item) "{{{ + +function! s:get_parent(item) let parent_line = 0 let cur_ln = prevnonblank(a:item.lnum) @@ -491,10 +519,11 @@ function! s:get_parent(item) "{{{ endif endwhile return s:get_item(parent_line) -endfunction "}}} +endfunction + "Returns: the item above or the item below or an empty item -function! s:get_a_neighbor_item(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 @@ -505,9 +534,10 @@ function! s:get_a_neighbor_item(item) "{{{ endif endif return s:empty_item() -endfunction "}}} +endfunction -function! s:get_a_neighbor_item_in_column(lnum, column) "{{{ + +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 @@ -516,11 +546,12 @@ function! s:get_a_neighbor_item_in_column(lnum, column) "{{{ let cur_ln = s:get_prev_line(cur_ln) endwhile return s:empty_item() -endfunction "}}} +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) "{{{ +function! s:get_corresponding_item(lnum) let item = s:get_item(a:lnum) if item.type != 0 return item @@ -539,10 +570,11 @@ function! s:get_corresponding_item(lnum) "{{{ let cur_ln = s:get_prev_line(cur_ln) endwhile return s:empty_item() -endfunction "}}} +endfunction + "Returns: the last line of a (possibly multiline) item, including all children -function! s:get_last_line_of_item_incl_children(item) "{{{ +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 @@ -552,11 +584,12 @@ function! s:get_last_line_of_item_incl_children(item) "{{{ endif let cur_ln = next_line endwhile -endfunction "}}} +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) "{{{ +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 @@ -571,20 +604,21 @@ function! s:get_last_line_of_item(item) "{{{ 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)) + let cur_ln = s:get_next_line(s:get_last_line_of_item_incl_children(cur_item)) endif endwhile return last_corresponding_line -endfunction "}}} +endfunction -"functions for navigating between items }}} -"renumber list items {{{ +" --------------------------------------------------------- +" 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) "{{{ +function! s:adjust_numbered_list_below(item, recursive) if !(a:item.type == 2 || (a:item.type == 1 && a:recursive)) return a:item endif @@ -611,9 +645,10 @@ function! s:adjust_numbered_list_below(item, recursive) "{{{ let cur_item = next_item endwhile return cur_item -endfunction "}}} +endfunction -function! s:adjust_items_recursively(parent) "{{{ + +function! s:adjust_items_recursively(parent) if a:parent.type == 0 return s:empty_item() end @@ -630,13 +665,14 @@ function! s:adjust_items_recursively(parent) "{{{ return last_item endif endwhile -endfunction "}}} +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) "{{{ +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 @@ -645,10 +681,8 @@ function! s:adjust_numbered_list(item, ignore_kind, recursive) "{{{ 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 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 @@ -660,20 +694,22 @@ function! s:adjust_numbered_list(item, ignore_kind, recursive) "{{{ endif let first_item = next_first_item endwhile -endfunction "}}} +endfunction + "Renumbers the list the cursor is in "also update its parents checkbox state -function! vimwiki#lst#adjust_numbered_list() "{{{ +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 "}}} +endfunction + "Renumbers all lists of the buffer "of course, this might take some seconds -function! vimwiki#lst#adjust_whole_buffer() "{{{ +function! vimwiki#lst#adjust_whole_buffer() let cur_ln = 1 while 1 let cur_item = s:get_item(cur_ln) @@ -685,24 +721,30 @@ function! vimwiki#lst#adjust_whole_buffer() "{{{ return endif endwhile -endfunction "}}} +endfunction -"renumber list items }}} -"checkbox stuff {{{ +" --------------------------------------------------------- +" checkbox stuff +" --------------------------------------------------------- "Returns: the rate of checkboxed list item in percent -function! s:get_rate(item) "{{{ +function! s:get_rate(item) if a:item.type == 0 || a:item.cb == '' return -1 endif let state = a:item.cb - return index(vimwiki#vars#get_syntaxlocal('listsyms_list'), state) * 25 -endfunction "}}} + 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) "{{{ +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 @@ -711,11 +753,12 @@ function! s:set_state(item, new_rate) "{{{ else return 0 endif -endfunction "}}} +endfunction + "Set state of the list item to [ ] or [o] or whatever "Updates the states of its child items -function! s:set_state_plus_children(item, new_rate) "{{{ +function! s:set_state_plus_children(item, new_rate) call s:set_state(a:item, a:new_rate) let child_item = s:get_first_child(a:item) @@ -728,28 +771,31 @@ function! s:set_state_plus_children(item, new_rate) "{{{ endif let child_item = s:get_next_child_item(a:item, child_item) endwhile -endfunction "}}} +endfunction + "Returns: the appropriate symbol for a given percent rate -function! s:rate_to_state(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 = vimwiki#vars#get_syntaxlocal('listsyms_list')[4] + let state = listsyms_list[n-1] elseif a:rate == 0 - let state = vimwiki#vars#get_syntaxlocal('listsyms_list')[0] - elseif a:rate >= 67 - let state = vimwiki#vars#get_syntaxlocal('listsyms_list')[3] - elseif a:rate >= 34 - let state = vimwiki#vars#get_syntaxlocal('listsyms_list')[2] + let state = listsyms_list[0] + elseif a:rate == -1 + let state = vimwiki#vars#get_global('listsym_rejected') else - let state = vimwiki#vars#get_syntaxlocal('listsyms_list')[1] + let index = float2nr(ceil(a:rate/100.0*(n-2))) + let state = listsyms_list[index] endif return state -endfunction "}}} +endfunction + "updates the symbol of a checkboxed item according to the symbols of its "children -function! s:update_state(item) "{{{ +function! s:update_state(item) if a:item.type == 0 || a:item.cb == '' return endif @@ -764,8 +810,11 @@ function! s:update_state(item) "{{{ break endif if child_item.cb != '' - let count_children_with_cb += 1 - let sum_children_rate += s:get_rate(child_item) + let rate = s:get_rate(child_item) + if rate != -1 + let count_children_with_cb += 1 + let sum_children_rate += rate + endif endif let child_item = s:get_next_child_item(a:item, child_item) endwhile @@ -779,18 +828,20 @@ function! s:update_state(item) "{{{ call s:set_state_recursively(a:item, 0) endif endif -endfunction "}}} +endfunction -function! s:set_state_recursively(item, new_rate) "{{{ + +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 "}}} +endfunction + "Creates checkbox in a list item. "Returns: 1 if successful -function! s:create_cb(item) "{{{ +function! s:create_cb(item) if a:item.type == 0 || a:item.cb != '' return 0 endif @@ -802,20 +853,22 @@ function! s:create_cb(item) "{{{ call s:update_state(new_item) return 1 -endfunction "}}} +endfunction -function! s:remove_cb(item) "{{{ + +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 "}}} +endfunction -"Toggles checkbox between [ ] and [X] or creates one + +"Change state of checkbox "in the lines of the given range -function! vimwiki#lst#toggle_cb(from_line, to_line) "{{{ +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 @@ -823,6 +876,32 @@ function! vimwiki#lst#toggle_cb(from_line, to_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) + 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 chceckboxes if there aren't any. +function! s:toggle_create_cb(from_line, to_line, state1, state2) + 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 @@ -839,32 +918,106 @@ function! vimwiki#lst#toggle_cb(from_line, to_line) "{{{ 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 == 100 ? 0 : 100 + let new_rate = rate_first_line == a:state1 ? a:state2 : a:state1 - 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, 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 + call s:change_cb(a:from_line, a:to_line, new_rate) endif - for parent_item in parent_items_of_lines - call s:update_state(parent_item) - endfor +endfunction -endfunction "}}} -function! vimwiki#lst#remove_cb(first_line, last_line) "{{{ +"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) +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) +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) +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) +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) @@ -889,11 +1042,11 @@ function! vimwiki#lst#remove_cb(first_line, last_line) "{{{ for parent_item in parent_items_of_lines call s:update_state(parent_item) endfor -endfunction "}}} +endfunction -function! vimwiki#lst#remove_cb_in_list() "{{{ - let first_item = s:get_first_item_in_list( - \ s:get_corresponding_item(line('.')), 0) + +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 @@ -907,29 +1060,31 @@ function! vimwiki#lst#remove_cb_in_list() "{{{ endwhile call s:update_state(s:get_parent(first_item)) -endfunction "}}} +endfunction -"checkbox stuff }}} -"change the level of list items {{{ -function! s:set_indent(lnum, new_indent) "{{{ +" --------------------------------------------------------- +" 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) + 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 "}}} +endfunction -function! s:decrease_level(item) "{{{ + +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 + \ 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), '') + call s:substitute_string_in_line(a:item.lnum, s:first_char(a:item.mrkr), '') let removed_indent = -1 endif else @@ -943,12 +1098,14 @@ function! s:decrease_level(item) "{{{ let removed_indent = new_indent - old_indent endif return removed_indent -endfunction "}}} +endfunction -function! s:increase_level(item) "{{{ + +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 + \ 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 @@ -963,31 +1120,32 @@ function! s:increase_level(item) "{{{ let additional_indent = new_indent - old_indent endif return additional_indent -endfunction "}}} +endfunction + "adds a:indent_by to the current indent "a:indent_by can be negative -function! s:indent_line_by(lnum, indent_by) "{{{ +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 + \ 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)) + 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 "}}} +endfunction + "changes lvl of lines in selection -function! s:change_level(from_line, to_line, direction, plus_children) "{{{ +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)) + 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 @@ -1028,8 +1186,7 @@ function! s:change_level(from_line, to_line, direction, plus_children) "{{{ 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') ? + 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) @@ -1059,36 +1216,41 @@ function! s:change_level(from_line, to_line, direction, plus_children) "{{{ call s:adjust_numbered_list(from_item, 0, 0) call s:adjust_numbered_list(to_be_adjusted, 0, 0) endif -endfunction "}}} +endfunction -function! vimwiki#lst#change_level(from_line, to_line, direction, plus_children) "{{{ + +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 "}}} +endfunction + "indent line a:lnum to be the continuation of a:prev_item -function! s:indent_multiline(prev_item, lnum) "{{{ +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 "}}} +endfunction -"change the level of list items }}} -"change markers of list items {{{ +" --------------------------------------------------------- +" change markers of list items +" --------------------------------------------------------- + "Returns: the position of a marker in g:vimwiki_list_markers -function! s:get_idx_list_markers(item) "{{{ +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 "}}} +endfunction + "changes the marker of the given item to the next in g:vimwiki_list_markers -function! s:get_next_mrkr(item) "{{{ +function! s:get_next_mrkr(item) let markers = vimwiki#vars#get_syntaxlocal('list_markers') if a:item.type == 0 let new_mrkr = markers[0] @@ -1097,10 +1259,11 @@ function! s:get_next_mrkr(item) "{{{ let new_mrkr = markers[(idx+1) % len(markers)] endif return new_mrkr -endfunction "}}} +endfunction + "changes the marker of the given item to the previous in g:vimwiki_list_markers -function! s:get_prev_mrkr(item) "{{{ +function! s:get_prev_mrkr(item) let markers = vimwiki#vars#get_syntaxlocal('list_markers') if a:item.type == 0 return markers[-1] @@ -1109,12 +1272,12 @@ function! s:get_prev_mrkr(item) "{{{ if idx == -1 return markers[-1] else - return markers[(idx - 1 + len(markers)) % - \ len(markers)] + return markers[(idx - 1 + len(markers)) % len(markers)] endif -endfunction "}}} +endfunction -function! s:set_new_mrkr(item, new_mrkr) "{{{ + +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') @@ -1123,9 +1286,10 @@ function! s:set_new_mrkr(item, new_mrkr) "{{{ else call s:substitute_string_in_line(a:item.lnum, a:item.mrkr, a:new_mrkr) endif -endfunction "}}} +endfunction -function! vimwiki#lst#change_marker(from_line, to_line, new_mrkr, mode) "{{{ + +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 @@ -1142,25 +1306,23 @@ function! vimwiki#lst#change_marker(from_line, to_line, new_mrkr, mode) "{{{ 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) + 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) + 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 + \ 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) + 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 @@ -1178,9 +1340,10 @@ function! vimwiki#lst#change_marker(from_line, to_line, new_mrkr, mode) "{{{ endwhile call cursor('.', col('$') - cur_col_from_eol) -endfunction "}}} +endfunction -function! vimwiki#lst#change_marker_in_list(new_mrkr) "{{{ + +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) @@ -1194,10 +1357,11 @@ function! vimwiki#lst#change_marker_in_list(new_mrkr) "{{{ endwhile call s:adjust_numbered_list(s:get_item(first_item_line), 0, 0) -endfunction "}}} +endfunction + "sets kind of the item depending on neighbor items and the parent item -function! s:adjust_mrkr(item) "{{{ +function! s:adjust_mrkr(item) if a:item.type == 0 || vimwiki#vars#get_syntaxlocal('recurring_bullets') return endif @@ -1210,20 +1374,20 @@ function! s:adjust_mrkr(item) "{{{ "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 + \ 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) + 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 "}}} +endfunction -function! s:clone_marker_from_to(from, to) "{{{ + +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 . ' ' @@ -1238,9 +1402,10 @@ function! s:clone_marker_from_to(from, to) "{{{ 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 "}}} +endfunction -function! s:remove_mrkr(item) "{{{ + +function! s:remove_mrkr(item) let item = a:item if item.cb != '' let item = s:remove_cb(item) @@ -1254,9 +1419,10 @@ function! s:remove_mrkr(item) "{{{ let item.type = 0 call s:update_state(parent_item) return item -endfunction "}}} +endfunction -function! s:create_marker(lnum) "{{{ + +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('.')) @@ -1268,12 +1434,14 @@ function! s:create_marker(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 "}}} +endfunction -"change markers of list items }}} -"handle keys {{{ -function! vimwiki#lst#kbd_o() "{{{ +" --------------------------------------------------------- +" 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) @@ -1286,9 +1454,10 @@ function! vimwiki#lst#kbd_o() "{{{ call s:clone_marker_from_to(cur_item.lnum, cur_item.lnum+1) endif startinsert! -endfunction "}}} +endfunction -function! vimwiki#lst#kbd_O() "{{{ + +function! vimwiki#lst#kbd_O() normal! Ox let cur_ln = line('.') if getline(cur_ln+1) !~# '^\s*$' @@ -1297,9 +1466,10 @@ function! vimwiki#lst#kbd_O() "{{{ call s:clone_marker_from_to(cur_ln-1, cur_ln) endif startinsert! -endfunction "}}} +endfunction -function! s:cr_on_empty_list_item(lnum, behavior) "{{{ + +function! s:cr_on_empty_list_item(lnum, behavior) if a:behavior == 1 "just make a new list item normal! gi  @@ -1353,18 +1523,20 @@ function! s:cr_on_empty_list_item(lnum, behavior) "{{{ endif return endif -endfunction "}}} +endfunction -function! s:cr_on_empty_line(lnum, behavior) "{{{ + +function! s:cr_on_empty_line(lnum, behavior) "inserting and deleting the x is necessary "because otherwise the indent is lost normal! gi x if a:behavior == 2 || a:behavior == 3 call s:create_marker(a:lnum+1) endif -endfunction "}}} +endfunction -function! s:cr_on_list_item(lnum, insert_new_marker, not_at_eol) "{{{ + +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 normal! gi  @@ -1380,9 +1552,10 @@ function! s:cr_on_list_item(lnum, insert_new_marker, not_at_eol) "{{{ 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 "}}} +endfunction -function! vimwiki#lst#kbd_cr(normal, just_mrkr) "{{{ + +function! vimwiki#lst#kbd_cr(normal, just_mrkr) let lnum = line('.') let has_bp = s:line_has_marker(lnum) @@ -1428,10 +1601,11 @@ function! vimwiki#lst#kbd_cr(normal, just_mrkr) "{{{ startinsert endif -endfunction "}}} +endfunction + "creates a list item in the current line or removes it -function! vimwiki#lst#toggle_list_item() "{{{ +function! vimwiki#lst#toggle_list_item() let cur_col_from_eol = col("$") - col("'^") let cur_item = s:get_item(line('.')) @@ -1460,12 +1634,14 @@ function! vimwiki#lst#toggle_list_item() "{{{ else startinsert endif -endfunction "}}} +endfunction -"handle keys }}} -"misc stuff {{{ -function! vimwiki#lst#TO_list_item(inner, visual) "{{{ +" --------------------------------------------------------- +" misc stuff +" --------------------------------------------------------- + +function! vimwiki#lst#TO_list_item(inner, visual) let lnum = prevnonblank('.') let item = s:get_corresponding_item(lnum) if item.type == 0 @@ -1481,9 +1657,10 @@ function! vimwiki#lst#TO_list_item(inner, visual) "{{{ call cursor(to_line, 0) normal! o call cursor(from_line, 0) -endfunction "}}} +endfunction -fun! vimwiki#lst#fold_level(lnum) "{{{ + +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) @@ -1496,6 +1673,5 @@ fun! vimwiki#lst#fold_level(lnum) "{{{ endif endif return '=' -endf "}}} +endfunction -"misc stuff }}} diff --git a/autoload/vimwiki/markdown_base.vim b/autoload/vimwiki/markdown_base.vim index a207f53..f1ce091 100644 --- a/autoload/vimwiki/markdown_base.vim +++ b/autoload/vimwiki/markdown_base.vim @@ -1,13 +1,17 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: Link functions for markdown syntax +" Description: Link functions for markdown syntax " Home: https://github.com/vimwiki/vimwiki/ -" MISC helper functions {{{ +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 -" vimwiki#markdown_base#scan_reflinks -function! vimwiki#markdown_base#scan_reflinks() " {{{ + +function! vimwiki#markdown_base#scan_reflinks() let mkd_refs = {} " construct list of references using vimgrep try @@ -16,7 +20,7 @@ function! vimwiki#markdown_base#scan_reflinks() " {{{ 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')) @@ -27,12 +31,11 @@ function! vimwiki#markdown_base#scan_reflinks() " {{{ endfor call vimwiki#vars#set_bufferlocal('markdown_refs', mkd_refs) return mkd_refs -endfunction "}}} +endfunction -" vimwiki#markdown_base#open_reflink " try markdown reference links -function! vimwiki#markdown_base#open_reflink(link) " {{{ +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') @@ -43,70 +46,10 @@ function! vimwiki#markdown_base#open_reflink(link) " {{{ else return 0 endif -endfunction " }}} -" }}} +endfunction -" WIKI link following functions {{{ -" vimwiki#markdown_base#follow_link -function! vimwiki#markdown_base#follow_link(split, ...) "{{{ Parse link at cursor and pass - " to VimwikiLinkHandler, or failing that, the default open_link handler - " echom "markdown_base#follow_link" - - if 0 - " Syntax-specific links - " XXX: @Stuart: do we still need it? - " XXX: @Maxim: most likely! I am still working on a seemless way to - " integrate regexp's without complicating syntax/vimwiki.vim - else - if a:split ==# "split" - let cmd = ":split " - elseif a:split ==# "vsplit" - let cmd = ":vsplit " - elseif a:split ==# "tabnew" - let cmd = ":tabnew " - else - let cmd = ":e " - endif - - " try WikiLink - let lnk = matchstr(vimwiki#base#matchstr_at_cursor(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 != "" - if !VimwikiLinkHandler(lnk) - if !vimwiki#markdown_base#open_reflink(lnk) - " remove the extension from the filename if exists - let lnk = substitute(lnk, vimwiki#vars#get_wikilocal('ext').'$', '', '') - call vimwiki#base#open_link(cmd, lnk) - endif - endif - return - endif - - if a:0 > 0 - execute "normal! ".a:1 - else - call vimwiki#base#normalize_link(0) - endif - endif - -endfunction " }}} - -" LINK functions {{{ - -" s:normalize_link_syntax_n -function! s:normalize_link_syntax_n() " {{{ +function! s:normalize_link_syntax_n() let lnum = line('.') " try WikiIncl @@ -120,27 +63,30 @@ function! s:normalize_link_syntax_n() " {{{ 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('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_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('rxWeblinkMatchUrl'), + \ vimwiki#vars#get_syntaxlocal('rxWeblinkMatchDescr'), \ vimwiki#vars#get_syntaxlocal('Weblink1Template')) call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'), sub) return @@ -158,10 +104,10 @@ function! s:normalize_link_syntax_n() " {{{ return endif -endfunction " }}} +endfunction -" s:normalize_link_syntax_v -function! s:normalize_link_syntax_v() " {{{ + +function! s:normalize_link_syntax_v() let lnum = line('.') let sel_save = &selection let &selection = "old" @@ -172,38 +118,33 @@ function! s:normalize_link_syntax_v() " {{{ try norm! gvy let visual_selection = @" - let link = substitute(vimwiki#vars#get_syntaxlocal('Weblink1Template'), '__LinkUrl__', '\='."'".visual_selection."'", '') - let link = substitute(link, '__LinkDescription__', '\='."'".visual_selection."'", '') + let link = s:safesubstitute(vimwiki#vars#get_syntaxlocal('Weblink1Template'), + \ '__LinkUrl__', visual_selection, '') + let link = s:safesubstitute(link, '__LinkDescription__', visual_selection, '') - call setreg('"', link, 'v') + call setreg('"', substitute(link, '\n', '', ''), visualmode()) " paste result - norm! `>pgvd + norm! `>""pgvd finally call setreg('"', rv, rt) let &selection = sel_save endtry -endfunction " }}} +endfunction -" vimwiki#base#normalize_link -function! vimwiki#markdown_base#normalize_link(is_visual_mode) "{{{ + +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 visualmode() ==# 'v' && line("'<") == line("'>") - " action undefined for 'line-wise' or 'multi-line' visual mode selections + elseif line("'<") == line("'>") + " action undefined for multi-line visual mode selections call s:normalize_link_syntax_v() endif endif -endfunction "}}} - -" }}} - -" ------------------------------------------------------------------------- -" Load syntax-specific Wiki functionality -" ------------------------------------------------------------------------- +endfunction diff --git a/autoload/vimwiki/path.vim b/autoload/vimwiki/path.vim index e12c048..4db1329 100644 --- a/autoload/vimwiki/path.vim +++ b/autoload/vimwiki/path.vim @@ -1,15 +1,15 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: Path manipulation functions +" Description: Path manipulation functions " Home: https://github.com/vimwiki/vimwiki/ -function! vimwiki#path#chomp_slash(str) "{{{ +function! vimwiki#path#chomp_slash(str) return substitute(a:str, '[/\\]\+$', '', '') -endfunction "}}} +endfunction + " Define path-compare function, either case-sensitive or not, depending on OS. -"{{{ " function! vimwiki#path#is_equal(p1, p2) if vimwiki#u#is_windows() function! vimwiki#path#is_equal(p1, p2) return a:p1 ==? a:p2 @@ -18,10 +18,11 @@ else function! vimwiki#path#is_equal(p1, p2) return a:p1 ==# a:p2 endfunction -endif "}}} +endif + " collapse sections like /a/b/../c to /a/c -function! vimwiki#path#normalize(path) "{{{ +function! vimwiki#path#normalize(path) let path = a:path while 1 let result = substitute(path, '/[^/]\+/\.\.', '', '') @@ -31,9 +32,10 @@ function! vimwiki#path#normalize(path) "{{{ let path = result endwhile return result -endfunction "}}} +endfunction -function! vimwiki#path#path_norm(path) "{{{ + +function! vimwiki#path#path_norm(path) " /-slashes if a:path !~# '^scp:' let path = substitute(a:path, '\', '/', 'g') @@ -44,21 +46,24 @@ function! vimwiki#path#path_norm(path) "{{{ else return a:path endif -endfunction "}}} +endfunction -function! vimwiki#path#is_link_to_dir(link) "{{{ + +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 "}}} +endfunction -function! vimwiki#path#abs_path_of_link(link) "{{{ + +function! vimwiki#path#abs_path_of_link(link) return vimwiki#path#normalize(expand("%:p:h").'/'.a:link) -endfunction "}}} +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) "{{{ +function! vimwiki#path#path_common_pfx(path1, path2) let p1 = split(a:path1, '[/\\]', 1) let p2 = split(a:path2, '[/\\]', 1) @@ -72,19 +77,26 @@ function! vimwiki#path#path_common_pfx(path1, path2) "{{{ else return join(p1[: idx-1], '/') endif -endfunction "}}} +endfunction -function! vimwiki#path#wikify_path(path) "{{{ - let result = resolve(expand(a:path, ':p')) + +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 "}}} +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) "{{{ +function! vimwiki#path#relpath(dir, file) let result = [] let dir = split(a:dir, '/') let file = split(a:file, '/') @@ -106,12 +118,13 @@ function! vimwiki#path#relpath(dir, file) "{{{ let result_path .= '/' endif return result_path -endfunction "}}} +endfunction + " If the optional argument provided and nonzero, -" it will ask before creating a directory +" it will ask before creating a directory " Returns: 1 iff directory exists or successfully created -function! vimwiki#path#mkdir(dir_obj, ...) "{{{ +function! vimwiki#path#mkdir(dir_obj, ...) if a:dir_obj.protocoll ==# 'scp' " we can not do much, so let's pretend everything is ok @@ -130,23 +143,23 @@ function! vimwiki#path#mkdir(dir_obj, ...) "{{{ 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' + 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 " }}} +endfunction -function! vimwiki#path#is_absolute(path) "{{{ + +function! vimwiki#path#is_absolute(path) if vimwiki#u#is_windows() return a:path =~? '\m^\a:' else return a:path =~# '\m^/\|\~/' endif -endfunction "}}} +endfunction " Combine a directory and a file into one path, doesn't generate duplicate diff --git a/autoload/vimwiki/style.css b/autoload/vimwiki/style.css index da2518c..431d15b 100644 --- a/autoload/vimwiki/style.css +++ b/autoload/vimwiki/style.css @@ -27,6 +27,13 @@ del {text-decoration: line-through; color: #777777;} .tag {background-color: #eeeeee; font-family: monospace; padding: 2px;} /* 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==); diff --git a/autoload/vimwiki/tags.vim b/autoload/vimwiki/tags.vim index 0a76019..d5b7d25 100644 --- a/autoload/vimwiki/tags.vim +++ b/autoload/vimwiki/tags.vim @@ -1,9 +1,11 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" 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':... } @@ -19,12 +21,13 @@ let s:TAGS_METADATA_FILE_NAME = '.tags' " an optional field, "vimwiki:". In this field, we encode tab-separated values " of missing parameters -- "pagename" and "link". -" vimwiki#tags#update_tags + + " 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) "{{{ +function! vimwiki#tags#update_tags(full_rebuild, all_files) let all_files = a:all_files != '' if !a:full_rebuild " Updating for one page (current) @@ -54,7 +57,8 @@ function! vimwiki#tags#update_tags(full_rebuild, all_files) "{{{ endfor call s:write_tags_metadata(metadata) endif -endfunction " }}} +endfunction + function! s:page_name(file_obj) let wiki_base_dir = vimwiki#vars#get_wikilocal('path') @@ -62,10 +66,9 @@ function! s:page_name(file_obj) return vimwiki#path#to_string(segment) endfunction -" s:scan_tags -" Scans the list of text lines (argument) and produces tags metadata as a -" list of tag entries. -function! s:scan_tags(lines, page_name) "{{{ + +" 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 = [] @@ -140,17 +143,18 @@ function! s:scan_tags(lines, page_name) "{{{ endfor " loop over lines return entries -endfunction " }}} +endfunction + + +" Returns tags metadata file path +function! vimwiki#tags#metadata_file_path() abort + return vimwiki#path#join(vimwiki#vars#get_wikilocal('path'), + \ vimwiki#path#file_segment(s:TAGS_METADATA_FILE_NAME)) +endfunction -" vimwiki#tags#metadata_file_path -" Returns tags metadata file path object -function! vimwiki#tags#metadata_file_path() abort "{{{ - return vimwiki#path#join(vimwiki#vars#get_wikilocal('path'), vimwiki#path#file_segment(s:TAGS_METADATA_FILE_NAME)) -endfunction " }}} -" s:load_tags_metadata " Loads tags metadata from file, returns a dictionary -function! s:load_tags_metadata() abort "{{{ +function! s:load_tags_metadata() abort let metadata_path = vimwiki#tags#metadata_file_path() if !filereadable(metadata_path) return {} @@ -197,29 +201,29 @@ function! s:load_tags_metadata() abort "{{{ endif endfor return metadata -endfunction " }}} +endfunction + -" s:remove_page_from_tags " 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) "{{{ +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 " }}} +endfunction + -" s:merge_tags " Merges metadata of one file into a:metadata -function! s:merge_tags(metadata, pagename, file_metadata) "{{{ +function! s:merge_tags(metadata, pagename, file_metadata) let metadata = a:metadata let metadata[a:pagename] = a:file_metadata return metadata -endfunction " }}} +endfunction + -" s:tags_entry_cmp " 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 @@ -229,7 +233,7 @@ endfunction " }}} " 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) "{{{ +function! s:tags_entry_cmp(i1, i2) let items = [] for orig_item in [a:i1, a:i2] let fields = split(orig_item, "\t") @@ -249,11 +253,11 @@ function! s:tags_entry_cmp(i1, i2) "{{{ else return 0 endif -endfunction " }}} +endfunction + -" s:write_tags_metadata " Saves metadata object into a file. Throws exceptions in case of problems. -function! s:write_tags_metadata(metadata) "{{{ +function! s:write_tags_metadata(metadata) let metadata_path = vimwiki#tags#metadata_file_path() let tags = [] for pagename in keys(a:metadata) @@ -275,11 +279,11 @@ function! s:write_tags_metadata(metadata) "{{{ call sort(tags, "s:tags_entry_cmp") call insert(tags, "!_TAG_FILE_SORTED\t1\t") call writefile(tags, metadata_path) -endfunction " }}} +endfunction + -" vimwiki#tags#get_tags " Returns list of unique tags found in the .tags file -function! vimwiki#tags#get_tags() "{{{ +function! vimwiki#tags#get_tags() let metadata = s:load_tags_metadata() let tags = {} for entries in values(metadata) @@ -288,13 +292,13 @@ function! vimwiki#tags#get_tags() "{{{ endfor endfor return keys(tags) -endfunction " }}} +endfunction + -" vimwiki#tags#generate_tags " 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 "{{{ +function! vimwiki#tags#generate_tags(...) abort let need_all_tags = (a:0 == 0) let specific_tags = a:000 @@ -313,8 +317,7 @@ function! vimwiki#tags#generate_tags(...) abort "{{{ endfor let lines = [] - let bullet = repeat(' ', vimwiki#lst#get_list_margin()). - \ vimwiki#lst#default_symbol().' ' + 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, [ @@ -322,8 +325,8 @@ function! vimwiki#tags#generate_tags(...) abort "{{{ \ 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, '')) + call add(lines, bullet . substitute(vimwiki#vars#get_global('WikiLinkTemplate1'), + \ '__LinkUrl__', taglink, '')) endfor endif endfor @@ -332,15 +335,14 @@ function! vimwiki#tags#generate_tags(...) abort "{{{ \ .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 " }}} + call vimwiki#base#update_listing_in_buffer(lines, 'Generated Tags', links_rx, line('$')+1, 1) +endfunction -" vimwiki#tags#complete_tags -function! vimwiki#tags#complete_tags(ArgLead, CmdLine, CursorPos) abort " {{{ + +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 " }}} +endfunction diff --git a/autoload/vimwiki/tbl.vim b/autoload/vimwiki/tbl.vim index d9c7134..1c049ce 100644 --- a/autoload/vimwiki/tbl.vim +++ b/autoload/vimwiki/tbl.vim @@ -1,28 +1,29 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: Tables +" Description: Tables " | Easily | manageable | text | tables | ! | " |--------|------------|-------|--------|---------| " | Have | fun! | Drink | tea | Period. | " " Home: https://github.com/vimwiki/vimwiki/ -" Load only once {{{ + + if exists("g:loaded_vimwiki_tbl_auto") || &cp finish endif let g:loaded_vimwiki_tbl_auto = 1 -"}}} + let s:textwidth = &tw -" Misc functions {{{ -function! s:rxSep() "{{{ +function! s:rxSep() return vimwiki#vars#get_syntaxlocal('rxTableSep') -endfunction "}}} +endfunction -function! s:wide_len(str) "{{{ + +function! s:wide_len(str) " vim73 has new function that gives correct string width. if exists("*strdisplaywidth") return strdisplaywidth(a:str) @@ -42,42 +43,49 @@ function! s:wide_len(str) "{{{ let &modified = savemodified endif return ret -endfunction "}}} +endfunction -function! s:cell_splitter() "{{{ + +function! s:cell_splitter() return '\s*'.s:rxSep().'\s*' -endfunction "}}} +endfunction -function! s:sep_splitter() "{{{ + +function! s:sep_splitter() return '-'.s:rxSep().'-' -endfunction "}}} +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) "{{{ +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 "}}} +endfunction -function! s:is_separator_tail(line) "{{{ + +function! s:is_separator_tail(line) return a:line =~# '^\{-1}\%(\s*\|-*\)\%('.s:rxSep().'-\+\)\+'.s:rxSep().'\s*$' -endfunction "}}} +endfunction -function! s:is_last_column(lnum, cnum) "{{{ + +function! s:is_last_column(lnum, cnum) let line = strpart(getline(a:lnum), a:cnum - 1) - "echomsg "DEBUG is_last_column> ".(line =~# s:rxSep().'\s*$' && line !~# s:rxSep().'.*'.s:rxSep().'\s*$') return line =~# s:rxSep().'\s*$' && line !~# s:rxSep().'.*'.s:rxSep().'\s*$' - -endfunction "}}} +endfunction -function! s:is_first_column(lnum, cnum) "{{{ + +function! s:is_first_column(lnum, cnum) let line = strpart(getline(a:lnum), 0, a:cnum - 1) - "echomsg "DEBUG is_first_column> ".(line =~# '^\s*'.s:rxSep() && line !~# '^\s*'.s:rxSep().'.*'.s:rxSep()) - return line =~# '^\s*$' || (line =~# '^\s*'.s:rxSep() && line !~# '^\s*'.s:rxSep().'.*'.s:rxSep()) -endfunction "}}} + return line =~# '^\s*$' || + \ (line =~# '^\s*'.s:rxSep() && line !~# '^\s*'.s:rxSep().'.*'.s:rxSep()) +endfunction -function! s:count_separators_up(lnum) "{{{ + +function! s:count_separators_up(lnum) let lnum = a:lnum - 1 while lnum > 1 if !s:is_separator(getline(lnum)) @@ -87,9 +95,10 @@ function! s:count_separators_up(lnum) "{{{ endwhile return (a:lnum-lnum) -endfunction "}}} +endfunction -function! s:count_separators_down(lnum) "{{{ + +function! s:count_separators_down(lnum) let lnum = a:lnum + 1 while lnum < line('$') if !s:is_separator(getline(lnum)) @@ -99,9 +108,10 @@ function! s:count_separators_down(lnum) "{{{ endwhile return (lnum-a:lnum) -endfunction "}}} +endfunction -function! s:create_empty_row(cols) "{{{ + +function! s:create_empty_row(cols) let row = s:rxSep() let cell = " ".s:rxSep() @@ -110,9 +120,10 @@ function! s:create_empty_row(cols) "{{{ endfor return row -endfunction "}}} +endfunction -function! s:create_row_sep(cols) "{{{ + +function! s:create_row_sep(cols) let row = s:rxSep() let cell = "---".s:rxSep() @@ -121,9 +132,10 @@ function! s:create_row_sep(cols) "{{{ endfor return row -endfunction "}}} +endfunction -function! vimwiki#tbl#get_cells(line) "{{{ + +function! vimwiki#tbl#get_cells(line) let result = [] let cell = '' let quote = '' @@ -174,13 +186,15 @@ function! vimwiki#tbl#get_cells(line) "{{{ call add(result, vimwiki#u#trim(cell.quote, '|')) endif return result -endfunction "}}} +endfunction -function! s:col_count(lnum) "{{{ + +function! s:col_count(lnum) return len(vimwiki#tbl#get_cells(getline(a:lnum))) -endfunction "}}} +endfunction -function! s:get_indent(lnum) "{{{ + +function! s:get_indent(lnum) if !s:is_table(getline(a:lnum)) return endif @@ -198,9 +212,10 @@ function! s:get_indent(lnum) "{{{ endwhile return indent -endfunction " }}} +endfunction -function! s:get_rows(lnum) "{{{ + +function! s:get_rows(lnum) if !s:is_table(getline(a:lnum)) return endif @@ -232,9 +247,10 @@ function! s:get_rows(lnum) "{{{ endwhile return upper_rows + lower_rows -endfunction "}}} +endfunction -function! s:get_cell_max_lens(lnum, ...) "{{{ + +function! s:get_cell_max_lens(lnum, ...) let max_lens = {} for [lnum, row] in s:get_rows(a:lnum) if s:is_separator(row) @@ -251,9 +267,10 @@ function! s:get_cell_max_lens(lnum, ...) "{{{ endfor endfor return max_lens -endfunction "}}} +endfunction -function! s:get_aligned_rows(lnum, col1, col2) "{{{ + +function! s:get_aligned_rows(lnum, col1, col2) let rows = s:get_rows(a:lnum) let startlnum = rows[0][0] let cells = [] @@ -271,10 +288,11 @@ function! s:get_aligned_rows(lnum, col1, col2) "{{{ call add(result, [lnum, new_row]) endfor return result -endfunction "}}} +endfunction + " Number of the current column. Starts from 0. -function! s:cur_column() "{{{ +function! s:cur_column() let line = getline('.') if !s:is_table(line) return -1 @@ -291,12 +309,10 @@ function! s:cur_column() "{{{ endif endwhile return col -endfunction "}}} +endfunction -" }}} -" Format functions {{{ -function! s:fmt_cell(cell, max_len) "{{{ +function! s:fmt_cell(cell, max_len) let cell = ' '.a:cell.' ' let diff = a:max_len - s:wide_len(a:cell) @@ -306,9 +322,10 @@ function! s:fmt_cell(cell, max_len) "{{{ let cell .= repeat(' ', diff) return cell -endfunction "}}} +endfunction -function! s:fmt_row(cells, max_lens, col1, col2) "{{{ + +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 @@ -326,17 +343,19 @@ function! s:fmt_row(cells, max_lens, col1, col2) "{{{ let idx += 1 endwhile return new_line -endfunction "}}} +endfunction -function! s:fmt_cell_sep(max_len) "{{{ + +function! s:fmt_cell_sep(max_len) if a:max_len == 0 return repeat('-', 3) else return repeat('-', a:max_len+2) endif -endfunction "}}} +endfunction -function! s:fmt_sep(max_lens, col1, col2) "{{{ + +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 @@ -347,11 +366,10 @@ function! s:fmt_sep(max_lens, col1, col2) "{{{ let new_line .= s:fmt_cell_sep(a:max_lens[idx]).s:rxSep() endfor return new_line -endfunction "}}} -"}}} +endfunction -" Keyboard functions "{{{ -function! s:kbd_create_new_row(cols, goto_first) "{{{ + +function! s:kbd_create_new_row(cols, goto_first) let cmd = "\o".s:create_empty_row(a:cols) let cmd .= "\:call vimwiki#tbl#format(line('.'))\" let cmd .= "\0" @@ -364,26 +382,29 @@ function! s:kbd_create_new_row(cols, goto_first) "{{{ let cmd .= "a" return cmd -endfunction "}}} +endfunction -function! s:kbd_goto_next_row() "{{{ + +function! s:kbd_goto_next_row() let cmd = "\j" let cmd .= ":call search('.\\(".s:rxSep()."\\)', 'c', line('.'))\" let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\" let cmd .= "a" return cmd -endfunction "}}} +endfunction -function! s:kbd_goto_prev_row() "{{{ + +function! s:kbd_goto_prev_row() let cmd = "\k" let cmd .= ":call search('.\\(".s:rxSep()."\\)', 'c', line('.'))\" let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\" let cmd .= "a" return cmd -endfunction "}}} +endfunction + " Used in s:kbd_goto_next_col -function! vimwiki#tbl#goto_next_col() "{{{ +function! vimwiki#tbl#goto_next_col() let curcol = virtcol('.') let lnum = line('.') let newcol = s:get_indent(lnum) @@ -396,9 +417,10 @@ function! vimwiki#tbl#goto_next_col() "{{{ endfor let newcol += 2 " +2 == 1 separator + 1 space | ".cmd return cmd -endfunction "}}} +endfunction -"}}} -" Global functions {{{ -function! vimwiki#tbl#kbd_cr() "{{{ +function! vimwiki#tbl#kbd_cr() let lnum = line('.') if !s:is_table(getline(lnum)) return "" @@ -459,9 +481,10 @@ function! vimwiki#tbl#kbd_cr() "{{{ else return s:kbd_goto_next_row() endif -endfunction "}}} +endfunction -function! vimwiki#tbl#kbd_tab() "{{{ + +function! vimwiki#tbl#kbd_tab() let lnum = line('.') if !s:is_table(getline(lnum)) return "\" @@ -475,9 +498,10 @@ function! vimwiki#tbl#kbd_tab() "{{{ return s:kbd_create_new_row(cols, 1) endif return s:kbd_goto_next_col(is_sep || last) -endfunction "}}} +endfunction -function! vimwiki#tbl#kbd_shift_tab() "{{{ + +function! vimwiki#tbl#kbd_shift_tab() let lnum = line('.') if !s:is_table(getline(lnum)) return "\" @@ -490,9 +514,10 @@ function! vimwiki#tbl#kbd_shift_tab() "{{{ return "" endif return s:kbd_goto_prev_col(is_sep || first) -endfunction "}}} +endfunction -function! vimwiki#tbl#format(lnum, ...) "{{{ + +function! vimwiki#tbl#format(lnum, ...) if !(&filetype ==? 'vimwiki') return endif @@ -520,11 +545,12 @@ function! vimwiki#tbl#format(lnum, ...) "{{{ let row = indentstring.row call setline(lnum, row) endfor - - let &tw = s:textwidth -endfunction "}}} -function! vimwiki#tbl#create(...) "{{{ + let &tw = s:textwidth +endfunction + + +function! vimwiki#tbl#create(...) if a:0 > 1 let cols = a:1 let rows = a:2 @@ -555,19 +581,21 @@ function! vimwiki#tbl#create(...) "{{{ for r in range(rows - 1) call add(lines, row) endfor - - call append(line('.'), lines) -endfunction "}}} -function! vimwiki#tbl#align_or_cmd(cmd) "{{{ + 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 "}}} +endfunction -function! vimwiki#tbl#reset_tw(lnum) "{{{ + +function! vimwiki#tbl#reset_tw(lnum) if !(&filetype ==? 'vimwiki') return endif @@ -575,14 +603,14 @@ function! vimwiki#tbl#reset_tw(lnum) "{{{ if !s:is_table(line) return endif - + let s:textwidth = &tw let &tw = 0 -endfunction "}}} +endfunction -" TODO: move_column_left and move_column_right are good candidates to be -" refactored. -function! vimwiki#tbl#move_column_left() "{{{ + +" 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: " @@ -598,7 +626,7 @@ function! vimwiki#tbl#move_column_left() "{{{ endif if cur_col > 0 - call vimwiki#tbl#format(line('.'), cur_col-1, cur_col) + call vimwiki#tbl#format(line('.'), cur_col-1, cur_col) call cursor(line('.'), 1) let sep = '\('.s:rxSep().'\).\zs' @@ -608,16 +636,16 @@ function! vimwiki#tbl#move_column_left() "{{{ let mpos = match(line, sep, mpos+1) if mpos != -1 let col += 1 - else + else break endif endwhile endif +endfunction -endfunction "}}} -function! vimwiki#tbl#move_column_right() "{{{ +function! vimwiki#tbl#move_column_right() let line = getline('.') @@ -631,7 +659,7 @@ function! vimwiki#tbl#move_column_right() "{{{ endif if cur_col < s:col_count(line('.'))-1 - call vimwiki#tbl#format(line('.'), cur_col, cur_col+1) + call vimwiki#tbl#format(line('.'), cur_col, cur_col+1) call cursor(line('.'), 1) let sep = '\('.s:rxSep().'\).\zs' @@ -641,33 +669,35 @@ function! vimwiki#tbl#move_column_right() "{{{ let mpos = match(line, sep, mpos+1) if mpos != -1 let col += 1 - else + else break endif endwhile - endif +endfunction -endfunction "}}} -function! vimwiki#tbl#get_rows(lnum) "{{{ +function! vimwiki#tbl#get_rows(lnum) return s:get_rows(a:lnum) -endfunction "}}} +endfunction -function! vimwiki#tbl#is_table(line) "{{{ + +function! vimwiki#tbl#is_table(line) return s:is_table(a:line) -endfunction "}}} +endfunction -function! vimwiki#tbl#is_separator(line) "{{{ + +function! vimwiki#tbl#is_separator(line) return s:is_separator(a:line) -endfunction "}}} +endfunction -function! vimwiki#tbl#cell_splitter() "{{{ + +function! vimwiki#tbl#cell_splitter() return s:cell_splitter() -endfunction "}}} +endfunction -function! vimwiki#tbl#sep_splitter() "{{{ + +function! vimwiki#tbl#sep_splitter() return s:sep_splitter() -endfunction "}}} +endfunction -"}}} diff --git a/autoload/vimwiki/u.vim b/autoload/vimwiki/u.vim index bf779ce..67af611 100644 --- a/autoload/vimwiki/u.vim +++ b/autoload/vimwiki/u.vim @@ -1,9 +1,9 @@ -" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: Utility functions +" Description: Utility functions " Home: https://github.com/vimwiki/vimwiki/ -function! vimwiki#u#trim(string, ...) "{{{ +function! vimwiki#u#trim(string, ...) let chars = '' if a:0 > 0 let chars = a:1 @@ -11,17 +11,20 @@ function! vimwiki#u#trim(string, ...) "{{{ let res = substitute(a:string, '^[[:space:]'.chars.']\+', '', '') let res = substitute(res, '[[:space:]'.chars.']\+$', '', '') return res -endfunction "}}} +endfunction + " Builtin cursor doesn't work right with unicode characters. -function! vimwiki#u#cursor(lnum, cnum) "{{{ +function! vimwiki#u#cursor(lnum, cnum) exe a:lnum exe 'normal! 0'.a:cnum.'|' -endfunction "}}} +endfunction -function! vimwiki#u#is_windows() "{{{ + +function! vimwiki#u#is_windows() return has("win32") || has("win64") || has("win95") || has("win16") -endfunction "}}} +endfunction + function! vimwiki#u#is_macos() if has("mac") || has("macunix") || has("gui_mac") @@ -32,27 +35,32 @@ function! vimwiki#u#is_macos() return os == 'Darwin' || os == 'Mac' endfunction -function! vimwiki#u#count_first_sym(line) "{{{ + +function! vimwiki#u#count_first_sym(line) let first_sym = matchstr(a:line, '\S') return len(matchstr(a:line, first_sym.'\+')) -endfunction "}}} +endfunction -function! vimwiki#u#escape(string) "{{{ + +function! vimwiki#u#escape(string) return escape(a:string, '~.*[]\^$') -endfunction "}}} +endfunction + " Load concrete Wiki syntax: sets regexes and templates for headers and links -function vimwiki#u#reload_regexes() "{{{ +function vimwiki#u#reload_regexes() execute 'runtime! syntax/vimwiki_'.vimwiki#vars#get_wikilocal('syntax').'.vim' -endfunction "}}} +endfunction + " Load syntax-specific functionality -function vimwiki#u#reload_regexes_custom() "{{{ +function vimwiki#u#reload_regexes_custom() execute 'runtime! syntax/vimwiki_'.vimwiki#vars#get_wikilocal('syntax').'_custom.vim' -endfunction "}}} +endfunction + " Backward compatible version of the built-in function shiftwidth() -if exists('*shiftwidth') "{{{ +if exists('*shiftwidth') func vimwiki#u#sw() return shiftwidth() endfunc @@ -60,7 +68,7 @@ else func vimwiki#u#sw() return &sw endfunc -endif "}}} +endif function vimwiki#u#error(message) diff --git a/autoload/vimwiki/vars.vim b/autoload/vimwiki/vars.vim index c91395c..455695e 100644 --- a/autoload/vimwiki/vars.vim +++ b/autoload/vimwiki/vars.vim @@ -1,12 +1,33 @@ " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 " Vimwiki autoload plugin file -" Desc: stuff concerning Vimwiki's state " Home: https://github.com/vimwiki/vimwiki/ -" copy the user's settings from variables of the form g:vimwiki_