From 8625978e9955c43a8135751a21da262b0e0d8af4 Mon Sep 17 00:00:00 2001 From: Hugues Hiegel Date: Tue, 23 Dec 2014 17:00:28 +0100 Subject: [plugins] VimWiki + Todo Power --- plugin/vimwiki.vim | 564 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 564 insertions(+) create mode 100644 plugin/vimwiki.vim (limited to 'plugin') diff --git a/plugin/vimwiki.vim b/plugin/vimwiki.vim new file mode 100644 index 0000000..aec7f5a --- /dev/null +++ b/plugin/vimwiki.vim @@ -0,0 +1,564 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" Vimwiki plugin file +" Author: Maxim Kim +" Home: http://code.google.com/p/vimwiki/ +" GetLatestVimScripts: 2226 1 :AutoInstall: vimwiki + +if exists("loaded_vimwiki") || &cp + finish +endif +let loaded_vimwiki = 1 + +let s:old_cpo = &cpo +set cpo&vim + +" Logging and performance instrumentation "{{{ +let g:VimwikiLog = {} +let g:VimwikiLog.path = 0 " # of calls to VimwikiGet with path or path_html +let g:VimwikiLog.path_html = 0 " # of calls to path_html() +let g:VimwikiLog.normalize_path = 0 " # of calls to normalize_path() +let g:VimwikiLog.subdir = 0 " # of calls to vimwiki#base#subdir() +let g:VimwikiLog.timing = [] " various timing measurements +let g:VimwikiLog.html = [] " html conversion timing +function! VimwikiLog_extend(what,...) "{{{ + call extend(g:VimwikiLog[a:what],a:000) +endfunction "}}} +"}}} + +" HELPER functions {{{ +function! s:default(varname, value) "{{{ + if !exists('g:vimwiki_'.a:varname) + let g:vimwiki_{a:varname} = a:value + endif +endfunction "}}} + +function! s:find_wiki(path) "{{{ + " XXX: find_wiki() does not (yet) take into consideration the ext + let path = vimwiki#u#path_norm(vimwiki#u#chomp_slash(a:path)) + let idx = 0 + while idx < len(g:vimwiki_list) + let idx_path = expand(VimwikiGet('path', idx)) + let idx_path = vimwiki#u#path_norm(vimwiki#u#chomp_slash(idx_path)) + if vimwiki#u#path_common_pfx(idx_path, path) == idx_path + return idx + endif + let idx += 1 + endwhile + return -1 + " an orphan page has been detected +endfunction "}}} + + +function! s:vimwiki_idx() " {{{ + if exists('b:vimwiki_idx') + return b:vimwiki_idx + else + return -1 + endif +endfunction " }}} + +function! s:setup_buffer_leave() "{{{ + if g:vimwiki_debug ==3 + echom "Setup_buffer_leave g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + if &filetype == 'vimwiki' + " cache global vars of current state XXX: SLOW!? + call vimwiki#base#cache_buffer_state() + endif + if g:vimwiki_debug ==3 + echom " Setup_buffer_leave g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + + let &autowriteall = s:vimwiki_autowriteall + + " Set up menu + if g:vimwiki_menu != "" + exe 'nmenu disable '.g:vimwiki_menu.'.Table' + endif +endfunction "}}} + +function! s:setup_filetype() "{{{ + if g:vimwiki_debug ==3 + echom "Setup_filetype g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + let time0 = reltime() " start the clock "XXX + " Find what wiki current buffer belongs to. + let path = expand('%:p:h') + " XXX: find_wiki() does not (yet) take into consideration the ext + let idx = s:find_wiki(path) + if g:vimwiki_debug ==3 + echom " Setup_filetype g:curr_idx=".g:vimwiki_current_idx." find_idx=".idx." b:curr_idx=".s:vimwiki_idx()."" + endif + + if idx == -1 && g:vimwiki_global_ext == 0 + return + endif + "XXX when idx = -1? (an orphan page has been detected) + + "TODO: refactor (same code in setup_buffer_enter) + " The buffer's file is not in the path and user *does* want his wiki + " extension(s) to be global -- Add new wiki. + if idx == -1 + let ext = '.'.expand('%:e') + " lookup syntax using g:vimwiki_ext2syntax + if has_key(g:vimwiki_ext2syntax, ext) + let syn = g:vimwiki_ext2syntax[ext] + else + let syn = s:vimwiki_defaults.syntax + endif + call add(g:vimwiki_list, {'path': path, 'ext': ext, 'syntax': syn, 'temp': 1}) + let idx = len(g:vimwiki_list) - 1 + endif + call vimwiki#base#validate_wiki_options(idx) + " initialize and cache global vars of current state + call vimwiki#base#setup_buffer_state(idx) + if g:vimwiki_debug ==3 + echom " Setup_filetype g:curr_idx=".g:vimwiki_current_idx." (reset_wiki_state) b:curr_idx=".s:vimwiki_idx()."" + endif + + unlet! b:vimwiki_fs_rescan + set filetype=vimwiki + if g:vimwiki_debug ==3 + echom " Setup_filetype g:curr_idx=".g:vimwiki_current_idx." (set ft=vimwiki) b:curr_idx=".s:vimwiki_idx()."" + endif + let time1 = vimwiki#u#time(time0) "XXX + call VimwikiLog_extend('timing',['plugin:setup_filetype:time1',time1]) +endfunction "}}} + +function! s:setup_buffer_enter() "{{{ + if g:vimwiki_debug ==3 + echom "Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + let time0 = reltime() " start the clock "XXX + if !vimwiki#base#recall_buffer_state() + " Find what wiki current buffer belongs to. + " If wiki does not exist in g:vimwiki_list -- add new wiki there with + " buffer's path and ext. + " Else set g:vimwiki_current_idx to that wiki index. + let path = expand('%:p:h') + " XXX: find_wiki() does not (yet) take into consideration the ext + let idx = s:find_wiki(path) + + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." find_idx=".idx." b:curr_idx=".s:vimwiki_idx()."" + endif + " The buffer's file is not in the path and user *does NOT* want his wiki + " extension to be global -- Do not add new wiki. + if idx == -1 && g:vimwiki_global_ext == 0 + return + endif + + "TODO: refactor (same code in setup_filetype) + " The buffer's file is not in the path and user *does* want his wiki + " extension(s) to be global -- Add new wiki. + if idx == -1 + let ext = '.'.expand('%:e') + " lookup syntax using g:vimwiki_ext2syntax + if has_key(g:vimwiki_ext2syntax, ext) + let syn = g:vimwiki_ext2syntax[ext] + else + let syn = s:vimwiki_defaults.syntax + endif + call add(g:vimwiki_list, {'path': path, 'ext': ext, 'syntax': syn, 'temp': 1}) + let idx = len(g:vimwiki_list) - 1 + endif + call vimwiki#base#validate_wiki_options(idx) + " initialize and cache global vars of current state + call vimwiki#base#setup_buffer_state(idx) + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." (reset_wiki_state) b:curr_idx=".s:vimwiki_idx()."" + endif + + endif + + " If you have + " au GUIEnter * VimwikiIndex + " Then change it to + " au GUIEnter * nested VimwikiIndex + if &filetype == '' + set filetype=vimwiki + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." (set ft vimwiki) b:curr_idx=".s:vimwiki_idx()."" + endif + elseif &syntax == 'vimwiki' + " to force a rescan of the filesystem which may have changed + " and update VimwikiLinks syntax group that depends on it; + " b:vimwiki_fs_rescan indicates that setup_filetype() has not been run + if exists("b:vimwiki_fs_rescan") && VimwikiGet('maxhi') + set syntax=vimwiki + if g:vimwiki_debug ==3 + echom " Setup_buffer_enter g:curr_idx=".g:vimwiki_current_idx." (set syntax=vimwiki) b:curr_idx=".s:vimwiki_idx()."" + endif + endif + let b:vimwiki_fs_rescan = 1 + endif + let time1 = vimwiki#u#time(time0) "XXX + + " Settings foldmethod, foldexpr and foldtext are local to window. Thus in a + " new tab with the same buffer folding is reset to vim defaults. So we + " insist vimwiki folding here. + if g:vimwiki_folding == 'expr' + setlocal fdm=expr + setlocal foldexpr=VimwikiFoldLevel(v:lnum) + setlocal foldtext=VimwikiFoldText() + elseif g:vimwiki_folding == 'list' || g:vimwiki_folding == 'lists' + setlocal fdm=expr + setlocal foldexpr=VimwikiFoldListLevel(v:lnum) + setlocal foldtext=VimwikiFoldText() + elseif g:vimwiki_folding == 'syntax' + setlocal fdm=syntax + setlocal foldtext=VimwikiFoldText() + endif + + " And conceal level too. + if g:vimwiki_conceallevel && exists("+conceallevel") + let &conceallevel = g:vimwiki_conceallevel + endif + + " Set up menu + if g:vimwiki_menu != "" + exe 'nmenu enable '.g:vimwiki_menu.'.Table' + endif + "let time2 = vimwiki#u#time(time0) "XXX + call VimwikiLog_extend('timing',['plugin:setup_buffer_enter:time1',time1]) +endfunction "}}} + +function! s:setup_buffer_reenter() "{{{ + if g:vimwiki_debug ==3 + echom "Setup_buffer_reenter g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + if !vimwiki#base#recall_buffer_state() + " Do not repeat work of s:setup_buffer_enter() and s:setup_filetype() + " Once should be enough ... + endif + if g:vimwiki_debug ==3 + echom " Setup_buffer_reenter g:curr_idx=".g:vimwiki_current_idx." b:curr_idx=".s:vimwiki_idx()."" + endif + if !exists("s:vimwiki_autowriteall") + let s:vimwiki_autowriteall = &autowriteall + endif + let &autowriteall = g:vimwiki_autowriteall +endfunction "}}} + +function! s:setup_cleared_syntax() "{{{ highlight groups that get cleared + " on colorscheme change because they are not linked to Vim-predefined groups + hi def VimwikiBold term=bold cterm=bold gui=bold + hi def VimwikiItalic term=italic cterm=italic gui=italic + hi def VimwikiBoldItalic term=bold cterm=bold gui=bold,italic + hi def VimwikiUnderline gui=underline + if g:vimwiki_hl_headers == 1 + for i in range(1,6) + execute 'hi def VimwikiHeader'.i.' guibg=bg guifg='.g:vimwiki_hcolor_guifg_{&bg}[i-1].' gui=bold ctermfg='.g:vimwiki_hcolor_ctermfg_{&bg}[i-1].' term=bold cterm=bold' + endfor + endif +endfunction "}}} + +" OPTION get/set functions {{{ +" return complete list of options +function! VimwikiGetOptionNames() "{{{ + return keys(s:vimwiki_defaults) +endfunction "}}} + +function! VimwikiGetOptions(...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + let option_dict = {} + for kk in keys(s:vimwiki_defaults) + let option_dict[kk] = VimwikiGet(kk, idx) + endfor + return option_dict +endfunction "}}} + +" Return value of option for current wiki or if second parameter exists for +" wiki with a given index. +" If the option is not found, it is assumed to have been previously cached in a +" buffer local dictionary, that acts as a cache. +" If the option is not found in the buffer local dictionary, an error is thrown +function! VimwikiGet(option, ...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + + if has_key(g:vimwiki_list[idx], a:option) + let val = g:vimwiki_list[idx][a:option] + elseif has_key(s:vimwiki_defaults, a:option) + let val = s:vimwiki_defaults[a:option] + let g:vimwiki_list[idx][a:option] = val + else + let val = b:vimwiki_list[a:option] + endif + + " XXX no call to vimwiki#base here or else the whole autoload/base gets loaded! + return val +endfunction "}}} + +" Set option for current wiki or if third parameter exists for +" wiki with a given index. +" If the option is not found or recognized (i.e. does not exist in +" s:vimwiki_defaults), it is saved in a buffer local dictionary, that acts +" as a cache. +" If the option is not found in the buffer local dictionary, an error is thrown +function! VimwikiSet(option, value, ...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + + if has_key(s:vimwiki_defaults, a:option) || + \ has_key(g:vimwiki_list[idx], a:option) + let g:vimwiki_list[idx][a:option] = a:value + elseif exists('b:vimwiki_list') + let b:vimwiki_list[a:option] = a:value + else + let b:vimwiki_list = {} + let b:vimwiki_list[a:option] = a:value + endif + +endfunction "}}} + +" Clear option for current wiki or if third parameter exists for +" wiki with a given index. +" Currently, only works if option was previously saved in the buffer local +" dictionary, that acts as a cache. +function! VimwikiClear(option, ...) "{{{ + let idx = a:0 == 0 ? g:vimwiki_current_idx : a:1 + + if exists('b:vimwiki_list') && has_key(b:vimwiki_list, a:option) + call remove(b:vimwiki_list, a:option) + endif + +endfunction "}}} +" }}} + +" }}} + +" CALLBACK functions "{{{ +" User can redefine it. +if !exists("*VimwikiLinkHandler") "{{{ + function VimwikiLinkHandler(url) + return 0 + endfunction +endif "}}} + +if !exists("*VimwikiWikiIncludeHandler") "{{{ + function! VimwikiWikiIncludeHandler(value) "{{{ + " Return the empty string when unable to process link + return '' + endfunction "}}} +endif "}}} +" CALLBACK }}} + +" DEFAULT wiki {{{ +let s:vimwiki_defaults = {} +let s:vimwiki_defaults.path = '~/vimwiki/' +let s:vimwiki_defaults.path_html = '' " '' is replaced by derived path.'_html/' +let s:vimwiki_defaults.css_name = 'style.css' +let s:vimwiki_defaults.index = 'index' +let s:vimwiki_defaults.ext = '.wiki' +let s:vimwiki_defaults.maxhi = 0 +let s:vimwiki_defaults.syntax = 'default' + +let s:vimwiki_defaults.template_path = '' +let s:vimwiki_defaults.template_default = '' +let s:vimwiki_defaults.template_ext = '' + +let s:vimwiki_defaults.nested_syntaxes = {} +let s:vimwiki_defaults.auto_export = 0 +" is wiki temporary -- was added to g:vimwiki_list by opening arbitrary wiki +" file. +let s:vimwiki_defaults.temp = 0 + +" diary +let s:vimwiki_defaults.diary_rel_path = 'diary/' +let s:vimwiki_defaults.diary_index = 'diary' +let s:vimwiki_defaults.diary_header = 'Diary' +let s:vimwiki_defaults.diary_sort = 'desc' + +" Do not change this! Will wait till vim become more datetime awareable. +let s:vimwiki_defaults.diary_link_fmt = '%Y-%m-%d' + +" NEW! in v2.0 +" custom_wiki2html +let s:vimwiki_defaults.custom_wiki2html = '' +" +let s:vimwiki_defaults.list_margin = -1 +"}}} + +" DEFAULT options {{{ +call s:default('list', [s:vimwiki_defaults]) +call s:default('auto_checkbox', 1) +call s:default('use_mouse', 0) +call s:default('folding', '') +call s:default('menu', 'Vimwiki') +call s:default('global_ext', 1) +call s:default('ext2syntax', {}) " syntax map keyed on extension +call s:default('hl_headers', 0) +call s:default('hl_cb_checked', 0) +call s:default('list_ignore_newline', 1) +call s:default('listsyms', ' .oOX') +call s:default('use_calendar', 1) +call s:default('table_mappings', 1) +call s:default('table_auto_fmt', 1) +call s:default('w32_dir_enc', '') +call s:default('CJK_length', 0) +call s:default('dir_link', '') +call s:default('valid_html_tags', 'b,i,s,u,sub,sup,kbd,br,hr,div,center,strong,em') +call s:default('user_htmls', '') +call s:default('autowriteall', 1) + +call s:default('html_header_numbering', 0) +call s:default('html_header_numbering_sym', '') +call s:default('conceallevel', 2) +call s:default('url_maxsave', 15) +call s:default('debug', 0) + +call s:default('diary_months', + \ { + \ 1: 'January', 2: 'February', 3: 'March', + \ 4: 'April', 5: 'May', 6: 'June', + \ 7: 'July', 8: 'August', 9: 'September', + \ 10: 'October', 11: 'November', 12: 'December' + \ }) + + +call s:default('current_idx', 0) + +" Scheme regexes should be defined even if syntax file is not loaded yet +" cause users should be able to ww without opening any +" vimwiki file first +" Scheme regexes {{{ +call s:default('schemes', 'wiki\d\+,diary,local') +call s:default('web_schemes1', 'http,https,file,ftp,gopher,telnet,nntp,ldap,'. + \ 'rsync,imap,pop,irc,ircs,cvs,svn,svn+ssh,git,ssh,fish,sftp') +call s:default('web_schemes2', 'mailto,news,xmpp,sip,sips,doi,urn,tel') + +let rxSchemes = '\%('. + \ join(split(g:vimwiki_schemes, '\s*,\s*'), '\|').'\|'. + \ join(split(g:vimwiki_web_schemes1, '\s*,\s*'), '\|').'\|'. + \ join(split(g:vimwiki_web_schemes2, '\s*,\s*'), '\|'). + \ '\)' + +call s:default('rxSchemeUrl', rxSchemes.':.*') +call s:default('rxSchemeUrlMatchScheme', '\zs'.rxSchemes.'\ze:.*') +call s:default('rxSchemeUrlMatchUrl', rxSchemes.':\zs.*\ze') +" scheme regexes }}} +"}}} + +" AUTOCOMMANDS for all known wiki extensions {{{ +let extensions = vimwiki#base#get_known_extensions() + +augroup filetypedetect + " clear FlexWiki's stuff + au! * *.wiki +augroup end + +augroup vimwiki + autocmd! + for ext in extensions + exe 'autocmd BufEnter *'.ext.' call s:setup_buffer_reenter()' + exe 'autocmd BufWinEnter *'.ext.' call s:setup_buffer_enter()' + exe 'autocmd BufLeave,BufHidden *'.ext.' call s:setup_buffer_leave()' + exe 'autocmd BufNewFile,BufRead, *'.ext.' call s:setup_filetype()' + exe 'autocmd ColorScheme *'.ext.' call s:setup_cleared_syntax()' + " Format tables when exit from insert mode. Do not use textwidth to + " autowrap tables. + if g:vimwiki_table_auto_fmt + exe 'autocmd InsertLeave *'.ext.' call vimwiki#tbl#format(line("."))' + exe 'autocmd InsertEnter *'.ext.' call vimwiki#tbl#reset_tw(line("."))' + endif + endfor +augroup END +"}}} + +" COMMANDS {{{ +command! VimwikiUISelect call vimwiki#base#ui_select() +" XXX: why not using instead of v:count1? +" See Issue 324. +command! -count=1 VimwikiIndex + \ call vimwiki#base#goto_index(v:count1) +command! -count=1 VimwikiTabIndex + \ call vimwiki#base#goto_index(v:count1, 1) + +command! -count=1 VimwikiDiaryIndex + \ call vimwiki#diary#goto_diary_index(v:count1) +command! -count=1 VimwikiMakeDiaryNote + \ call vimwiki#diary#make_note(v:count1) +command! -count=1 VimwikiTabMakeDiaryNote + \ call vimwiki#diary#make_note(v:count1, 1) + +command! VimwikiDiaryGenerateLinks + \ call vimwiki#diary#generate_diary_section() +"}}} + +" MAPPINGS {{{ +if !hasmapto('VimwikiIndex') + nmap ww VimwikiIndex +endif +nnoremap