diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim index 3d68a2c..bcb94ee 100644 --- a/autoload/vimwiki/base.vim +++ b/autoload/vimwiki/base.vim @@ -194,28 +194,6 @@ function! vimwiki#base#print_wiki_state() "{{{ print wiki options endfor endfunction "}}} -" vimwiki#base#mkdir -" If the optional argument 'confirm' == 1 is provided, -" vimwiki#base#mkdir will ask before creating a directory -function! vimwiki#base#mkdir(path, ...) "{{{ - let path = expand(a:path) - if path !~# '^scp:' - if !isdirectory(path) && exists("*mkdir") - let path = vimwiki#u#chomp_slash(path) - if vimwiki#u#is_windows() && !empty(g:vimwiki_w32_dir_enc) - let path = iconv(path, &enc, g:vimwiki_w32_dir_enc) - endif - if a:0 && a:1 && tolower(input("Vimwiki: Make new directory: ".path."\n [Y]es/[n]o? ")) !~ "y" - return 0 - endif - call mkdir(path, "p") - endif - return 1 - else - return 1 - endif -endfunction " }}} - " vimwiki#base#file_pattern function! vimwiki#base#file_pattern(files) "{{{ Get search regex from glob() " string. Aim to support *all* special characters, forcing the user to choose @@ -355,7 +333,7 @@ function! vimwiki#base#resolve_scheme(lnk, as_html) " {{{ Resolve scheme endif " default link for directories - if vimwiki#u#is_link_to_dir(lnk) + if vimwiki#path#is_link_to_dir(lnk) let ext = (g:vimwiki_dir_link != '' ? g:vimwiki_dir_link. ext : '') endif elseif scheme =~ 'diary' @@ -741,20 +719,24 @@ function! vimwiki#base#edit_file(command, filename, anchor, ...) "{{{ " you'll have E77: Too many file names let fname = escape(a:filename, '% *|#') let dir = fnamemodify(a:filename, ":p:h") - if vimwiki#base#mkdir(dir, 1) - " check if the file we want to open is already the current file - " which happens if we jump to an achor in the current file. - " This hack is necessary because apparently Vim messes up the result of - " getpos() directly after this command. Strange. - if !(a:command == ':e ' && a:filename == expand('%:p')) - execute a:command.' '.fname - endif - if a:anchor != '' - call s:jump_to_anchor(a:anchor) - endif - else + + let ok = vimwiki#path#mkdir(dir, 1) + + if !ok echom ' ' echom 'Vimwiki: Unable to edit file in non-existent directory: '.dir + return + endif + + " check if the file we want to open is already the current file + " which happens if we jump to an achor in the current file. + " This hack is necessary because apparently Vim messes up the result of + " getpos() directly after this command. Strange. + if !(a:command == ':e ' && a:filename == expand('%:p')) + execute a:command.' '.fname + endif + if a:anchor != '' + call s:jump_to_anchor(a:anchor) endif " save previous link diff --git a/autoload/vimwiki/diary.vim b/autoload/vimwiki/diary.vim index 0ad42ec..6588644 100644 --- a/autoload/vimwiki/diary.vim +++ b/autoload/vimwiki/diary.vim @@ -234,7 +234,7 @@ function! vimwiki#diary#make_note(wnum, ...) "{{{ let idx = 0 endif - call vimwiki#base#mkdir(VimwikiGet('path', idx).VimwikiGet('diary_rel_path', idx)) + call vimwiki#path#mkdir(VimwikiGet('path', idx).VimwikiGet('diary_rel_path', idx)) if a:0 && a:1 == 1 let cmd = 'tabedit' @@ -309,8 +309,8 @@ function! vimwiki#diary#goto_prev_day() "{{{ endfunction "}}} function! vimwiki#diary#generate_diary_section() "{{{ - let current_file = vimwiki#u#path_norm(expand("%:p")) - let diary_file = vimwiki#u#path_norm(s:diary_index()) + let current_file = vimwiki#path#path_norm(expand("%:p")) + let diary_file = vimwiki#path#path_norm(s:diary_index()) if current_file == diary_file call s:delete_diary_section() call s:insert_diary_section() diff --git a/autoload/vimwiki/html.vim b/autoload/vimwiki/html.vim index 47c755a..95861ee 100644 --- a/autoload/vimwiki/html.vim +++ b/autoload/vimwiki/html.vim @@ -76,7 +76,7 @@ endfunction "}}} function! s:create_default_CSS(path) " {{{ let css_full_name = s:default_CSS_full_name(a:path) if glob(css_full_name) == "" - call vimwiki#base#mkdir(fnamemodify(css_full_name, ':p:h')) + call vimwiki#path#mkdir(fnamemodify(css_full_name, ':p:h')) let default_css = s:find_autoload_file('style.css') if default_css != '' let lines = readfile(default_css) @@ -1312,7 +1312,7 @@ function! s:use_custom_wiki2html() "{{{ endfunction " }}} function! vimwiki#html#CustomWiki2HTML(path, wikifile, force) "{{{ - call vimwiki#base#mkdir(a:path) + call vimwiki#path#mkdir(a:path) echomsg system(VimwikiGet('custom_wiki2html'). ' '. \ a:force. ' '. \ VimwikiGet('syntax'). ' '. @@ -1351,7 +1351,7 @@ function! vimwiki#html#Wiki2HTML(path_html, wikifile) "{{{ " echo 'Generating HTML ... ' "endif - call vimwiki#base#mkdir(path_html) + call vimwiki#path#mkdir(path_html) " nohtml placeholder -- to skip html generation. let nohtml = 0 @@ -1493,7 +1493,7 @@ function! vimwiki#html#WikiAll2HTML(path_html) "{{{ let &eventignore = save_eventignore let path_html = expand(a:path_html) - call vimwiki#base#mkdir(path_html) + call vimwiki#path#mkdir(path_html) echomsg 'Deleting non-wiki html files...' call s:delete_html_files(path_html) diff --git a/autoload/vimwiki/path.vim b/autoload/vimwiki/path.vim new file mode 100644 index 0000000..67b563f --- /dev/null +++ b/autoload/vimwiki/path.vim @@ -0,0 +1,126 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" Vimwiki autoload plugin file +" Path manipulation functions +" Author: Daniel Schemala +" Home: http://code.google.com/p/vimwiki/ + + +function! vimwiki#path#chomp_slash(str) "{{{ + return substitute(a:str, '[/\\]\+$', '', '') +endfunction "}}} + +" collapse sections like /a/b/../c to /a/c +function! vimwiki#path#normalize(path) "{{{ + let path = a:path + while 1 + let result = substitute(path, '/[^/]\+/\.\.', '', '') + if result == path + break + endif + let path = result + endwhile + return result +endfunction "}}} + +function! vimwiki#path#path_norm(path) "{{{ + " /-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 +endfunction "}}} + +function! vimwiki#path#is_link_to_dir(link) "{{{ + " Check if link is to a directory. + " It should be ended with \ or /. + if a:link =~ '.\+[/\\]$' + return 1 + endif + return 0 +endfunction "}}} + +function! vimwiki#path#abs_path_of_link(link) "{{{ + 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' +function! vimwiki#path#path_common_pfx(path1, path2) "{{{ + let p1 = split(a:path1, '[/\\]', 1) + let p2 = split(a:path2, '[/\\]', 1) + + let idx = 0 + let minlen = min([len(p1), len(p2)]) + while (idx < minlen) && (p1[idx] ==? p2[idx]) + let idx = idx + 1 + endwhile + if idx == 0 + return '' + else + return join(p1[: idx-1], '/') + endif +endfunction "}}} + +function! vimwiki#path#wikify_path(path) "{{{ + let result = resolve(expand(a:path, ':p')) + if vimwiki#u#is_windows() + let result = substitute(result, '\\', '/', 'g') + endif + let result = vimwiki#path#chomp_slash(result) + return result +endfunction "}}} + +" Returns: the relative path from a:dir to a:file +function! vimwiki#path#relpath(dir, file) "{{{ + let result = [] + let dir = split(a:dir, '/') + let file = split(a:file, '/') + while (len(dir) > 0 && len(file) > 0) && dir[0] == file[0] + call remove(dir, 0) + call remove(file, 0) + endwhile + for segment in dir + let result += ['..'] + endfor + for segment in file + let result += [segment] + endfor + return join(result, '/') +endfunction "}}} + +" If the optional argument provided and nonzero, +" it will ask before creating a directory +" Returns: 1 iff directory exists or successfully created +function! vimwiki#path#mkdir(path, ...) "{{{ + let path = expand(a:path) + + if path =~# '^scp:' + " we can not do much, so let's pretend everything is ok + return 1 + endif + + if isdirectory(path) + return 1 + else + if !exists("*mkdir") + return 0 + endif + + let path = vimwiki#path#chomp_slash(path) + if vimwiki#u#is_windows() && !empty(g:vimwiki_w32_dir_enc) + let path = iconv(path, &enc, g:vimwiki_w32_dir_enc) + endif + + if a:0 && a:1 && tolower(input("Vimwiki: Make new directory: ".path."\n [Y]es/[n]o? ")) !~ "^y" + return 0 + endif + + call mkdir(path, "p") + return 1 + endif +endfunction " }}} diff --git a/autoload/vimwiki/u.vim b/autoload/vimwiki/u.vim index 9104e64..b3020fc 100644 --- a/autoload/vimwiki/u.vim +++ b/autoload/vimwiki/u.vim @@ -14,7 +14,6 @@ function! vimwiki#u#trim(string, ...) "{{{ return res endfunction "}}} - " Builtin cursor doesn't work right with unicode characters. function! vimwiki#u#cursor(lnum, cnum) "{{{ exe a:lnum @@ -25,91 +24,20 @@ function! vimwiki#u#is_windows() "{{{ return has("win32") || has("win64") || has("win95") || has("win16") endfunction "}}} -function! vimwiki#u#chomp_slash(str) "{{{ - return substitute(a:str, '[/\\]\+$', '', '') -endfunction "}}} - function! vimwiki#u#time(starttime) "{{{ " measure the elapsed time and cut away miliseconds and smaller return matchstr(reltimestr(reltime(a:starttime)),'\d\+\(\.\d\d\)\=') endfunction "}}} -function! vimwiki#u#path_norm(path) "{{{ - " /-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 -endfunction "}}} - -function! vimwiki#u#is_link_to_dir(link) "{{{ - " Check if link is to a directory. - " It should be ended with \ or /. - if a:link =~ '.\+[/\\]$' - return 1 - endif - return 0 -endfunction " }}} - function! vimwiki#u#count_first_sym(line) "{{{ let first_sym = matchstr(a:line, '\S') return len(matchstr(a:line, first_sym.'\+')) endfunction "}}} -" return longest common path prefix of 2 given paths. -" '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki' -function! vimwiki#u#path_common_pfx(path1, path2) "{{{ - let p1 = split(a:path1, '[/\\]', 1) - let p2 = split(a:path2, '[/\\]', 1) - - let idx = 0 - let minlen = min([len(p1), len(p2)]) - while (idx < minlen) && (p1[idx] ==? p2[idx]) - let idx = idx + 1 - endwhile - if idx == 0 - return '' - else - return join(p1[: idx-1], '/') - endif -endfunction "}}} - function! vimwiki#u#escape(string) "{{{ return escape(a:string, '.*[]\^$') endfunction "}}} -function! vimwiki#u#wikify_path(path) "{{{ - let result = resolve(expand(a:path, ':p')) - if vimwiki#u#is_windows() - let result = substitute(result, '\\', '/', 'g') - endif - let result = vimwiki#u#chomp_slash(result) - return result -endfunction "}}} - -" Returns: the relative path from a:dir to a:file -function! vimwiki#u#relpath(dir, file) "{{{ - let result = [] - let dir = split(a:dir, '/') - let file = split(a:file, '/') - while (len(dir) > 0 && len(file) > 0) && dir[0] == file[0] - call remove(dir, 0) - call remove(file, 0) - endwhile - for segment in dir - let result += ['..'] - endfor - for segment in file - let result += [segment] - endfor - return join(result, '/') -endfunction "}}} - " Load concrete Wiki syntax: sets regexes and templates for headers and links function vimwiki#u#reload_regexes() "{{{ execute 'runtime! syntax/vimwiki_'.VimwikiGet('syntax').'.vim' diff --git a/plugin/vimwiki.vim b/plugin/vimwiki.vim index 5ed32ad..8d3a577 100644 --- a/plugin/vimwiki.vim +++ b/plugin/vimwiki.vim @@ -34,12 +34,12 @@ endfunction "}}} function! s:find_wiki(path) "{{{ " XXX: find_wiki() does not (yet) take into consideration the ext - let path = vimwiki#u#path_norm(vimwiki#u#chomp_slash(a:path)) + let path = vimwiki#path#path_norm(vimwiki#path#chomp_slash(a:path)) let idx = 0 while idx < len(g:vimwiki_list) let idx_path = expand(VimwikiGet('path', idx)) - let idx_path = vimwiki#u#path_norm(vimwiki#u#chomp_slash(idx_path)) - if vimwiki#u#path_common_pfx(idx_path, path) == idx_path + let idx_path = vimwiki#path#path_norm(vimwiki#path#chomp_slash(idx_path)) + if vimwiki#path#path_common_pfx(idx_path, path) == idx_path return idx endif let idx += 1