Feature: VimwikiRenameFile 1/ to other dir 2/ take argument (completable) (Issue #926)

This commit is contained in:
Tinmarino 2020-07-29 00:37:44 -04:00
parent e785c6f5b4
commit 369a64cdc8
3 changed files with 172 additions and 37 deletions

View File

@ -1043,6 +1043,7 @@ endfunction
" Update link for all files in dir " Update link for all files in dir
" Param: old_url, new_url: path of the old, new url relative to ... " Param: old_url, new_url: path of the old, new url relative to ...
" Param: dir: directory of the files, relative to wiki_root " 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 function! s:update_wiki_links(wiki_nr, dir, old_url, new_url) abort
" Get list of wiki files " Get list of wiki files
let wiki_root = vimwiki#vars#get_wikilocal('path', a:wiki_nr) 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 = {} let cache_dict = {}
" Regex from path " Regex from path
function! s:compute_old_url_r(wiki_nr, dir_rel_fsource, old_url) abort " Param: wiki_nr <int> to get the syntax template
" Old url " Param: old_location <string> relative to the current wiki fsource
let old_url_r = a:dir_rel_fsource . a:old_url 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 ./ " Add potential ./
let old_url_r = '\%(\.[/\\]\)\?' . old_url_r let old_url_r = '\%(\.[/\\]\)\?' . old_url_r
" Compute old url regex with filename between \zs and \ze " 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 endif
" New url " New url
let new_url = dir_rel_fsource . a:new_url let new_url = simplify(dir_rel_fsource . a:new_url)
" Old url " Old url
" Avoid E713 " Avoid E713
let key = empty(dir_rel_fsource) ? 'NaF' : dir_rel_fsource let key = empty(dir_rel_fsource) ? 'NaF' : dir_rel_fsource
if index(keys(cache_dict), key) == -1 if index(keys(cache_dict), key) == -1
let cache_dict[key] = s:compute_old_url_r( 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 endif
let old_url_r = cache_dict[key] let old_url_r = cache_dict[key]
@ -1536,57 +1541,84 @@ function! vimwiki#base#delete_link() abort
endfunction endfunction
" Rename current file, update all links to it " Ask user for a new filepath
function! vimwiki#base#rename_link() abort " Returns: '' if fails
" Get filename relative to wiki root " Called: rename_link
let subdir = vimwiki#vars#get_bufferlocal('subdir') function! s:input_rename_link() abort
let old_fname = subdir.expand('%:t') " Ask confirmation
" 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
let val = input('Rename "'.expand('%:t:r').'" [y]es/[N]o? ') let val = input('Rename "'.expand('%:t:r').'" [y]es/[N]o? ')
if val !~? '^y' if val !~? '^y'
return return
endif endif
" Ask new name
let new_link = input('Enter new name: ') let new_link = input('Enter new name: ')
" Guard: Check link
if new_link =~# '[/\\]' if new_link =~# '[/\\]'
echomsg 'Vimwiki Error: Cannot rename to a filename with path!' echomsg 'Vimwiki Error: Cannot rename to a filename with path!'
return return
endif endif
if substitute(new_link, '\s', '', 'g') ==? '' if substitute(new_link, '\s', '', 'g') ==? ''
echomsg 'Vimwiki Error: Cannot rename to an empty filename!' echomsg 'Vimwiki Error: Cannot rename to an empty filename!'
return return
endif endif
" Check if new file well formed
let url = matchstr(new_link, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl')) let url = matchstr(new_link, vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'))
if url !=? '' if url !=? ''
let new_link = url return url
endif 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 new_link = subdir.new_link
let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr') 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) let fname = glob(new_fname)
if fname !=? '' if fname !=? ''
echomsg 'Vimwiki Error: Cannot rename to "'.new_fname.'". File with that name exist!' echomsg 'Vimwiki Error: Cannot rename to "'.new_fname.'". File with that name exist!'
return return
endif 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 try
echomsg 'Vimwiki: Renaming '.vimwiki#vars#get_wikilocal('path').old_fname.' to '.new_fname call mkdir(new_dir, 'p')
catch | endtry
endif
" Rename wiki link file
try
echomsg 'Vimwiki: Renaming '.wikiroot_path.old_fname.' to '.new_fname
let res = rename(expand('%:p'), expand(new_fname)) let res = rename(expand('%:p'), expand(new_fname))
if res != 0 if res != 0
throw 'Cannot rename!' throw 'Cannot rename!'
@ -1598,11 +1630,13 @@ function! vimwiki#base#rename_link() abort
let &buftype='nofile' let &buftype='nofile'
" Save current buffer: [file_name, buffer_name]
let cur_buffer = [expand('%:p'), vimwiki#vars#get_bufferlocal('prev_links')] let cur_buffer = [expand('%:p'), vimwiki#vars#get_bufferlocal('prev_links')]
" Get all wiki buffer
let blist = s:get_wiki_buffers() let blist = s:get_wiki_buffers()
" save wiki buffers " Save wiki buffers
for bitem in blist for bitem in blist
execute ':b '.escape(bitem[0], ' ') execute ':b '.escape(bitem[0], ' ')
execute ':update' execute ':update'
@ -1610,30 +1644,39 @@ function! vimwiki#base#rename_link() abort
execute ':b '.escape(cur_buffer[0], ' ') execute ':b '.escape(cur_buffer[0], ' ')
" remove wiki buffers " Remove wiki buffers
for bitem in blist for bitem in blist
execute 'bwipeout '.escape(bitem[0], ' ') execute 'bwipeout '.escape(bitem[0], ' ')
endfor endfor
let setting_more = &more let more_save = &more
setlocal nomore setlocal nomore
" update links " Update links
call s:update_wiki_links(wiki_nr, old_dir, s:tail_name(old_fname), s:tail_name(new_fname)) 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 " Restore wiki buffers
for bitem in blist for bitem in blist
if !vimwiki#path#is_equal(bitem[0], cur_buffer[0]) if !vimwiki#path#is_equal(bitem[0], cur_buffer[0])
call s:open_wiki_buffer(bitem) call s:open_wiki_buffer(bitem)
endif endif
endfor endfor
" Open the new buffer
call s:open_wiki_buffer([new_fname, cur_buffer[1]]) call s:open_wiki_buffer([new_fname, cur_buffer[1]])
" execute 'bwipeout '.escape(cur_buffer[0], ' ') " execute 'bwipeout '.escape(cur_buffer[0], ' ')
" Log success
echomsg 'Vimwiki: '.old_fname.' is renamed to '.new_fname echomsg 'Vimwiki: '.old_fname.' is renamed to '.new_fname
let &more = setting_more let &more = more_save
endfunction endfunction
@ -2442,6 +2485,23 @@ function! vimwiki#base#complete_links_escaped(ArgLead, CmdLine, CursorPos) abort
endfunction 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 " Read caption
" Called: by generate_links " Called: by generate_links
function! vimwiki#base#read_caption(file) abort function! vimwiki#base#read_caption(file) abort

View File

@ -264,7 +264,8 @@ command! -buffer VimwikiDeleteFile call vimwiki#base#delete_link()
command! -buffer VimwikiDeleteLink command! -buffer VimwikiDeleteLink
\ call vimwiki#base#deprecate("VimwikiDeleteLink", "VimwikiDeleteFile") | \ call vimwiki#base#deprecate("VimwikiDeleteLink", "VimwikiDeleteFile") |
\ call vimwiki#base#delete_link() \ 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 command! -buffer VimwikiRenameLink
\ call vimwiki#base#deprecate("VimwikiRenameLink", "VimwikiRenameFile") | \ call vimwiki#base#deprecate("VimwikiRenameLink", "VimwikiRenameFile") |
\ call vimwiki#base#rename_link() \ call vimwiki#base#rename_link()

View File

@ -1,6 +1,9 @@
Include: vader_includes/vader_setup.vader Include: vader_includes/vader_setup.vader
# Create directories I remove at end {{{1
##########################################
Execute (Copy Wiki's Resources): Execute (Copy Wiki's Resources):
Log "Start: Copy Resources" Log "Start: Copy Resources"
call CopyResources() call CopyResources()
@ -13,6 +16,74 @@ Execute (Mkdir dir1 dir2 dir11 dir12):
call system("mkdir $HOME/testmarkdown/dir2") 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): Given vimwiki (Void):
@ -86,7 +157,10 @@ Execute (Fill in_dir11 content):
call WriteMe() 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> :edit $HOME/testmarkdown/dir1/dir11/in_dir11.md\<CR>
:AssertEqual 'file ' . $HOME . '/testmarkdown/dir1/dir11/in_dir11.md', 'file ' . expand('%')\<CR> :AssertEqual 'file ' . $HOME . '/testmarkdown/dir1/dir11/in_dir11.md', 'file ' . expand('%')\<CR>
:AssertEqual 1, vimwiki#vars#get_bufferlocal('wiki_nr')\<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 Include: vader_includes/vader_teardown.vader
# vim: sw=2 foldmethod=indent foldlevel=30 foldignore=# # vim: sw=2 foldmethod=marker foldlevel=30 foldignore=#