" Vimwiki autoload plugin file " Desc: Handle diary notes " Author: Maxim Kim " Home: http://code.google.com/p/vimwiki/ " Load only once {{{ if exists("g:loaded_vimwiki_diary_auto") || &cp finish endif let g:loaded_vimwiki_diary_auto = 1 "}}} function! s:prefix_zero(num) "{{{ if a:num < 10 return '0'.a:num endif return a:num endfunction "}}} function! s:desc(d1, d2) "{{{ return a:d1 == a:d2 ? 0 : a:d1 < a:d2 ? 1 : -1 endfunction "}}} function! s:get_date_link(fmt) "{{{ return strftime(a:fmt) endfunction "}}} function! s:link_exists(lines, link) "{{{ let link_exists = 0 for line in a:lines if line =~ escape(a:link, '[]\') let link_exists = 1 break endif endfor return link_exists endfunction "}}} function! s:diary_path() "{{{ return VimwikiGet('path').VimwikiGet('diary_rel_path') endfunction "}}} function! s:diary_index() "{{{ return s:diary_path().VimwikiGet('diary_index').VimwikiGet('ext') endfunction "}}} function! s:get_diary_range(lines, header) "{{{ let rx = '\[\[\d\{4}-\d\d-\d\d\]\]' let idx = 0 let ln_start = -1 let ln_end = -1 for line in a:lines if ln_start != -1 if line =~ '^\s*\(=\)\+.*\1\s*$' || (line !~ rx && line !~ '^\s*$') break endif endif if line =~ '^\s*\(=\)\+\s*'.a:header.'\s*\1\s*$' let ln_start = idx + 1 endif let idx += 1 endfor let ln_end = idx - 1 return [ln_start, ln_end] endfunction "}}} function! s:diary_date_link() "{{{ return s:get_date_link(VimwikiGet('diary_link_fmt')) endfunction "}}} function! s:get_file_contents(file_name) "{{{ let lines = [] let bufnr = bufnr(expand(a:file_name)) if bufnr != -1 let lines = getbufline(bufnr, 1, '$') else try let lines = readfile(expand(a:file_name)) catch endtry endif return [lines, bufnr] endfunction "}}} function! s:get_links() "{{{ let rx = '\d\{4}-\d\d-\d\d' let s_links = glob(VimwikiGet('path').VimwikiGet('diary_rel_path').'*.wiki') "let s_links = substitute(s_links, '\'.VimwikiGet('ext'), "", "g") let s_links = substitute(s_links, '\.wiki', "", "g") let links = split(s_links, '\n') " remove backup files (.wiki~) call filter(links, 'v:val !~ ''.*\~$''') " remove paths call map(links, 'fnamemodify(v:val, ":t")') call filter(links, 'v:val =~ "'.escape(rx, '\').'"') call map(links, '"[[".v:val."]]"') return links endfunction "}}} function! s:format_links(links) "{{{ let lines = [] let line = '| ' let idx = 0 let trigger = 0 while idx < len(a:links) if idx/VimwikiGet('diary_link_count') > trigger let trigger = idx/VimwikiGet('diary_link_count') call add(lines, substitute(line, '\s\+$', '', '')) let line = '| ' endif let line .= a:links[idx].' | ' let idx += 1 endwhile call add(lines, substitute(line, '\s\+$', '', '')) call extend(lines, ['']) return lines endfunction "}}} function! s:add_link(page, header, link) "{{{ let [lines, bufnr] = s:get_file_contents(a:page) let [ln_start, ln_end] = s:get_diary_range(lines, a:header) let link = '[['.a:link.']]' let link_exists = s:link_exists(lines[ln_start : ln_end], link) if !link_exists if ln_start == -1 call insert(lines, '= '.a:header.' =') let ln_start = 1 endif " removing 'old' links let idx = ln_end - ln_start while idx > 0 call remove(lines, ln_start) let idx -= 1 endwhile " get all diary links from filesystem let links = s:get_links() " add current link if index(links, link) == -1 call add(links, link) endif let links = sort(links, 's:desc') call extend(lines, s:format_links(links), ln_start) if bufnr != -1 exe 'buffer '.bufnr if !&readonly 1,$delete _ call append(1, lines) 1,1delete _ endif else call writefile(lines, expand(a:page)) endif endif endfunction "}}} function! s:make_date_link(...) "{{{ if a:0 let link = a:1 else let link = s:diary_date_link() endif let header = VimwikiGet('diary_header') call s:add_link(s:diary_index(), header, link) return VimwikiGet('diary_rel_path').link endfunction "}}} function! vimwiki_diary#make_note(index, ...) "{{{ call vimwiki#select(a:index) call vimwiki#mkdir(VimwikiGet('path').VimwikiGet('diary_rel_path')) if a:0 let link = s:make_date_link(a:1) else let link = s:make_date_link() endif call vimwiki#open_link(':e ', link, s:diary_index()) endfunction "}}} " Calendar.vim callback. function! vimwiki_diary#calendar_action(day, month, year, week, dir) "{{{ let day = s:prefix_zero(a:day) let month = s:prefix_zero(a:month) let link = a:year.'-'.month.'-'.day if winnr('#') == 0 if a:dir == 'V' vsplit else split endif else wincmd p if !&hidden && &modified new endif endif " Create diary note for a selected date in default wiki. call vimwiki_diary#make_note(1, link) endfunction