commit 642a94ffaedc68f7ea63df16a3a946927805aa95
parent 7aa273fd7c3e0cec792ddb6f45a232115c791de1
Author: EinfachToll <istjanichtzufassen@googlemail.com>
Date: Mon, 9 Nov 2015 15:45:56 +0100
:VimwikiGenerateTags now updates a potentially existing listing
instead of adding it to the end.
Ref #85
Diffstat:
3 files changed, 104 insertions(+), 106 deletions(-)
diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim
@@ -465,10 +465,9 @@ endfunction " }}}
" vimwiki#base#generate_links
function! vimwiki#base#generate_links() "{{{
- let links = vimwiki#base#get_wikilinks(g:vimwiki_current_idx, 0)
-
- call append(line('$'), substitute(g:vimwiki_rxH1_Template, '__Header__', 'Generated Links', ''))
+ let lines = []
+ let links = vimwiki#base#get_wikilinks(g:vimwiki_current_idx, 0)
call sort(links)
let bullet = repeat(' ', vimwiki#lst#get_list_margin()).
@@ -476,10 +475,15 @@ function! vimwiki#base#generate_links() "{{{
for link in links
let abs_filepath = vimwiki#path#abs_path_of_link(link)
if !s:is_diary_file(abs_filepath)
- call append(line('$'), bullet.
+ call add(lines, bullet.
\ substitute(g:vimwiki_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 " }}}
" vimwiki#base#goto
@@ -1087,6 +1091,74 @@ function! vimwiki#base#nested_syntax(filetype, start, end, textSnipHl) abort "{{
endif
endfunction "}}}
+" creates or updates auto-generated listings in a wiki file, like TOC, diary
+" links, tags list etc.
+" - the listing consists of a level 1 header and a list of strings as content
+" - a:content_regex is used to determine how long a potentially existing list is
+" - a:default_lnum is the line number where the new listing should be placed if
+" it's not already present
+" - if a:create is true, it will be created if it doesn't exist, otherwise it
+" will only be updated if it already exists
+function! vimwiki#base#update_listing_in_buffer(strings, start_header,
+ \ content_regex, default_lnum, create) "{{{
+ " apparently, Vim behaves strange when files change while in diff mode
+ if &diff || &readonly
+ return
+ endif
+
+ " check if the listing is already there
+ let already_there = 0
+
+ let header_rx = '\m^\s*'.
+ \ substitute(g:vimwiki_rxH1_Template, '__Header__', a:start_header, '')
+ \ .'\s*$'
+
+ let start_lnum = 1
+ while start_lnum <= line('$')
+ if getline(start_lnum) =~# header_rx
+ let already_there = 1
+ break
+ endif
+ let start_lnum += 1
+ endwhile
+
+ if !already_there && !a:create
+ return
+ endif
+
+ let old_cursor_pos = getpos('.')
+
+ if already_there
+ " delete the old listing
+ let whitespaces_in_first_line = matchstr(getline(start_lnum), '\m^\s*')
+ let end_lnum = start_lnum + 1
+ while end_lnum <= line('$') && getline(end_lnum) =~# a:content_regex
+ let end_lnum += 1
+ endwhile
+ silent exe start_lnum.','.string(end_lnum - 1).'delete _'
+ else
+ let start_lnum = a:default_lnum
+ let whitespaces_in_first_line = ''
+ endif
+
+ " write new listing
+ let new_header = whitespaces_in_first_line
+ \ . substitute(g:vimwiki_rxH1_Template,
+ \ '__Header__', '\='."'".a:start_header."'", '')
+ call append(start_lnum - 1, new_header)
+ let start_lnum += 1
+ for string in a:strings
+ call append(start_lnum - 1, string)
+ let start_lnum += 1
+ endfor
+ " append an empty line if there is not one
+ if start_lnum <= line('$') && getline(start_lnum) !~# '\m^\s*$'
+ call append(start_lnum - 1, '')
+ endif
+
+ call setpos('.', old_cursor_pos)
+endfunction "}}}
+
" WIKI link following functions {{{
" vimwiki#base#find_next_link
function! vimwiki#base#find_next_link() "{{{
@@ -1630,44 +1702,6 @@ 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)
- " apparently, Vim behaves strange when files change while in diff mode
- if &diff
- return
- endif
-
- " look for existing TOC
- let toc_header = '^\s*'.substitute(g:vimwiki_rxH1_Template, '__Header__',
- \ '\='."'".g:vimwiki_toc_header."'", '').'\s*$'
- let toc_line = 0
- let lnum = 1
- while lnum <= &modelines + 2 && lnum <= line('$')
- if getline(lnum) =~# toc_header
- let toc_line = lnum
- break
- endif
- let lnum += 1
- endwhile
-
- if !a:create && toc_line <= 0
- return
- endif
-
- let old_cursor_pos = getpos('.')
- let bullet = vimwiki#lst#default_symbol().' '
- let rx_bullet = vimwiki#u#escape(bullet)
- let whitespaces = matchstr(getline(toc_line), '^\s*')
-
- " delete old TOC
- if toc_line > 0
- let endoftoc = toc_line+1
- while endoftoc <= line('$') && getline(endoftoc) =~# '^\s*'.rx_bullet.g:vimwiki_rxWikiLink.'\s*$'
- let endoftoc += 1
- endwhile
- silent exe toc_line.','.string(endoftoc-1).'delete _'
- else
- let toc_line = 1
- endif
-
" collect new headers
let headers = []
let headers_levels = [['', 0], ['', 0], ['', 0], ['', 0], ['', 0], ['', 0]]
@@ -1678,6 +1712,9 @@ function! vimwiki#base#table_of_contents(create)
endif
let h_level = vimwiki#u#count_first_sym(line_content)
let h_text = vimwiki#u#trim(matchstr(line_content, g:vimwiki_rxHeader))
+ if h_text ==# g:vimwiki_toc_header " don't include the TOC's header itself
+ continue
+ endif
let headers_levels[h_level-1] = [h_text, headers_levels[h_level-1][1]+1]
for idx in range(h_level, 5) | let headers_levels[idx] = ['', 0] | endfor
@@ -1700,25 +1737,23 @@ function! vimwiki#base#table_of_contents(create)
call add(headers, [h_level, h_complete_id, h_text])
endfor
- " write new TOC
- call append(toc_line-1, whitespaces . substitute(g:vimwiki_rxH1_Template,
- \ '__Header__', '\='."'".g:vimwiki_toc_header."'", ''))
-
+ 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
let esc_link = substitute(link, "'", "''", 'g')
let esc_desc = substitute(desc, "'", "''", 'g')
let link = substitute(g:vimwiki_WikiLinkTemplate2, '__LinkUrl__',
\ '\='."'".'#'.esc_link."'", '')
let link = substitute(link, '__LinkDescription__', '\='."'".esc_desc."'", '')
- call append(toc_line, startindent.repeat(indentstring, lvl-1).bullet.link)
- let toc_line += 1
+ call add(lines, startindent.repeat(indentstring, lvl-1).bullet.link)
endfor
- if getline(toc_line+1) !~# '^\s*$'
- call append(toc_line, '')
- endif
- call setpos('.', old_cursor_pos)
+
+ let links_rx = '\m^\s*'.vimwiki#u#escape(vimwiki#lst#default_symbol()).' '
+
+ call vimwiki#base#update_listing_in_buffer(lines, g:vimwiki_toc_header, links_rx,
+ \ 1, a:create)
endfunction
"}}}
diff --git a/autoload/vimwiki/diary.vim b/autoload/vimwiki/diary.vim
@@ -121,36 +121,31 @@ fun! s:group_links(links) "{{{
return result
endfun "}}}
-fun! s:sort(lst) "{{{
+function! s:sort(lst) "{{{
if VimwikiGet("diary_sort") ==? 'desc'
return reverse(sort(a:lst))
else
return sort(a:lst)
endif
-endfun "}}}
+endfunction "}}}
-fun! s:format_diary(...) "{{{
+function! s:format_diary(...) "{{{
let result = []
- call add(result, substitute(g:vimwiki_rxH1_Template, '__Header__', VimwikiGet('diary_header'), ''))
-
if a:0
let g_files = s:group_links(s:get_diary_links(a:1))
else
let g_files = s:group_links(s:get_diary_links())
endif
- " for year in s:rev(sort(keys(g_files)))
for year in s:sort(keys(g_files))
call add(result, '')
call add(result, substitute(g:vimwiki_rxH2_Template, '__Header__', year , ''))
- " for month in s:rev(sort(keys(g_files[year])))
for month in s:sort(keys(g_files[year]))
call add(result, '')
call add(result, substitute(g:vimwiki_rxH3_Template, '__Header__', s:get_month_name(month), ''))
- " for [fl, cap] in s:rev(sort(items(g_files[year][month])))
for [fl, cap] in s:sort(items(g_files[year][month]))
if empty(cap)
let entry = substitute(g:vimwiki_WikiLinkTemplate1, '__LinkUrl__', fl, '')
@@ -165,46 +160,8 @@ fun! s:format_diary(...) "{{{
endfor
endfor
- call add(result, '')
return result
-endfun "}}}
-
-function! s:delete_diary_section() "{{{
- " remove diary section
- let old_pos = getpos('.')
- let ln_start = -1
- let ln_end = -1
- call cursor(1, 1)
- if search(substitute(g:vimwiki_rxH1_Template, '__Header__', VimwikiGet('diary_header'), ''), 'Wc')
- let ln_start = line('.')
- if search(g:vimwiki_rxH1, 'W')
- let ln_end = line('.') - 1
- else
- let ln_end = line('$')
- endif
- endif
-
- if ln_start < 0 || ln_end < 0
- call setpos('.', old_pos)
- return
- endif
-
- if !&readonly
- exe ln_start.",".ln_end."delete _"
- endif
-
- call setpos('.', old_pos)
-endfunction "}}}
-
-function! s:insert_diary_section() "{{{
- if !&readonly
- let ln = line('.')
- call append(ln, s:format_diary())
- if ln == 1 && getline(ln) == ''
- 1,1delete
- endif
- endif
endfunction "}}}
" Diary index stuff }}}
@@ -300,8 +257,9 @@ 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)
- call s:delete_diary_section()
- call s:insert_diary_section()
+ let content_rx = '^\%(\s*\* \)\|\%(^\s*$\)\|\%('.g:vimwiki_rxHeader.'\)'
+ call vimwiki#base#update_listing_in_buffer(s:format_diary(),
+ \ VimwikiGet('diary_header'), content_rx, line('$')+1, 1)
else
echom "vimwiki: You can generate diary links only in a diary index page!"
endif
diff --git a/autoload/vimwiki/tags.vim b/autoload/vimwiki/tags.vim
@@ -261,10 +261,6 @@ function! vimwiki#tags#generate_tags(...) abort "{{{
let metadata = s:load_tags_metadata()
- call append(line('$'), [
- \ '',
- \ substitute(g:vimwiki_rxH1_Template, '__Header__', 'Generated Tags', '') ])
-
" make a dictionary { tag_name: [tag_links, ...] }
let tags_entries = {}
for entries in values(metadata)
@@ -277,19 +273,28 @@ function! vimwiki#tags#generate_tags(...) abort "{{{
endfor
endfor
+ let lines = []
let bullet = repeat(' ', vimwiki#lst#get_list_margin()).
\ vimwiki#lst#default_symbol().' '
for tagname in sort(keys(tags_entries))
if need_all_tags || index(specific_tags, tagname) != -1
- call append(line('$'), [
+ call extend(lines, [
\ '',
\ substitute(g:vimwiki_rxH2_Template, '__Header__', tagname, ''),
\ '' ])
for taglink in tags_entries[tagname]
- call append(line('$'), bullet . '[[' . taglink . ']]')
+ call add(lines, bullet .
+ \ substitute(g:vimwiki_WikiLinkTemplate1, '__LinkUrl__', taglink, ''))
endfor
endif
endfor
+
+ let links_rx = '\m\%(^\s*$\)\|\%('.g:vimwiki_rxH2.'\)\|\%(^\s*'
+ \ .vimwiki#u#escape(vimwiki#lst#default_symbol()).' '
+ \ .g:vimwiki_rxWikiLink.'$\)'
+
+ call vimwiki#base#update_listing_in_buffer(lines, 'Generated Tags', links_rx,
+ \ line('$')+1, 1)
endfunction " }}}
" vimwiki#tags#complete_tags