|
| 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, level) |
| 10 | + |
| 11 | + let l:source = wiki#toc#get_section() |
| 12 | + if !empty(l:source) |
| 13 | + let l:source.path = expand('%:p') |
| 14 | + endif |
| 15 | + |
| 16 | + return l:source |
| 17 | +endfunction |
| 18 | + |
| 19 | +" }}}1 |
| 20 | +function! wiki#page#refile#collect_target(opts, source) abort " {{{1 |
| 21 | + " Arguments: |
| 22 | + " opts: dict( |
| 23 | + " target_page, |
| 24 | + " target_lnum, |
| 25 | + " target_anchor_before?, |
| 26 | + " ) |
| 27 | + " source: dict(path, lnum, lnum_end, header, anchor) |
| 28 | + " Returns: |
| 29 | + " target: dict(path, lnum, anchor, level) |
| 30 | + |
| 31 | + let l:path = wiki#u#eval_filename(a:opts.target_page) |
| 32 | + if !filereadable(l:path) |
| 33 | + throw 'wiki.vim: target page not found' |
| 34 | + endif |
| 35 | + |
| 36 | + |
| 37 | + if has_key(a:opts, 'target_anchor_before') |
| 38 | + return s:collect_target_by_anchor_before( |
| 39 | + \ l:path, |
| 40 | + \ a:opts.target_anchor_before, |
| 41 | + \ a:source |
| 42 | + \) |
| 43 | + endif |
| 44 | + |
| 45 | + return s:collect_target_by_lnum(l:path, a:opts.target_lnum, a:source) |
| 46 | +endfunction |
| 47 | + |
| 48 | +" }}}1 |
| 49 | +function! wiki#page#refile#move(source, target) abort " {{{1 |
| 50 | + " Arguments: |
| 51 | + " source: dict(path, lnum, lnum_end) |
| 52 | + " target: dict(path, lnum) |
| 53 | + |
| 54 | + if a:target.level < a:source.level |
| 55 | + call execute(printf('%d,%dg/^#/normal! 0%dx', |
| 56 | + \ a:source.lnum, a:source.lnum_end, a:source.level - a:target.level)) |
| 57 | + elseif a:target.level > a:source.level |
| 58 | + call execute(printf('%d,%dg/^#/normal! 0%di#', |
| 59 | + \ a:source.lnum, a:source.lnum_end, a:target.level - a:source.level)) |
| 60 | + endif |
| 61 | + |
| 62 | + if a:target.path ==# a:source.path |
| 63 | + call execute(printf('%d,%dm %d', |
| 64 | + \ a:source.lnum, a:source.lnum_end, a:target.lnum)) |
| 65 | + silent write |
| 66 | + else |
| 67 | + let l:lines = getline(a:source.lnum, a:source.lnum_end) |
| 68 | + call deletebufline('', a:source.lnum, a:source.lnum_end) |
| 69 | + silent write |
| 70 | + |
| 71 | + let l:current_bufnr = bufnr('') |
| 72 | + let l:was_loaded = bufloaded(a:target.path) |
| 73 | + keepalt execute 'silent edit' fnameescape(a:target.path) |
| 74 | + call append(a:target.lnum, l:lines) |
| 75 | + silent write |
| 76 | + if !l:was_loaded |
| 77 | + keepalt execute 'bwipeout' |
| 78 | + endif |
| 79 | + keepalt execute 'buffer' l:current_bufnr |
| 80 | + endif |
| 81 | +endfunction |
| 82 | + |
| 83 | +" }}}1 |
| 84 | + |
| 85 | +function! s:collect_target_by_anchor_before(path, anchor, source) abort " {{{1 |
| 86 | + let l:section = {} |
| 87 | + for l:section in wiki#toc#gather_entries(#{ path: a:path }) |
| 88 | + if l:section.anchor ==# a:anchor |
| 89 | + break |
| 90 | + endif |
| 91 | + endfor |
| 92 | + |
| 93 | + if empty(l:section) |
| 94 | + throw 'wiki.vim: anchor not recognized' |
| 95 | + endif |
| 96 | + |
| 97 | + let l:anchors = get(l:section, 'anchors', []) |
| 98 | + if len(l:anchors) > 0 |
| 99 | + call remove(l:anchors, -1) |
| 100 | + endif |
| 101 | + let l:anchors += [a:source.anchors[-1]] |
| 102 | + |
| 103 | + return #{ |
| 104 | + \ path: a:path, |
| 105 | + \ lnum: l:section.lnum - 1, |
| 106 | + \ anchor: '#' . join(l:anchors, '#'), |
| 107 | + \ level: len(l:anchors) |
| 108 | + \} |
| 109 | +endfunction |
| 110 | + |
| 111 | +" }}}1 |
| 112 | +function! s:collect_target_by_lnum(path, lnum, source) abort " {{{1 |
| 113 | + let l:anchors = [a:source.anchors[-1]] |
| 114 | + |
| 115 | + if a:source.level > 1 |
| 116 | + let l:section = wiki#toc#get_section(#{ path: a:path, at_lnum: a:lnum }) |
| 117 | + let l:target_anchors = get(l:section, 'anchors', []) |
| 118 | + call extend( |
| 119 | + \ l:anchors, |
| 120 | + \ l:target_anchors[:a:source.level - 2], |
| 121 | + \ 0 |
| 122 | + \) |
| 123 | + endif |
| 124 | + |
| 125 | + return #{ |
| 126 | + \ path: a:path, |
| 127 | + \ lnum: a:lnum, |
| 128 | + \ anchor: '#' . join(l:anchors, '#'), |
| 129 | + \ level: len(l:anchors) |
| 130 | + \} |
| 131 | +endfunction |
| 132 | + |
| 133 | +" }}}1 |
0 commit comments