Skip to content

Commit 89ce772

Browse files
committed
feat: add initial version of WikiPageRefile
refer: #58
1 parent 83be90c commit 89ce772

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

autoload/wiki/buffer.vim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function! s:init_buffer_commands() abort " {{{1
5959
command! -buffer WikiLinkReturn call wiki#nav#return()
6060
command! -buffer WikiLinkTransform call wiki#link#transform_current()
6161
command! -buffer WikiPageDelete call wiki#page#delete()
62+
command! -buffer WikiPageRefile call wiki#page#refile()
6263
command! -buffer WikiPageRename call wiki#page#rename()
6364
command! -buffer WikiPageRenameSection call wiki#page#rename_section()
6465
command! -buffer WikiTocGenerate call wiki#toc#create(0)
@@ -109,6 +110,7 @@ function! s:init_buffer_mappings() abort " {{{1
109110
nnoremap <silent><buffer> <plug>(wiki-link-return) :WikiLinkReturn<cr>
110111
nnoremap <silent><buffer> <plug>(wiki-link-transform) :WikiLinkTransform<cr>
111112
nnoremap <silent><buffer> <plug>(wiki-page-delete) :WikiPageDelete<cr>
113+
nnoremap <silent><buffer> <plug>(wiki-page-refile) :WikiPageRefile<cr>
112114
nnoremap <silent><buffer> <plug>(wiki-page-rename) :WikiPageRename<cr>
113115
nnoremap <silent><buffer> <plug>(wiki-page-rename-section) :WikiPageRenameSection<cr>
114116
nnoremap <silent><buffer> <plug>(wiki-toc-generate) :WikiTocGenerate<cr>
@@ -166,6 +168,7 @@ function! s:init_buffer_mappings() abort " {{{1
166168
\ '<plug>(wiki-link-transform)': '<leader>wf',
167169
\ '<plug>(wiki-link-transform-operator)': 'gl',
168170
\ '<plug>(wiki-page-delete)': '<leader>wd',
171+
\ '<plug>(wiki-page-refile)' : '<leader>wq',
169172
\ '<plug>(wiki-page-rename)': '<leader>wr',
170173
\ '<plug>(wiki-page-rename-section)': '<f2>',
171174
\ '<plug>(wiki-toc-generate)': '<leader>wt',

autoload/wiki/page.vim

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,84 @@ function! wiki#page#rename_section(...) abort "{{{1
169169
call s:update_links(l:old_anchor, l:new_anchor, 'rename_section')
170170
endfunction
171171

172+
" }}}1
173+
function! wiki#page#refile(...) abort "{{{1
174+
" This function refiles a page section from one page to another.
175+
"
176+
" Input: An optional dictionary with the following keys:
177+
" target_page: The target page name
178+
" target_lnum: The line number in target page where to refile
179+
180+
" Parse options
181+
let l:opts = extend(#{
182+
\ target_page: '',
183+
\ target_lnum: 0,
184+
\}, a:0 > 0 ? a:1 : {})
185+
if empty(l:opts.target_page)
186+
let l:opts.target_page = input('> ', '', 'customlist,wiki#complete#link')
187+
endif
188+
189+
let l:resolved_page = wiki#url#resolve(l:opts.target_page)
190+
if !filereadable(l:resolved_page.path)
191+
echo wiki#log#warn(l:resolved_page)
192+
return wiki#log#error('Target page was not found!')
193+
endif
194+
195+
" Get the relevant sections and start/end line numbers
196+
let l:sections = wiki#toc#gather_entries()
197+
let l:idx = indexof(l:sections, { _, x -> x.lnum > line('.') }) - 1
198+
if l:idx < 0
199+
return wiki#log#error('No current section recognized!')
200+
endif
201+
202+
let l:sections = l:sections[l:idx:]
203+
let l:sec = l:sections[0]
204+
let l:lnum_start = l:sec.lnum
205+
let l:lnum_end = line('$')
206+
if len(l:sections) > 1
207+
let l:idx = indexof(l:sections[1:], { _, x -> x.level <= l:sec.level })
208+
if l:idx >= 0
209+
let l:sections = l:sections[:l:idx + 1]
210+
let l:lnum_end = l:sections[1].lnum - 1
211+
endif
212+
endif
213+
214+
call wiki#log#info(
215+
\ printf('Refiling section "%s" to page "%s"',
216+
\ l:sec.header, l:opts.target_page))
217+
218+
" Get the lines of the section to refile
219+
let l:lines = getline(l:lnum_start, l:lnum_end)
220+
221+
" Append lines to target page
222+
let l:current_bufnr = bufnr('')
223+
silent execute 'edit' fnameescape(l:resolved_page.path)
224+
call append(l:opts.target_lnum, l:lines)
225+
silent update
226+
execute 'buffer' l:current_bufnr
227+
228+
" Delete lines from source page
229+
call deletebufline('', l:lnum_start, l:lnum_end)
230+
231+
" Update local links
232+
let l:pos = getcurpos()
233+
keepjumps execute printf(
234+
\ '%%s/\V\ze%s/%s/e%s',
235+
\ l:sec.anchor,
236+
\ wiki#paths#to_wiki_url(l:resolved_page.path, wiki#get_root()),
237+
\ &gdefault ? '' : 'g')
238+
call cursor(l:pos[1:])
239+
silent update
240+
241+
" Update links
242+
" * It is enough to update the "outer" anchor because the more specific
243+
" anchors should be covered by these as well.
244+
call s:update_links(
245+
\ #{anchor: l:sec.anchor, path: expand('%:p')},
246+
\ #{anchor: l:sec.anchor, path: l:resolved_page.path},
247+
\ 'refile')
248+
endfunction
249+
172250
" }}}1
173251
function! wiki#page#export(line1, line2, ...) abort " {{{1
174252
let l:cfg = deepcopy(g:wiki_export)
@@ -381,6 +459,35 @@ function! s:update_link_rename_section(anchor_old, anchor_new) abort "{{{1
381459
return [len(l:all_links), len(l:files_with_links)]
382460
endfunction
383461

462+
" }}}1
463+
function! s:update_link_refile(old, new) abort "{{{1
464+
let l:replacement_patterns
465+
\ = s:get_replacement_patterns(a:old.path, a:new.path)
466+
467+
let l:graph = wiki#graph#builder#get()
468+
let l:all_links = filter(
469+
\ l:graph.get_links_to(a:old.path),
470+
\ { _, x -> x.anchor =~# '^' . a:old.anchor })
471+
let l:files_with_links = wiki#u#group_by(l:all_links, 'filename_from')
472+
for [l:file, l:file_links] in items(l:files_with_links)
473+
let l:lines = readfile(l:file)
474+
475+
for l:link in l:file_links
476+
for [l:pattern, l:replace] in l:replacement_patterns
477+
let l:lines[l:link.lnum - 1] = substitute(
478+
\ l:lines[l:link.lnum - 1],
479+
\ l:pattern,
480+
\ l:replace,
481+
\ 'g')
482+
endfor
483+
endfor
484+
485+
call writefile(l:lines, l:file, 's')
486+
endfor
487+
488+
return [len(l:all_links), len(l:files_with_links)]
489+
endfunction
490+
384491
" }}}1
385492
function! s:get_replacement_patterns(path_old, path_new) abort " {{{1
386493
" Update "absolute" links (i.e. assume link is rooted)

0 commit comments

Comments
 (0)