commit c9ba53e204a64d106fe4e2c3208f60ebe17eb202
parent 81c67f97e4a240f5607295d2d96c8f073276eff1
Author: Tinmarino <tinmarino@gmail.com>
Date: Sat, 25 Jul 2020 03:40:50 -0400
Refractor: Path Add utility unixify #478
Basically unixify all before workingm then transofom in function os os
Util: Add function sort_len that a list of string according to the lenght of its content
Fix: VimwikiRenameLink doesn't update links in diary #90
Test: VimwikiRenameLink with nested directories
Prettify comments in autoload/path + remove antipattern
Define osxify function helper to solve windows Vs Unix : see #478
Path: remove useless temporary fix convertion before calling relpath (redundant) : see #478
Test: Fix typo
Path corrected (Thanks to test)
Diffstat:
5 files changed, 78 insertions(+), 62 deletions(-)
diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim
@@ -572,10 +572,6 @@ function! vimwiki#base#get_wikilinks(wiki_nr, also_absolute_links, pattern) abor
let result = []
for wikifile in files
let wikifile = fnamemodify(wikifile, ':r') " strip extension
- if vimwiki#u#is_windows()
- " TODO temporary fix see #478
- let wikifile = substitute(wikifile , '/', '\', 'g')
- endif
let wikifile = vimwiki#path#relpath(cwd, wikifile)
call add(result, wikifile)
endfor
@@ -587,10 +583,6 @@ function! vimwiki#base#get_wikilinks(wiki_nr, also_absolute_links, pattern) abor
let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path')
endif
let wikifile = fnamemodify(wikifile, ':r') " strip extension
- if vimwiki#u#is_windows()
- " TODO temporary fix see #478
- let wikifile = substitute(wikifile , '/', '\', 'g')
- endif
let wikifile = '/'.vimwiki#path#relpath(cwd, wikifile)
call add(result, wikifile)
endfor
diff --git a/autoload/vimwiki/path.vim b/autoload/vimwiki/path.vim
@@ -4,7 +4,32 @@
" Home: https://github.com/vimwiki/vimwiki/
-" Remove: trailing /
+
+" Unixify path
+function! s:unixify(path) abort
+ return substitute(a:path, '\', '/', 'g')
+endfunction
+
+
+" Windowsify path
+function! s:windowsify(path) abort
+ return substitute(a:path, '/', '\', 'g')
+endfunction
+
+
+" Define os specific path convertion
+if vimwiki#u#is_windows()
+ function! s:osxify(path) abort
+ return s:windowsify(a:path)
+ endfunction
+else
+ function! s:osxify(path) abort
+ return s:unixify(a:path)
+ endfunction
+endif
+
+
+" Remove last path delimitator (slash or backslash)
function! vimwiki#path#chomp_slash(str) abort
return substitute(a:str, '[/\\]\+$', '', '')
endfunction
@@ -22,7 +47,7 @@ else
endif
-" Collapse: sections like /a/b/../c to /a/c and /a/b/./c to /a/b/c
+" Collapse sections like /a/b/../c to /a/c and /a/b/./c to /a/b/c
function! vimwiki#path#normalize(path) abort
let path = a:path
while 1
@@ -37,36 +62,34 @@ function! vimwiki#path#normalize(path) abort
endfunction
-" Normalize: Convert \ -> /
+" Normalize path: \ -> / && /// -> / && resolve(symlinks)
function! vimwiki#path#path_norm(path) abort
- " /-slashes
- if a:path !~# '^scp:'
- let path = substitute(a:path, '\', '/', 'g')
- " treat multiple consecutive slashes as one path separator
- let path = substitute(path, '/\+', '/', 'g')
- " ensure that we are not fooled by a symbolic link
- return resolve(path)
- else
- return a:path
- endif
+ " return if scp
+ if a:path =~# '^scp:' | return a:path | endif
+ " convert backslash to slash
+ let path = substitute(a:path, '\', '/', 'g')
+ " treat multiple consecutive slashes as one path separator
+ let path = substitute(path, '/\+', '/', 'g')
+ " ensure that we are not fooled by a symbolic link
+ return resolve(path)
endfunction
-" Check: if link is to a directory.
+" Check if link is to a directory
function! vimwiki#path#is_link_to_dir(link) abort
" It should be ended with \ or /.
return a:link =~# '\m[/\\]$'
endfunction
-" Return: Absolute path, from a relative link
+" Get absolute path <- path relative to current file
function! vimwiki#path#abs_path_of_link(link) abort
return vimwiki#path#normalize(expand('%:p:h').'/'.a:link)
endfunction
-" Return: longest common path prefix of 2 given paths.
-" '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki'
+" Returns: longest common path prefix of 2 given paths.
+" Ex: '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki'
function! vimwiki#path#path_common_pfx(path1, path2) abort
let p1 = split(a:path1, '[/\\]', 1)
let p2 = split(a:path2, '[/\\]', 1)
@@ -84,7 +107,7 @@ function! vimwiki#path#path_common_pfx(path1, path2) abort
endfunction
-" Return: Relative path
+" Convert path -> full resolved slashed path
function! vimwiki#path#wikify_path(path) abort
let result = resolve(fnamemodify(a:path, ':p'))
if vimwiki#u#is_windows()
@@ -107,50 +130,41 @@ function! vimwiki#path#relpath(dir, file) abort
if empty(a:dir) || a:dir =~# '^\.[/\\]\?$'
return a:file
endif
- let result = []
- if vimwiki#u#is_windows()
- " TODO temporary fix see #478
- " not sure why paths get converted back to using forward slash
- " when passed to the function in the form C:\path\to\file
- let dir = substitute(a:dir, '/', '\', 'g')
- let file = substitute(a:file, '/', '\', 'g')
- let dir = split(dir, '\')
- let file = split(file, '\')
- else
- let dir = split(a:dir, '/')
- let file = split(a:file, '/')
- endif
+ " Unixify && Expand in
+ let s_dir = expand(s:unixify(a:dir))
+ let s_file = expand(s:unixify(a:file))
+
+ " Split path
+ let dir = split(s_dir, '/')
+ let file = split(s_file, '/')
+
+ " Shorten loop till equality
while (len(dir) > 0 && len(file) > 0) && vimwiki#path#is_equal(dir[0], file[0])
call remove(dir, 0)
call remove(file, 0)
endwhile
+
+ " Return './' if nothing left
if empty(dir) && empty(file)
- if vimwiki#u#is_windows()
- " TODO temporary fix see #478
- return '.\'
- else
- return './'
- endif
+ return s:osxify('./')
endif
+
+ " Build path segment
+ let segments = []
for segment in dir
- let result += ['..']
+ let segments += ['..']
endfor
for segment in file
- let result += [segment]
+ let segments += [segment]
endfor
- if vimwiki#u#is_windows()
- " TODO temporary fix see #478
- let result_path = join(result, '\')
- if a:file =~? '\m\\$'
- let result_path .= '\'
- endif
- else
- let result_path = join(result, '/')
- if a:file =~? '\m/$'
- let result_path .= '/'
- endif
+
+ " Join segments
+ let result_path = join(segments, '/')
+ if a:file =~# '\m/$'
+ let result_path .= '/'
endif
- return result_path
+
+ return s:osxify(result_path)
endfunction
diff --git a/autoload/vimwiki/u.vim b/autoload/vimwiki/u.vim
@@ -62,6 +62,16 @@ endfunction
" Trim spaces: leading and trailing
+function! vimwiki#u#sort_len(list) abort
+ function! s:len_compare(s1, s2) abort
+ let i1 = len(a:s1)
+ let i2 = len(a:s2)
+ return i1 == i2 ? 0 : i1 > i2 ? 1 : -1
+ endfunction
+ return sort(a:list, 's:len_compare')
+endfunction
+
+
function! vimwiki#u#trim(string, ...) abort
let chars = ''
if a:0 > 0
diff --git a/doc/vimwiki.txt b/doc/vimwiki.txt
@@ -808,7 +808,7 @@ Vimwiki file.
The status of parents is updated accordingly.
If you want to remove only items of the current nesting level, (re)define
a command that calls the same function with `0` as first argument: >
- :command! -buffer -range VimwikiRemoveDone call
+ :command! -buffer -range VimwikiRemoveDone call
\ vimwiki#lst#remove_done(0, "<range>", <line1>, <line2>)
<
*:VimwikiNextTask*
@@ -3675,6 +3675,7 @@ Contributors and their Github usernames in roughly chronological order:
- Rafael Castillo (@eltrufas)
- Reiner Herrmann (@reinerh)
+
==============================================================================
16. Changelog *vimwiki-changelog*
diff --git a/test/command_rename_link.vader b/test/command_rename_link.vader
@@ -129,7 +129,6 @@ Expect (Link to in_dir11_new):
[dir2 in_dir2](dir2/in_dir2.md)
-
Do (in_dir2 -> in_dir2_new):
:edit $HOME/testmarkdown/dir2/in_dir2.md\<CR>
@@ -148,7 +147,7 @@ Do (in_dir2 -> in_dir2_new):
Expect (old and new filenames):
-
+
/home/vimtest/testmarkdown/dir2/in_dir2.md
/home/vimtest/testmarkdown/dir2/in_dir2_new.md