Skip to content

Commit 6ecf201

Browse files
committed
wip: refile
1 parent 34838e9 commit 6ecf201

File tree

2 files changed

+121
-47
lines changed

2 files changed

+121
-47
lines changed

autoload/wiki/page.vim

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -169,60 +169,27 @@ function! wiki#page#refile(...) abort "{{{1
169169
\ target_lnum: 0,
170170
\}, a:0 > 0 ? a:1 : {})
171171

172-
" Collect source data
173-
let l:source = wiki#toc#get_section()
172+
" target_page could be given by user input with something like this:
173+
" let l:opts.target_page = input('> ', '', 'customlist,wiki#complete#url')
174+
175+
let l:source = wiki#page#refile#collect_source(l:opts)
174176
if empty(l:source)
175177
return wiki#log#error('No source section recognized!')
176178
endif
177-
let l:source.path = expand('%:p')
178179

179-
" Collect target data
180-
let l:target = {}
181-
let l:target.path = wiki#u#eval_filename(l:opts.target_page)
182-
if !filereadable(l:target.path)
180+
try
181+
let l:target = wiki#page#refile#collect_target(l:opts)
182+
catch /wiki.vim: target page not found/
183183
return wiki#log#error('Target page was not found!')
184-
endif
185-
let l:target.lnum = l:opts.target_lnum
186-
let l:target.node = wiki#paths#to_node(l:target.path)
187-
let l:target.url = l:target.path !=# l:source.path
188-
\ ? wiki#paths#to_wiki_url(l:target.path, wiki#get_root())
189-
\ : ''
184+
catch /wiki.vim: anchor not recognized/
185+
return wiki#log#error('Target anchor not recognized!')
186+
endtry
190187

191188
call wiki#log#info(
192-
\ printf('Refiling section "%s" to page "%s"',
193-
\ l:source.header, l:target.node))
194-
195-
" Determine target anchor
196-
let l:current_anchors = get(wiki#toc#get_section(#{
197-
\ path: l:target.path,
198-
\ at_lnum: l:opts.target_lnum
199-
\}), 'anchors', [])
200-
let l:target_anchors = l:source.level > 1
201-
\ ? l:current_anchors[:l:source.level - 2]
202-
\ : []
203-
call add(l:target_anchors, l:source.anchors[-1])
204-
let l:target.anchor = '#' . join(l:target_anchors, '#')
205-
206-
" Move the section lines
207-
if empty(l:target.url)
208-
call execute(printf('%d,%dm %d',
209-
\ l:source.lnum, l:source.lnum_end, l:target.lnum))
210-
silent write
211-
else
212-
let l:lines = getline(l:source.lnum, l:source.lnum_end)
213-
call deletebufline('', l:source.lnum, l:source.lnum_end)
214-
silent write
215-
216-
let l:current_bufnr = bufnr('')
217-
let l:was_loaded = bufloaded(l:target.path)
218-
keepalt execute 'silent edit' fnameescape(l:target.path)
219-
call append(l:target.lnum, l:lines)
220-
silent write
221-
if !l:was_loaded
222-
keepalt execute 'bwipeout'
223-
endif
224-
keepalt execute 'buffer' l:current_bufnr
225-
endif
189+
\ printf('Moving section "%s" into "%s"',
190+
\ l:source.header, wiki#paths#to_node(l:target.path)))
191+
192+
call wiki#page#refile#move(l:source, l:target)
226193

227194
call s:update_links_local(l:source, l:target)
228195
call s:update_links_external(l:source, l:target)

autoload/wiki/page/refile.vim

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
" A wiki plugin for Vim
2+
"
3+
" Maintainer: Karl Yngve Lervåg
4+
5+
"
6+
7+
function! wiki#page#refile#collect_source() abort " {{{1
8+
" Returns:
9+
" source: dict(path, lnum, lnum_end, header, anchor)
10+
let l:source = wiki#toc#get_section()
11+
if !empty(l:source)
12+
let l:source.path = expand('%:p')
13+
endif
14+
15+
return l:source
16+
endfunction
17+
18+
" }}}1
19+
function! wiki#page#refile#collect_target(opts) abort " {{{1
20+
" Returns:
21+
" source: dict(path, lnum, anchor)
22+
23+
let l:path = wiki#u#eval_filename(l:opts.target_page)
24+
if !filereadable(l:path)
25+
throw 'wiki.vim: target page not found'
26+
endif
27+
28+
29+
if has_key(l:opts, 'target_anchor_before')
30+
return s:collect_target_by_anchor_before(l:path, l:opts.target_anchor_before)
31+
endif
32+
33+
return s:collect_target_by_lnum(l:path, l:opts.target_lnum)
34+
endfunction
35+
36+
" }}}1
37+
function! wiki#page#refile#move(source, target) abort " {{{1
38+
" Arguments:
39+
" source: dict(path, lnum, lnum_end)
40+
" target: dict(path, lnum)
41+
42+
if l:target.path ==# l:source.path
43+
call execute(printf('%d,%dm %d',
44+
\ l:source.lnum, l:source.lnum_end, l:target.lnum))
45+
silent write
46+
else
47+
let l:lines = getline(l:source.lnum, l:source.lnum_end)
48+
call deletebufline('', l:source.lnum, l:source.lnum_end)
49+
silent write
50+
51+
let l:current_bufnr = bufnr('')
52+
let l:was_loaded = bufloaded(l:target.path)
53+
keepalt execute 'silent edit' fnameescape(l:target.path)
54+
call append(l:target.lnum, l:lines)
55+
silent write
56+
if !l:was_loaded
57+
keepalt execute 'bwipeout'
58+
endif
59+
keepalt execute 'buffer' l:current_bufnr
60+
endif
61+
endfunction
62+
63+
" }}}1
64+
65+
function! s:collect_target_anchor_before(path, anchor) abort " {{{1
66+
let l:target_toc = wiki#toc#get_entries(#{ path: l:target.path })
67+
68+
for l:target_sec in l:target_toc
69+
if l:target_sec.anchor ==# l:opts.target_anchor_before
70+
break
71+
endif
72+
endfor
73+
74+
if empty(l:target_sec)
75+
throw 'wiki.vim: anchor not recognized'
76+
endif
77+
78+
let l:target.lnum = l:target_sec.lnum
79+
80+
let l:target_anchors = get(l:target_sec, 'anchors', [])
81+
if len(l:target_anchors) > 0
82+
call remove(l:target_anchors, -1)
83+
endif
84+
call add(l:target_anchors, l:source.anchors[-1])
85+
let l:target.anchor = '#' . join(l:target_anchors, '#')
86+
endfunction
87+
88+
" }}}1
89+
function! s:collect_target_by_lnum(path, lnum) abort " {{{1
90+
let l:current_anchors = get(wiki#toc#get_section(#{
91+
\ path: l:target.path,
92+
\ at_lnum: l:.target_lnum
93+
\}), 'anchors', [])
94+
let l:target_anchors = l:source.level > 1
95+
\ ? l:current_anchors[:l:source.level - 2]
96+
\ : []
97+
call add(l:target_anchors, l:source.anchors[-1])
98+
let l:target.anchor = '#' . join(l:target_anchors, '#')
99+
100+
let l:target = {
101+
\ 'path': a:path,
102+
\ 'lnum': a:lnum,
103+
\}
104+
105+
endfunction
106+
107+
" }}}1

0 commit comments

Comments
 (0)