~gpanders/dotfiles

530ed42a46d04e7c1edef3fa5671b23796260773 — Greg Anders 4 months ago 9fa40bf
[vim] Complete zettel tags as well as links
1 files changed, 54 insertions(+), 8 deletions(-)

M .vim/autoload/zet.vim
M .vim/autoload/zet.vim => .vim/autoload/zet.vim +54 -8
@@ 1,22 1,68 @@
function! zet#complete(findstart, base)
    let line = getline('.')
    if line =~# '^tags:'
        return s:compltag(line, a:findstart, a:base)
    else
        return s:compllink(line, a:findstart, a:base)
    endif
endfunction

function! s:zettels(base) abort
    let zettels = glob($ZETTEL_DIR . '/*.md', 0, 1)
    call map(zettels, 'fnamemodify(v:val, '':t'')')
    call filter(zettels, 'v:val =~# ''^\d\{14}'' && v:val =~? a:base')
    return zettels
endfunction

function! s:compltag(line, findstart, base)
    if a:findstart
        let line = getline('.')
        let start = col('.') - 1
        while start > 0 && line[start - 2:start - 1] !=# '[['
        while start > 0 && a:line[start - 1] !~# '[, ]'
            let start -= 1
        endwhile
        return start
    else
        let zettels = glob($ZETTEL_DIR . '/*.md', 0, 1)
        call map(zettels, 'fnamemodify(v:val, '':t'')')
        call filter(zettels, 'v:val =~? a:base')
        let zettels = s:zettels('')
        let alltags = []
        for zet in zettels
            let contents = readfile($ZETTEL_DIR . '/' . zet, 0, 5)
            let tags = split(matchstr(contents, '^tags:\s\+.\+$'), '^tags:\s\+')
            if empty(tags)
                continue
            endif

            call extend(alltags, split(tags[0], ', \?'))
        endfor

        call uniq(sort(alltags))

        let matches = []
        for tag in alltags
            if tag =~# a:base
                call add(matches, tag)
            endif
        endfor
        return matches
    endif
endfunction

function! s:compllink(line, findstart, base)
    if a:findstart
        let start = col('.') - 1
        while start > 0 && a:line[start - 2:start - 1] !=# '[['
            let start -= 1
        endwhile
        return start
    else
        let zettels = s:zettels(a:base)
        let matches = []
        for zet in zettels
            let word = matchstr(zet, '^\d\+')
            let contents = readfile($ZETTEL_DIR . '/' . zet, 0, 5)
            let title = split(matchstr(contents, '^title: .\+$'), '^title: ')
            call add(matches, {'word': word, 'menu': title[0]})
            let title = split(matchstr(contents, '^title:\s\+.\+$'), '^title:\s\+')
            if !empty(title)
                let word = matchstr(zet, '^\d\+')
                call add(matches, {'word': word, 'menu': title[0]})
            endif
        endfor
        return matches
    endif