commit 369a64cdc830526d40669fd319b09056f0b1fc4c
parent e785c6f5b4c946eba940d630c208311f574c5c5c
Author: Tinmarino <tinmarino@gmail.com>
Date: Wed, 29 Jul 2020 00:37:44 -0400
Feature: VimwikiRenameFile 1/ to other dir 2/ take argument (completable) (Issue #926)
Diffstat:
3 files changed, 173 insertions(+), 38 deletions(-)
diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim
@@ -1043,6 +1043,7 @@ endfunction
" Update link for all files in dir
" Param: old_url, new_url: path of the old, new url relative to ...
" Param: dir: directory of the files, relative to wiki_root
+" Called: rename_link
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)
@@ -1055,9 +1056,13 @@ function! s:update_wiki_links(wiki_nr, dir, old_url, new_url) abort
let cache_dict = {}
" 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
+ " Param: wiki_nr <int> to get the syntax template
+ " Param: old_location <string> relative to the current wiki fsource
+ function! s:compute_old_url_r(wiki_nr, old_location) abort
+ " Start, Read param
+ let old_url_r = a:old_location
+ " Escape the '\\/'
+ let old_url_r = escape(old_url_r, '\/')
" Add potential ./
let old_url_r = '\%(\.[/\\]\)\?' . old_url_r
" Compute old url regex with filename between \zs and \ze
@@ -1087,14 +1092,14 @@ function! s:update_wiki_links(wiki_nr, dir, old_url, new_url) abort
endif
" New url
- let new_url = dir_rel_fsource . a:new_url
+ let new_url = simplify(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)
+ \ a:wiki_nr, dir_rel_fsource . a:old_url)
endif
let old_url_r = cache_dict[key]
@@ -1536,57 +1541,84 @@ function! vimwiki#base#delete_link() abort
endfunction
-" Rename current file, update all links to it
-function! vimwiki#base#rename_link() abort
- " Get filename relative to wiki root
- let subdir = vimwiki#vars#get_bufferlocal('subdir')
- let old_fname = subdir.expand('%:t')
-
- " Get current path
- let old_dir = expand('%:p:h')
-
- " there is no file (new one maybe)
- if glob(expand('%:p')) ==? ''
- echomsg 'Vimwiki Error: Cannot rename "'.expand('%:p').
- \'". It does not exist! (New file? Save it before renaming.)'
- return
- endif
-
+" Ask user for a new filepath
+" Returns: '' if fails
+" Called: rename_link
+function! s:input_rename_link() abort
+ " Ask confirmation
let val = input('Rename "'.expand('%:t:r').'" [y]es/[N]o? ')
if val !~? '^y'
return
endif
+ " Ask new name
let new_link = input('Enter new name: ')
+ " Guard: Check link
if new_link =~# '[/\\]'
echomsg 'Vimwiki Error: Cannot rename to a filename with path!'
return
endif
-
if substitute(new_link, '\s', '', 'g') ==? ''
echomsg 'Vimwiki Error: Cannot rename to an empty filename!'
return
endif
+ " Check if new file well formed
let url = matchstr(new_link, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'))
if url !=? ''
- let new_link = url
+ return url
endif
+ return new_link
+endfunction
+
+
+" Rename current file, update all links to it
+" Param: [new_filepath <string>]
+function! vimwiki#base#rename_link(...) abort
+ " Get filename and dir relative to wiki root
+ let subdir = vimwiki#vars#get_bufferlocal('subdir')
+ " Get old file directory relative to current path
+ let old_dir = expand('%:p:h')
+ let old_fname = subdir.expand('%:t')
+ let wikiroot_path = vimwiki#vars#get_wikilocal('path')
+
+ " Clause: Check if there current buffer is a file (new buffer maybe)
+ if glob(expand('%:p')) ==? ''
+ echomsg 'Vimwiki Error: Cannot rename "'.expand('%:p').
+ \'". Current file does not exist! (New file? Save it before renaming.)'
+ return
+ endif
+
+ " Read new_link <- command line || input()
+ let new_link = a:0 > 0 ? a:1 : s:input_rename_link()
+ if new_link ==# '' | return | endif
+
let new_link = subdir.new_link
let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr')
- let new_fname = vimwiki#vars#get_wikilocal('path') . new_link . vimwiki#vars#get_wikilocal('ext')
+ let new_fname = simplify(wikiroot_path . new_link . vimwiki#vars#get_wikilocal('ext'))
- " do not rename if file with such name exists
+ " Guard: Do not rename if file with such name exists
let fname = glob(new_fname)
if fname !=? ''
echomsg 'Vimwiki Error: Cannot rename to "'.new_fname.'". File with that name exist!'
return
endif
- " rename wiki link file
+
+ " TODO Check new_file is in a wiki dir and warn user if not
+ " Create new directory if needed
+ let new_dir = fnamemodify(new_fname, ':h')
+ if exists('*mkdir')
+ " Sometimes complaining E739 if directory exists
+ try
+ call mkdir(new_dir, 'p')
+ catch | endtry
+ endif
+
+ " Rename wiki link file
try
- echomsg 'Vimwiki: Renaming '.vimwiki#vars#get_wikilocal('path').old_fname.' to '.new_fname
+ echomsg 'Vimwiki: Renaming '.wikiroot_path.old_fname.' to '.new_fname
let res = rename(expand('%:p'), expand(new_fname))
if res != 0
throw 'Cannot rename!'
@@ -1598,11 +1630,13 @@ function! vimwiki#base#rename_link() abort
let &buftype='nofile'
+ " Save current buffer: [file_name, buffer_name]
let cur_buffer = [expand('%:p'), vimwiki#vars#get_bufferlocal('prev_links')]
+ " Get all wiki buffer
let blist = s:get_wiki_buffers()
- " save wiki buffers
+ " Save wiki buffers
for bitem in blist
execute ':b '.escape(bitem[0], ' ')
execute ':update'
@@ -1610,30 +1644,39 @@ function! vimwiki#base#rename_link() abort
execute ':b '.escape(cur_buffer[0], ' ')
- " remove wiki buffers
+ " Remove wiki buffers
for bitem in blist
execute 'bwipeout '.escape(bitem[0], ' ')
endfor
- let setting_more = &more
+ let more_save = &more
setlocal nomore
- " update links
- call s:update_wiki_links(wiki_nr, old_dir, s:tail_name(old_fname), s:tail_name(new_fname))
-
- " restore wiki buffers
+ " Update links
+ let old_fname_abs = wikiroot_path . old_fname
+ let old_fname_rel_dir = vimwiki#path#relpath(old_dir, old_fname_abs)
+ let new_fname_rel_dir = vimwiki#path#relpath(old_dir, new_fname)
+ call s:update_wiki_links(
+ \ wiki_nr, old_dir,
+ \ fnamemodify(old_fname_rel_dir, ':r'),
+ \ fnamemodify(new_fname_rel_dir, ':r')
+ \ )
+
+ " Restore wiki buffers
for bitem in blist
if !vimwiki#path#is_equal(bitem[0], cur_buffer[0])
call s:open_wiki_buffer(bitem)
endif
endfor
+ " Open the new buffer
call s:open_wiki_buffer([new_fname, cur_buffer[1]])
" execute 'bwipeout '.escape(cur_buffer[0], ' ')
+ " Log success
echomsg 'Vimwiki: '.old_fname.' is renamed to '.new_fname
- let &more = setting_more
+ let &more = more_save
endfunction
@@ -2442,6 +2485,23 @@ function! vimwiki#base#complete_links_escaped(ArgLead, CmdLine, CursorPos) abort
endfunction
+" Complete filename relatie to current file
+" Called: rename_link
+function! vimwiki#base#complete_file(ArgLead, CmdLine, CursorPos) abort
+ " Start from current file
+ let base_path = expand('%:h')
+
+ " Get every file you can
+ let completion_pattern = base_path . '/' . a:ArgLead . '*'
+ let completion_list = split(glob(completion_pattern), '\n')
+
+ " Remove base_path prefix from the result
+ let base_len = len(base_path)
+ let completion_list = map(completion_list, 'v:val[base_len+1:]')
+ return completion_list
+endfunction
+
+
" Read caption
" Called: by generate_links
function! vimwiki#base#read_caption(file) abort
diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim
@@ -264,7 +264,8 @@ command! -buffer VimwikiDeleteFile call vimwiki#base#delete_link()
command! -buffer VimwikiDeleteLink
\ call vimwiki#base#deprecate("VimwikiDeleteLink", "VimwikiDeleteFile") |
\ call vimwiki#base#delete_link()
-command! -buffer VimwikiRenameFile call vimwiki#base#rename_link()
+command! -buffer -nargs=? -complete=customlist,vimwiki#base#complete_file
+ \ VimwikiRenameFile call vimwiki#base#rename_link(<f-args>)
command! -buffer VimwikiRenameLink
\ call vimwiki#base#deprecate("VimwikiRenameLink", "VimwikiRenameFile") |
\ call vimwiki#base#rename_link()
diff --git a/test/command_rename_link.vader b/test/command_rename_link.vader
@@ -1,6 +1,9 @@
Include: vader_includes/vader_setup.vader
+# Create directories I remove at end {{{1
+##########################################
+
Execute (Copy Wiki's Resources):
Log "Start: Copy Resources"
call CopyResources()
@@ -13,6 +16,74 @@ Execute (Mkdir dir1 dir2 dir11 dir12):
call system("mkdir $HOME/testmarkdown/dir2")
+# Test Transdirectory and argument {{{1
+# New feature #926
+
+# Create smaller unit {{{2
+
+# we stick all along with these 3 files,
+# Follow them !
+Execute (Create 3 files):
+ edit $HOME/testmarkdown/Test-Rename-zzz.md
+ call WriteMe()
+ edit $HOME/testmarkdown/dir1/dir11/Test-Rename.md
+ call WriteMe()
+ edit $HOME/testmarkdown/Test-Rename-Completion.md
+ call WriteMe()
+
+Do (Testing Completion {{{2):
+# Rename and test (zzz)
+ :VimwikiRenameFile Test-Rename-z\<C-l>1\<Cr>
+ :AssertEqual $HOME . '/testmarkdown/Test-Rename-zzz1.md', expand('%')\<CR>\<Esc>
+# Restore old name
+ :call WriteMe()\<Cr>
+ :VimwikiRenameFile Test-Rename-zzz\<Cr>
+
+
+Do (Testing transforward {{{2):
+ :Log 'Forward: root -> dir1/dir11 {{{3'\<Cr>
+# Create dir1/dir11/Test-Rename and link to it
+ :edit $HOME/testmarkdown/Test-Rename-Completion.md\<Cr>
+ idir1/dir11/Test-Rename.md\<Esc>
+ \<Cr>\<Cr>
+ :VimwikiRenameFile ../Test-Rename-2\<Cr>
+ :AssertEqual expand('%'), $HOME . '/testmarkdown/dir1/Test-Rename-2.md'\<CR>\<Esc>
+
+# See what happend in root
+ :call WriteMe()\<Cr>
+ :edit $HOME/testmarkdown/Test-Rename-Completion.md\<Cr>
+ :AssertEqual getline(1), '[dir1 dir11 Test Rename](dir1/Test-Rename-2.md)'\<Cr>
+
+ :Log 'Backward dir1/dir11 -> root {{{3'\<Cr>
+# See what happend in dir1/dir11
+# I am in root so pressing Enter sends me to dir1/dir11
+ \<Cr>
+# Write forward path
+ dd
+ i../Test-Rename-Completion\<Esc>
+# Convert it to link
+ 0\<Cr>\<Cr>
+
+# Now in root
+ :AssertEqual expand('%'), $HOME . '/testmarkdown/Test-Rename-Completion.md'\<Cr>
+ :VimwikiRenameFile dir1/Test-Rename-Completion-2\<Cr>
+ :AssertEqual expand('%'), $HOME . '/testmarkdown/dir1/Test-Rename-Completion-2.md'\<Cr>
+
+# Delete smaller unit changed {{{2
+
+Execute (Clean):
+ call DeleteFile('$HOME/testmarkdown/Test-Rename-zzz.md')
+ call DeleteFile('$HOME/testmarkdown/dir1/Test-Rename-Completion_2.md')
+ call DeleteFile('$HOME/testmarkdown/dir1/Test-Rename-2.md')
+
+
+# VimwikiRename Test same directory {{{1
+# Old big conf, from bad unit test design
+# Changing file in a single dir
+# Feel free to modify but as long as it works
+# I delay the cleaning
+####################################
+
Given vimwiki (Void):
@@ -86,7 +157,10 @@ Execute (Fill in_dir11 content):
call WriteMe()
-Do (RenameLink in_dir11 -> new_dir11):
+# Rename local {{{1
+###################
+
+Do (RenameLink in_dir11 -> in_dir11_new):
: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>
@@ -185,4 +259,4 @@ Execute (Clean dir1 and dir2):
Include: vader_includes/vader_teardown.vader
-# vim: sw=2 foldmethod=indent foldlevel=30 foldignore=#
+# vim: sw=2 foldmethod=marker foldlevel=30 foldignore=#