Fix relative paths for VimwikiRenameLink. Merge PR #787.

Fixes #90 

__Problem__: VimwikiRenameLink does not rename dir1/toto url in dir2/tata
because the dirs (dir2 and .) were well crossed but badly inspected.
__Solution__: `blob(.ext*)` -> `glob(**/*.ext)` + find the relative URL

* Fasten: VimwikiRenameLink goes faster with cache
More: To compute old_url regex, use a cache dict because it is the same
for files in the same directories

* Util DeleteHiddenBuffer -> do not delete Vader buffer

* Test: Prettify: Util: teardown delete defined function

* Remove unnecessary trailing spaces
Note: list_VimwikiReturn.vader has some necessary trailing spaces
This commit is contained in:
Tinmarino 2020-01-05 00:21:52 -04:00 committed by Rane Brown
parent 8ccfeb4fdb
commit d9412218e3
12 changed files with 728 additions and 492 deletions

View File

@ -961,6 +961,10 @@ function! s:print_wiki_list() abort
endfunction endfunction
" Update link: in fname.ext
" Param: fname: the source file where to change links
" Param: old: url regex of old path relative to wiki root
" Param: new: url string of new path
function! s:update_wiki_link(fname, old, new) abort function! s:update_wiki_link(fname, old, new) abort
echo 'Updating links in '.a:fname echo 'Updating links in '.a:fname
let has_updates = 0 let has_updates = 0
@ -981,18 +985,66 @@ function! s:update_wiki_link(fname, old, new) abort
endfunction endfunction
function! s:update_wiki_links_dir(wiki_nr, dir, old_fname, new_fname) abort " Update link for all files in dir
let old_fname = substitute(a:old_fname, '[/\\]', '[/\\\\]', 'g') " Param: old_url, new_url: path of the old, new url relative to ...
let new_fname = a:new_fname " Param: dir: directory of the files, relative to wiki_root
function! s:update_wiki_links(wiki_nr, dir, old_url, new_url) abort
" Get list of wiki files
let wiki_root = vimwiki#vars#get_wikilocal('path', a:wiki_nr)
let fsources = vimwiki#base#find_files(a:wiki_nr, 0)
let old_fname_r = vimwiki#base#apply_template( " Shorten dirname
\ vimwiki#vars#get_syntaxlocal('WikiLinkMatchUrlTemplate', let dir_rel_root = vimwiki#path#relpath(wiki_root, a:dir)
\ vimwiki#vars#get_wikilocal('syntax', a:wiki_nr)), old_fname, '', '')
let files = split(glob(vimwiki#vars#get_wikilocal('path', a:wiki_nr).a:dir.'*'. " Cache relative url, because they are often the same, like `../dir1/vim-vimwiki.md`
\ vimwiki#vars#get_wikilocal('ext', a:wiki_nr)), '\n') let cache_dict = {}
for fname in l:files
call s:update_wiki_link(fname, old_fname_r, new_fname) " Regex from path
function! s:compute_old_url_r(wiki_nr, dir_rel_fsource, old_url) abort
" Old url
let old_url_r = a:dir_rel_fsource . a:old_url
" Add potential ./
let old_url_r = '\%(\.[/\\]\)\?' . old_url_r
" Compute old url regex with filename between \zs and \ze
let old_url_r = vimwiki#base#apply_template(
\ vimwiki#vars#get_syntaxlocal('WikiLinkMatchUrlTemplate',
\ vimwiki#vars#get_wikilocal('syntax', a:wiki_nr)), old_url_r, '', '')
return old_url_r
endfunction
" For each wikifile
for fsource in fsources
" Shorten fname directory
let fsource_rel_root = vimwiki#path#relpath(wiki_root, fsource)
let fsource_rel_root = fnamemodify(fsource_rel_root, ':h')
" Compute old_url relative to fname
let dir_rel_fsource = vimwiki#path#relpath(fsource_rel_root, dir_rel_root)
" TODO get relpath coherent (and remove next 2 stuff)
" Remove the trailing ./
if dir_rel_fsource =~# '.[/\\]$'
let dir_rel_fsource = dir_rel_fsource[:-3]
endif
" Append a / if needed
if !empty(dir_rel_fsource) && dir_rel_fsource !~# '[/\\]$'
let dir_rel_fsource .= '/'
endif
" New url
let new_url = dir_rel_fsource . a:new_url
" Old url
" Avoid E713
let key = empty(dir_rel_fsource) ? 'NaF' : dir_rel_fsource
if index(keys(cache_dict), key) == -1
let cache_dict[key] = s:compute_old_url_r(
\ a:wiki_nr, dir_rel_fsource, a:old_url)
endif
let old_url_r = cache_dict[key]
" Update url in source file
call s:update_wiki_link(fsource, old_url_r, new_url)
endfor endfor
endfunction endfunction
@ -1005,38 +1057,6 @@ function! s:tail_name(fname) abort
endfunction endfunction
function! s:update_wiki_links(wiki_nr, old_fname, new_fname,old_fname_relpath) abort
let old_fname = a:old_fname
let new_fname = a:new_fname
let subdirs = split(a:old_fname_relpath, '[/\\]')[: -2]
" TODO: Use Dictionary here...
let dirs_keys = ['']
let dirs_vals = ['']
if len(subdirs) > 0
let dirs_keys = ['']
let dirs_vals = [join(subdirs, '/').'/']
let idx = 0
while idx < len(subdirs) - 1
call add(dirs_keys, join(subdirs[: idx], '/').'/')
call add(dirs_vals, join(subdirs[idx+1 :], '/').'/')
let idx = idx + 1
endwhile
call add(dirs_keys,join(subdirs, '/').'/')
call add(dirs_vals, '')
endif
let idx = 0
while idx < len(dirs_keys)
let dir = dirs_keys[idx]
let new_dir = dirs_vals[idx]
call s:update_wiki_links_dir(a:wiki_nr, dir, new_dir.old_fname, new_dir.new_fname)
let idx = idx + 1
endwhile
endfunction
function! s:get_wiki_buffers() abort function! s:get_wiki_buffers() abort
let blist = [] let blist = []
let bcount = 1 let bcount = 1
@ -1443,9 +1463,13 @@ endfunction
" Rename current file, update all links to it " Rename current file, update all links to it
function! vimwiki#base#rename_link() abort function! vimwiki#base#rename_link() abort
" Get filename relative to wiki root
let subdir = vimwiki#vars#get_bufferlocal('subdir') let subdir = vimwiki#vars#get_bufferlocal('subdir')
let old_fname = subdir.expand('%:t') let old_fname = subdir.expand('%:t')
" Get current path
let old_dir = expand('%:p:h')
" there is no file (new one maybe) " there is no file (new one maybe)
if glob(expand('%:p')) ==? '' if glob(expand('%:p')) ==? ''
echomsg 'Vimwiki Error: Cannot rename "'.expand('%:p'). echomsg 'Vimwiki Error: Cannot rename "'.expand('%:p').
@ -1520,7 +1544,7 @@ function! vimwiki#base#rename_link() abort
setlocal nomore setlocal nomore
" update links " update links
call s:update_wiki_links(wiki_nr, s:tail_name(old_fname), s:tail_name(new_link),old_fname) call s:update_wiki_links(wiki_nr, old_dir, s:tail_name(old_fname), s:tail_name(new_fname))
" restore wiki buffers " restore wiki buffers
for bitem in blist for bitem in blist

View File

@ -2,7 +2,7 @@
# #
# This script converts markdown into html, to be used with vimwiki's # This script converts markdown into html, to be used with vimwiki's
# "customwiki2html" option. Experiment with the two proposed methods by # "customwiki2html" option. Experiment with the two proposed methods by
# commenting / uncommenting the relevant lines below. # commenting / uncommenting the relevant lines below.
# #
# NEW! An alternative converter was developed by Jason6Anderson, and can # NEW! An alternative converter was developed by Jason6Anderson, and can
@ -46,7 +46,7 @@ OUTPUT="$OUTPUTDIR"/$(basename "$INPUT" .$EXTENSION).html
# # Method 1: # # Method 1:
# # markdown [-d] [-T] [-V] [-b url-base] [-C prefix] [-F bitmap] [-f flags] [-o file] [-s text] [-t text] [textfile] # # markdown [-d] [-T] [-V] [-b url-base] [-C prefix] [-F bitmap] [-f flags] [-o file] [-s text] [-t text] [textfile]
# #
# URLBASE=http://example.com # URLBASE=http://example.com
# $MARKDOWN -T -b $URLBASE -o $OUTPUT $INPUT # $MARKDOWN -T -b $URLBASE -o $OUTPUT $INPUT

View File

@ -97,6 +97,10 @@ endfunction
" Returns: the relative path from a:dir to a:file " Returns: the relative path from a:dir to a:file
function! vimwiki#path#relpath(dir, file) abort function! vimwiki#path#relpath(dir, file) abort
" Check if dir here ('.') -> return file
if empty(a:dir) || a:dir =~# '^\.[/\\]\?$'
return a:file
endif
let result = [] let result = []
if vimwiki#u#is_windows() if vimwiki#u#is_windows()
" TODO temporary fix see #478 " TODO temporary fix see #478

View File

@ -3471,6 +3471,7 @@ Contributors and their Github usernames in roughly chronological order:
- Robin Lowe (@defau1t) - Robin Lowe (@defau1t)
- Abhinav Gupta (@abhinav) - Abhinav Gupta (@abhinav)
- Dave Gauer (@ratfactor) - Dave Gauer (@ratfactor)
- Martin Tourneboeuf (@tinmarino)
============================================================================== ==============================================================================
@ -3486,6 +3487,8 @@ https://github.com/vimwiki-backup/vimwiki/issues.
2.5 (in progress)~ 2.5 (in progress)~
New:~ New:~
* PR #787: |:VimwikiRenameLink| works for all directories: even
wiki_root/diary/2019-12-11.md if current file is wiki_root/dir1/file.md.
* Add support for markdown indented code blocks. * Add support for markdown indented code blocks.
* Issue #764: fenced code blocks are properly supported for markdown * Issue #764: fenced code blocks are properly supported for markdown
syntax i.e. more than 3 backticks, adds tilde support. syntax i.e. more than 3 backticks, adds tilde support.
@ -3561,6 +3564,7 @@ Removed:~
point. point.
Fixed:~ Fixed:~
* Issue #90: VimwikiRenameLink doesn't update links in diary.
* Issue #796: Rename |:VimwikiGenerateTags| to |:VimwikiGenerateTagLinks| * Issue #796: Rename |:VimwikiGenerateTags| to |:VimwikiGenerateTagLinks|
* Issue #790: Allow tags before a header with markdown syntax. * Issue #790: Allow tags before a header with markdown syntax.
* Issue #779: Vimwiki tags file meets ctags standard. * Issue #779: Vimwiki tags file meets ctags standard.

View File

@ -172,7 +172,7 @@ endif
" Tables " Tables
syntax match VimwikiTableRow /^\s*|.\+|\s*$/ syntax match VimwikiTableRow /^\s*|.\+|\s*$/
\ transparent contains=VimwikiCellSeparator, \ transparent contains=VimwikiCellSeparator,
\ VimwikiLinkT, \ VimwikiLinkT,
\ VimwikiWeblink1T, \ VimwikiWeblink1T,

View File

@ -33,19 +33,19 @@ Execute (:VimwikiGoto + Completion in directory):
" Return to base " Return to base
VimwikiIndex 2 VimwikiIndex 2
AssertEqual $HOME . '/testmarkdown/index.md', expand('%') AssertEqual $HOME . '/testmarkdown/index.md', expand('%')
" Complete without argment " Complete without argment
let s_complete1=string(vimwiki#base#get_globlinks_escaped()) let s_complete1=string(vimwiki#base#get_globlinks_escaped())
Assert -1 != stridx(s_complete1, 'test_goto_file') Assert -1 != stridx(s_complete1, 'test_goto_file')
" Complete with file argument " Complete with file argument
let s_complete2=string(vimwiki#base#get_globlinks_escaped('test_goto_file')) let s_complete2=string(vimwiki#base#get_globlinks_escaped('test_goto_file'))
Assert -1 != stridx(s_complete2, 'test_goto_file') Assert -1 != stridx(s_complete2, 'test_goto_file')
" Complete with start of file argument " Complete with start of file argument
let s_complete3=string(vimwiki#base#get_globlinks_escaped('test_got')) let s_complete3=string(vimwiki#base#get_globlinks_escaped('test_got'))
Assert -1 != stridx(s_complete3, 'test_goto_file') Assert -1 != stridx(s_complete3, 'test_goto_file')
" Complete with (nested) dir2 argument " Complete with (nested) dir2 argument
let s_complete4=string(vimwiki#base#get_globlinks_escaped('dir2')) let s_complete4=string(vimwiki#base#get_globlinks_escaped('dir2'))
Assert -1 != stridx(s_complete4, 'test_goto_file') Assert -1 != stridx(s_complete4, 'test_goto_file')

View File

@ -0,0 +1,189 @@
Include: vader_includes/vader_setup.vader
Execute (Copy Wiki's Resources):
Log "Start: Copy Resources"
call CopyResources()
Execute (Mkdir dir1 dir2 dir11 dir12):
call system("mkdir $HOME/testmarkdown/dir1")
call system("mkdir $HOME/testmarkdown/dir1/dir11")
call system("mkdir $HOME/testmarkdown/dir1/dir12")
call system("mkdir $HOME/testmarkdown/dir2")
Given vimwiki (Void):
Execute (Create Test-Rename -> dir1/dir11/in_dir11.md and dir1/dir12/in_dir12.md and dir2/in_dir2.md):
edit $HOME/testmarkdown/Test-Rename.md
AssertEqual $HOME . '/testmarkdown/Test-Rename.md', expand('%')
AssertEqual 'markdown', vimwiki#vars#get_wikilocal('syntax')
AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr')
call append(0, ['# Test Rename', 'in_root.md', 'dir1/dir11/in_dir11.md', 'dir1/dir12/in_dir12.md', 'dir2/in_dir2.md'])
call WriteMe()
Do (Create in_root):
:Log 'Open Test-Rename.md'\<CR>
:edit $HOME/testmarkdown/Test-Rename.md\<CR>
:AssertEqual $HOME . '/testmarkdown/Test-Rename.md', expand('%')\<CR>\<Esc>
:Log 'Delete last line (easyer latter checks without trailing spaces)'\<CR>
Gdd
:Log 'Open in_root.md'\<CR>
gg
j\<CR>
j\<CR>
j\<CR>
j\<CR>
ggj0y$
:AssertEqual '[in_root](in_root.md)', @"\<CR>
0\<CR>
:AssertEqual $HOME . '/testmarkdown/in_root.md', expand('%')\<CR>
:Log 'Add link in_root.md -> dir1/dir11/in_dir11'\<CR>
ggi# Title in root\<CR>\<Esc>
idir1/dir11/in_dir11\<Esc>
:call WriteMe()\<CR>
:AssertEqual $HOME . '/testmarkdown/in_root.md', expand('%')\<CR>
:Log 'Open in_dir11.md: creating dirs'\<CR>
ggj"ay$
:AssertEqual 'reg dir1/dir11/in_dir11', 'reg ' . @a\<CR>
0\<CR>\<CR>
:AssertEqual 'file ' . $HOME . '/testmarkdown/dir1/dir11/in_dir11.md', 'file ' . expand('%')\<CR>
:Log 'One backspace for fun'\<CR>
\<BS>
:AssertEqual 'file ' . $HOME . '/testmarkdown/in_root.md', 'file ' . expand('%')\<CR>
Do (Create dir_11 -> dir_11):
:edit $HOME/testmarkdown/dir1/dir11/in_dir11_fix.md\<CR>
:Log 'Add link in_dir11_fix.md -> in_dir11'\<CR>
ggi# Title in dir11 fix\<CR>\<Esc>
iin_dir11\<Esc>
:call WriteMe()\<CR>
:Log 'Open in_dir11.md: creating dirs'\<CR>
ggj"ay$
:AssertEqual 'reg in_dir11', 'reg ' . @a\<CR>
0\<CR>\<CR>
y\<CR>
:AssertEqual 'file ' . $HOME . '/testmarkdown/dir1/dir11/in_dir11.md', 'file ' . expand('%')\<CR>
:Log 'One backspace for fun'\<CR>
\<BS>
:AssertEqual 'file ' . $HOME . '/testmarkdown/dir1/dir11/in_dir11_fix.md', 'file ' . expand('%')\<CR>
Execute (Fill in_dir11 content):
edit $HOME/testmarkdown/dir1/dir11/in_dir11.md
call append(0, ['# Title in_dir11', '[dir2 link](../../dir2/in_dir2.md)'])
call WriteMe()
Do (RenameLink in_dir11 -> new_dir11):
:edit $HOME/testmarkdown/dir1/dir11/in_dir11.md\<CR>
:AssertEqual 'file ' . $HOME . '/testmarkdown/dir1/dir11/in_dir11.md', 'file ' . expand('%')\<CR>
:AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr')\<CR>
:Log 'Rename'\<CR>
:call WriteMe()\<CR>
:VimwikiRenameLink\<CR>
y\<CR>
in_dir11_new\<CR>
:call WriteMe()\<Cr>
:Log 'Append filename'\<CR>
:call append('$', [expand('%')])\<CR>
Expect(With new filename at the end):
# Title in_dir11
[dir2 link](../../dir2/in_dir2.md)
/home/vimtest/testmarkdown/dir1/dir11/in_dir11_new.md
Execute (edit in_dir11_fix):
edit $HOME/testmarkdown/dir1/dir11/in_dir11_fix.md
Expect(Link to in_dir11_new):
# Title in dir11 fix
[in_dir11](in_dir11_new)
Execute (edit Test-Rename.md):
edit $HOME/testmarkdown/Test-Rename.md
Expect (Link to in_dir11_new):
# Test Rename
[in_root](in_root.md)
[dir1 dir11 in_dir11](dir1/dir11/in_dir11_new.md)
[dir1 dir12 in_dir12](dir1/dir12/in_dir12.md)
[dir2 in_dir2](dir2/in_dir2.md)
Do (in_dir2 -> in_dir2_new):
:edit $HOME/testmarkdown/dir2/in_dir2.md\<CR>
:Log 'Append filename'\<CR>
:call append('$', [expand('%')])\<CR>
:Log 'Rename'\<CR>
:call WriteMe()\<CR>
:VimwikiRenameLink\<CR>
y\<CR>
in_dir2_new\<CR>
:call WriteMe()\<Cr>
:Log 'Append filename'\<CR>
:call append('$', [expand('%')])\<CR>
Expect (old and new filenames):
/home/vimtest/testmarkdown/dir2/in_dir2.md
/home/vimtest/testmarkdown/dir2/in_dir2_new.md
Execute (edit Test-Rename.md):
edit $HOME/testmarkdown/Test-Rename.md
Expect (Link to in_dir11_new):
# Test Rename
[in_root](in_root.md)
[dir1 dir11 in_dir11](dir1/dir11/in_dir11_new.md)
[dir1 dir12 in_dir12](dir1/dir12/in_dir12.md)
[dir2 in_dir2](dir2/in_dir2_new.md)
Execute (edit in_dir11.md):
edit $HOME/testmarkdown/dir1/dir11/in_dir11_new.md
Expect (Link to in_dir2_new):
# Title in_dir11
[dir2 link](../../dir2/in_dir2_new.md)
/home/vimtest/testmarkdown/dir1/dir11/in_dir11_new.md
Execute (Clean dir1 and dir2):
Log "End: Clean"
call DeleteHiddenBuffers()
call system('rm $HOME/testmarkdown/Test-Rename.md')
call system('rm $HOME/testmarkdown/in_root.md')
call system('rm -r $HOME/testmarkdown/dir1')
call system('rm -r $HOME/testmarkdown/dir2')
Include: vader_includes/vader_teardown.vader
# vim: sw=2 foldmethod=indent foldlevel=30 foldignore=#

View File

@ -2,18 +2,18 @@ Include: vader_includes/vader_setup.vader
Given vimwiki (Internal links + one link to filenew): Given vimwiki (Internal links + one link to filenew):
# Contents # Contents
- [Test1](#Test1) - [Test1](#Test1)
- [Test2](#Test2) - [Test2](#Test2)
# Test1 # Test1
- [Test1](#Test1) - [Test1](#Test1)
- [Test2](#Test2) - [Test2](#Test2)
- [filenew](filenew) - [filenew](filenew)
# Test2 # Test2
- [Test1](#Test1) - [Test1](#Test1)
- [Test2](#Test2) - [Test2](#Test2)
- [filenew](filenew) - [filenew](filenew)

View File

@ -1,3 +1,9 @@
# Testting <CR> keypress in insert mode on list item
#
# Note: some trailing spaces are necessary at the end of list items like `1.`
# better read this file with `set list`
Include: vader_includes/vader_setup.vader Include: vader_includes/vader_setup.vader
Given vimwiki (List with hard wraps): Given vimwiki (List with hard wraps):
@ -112,13 +118,13 @@ Expect (No list continuation in code block):
Given vimwiki (List from help file): Given vimwiki (List from help file):
1. item 1. item
--- ---
1. item 1. item
continue continue
--- ---
1. 1.
--- ---
1. 1.
@ -135,19 +141,20 @@ Do (List ops):
3j 3j
A\<CR>\<Esc> A\<CR>\<Esc>
# Note: trailing space <- autoindent
Expect (List per VimwikiReturn 1 1): Expect (List per VimwikiReturn 1 1):
1. item 1. item
2. 2.
--- ---
1. item 1. item
continue continue
--- ---
1. 1.
2. 2.
--- ---
1. 1.
2. 2.
@ -165,21 +172,22 @@ Do (List ops):
3j 3j
A\<CR>\<Esc> A\<CR>\<Esc>
# Note: some trailing space added
Expect (List per VimwikiReturn 2 2): Expect (List per VimwikiReturn 2 2):
1. item 1. item
--- ---
1. item 1. item
continue continue
2. 2.
--- ---
1. 1.
--- ---
1. 1.
--- ---
@ -195,18 +203,19 @@ Do (List ops):
3j 3j
A\<CR>\<Esc> A\<CR>\<Esc>
Expect (List per VimwikiReturn 3 3): Expect (List per VimwikiReturn 3 3):
1. item 1. item
2. 2.
--- ---
1. item 1. item
continue continue
2. 2.
--- ---
--- ---
@ -227,19 +236,19 @@ Expect (List per VimwikiReturn 4 4):
1. item 1. item
--- ---
1. item 1. item
continue continue
--- ---
--- ---
--- ---
Execute (Map CR): Execute (Map CR):
@ -258,14 +267,14 @@ Expect (List per VimwikiReturn 3 5):
1. item 1. item
2. 2.
--- ---
1. item 1. item
continue continue
2. 2.
--- ---
--- ---
1. 1.

File diff suppressed because it is too large Load Diff

View File

@ -58,11 +58,14 @@ Before (Define functions):
" Delete Hidden buffer, usefull to clean " Delete Hidden buffer, usefull to clean
" Stole from: https://stackoverflow.com/a/8459043/2544873 " Stole from: https://stackoverflow.com/a/8459043/2544873
function! DeleteHiddenBuffers() function! DeleteHiddenBuffers()
let tpbl=[] let tpbl=[]
call map(range(1, tabpagenr('$')), 'extend(tpbl, tabpagebuflist(v:val))') call map(range(1, tabpagenr('$')), 'extend(tpbl, tabpagebuflist(v:val))')
for buf in filter(range(1, bufnr('$')), 'bufexists(v:val) && index(tpbl, v:val)==-1') for buf in filter(range(1, bufnr('$')), 'bufexists(v:val) && index(tpbl, v:val)==-1')
silent execute 'bwipeout!' buf if bufname(buf) =~ 'Vader'
endfor continue
endif
silent execute 'bwipeout!' buf
endfor
endfunction endfunction
" Write current file: helper to hide `set bt=` " Write current file: helper to hide `set bt=`

View File

@ -1,3 +1,6 @@
After (Cleanup): After (Cleanup):
delfunction SetSyntax delfunction SetSyntax
delfunction ReloadVimwiki delfunction ReloadVimwiki
delfunction DeleteHiddenBuffers
delfunction WriteMe
delfunction PrintCommand