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)
This commit is contained in:
Tinmarino 2020-07-25 03:40:50 -04:00
parent 81c67f97e4
commit c9ba53e204
5 changed files with 78 additions and 62 deletions

View File

@ -572,10 +572,6 @@ function! vimwiki#base#get_wikilinks(wiki_nr, also_absolute_links, pattern) abor
let result = [] let result = []
for wikifile in files for wikifile in files
let wikifile = fnamemodify(wikifile, ':r') " strip extension 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) let wikifile = vimwiki#path#relpath(cwd, wikifile)
call add(result, wikifile) call add(result, wikifile)
endfor 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') let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path')
endif endif
let wikifile = fnamemodify(wikifile, ':r') " strip extension 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) let wikifile = '/'.vimwiki#path#relpath(cwd, wikifile)
call add(result, wikifile) call add(result, wikifile)
endfor endfor

View File

@ -4,7 +4,32 @@
" Home: https://github.com/vimwiki/vimwiki/ " 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 function! vimwiki#path#chomp_slash(str) abort
return substitute(a:str, '[/\\]\+$', '', '') return substitute(a:str, '[/\\]\+$', '', '')
endfunction endfunction
@ -22,7 +47,7 @@ else
endif 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 function! vimwiki#path#normalize(path) abort
let path = a:path let path = a:path
while 1 while 1
@ -37,36 +62,34 @@ function! vimwiki#path#normalize(path) abort
endfunction endfunction
" Normalize: Convert \ -> / " Normalize path: \ -> / && /// -> / && resolve(symlinks)
function! vimwiki#path#path_norm(path) abort function! vimwiki#path#path_norm(path) abort
" /-slashes " return if scp
if a:path !~# '^scp:' if a:path =~# '^scp:' | return a:path | endif
let path = substitute(a:path, '\', '/', 'g') " convert backslash to slash
" treat multiple consecutive slashes as one path separator let path = substitute(a:path, '\', '/', 'g')
let path = substitute(path, '/\+', '/', 'g') " treat multiple consecutive slashes as one path separator
" ensure that we are not fooled by a symbolic link let path = substitute(path, '/\+', '/', 'g')
return resolve(path) " ensure that we are not fooled by a symbolic link
else return resolve(path)
return a:path
endif
endfunction endfunction
" Check: if link is to a directory. " Check if link is to a directory
function! vimwiki#path#is_link_to_dir(link) abort function! vimwiki#path#is_link_to_dir(link) abort
" It should be ended with \ or /. " It should be ended with \ or /.
return a:link =~# '\m[/\\]$' return a:link =~# '\m[/\\]$'
endfunction 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 function! vimwiki#path#abs_path_of_link(link) abort
return vimwiki#path#normalize(expand('%:p:h').'/'.a:link) return vimwiki#path#normalize(expand('%:p:h').'/'.a:link)
endfunction endfunction
" Return: longest common path prefix of 2 given paths. " Returns: longest common path prefix of 2 given paths.
" '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki' " Ex: '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki'
function! vimwiki#path#path_common_pfx(path1, path2) abort function! vimwiki#path#path_common_pfx(path1, path2) abort
let p1 = split(a:path1, '[/\\]', 1) let p1 = split(a:path1, '[/\\]', 1)
let p2 = split(a:path2, '[/\\]', 1) let p2 = split(a:path2, '[/\\]', 1)
@ -84,7 +107,7 @@ function! vimwiki#path#path_common_pfx(path1, path2) abort
endfunction endfunction
" Return: Relative path " Convert path -> full resolved slashed path
function! vimwiki#path#wikify_path(path) abort function! vimwiki#path#wikify_path(path) abort
let result = resolve(fnamemodify(a:path, ':p')) let result = resolve(fnamemodify(a:path, ':p'))
if vimwiki#u#is_windows() if vimwiki#u#is_windows()
@ -107,50 +130,41 @@ function! vimwiki#path#relpath(dir, file) abort
if empty(a:dir) || a:dir =~# '^\.[/\\]\?$' if empty(a:dir) || a:dir =~# '^\.[/\\]\?$'
return a:file return a:file
endif endif
let result = [] " Unixify && Expand in
if vimwiki#u#is_windows() let s_dir = expand(s:unixify(a:dir))
" TODO temporary fix see #478 let s_file = expand(s:unixify(a:file))
" not sure why paths get converted back to using forward slash
" when passed to the function in the form C:\path\to\file " Split path
let dir = substitute(a:dir, '/', '\', 'g') let dir = split(s_dir, '/')
let file = substitute(a:file, '/', '\', 'g') let file = split(s_file, '/')
let dir = split(dir, '\')
let file = split(file, '\') " Shorten loop till equality
else
let dir = split(a:dir, '/')
let file = split(a:file, '/')
endif
while (len(dir) > 0 && len(file) > 0) && vimwiki#path#is_equal(dir[0], file[0]) while (len(dir) > 0 && len(file) > 0) && vimwiki#path#is_equal(dir[0], file[0])
call remove(dir, 0) call remove(dir, 0)
call remove(file, 0) call remove(file, 0)
endwhile endwhile
" Return './' if nothing left
if empty(dir) && empty(file) if empty(dir) && empty(file)
if vimwiki#u#is_windows() return s:osxify('./')
" TODO temporary fix see #478
return '.\'
else
return './'
endif
endif endif
" Build path segment
let segments = []
for segment in dir for segment in dir
let result += ['..'] let segments += ['..']
endfor endfor
for segment in file for segment in file
let result += [segment] let segments += [segment]
endfor endfor
if vimwiki#u#is_windows()
" TODO temporary fix see #478 " Join segments
let result_path = join(result, '\') let result_path = join(segments, '/')
if a:file =~? '\m\\$' if a:file =~# '\m/$'
let result_path .= '\' let result_path .= '/'
endif
else
let result_path = join(result, '/')
if a:file =~? '\m/$'
let result_path .= '/'
endif
endif endif
return result_path
return s:osxify(result_path)
endfunction endfunction

View File

@ -62,6 +62,16 @@ endfunction
" Trim spaces: leading and trailing " 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 function! vimwiki#u#trim(string, ...) abort
let chars = '' let chars = ''
if a:0 > 0 if a:0 > 0

View File

@ -808,7 +808,7 @@ Vimwiki file.
The status of parents is updated accordingly. The status of parents is updated accordingly.
If you want to remove only items of the current nesting level, (re)define 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: > 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>) \ vimwiki#lst#remove_done(0, "<range>", <line1>, <line2>)
< <
*:VimwikiNextTask* *:VimwikiNextTask*
@ -3675,6 +3675,7 @@ Contributors and their Github usernames in roughly chronological order:
- Rafael Castillo (@eltrufas) - Rafael Castillo (@eltrufas)
- Reiner Herrmann (@reinerh) - Reiner Herrmann (@reinerh)
============================================================================== ==============================================================================
16. Changelog *vimwiki-changelog* 16. Changelog *vimwiki-changelog*

View File

@ -129,7 +129,6 @@ Expect (Link to in_dir11_new):
[dir2 in_dir2](dir2/in_dir2.md) [dir2 in_dir2](dir2/in_dir2.md)
Do (in_dir2 -> in_dir2_new): Do (in_dir2 -> in_dir2_new):
:edit $HOME/testmarkdown/dir2/in_dir2.md\<CR> :edit $HOME/testmarkdown/dir2/in_dir2.md\<CR>
@ -148,7 +147,7 @@ Do (in_dir2 -> in_dir2_new):
Expect (old and new filenames): Expect (old and new filenames):
/home/vimtest/testmarkdown/dir2/in_dir2.md /home/vimtest/testmarkdown/dir2/in_dir2.md
/home/vimtest/testmarkdown/dir2/in_dir2_new.md /home/vimtest/testmarkdown/dir2/in_dir2_new.md