From 12d62651939df83800e9ef2424646d17863e4dcb Mon Sep 17 00:00:00 2001 From: EinfachToll Date: Wed, 8 Nov 2017 21:56:59 +0100 Subject: [PATCH] Unify path handling -- part 2 --- autoload/vimwiki/base.vim | 24 ++++----- autoload/vimwiki/diary.vim | 8 +-- autoload/vimwiki/html.vim | 2 +- autoload/vimwiki/path.vim | 104 ++++++++++++++++++++++++------------- autoload/vimwiki/vars.vim | 28 ++++------ plugin/vimwiki.vim | 2 +- 6 files changed, 96 insertions(+), 72 deletions(-) diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim index 6a87cf4..0f6a44a 100644 --- a/autoload/vimwiki/base.vim +++ b/autoload/vimwiki/base.vim @@ -185,8 +185,7 @@ function! vimwiki#base#resolve_link(link_text, ...) "{{{ let link_infos.index = source_wiki let link_infos.filename = - \ vimwiki#vars#get_wikilocal('path', link_infos.index) . - \ vimwiki#vars#get_wikilocal('diary_rel_path', link_infos.index) . + \ vimwiki#vars#get_wikilocal('diary_path', link_infos.index) . \ link_text . \ vimwiki#vars#get_wikilocal('ext', link_infos.index) elseif (link_infos.scheme ==# 'file' || link_infos.scheme ==# 'local') @@ -367,7 +366,7 @@ function! vimwiki#base#find_files(wiki_nr, directories_only) if wiki_nr >= 0 let root_directory = vimwiki#vars#get_wikilocal('path', wiki_nr) else - let root_directory = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path') + let root_directory = vimwiki#vars#get_wikilocal('diary_path') let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr') endif if a:directories_only @@ -395,7 +394,7 @@ function! vimwiki#base#get_wikilinks(wiki_nr, also_absolute_links) if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr') let cwd = vimwiki#path#wikify_path(expand('%:p:h')) elseif a:wiki_nr < 0 - let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path') + let cwd = vimwiki#vars#get_wikilocal('diary_path') else let cwd = vimwiki#vars#get_wikilocal('path', a:wiki_nr) endif @@ -410,7 +409,7 @@ function! vimwiki#base#get_wikilinks(wiki_nr, also_absolute_links) if a:wiki_nr == vimwiki#vars#get_bufferlocal('wiki_nr') let cwd = vimwiki#vars#get_wikilocal('path') elseif a:wiki_nr < 0 - let cwd = vimwiki#vars#get_wikilocal('path') . vimwiki#vars#get_wikilocal('diary_rel_path') + let cwd = vimwiki#vars#get_wikilocal('diary_path') endif let wikifile = fnamemodify(wikifile, ':r') " strip extension let wikifile = '/'.vimwiki#path#relpath(cwd, wikifile) @@ -1707,9 +1706,9 @@ endfunction " }}} " s:is_diary_file function! s:is_diary_file(filename) " {{{ let file_path = vimwiki#path#path_norm(a:filename) - let rel_path = vimwiki#vars#get_wikilocal('diary_rel_path') - let diary_path = vimwiki#path#path_norm(vimwiki#vars#get_wikilocal('path') . rel_path) - return rel_path != '' + let diary_path = vimwiki#path#path_norm(vimwiki#vars#get_wikilocal('diary_path')) + return vimwiki#path#equal(vimwiki#vars#get_wikilocal('path'), + \ vimwiki#vars#get_wikilocal('diary_path')) \ && file_path =~# '^'.vimwiki#u#escape(diary_path) endfunction " }}} @@ -1739,8 +1738,7 @@ endfunction " }}} function! s:normalize_link_in_diary(lnk) " {{{ let link = a:lnk . vimwiki#vars#get_wikilocal('ext') let link_wiki = vimwiki#vars#get_wikilocal('path') . '/' . link - let link_diary = vimwiki#vars#get_wikilocal('path') . '/' - \ . vimwiki#vars#get_wikilocal('diary_rel_path') . '/' . link + let link_diary = vimwiki#vars#get_wikilocal('diary_path') . '/' . link let link_exists_in_diary = filereadable(link_diary) let link_exists_in_wiki = filereadable(link_wiki) let link_is_date = a:lnk =~# '\d\d\d\d-\d\d-\d\d' @@ -1751,8 +1749,10 @@ function! s:normalize_link_in_diary(lnk) " {{{ let rxDesc = '' let template = vimwiki#vars#get_global('WikiLinkTemplate1') else - let depth = len(split(vimwiki#vars#get_wikilocal('diary_rel_path'), '/')) - let str = repeat('../', depth) . a:lnk . '|' . a:lnk + let relative_link = + \ vimwiki#path#relpath(vimwiki#vars#get_wikilocal('diary_path'), + \ vimwiki#vars#get_wikilocal('path')) + let str = relative_link . a:lnk . '|' . a:lnk let rxUrl = '^.*\ze|' let rxDesc = '|\zs.*$' let template = vimwiki#vars#get_global('WikiLinkTemplate2') diff --git a/autoload/vimwiki/diary.vim b/autoload/vimwiki/diary.vim index 3f662ed..52d1b22 100644 --- a/autoload/vimwiki/diary.vim +++ b/autoload/vimwiki/diary.vim @@ -22,7 +22,7 @@ endfunction "}}} function! s:diary_path(...) "{{{ let idx = a:0 == 0 ? vimwiki#vars#get_bufferlocal('wiki_nr') : a:1 - return vimwiki#vars#get_wikilocal('path', idx).vimwiki#vars#get_wikilocal('diary_rel_path', idx) + return vimwiki#vars#get_wikilocal('diary_path', idx) endfunction "}}} function! s:diary_index(...) "{{{ @@ -85,7 +85,7 @@ endfun "}}} fun! s:get_diary_links() "{{{ let rx = '^\d\{4}-\d\d-\d\d' - let s_files = glob(vimwiki#vars#get_wikilocal('path').vimwiki#vars#get_wikilocal('diary_rel_path').'*'.vimwiki#vars#get_wikilocal('ext')) + let s_files = glob(vimwiki#vars#get_wikilocal('diary_path') . '*' . vimwiki#vars#get_wikilocal('ext')) let files = split(s_files, '\n') call filter(files, 'fnamemodify(v:val, ":t") =~# "'.escape(rx, '\').'"') @@ -172,7 +172,7 @@ function! vimwiki#diary#make_note(wnum, ...) "{{{ let idx = 0 endif - call vimwiki#path#mkdir(vimwiki#vars#get_wikilocal('path', idx).vimwiki#vars#get_wikilocal('diary_rel_path', idx)) + call vimwiki#path#mkdir(vimwiki#vars#get_wikilocal('diary_path', idx)) if a:0 && a:1 == 1 let cmd = 'tabedit' @@ -284,7 +284,7 @@ endfunction "}}} function vimwiki#diary#calendar_sign(day, month, year) "{{{ let day = s:prefix_zero(a:day) let month = s:prefix_zero(a:month) - let sfile = vimwiki#vars#get_wikilocal('path').vimwiki#vars#get_wikilocal('diary_rel_path'). + let sfile = vimwiki#vars#get_wikilocal('diary_path') . \ a:year.'-'.month.'-'.day.vimwiki#vars#get_wikilocal('ext') return filereadable(expand(sfile)) endfunction "}}} diff --git a/autoload/vimwiki/html.vim b/autoload/vimwiki/html.vim index a8312a4..17c4b59 100644 --- a/autoload/vimwiki/html.vim +++ b/autoload/vimwiki/html.vim @@ -53,7 +53,7 @@ function! s:default_CSS_full_name(target_dir) " {{{ return vimwiki#path#join(path, vimwiki#vars#get_wikilocal('css_name')) endfunction "}}} -" Returns: 1 if it was createt, 0 if it already existed +" Returns: 1 if it was created, 0 if it already existed function! s:create_default_CSS(target_dir) " {{{ let css_full_name = s:default_CSS_full_name(a:target_dir) if vimwiki#path#exists(css_full_name) diff --git a/autoload/vimwiki/path.vim b/autoload/vimwiki/path.vim index a1a90af..94aa725 100644 --- a/autoload/vimwiki/path.vim +++ b/autoload/vimwiki/path.vim @@ -168,38 +168,43 @@ else endif +"---------------------------------------------------------- +" Path manipulation, i.e. do stuff with the paths of (not necessarily existing) files +"---------------------------------------------------------- -"XXX das kann man aber Einheitstesten! -" XXX überlegen, ob wir auch n Objekt für Wikilinks machen -" Alternativ kann man auch einen Dateipfad als Ordner + Dateinamen modellieren -" The used data types are + +" The used data types are (with their internal representation) " - directory object: a dictionary with the following entries: -" - 'protocoll' -- how to access the file. Supportet are 'scp' or 'file' +" - 'protocoll' -- how to access the file. Supported are 'scp' or 'file' " - 'is_unix' -- 1 if it's supposed to be a unix-like path " - 'path' -- a list containing the directory names starting at the root -" - file object: a list [directory_object, file name] +" - file object: a list [dir_obj, file name] " - file segment: representing e.g. a relative path. Is a list where the first " element is a list of directory names and the second the file name +" - directory segment: a list of directory names -" create and return a path object from a string. It is assumed that the given -" path is abolute and points to a file (not a directory) -function! vimwiki#path#from_absolute_file(filepath) + +" create and return a file object from a string. It is assumed that the given +" path is absolute and points to a file (not a directory) +function! vimwiki#path#file_obj(filepath) let filename = fnamemodify(a:filepath, ':p:t') let path = fnamemodify(a:filepath, ':p:h') - return [vimwiki#path#from_absolute_dir(path), filename] + return [vimwiki#path#dir_obj(path), filename] endfunction -function! vimwiki#path#from_absolute_dir(filepath) - if a:filepath =~# '^scp:' - let filepath = a:filepath[4:] +" create and return a dir object from a string. The given path should be +" absolute and point to a directory. +function! vimwiki#path#dir_obj(dirpath) + if a:dirpath =~# '^scp:' + let dirpath = a:dirpath[4:] let protocoll = 'scp' else - let filepath = resolve(a:filepath) + let dirpath = resolve(a:dirpath) let protocoll = 'file' endif - let path = split(vimwiki#path#chomp_slash(filepath), '\m[/\\]', 1) - let is_unix = filepath[0] ==# '/' + let path = split(vimwiki#path#chomp_slash(dirpath), '\m[/\\]', 1) + let is_unix = dirpath[0] ==# '/' let result = { \ 'is_unix' : is_unix, \ 'protocoll' : protocoll, @@ -208,43 +213,56 @@ function! vimwiki#path#from_absolute_dir(filepath) return result endfunction -function! vimwiki#path#current_file() - return vimwiki#path#from_absolute_file(expand('%:p')) -endfunction function! vimwiki#path#extension(file_object) return fnamemodify(a:file_object[1], ':e') endfunction + " Returns: the dir of the file object as dir object -function! vimwiki#path#directory(file_object) +function! vimwiki#path#directory_of_file(file_object) return copy(a:file_object[0]) endfunction + +" Returns: the file_obj's file name as a string function! vimwiki#path#filename(file_object) return a:file_object[1] endfunction -" XXX überlegen, ob man das scp vorne dranpackt -function! vimwiki#path#to_string(path) - let dir_obj = type(a:path) == 4 ? a:path : a:path[0] + +" Returns: the dir_obj or file_obj as string, ready to be used with the regular +" path handling functions in Vim +function! vimwiki#path#to_string(obj) + let dir_obj = type(a:obj) == 4 ? a:obj : a:obj[0] let separator = dir_obj.is_unix ? '/' : '\' let address = join(dir_obj.path, separator) . separator - if type(a:path) == 3 + if type(a:obj) == 3 let address .= a:path[1] endif return address endfunction +" Returns: the given a:dir_obj with a:str appended to the dir name +function! vimwiki#path#append_to_dirname(dir_obj, str) + let a:dir_obj.path[-1] .= a:str + return a:dir_obj +endfunction + + " Assume it is not an absolute path function! vimwiki#path#from_segment_file(path_segment) let filename = fnamemodify(a:path_segment, ':t') - let path = fnamemodify(a:filepath, ':h') + let path = fnamemodify(a:path_segment, ':h') let path_list = (path ==# '.' ? [] : split(path, '\m[/\\]', 1)) return [path_list, filename] endfunction +" Assume it is not an absolute path +function! vimwiki#path#from_segment_dir(path_segment) + return split(a:path_segment, '\m[/\\]', 1) +endfunction function! vimwiki#path#join(dir_path, file_segment) let new_dir_object = copy(a:dir_path) @@ -252,17 +270,13 @@ function! vimwiki#path#join(dir_path, file_segment) return [new_dir_object, a:file_segment[1]] endfunction - -function! vimwiki#path#exists(object) - if type(a:object) == 4 - return isdirectory(vimwiki#path#to_string(a:object)) - else - " glob() checks whether or not a file exists (readable, writable or not) - return glob(vimwiki#path#to_string(a:file_object)) != '' - endif +function! vimwiki#path#join_dir(dir_path, dir_segment) + let new_dir_object = copy(a:dir_path) + let new_dir_object.path += a:dir_segment + return new_dir_object endfunction -" returns the segment s, so that jon(dir, s) == file +" returns the segment s, so that join(dir, s) == file " we just assume the file is somewhere in dir function! vimwiki#path#subtract(dir_object, file_object) let path_rest = a:file_object[0].path[len(a:dir_object.path):] @@ -292,11 +306,31 @@ function! vimwiki#path#relpath(dir1_object, dir2_object) return result endfunction + +"----------------- +" File manipulation, i.e. do stuff with actually existing files +"----------------- + + +function! vimwiki#path#current_file() + return vimwiki#path#file_obj(expand('%:p')) +endfunction + +function! vimwiki#path#exists(object) + if type(a:object) == 4 + return isdirectory(vimwiki#path#to_string(a:object)) + else + " glob() checks whether or not a file exists (readable or writable) + return glob(vimwiki#path#to_string(a:object)) != '' + endif +endfunction + " this must be outside a function, because only outside a function expands " to the directory where this file is in let s:vimwiki_autoload_dir = expand(':p:h') + function! vimwiki#path#find_autoload_file(filename) - let autoload_dir = vimwiki#path#from_absolute_dir(s:vimwiki_autoload_dir) + let autoload_dir = vimwiki#path#dir_obj(s:vimwiki_autoload_dir) let filename_obj = vimwiki#path#from_segment_file(a:filename) let file = vimwiki#path#join(autoload_dir, filename_obj) if !vimwiki#path#exists(file) diff --git a/autoload/vimwiki/vars.vim b/autoload/vimwiki/vars.vim index 2872796..b907c20 100644 --- a/autoload/vimwiki/vars.vim +++ b/autoload/vimwiki/vars.vim @@ -152,19 +152,8 @@ function! s:populate_global_variables() endfunction -function! s:normalize_path(path) "{{{ - " trim trailing / and \ because otherwise resolve() doesn't work quite right - let path = substitute(a:path, '[/\\]\+$', '', '') - if path !~# '^scp:' - return resolve(expand(path)).'/' - else - return path.'/' - endif -endfunction "}}} - - -" g:vimwiki_wikilocal_vars is a list of dictionaries. One dict for every registered wiki. The last -" dictionary contains default values (used for temporary wikis) +" g:vimwiki_wikilocal_vars is a list of dictionaries: one dict for every registered wiki plus one +" (the last in the list) which contains the default values (used for temporary wikis). function! s:populate_wikilocal_options() let default_values = { \ 'auto_export': 0, @@ -230,18 +219,19 @@ endfunction function! s:validate_settings() for wiki_settings in g:vimwiki_wikilocal_vars - let wiki_settings['path'] = s:normalize_path(wiki_settings['path']) + let wiki_settings['path'] = vimwiki#path#dir_obj(wiki_settings['path']) let path_html = wiki_settings['path_html'] if !empty(path_html) - let wiki_settings['path_html'] = s:normalize_path(path_html) + let wiki_settings['path_html'] = vimwiki#path#dir_obj(path_html) else - let wiki_settings['path_html'] = s:normalize_path( - \ substitute(wiki_settings['path'], '[/\\]\+$', '', '').'_html/') + let wiki_settings['path_html'] = vimwiki#path#append_to_dirname(wiki_settings['path'], + \ '_html') endif - let wiki_settings['template_path'] = s:normalize_path(wiki_settings['template_path']) - let wiki_settings['diary_rel_path'] = s:normalize_path(wiki_settings['diary_rel_path']) + let wiki_settings['template_path'] = vimwiki#path#dir_obj(wiki_settings['template_path']) + let wiki_settings['diary_path'] = vimwiki#path#join_dir(wiki_settings['path'], + \ vimwiki#path#from_segment_dir(wiki_settings['diary_rel_path'])) endfor endfunction diff --git a/plugin/vimwiki.vim b/plugin/vimwiki.vim index 0eb33ae..317834c 100644 --- a/plugin/vimwiki.vim +++ b/plugin/vimwiki.vim @@ -31,7 +31,7 @@ endfunction "}}} " create a new temporary wiki for the current buffer function! s:create_temporary_wiki() let current_file = vimwiki#path#current_file() - let path = vimwiki#path#directory(current_file) + let path = vimwiki#path#directory_of_file(current_file) let ext = '.'.vimwiki#path#extension(current_file) let syntax_mapping = vimwiki#vars#get_global('ext2syntax')