Source

aurum / autoload / aurum / annotate.vim

"▶1 
scriptencoding utf-8
execute frawor#Setup('1.0', {'@%aurum/cmdutils': '3.0',
            \                 '@%aurum/bufvars': '0.0',
            \                    '@%aurum/edit': '1.0',
            \                          '@aurum': '1.0',
            \                     '@/resources': '0.0',
            \                         '@/table': '0.1',})
let s:_messages={
            \'nocsfile': 'File “%s” is not present in changeset %s '.
            \            'from the repository %s',
        \}
"▶1 formatann :: repo, cs, lnum, numlen → String
function s:F.formatann(repo, cs, lnum, numlen)
    if !has_key(self, a:cs.hex)
        let description=matchstr(a:cs.description, '\v\S@=\p.*\S@=\p')
        let oldlen=len(description)
        while s:_r.strdisplaywidth(description, a:numlen+1)>30
            let description=substitute(description, '.$', '', '')
        endwhile
        if len(description)<oldlen
            let description.='…'
        endif
        let descwidth=s:_r.strdisplaywidth(description, a:numlen+1)
        if descwidth<31
            let description.=repeat(' ', 31-descwidth)
        endif
        let user=substitute(a:cs.user, '\m\s*<[^>]\+>$', '', '')
        let self[a:cs.hex]=printf('%*s %s / %s', a:numlen, a:cs.rev,
                    \                            description, user)
    endif
    return self[a:cs.hex]
endfunction
"▶1 unload
function s:F.unload(bvar)
    if has_key(a:bvar, 'annbuf') && bufexists(a:bvar.annbuf)
        let annwin=s:F.findwin(a:bvar.annbuf)
        if annwin==-1
            let annwin=bufwinnr(a:bvar.annbuf)
        endif
        if annwin!=-1
            for [o, v] in items(a:bvar.saved)
                call setwinvar(annwin, '&'.o, v)
            endfor
        endif
    endif
endfunction
"▶1 setup
"▶2 getcs :: rev + self → cs + self
function s:F.getcs(rev)
    if has_key(self, a:rev)
        return self[a:rev]
    endif
    let cs=self.repo.functions.getcs(self.repo, a:rev)
    let self[a:rev]=cs
    return cs
endfunction
"▲2
function s:F.setup(read, repo, rev, file)
    let rev=a:repo.functions.getrevhex(a:repo, a:rev)
    let bvar={'rev': rev, 'file': a:file}
    let ann=copy(a:repo.functions.annotate(a:repo, rev, a:file))
    let d={'repo': a:repo, 'getcs': s:F.getcs}
    let css=map(copy(ann), 'd.getcs(v:val[1])')
    let d={}
    let nl=max(map(copy(css), 'len(v:val.rev)'))
    let bvar.files=map(copy(ann), 'v:val[0]')
    let bvar.linenumbers=map(copy(ann), 'v:val[2]')
    let bvar.revisions=map(copy(css), 'v:val.hex')
    let bvar.bwfunc=s:F.unload
    let lines=map(copy(css), 'call(s:F.formatann, [a:repo, v:val, v:key, '.
                \                                  nl.'],d)')
    if a:read
        call append('.', lines)
    else
        call setline('.', lines)
        setlocal readonly nomodifiable
    endif
    return bvar
endfunction
"▶1 findwin :: buf → win
function s:F.findwin(buf)
    let win=winnr()
    if win>1 && winbufnr(win-1)==a:buf
        return win-1
    elseif winbufnr(win+1)==a:buf
        return win+1
    else
        return -1
    endif
endfunction
"▶1 setannbuf
function s:F.setannbuf(bvar, annbuf)
    let a:bvar.annbuf=a:annbuf
    let a:bvar.saved={}
    let a:bvar.saved.scrollbind = &scrollbind
    let a:bvar.saved.cursorbind = &cursorbind
    let a:bvar.saved.wrap       = &wrap
    setlocal scrollbind cursorbind nowrap
    let buf=bufnr('%')
    let annwin=s:F.findwin(a:annbuf)
    if annwin==-1
        return
    endif
    execute annwin.'wincmd w'
    setlocal scrollbind cursorbind nowrap
    augroup AuAnnotateBW
        execute 'autocmd BufWipeOut,BufHidden <buffer='.a:annbuf.'> '.
                    \':if bufexists('.buf.') | '.
                    \   'call feedkeys("\<C-\>\<C-n>'.
                    \                 ':silent! bw '.buf.'\n") | '.
                    \ 'endif'
    augroup END
endfunction
let s:_augroups+=['AuAnnotateBW']
"▶1 foldopen
if has('folding')
    function s:F.foldopen()
        if &foldenable
            try
                " XXX Using silent! here because I am unable to catch E490 for 
                " unknown reason
                silent! %foldopen!
            catch /^Vim:(foldopen):E490:/
                " No folds found — ignore
            endtry
        endif
    endfunction
else
    function s:F.foldopen()
        " Doing nothing if there is no folding support
    endfunction
endif
"▶1 annfunc
" TODO Investigate why wiping out annotate buffer causes consumption of next
"      character under wine
function s:cmd.function(opts)
    let [hasannbuf, repo, rev, file]=s:_r.cmdutils.getrrf(a:opts, 'noafile',
                \                                         'annotate')
    if repo is 0
        return
    endif
    if rev is 0
        let rev=repo.functions.getworkhex(repo)
    endif
    let allfiles=repo.functions.getcsprop(repo, rev, 'allfiles')
    if index(allfiles, file)==-1
        call s:_f.throw('nocsfile', file, rev, repo.path)
    endif
    if hasannbuf==2
        let hasannbuf=!repo.functions.dirty(repo, file)
    endif
    if hasannbuf
        let annbuf=bufnr('%')
    else
        " TODO Check for errors
        let existed=s:_r.run('silent edit', 'file', repo, rev, file)
        let annbuf=bufnr('%')
        if !existed
            setlocal bufhidden=wipe
        endif
    endif
    let annwin=winnr()
    call s:F.foldopen()
    let lnr=line('.')
    let anwidth=min([42, winwidth(0)/2-1])
    call s:_r.run('silent leftabove '.anwidth.'vsplit', 'annotate', repo,
                \ rev, file)
    execute lnr
    setlocal bufhidden=wipe
    call s:F.setannbuf(s:_r.bufvars[bufnr('%')], annbuf)
endfunction
let s:_augroups+=['AuAnnotateBW']
"▶1 aurum://annotate
call s:_f.newcommand({'function': s:F.setup,
            \        'arguments': 2,
            \         'filetype': 'aurumannotate',})
"▶1 Post resource
call s:_f.postresource('annotate', {'setannbuf': s:F.setannbuf,
            \                        'foldopen': s:F.foldopen,})
"▶1
call frawor#Lockvar(s:, '_r,_pluginloaded')
" vim: ft=vim ts=4 sts=4 et fmr=▶,▲
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.