Source

aurum / autoload / aurum / integrate.vim

"▶1 
scriptencoding utf-8
execute frawor#Setup('0.1', {'@%aurum/cmdutils': '4.3',
            \                '@%aurum/maputils': '0.1',
            \                 '@%aurum/bufvars': '0.0',
            \               '@%aurum/lineutils': '0.0',
            \                    '@%aurum/edit': '1.2',
            \                           '@/fwc': '0.0',
            \                            '@/os': '0.0',
            \                      '@/mappings': '0.0',})
let s:_messages={
            \'unresolved': 'Unable to commit: not all conflicts were resolved',
        \}
"▶1 genstatus
function s:F.genstatus(mergedict)
    let files=[]
    let statuses=[]
    let lines=[]
    for [file, st] in a:mergedict.filemap
        let [conflicted, curstatus, otherstatus]=st
        let line=     (conflicted ? '!' : ' ')
                    \.toupper(curstatus[0])
                    \.toupper(otherstatus)[0]
                    \.' '.file
        call add(files, file)
        call add(statuses, st)
        call add(lines, line)
    endfor
    return [files, statuses, lines]
endfunction
"▶1 setup
function s:F.setup(read, repo, rev, method)
    let mergedict=a:repo.functions.merge((empty(a:rev) ? 0 : a:rev),
                \                        a:method is# 'markers')
    let bvar={}
    let [files, statuses, lines]=s:F.genstatus(mergedict)
    let bvar.files=files
    let bvar.statuses=statuses
    let bvar.lines=lines
    call setline('.', lines)
    return bvar
endfunction
"▶1 aurum://integrate
call s:_f.newcommand({
            \'function': s:F.setup,
            \'arguments': 2,
            \'filetype': 'aurumintegrate',
            \'readable': 0,
        \})
"▶1 unload
function s:F.unload(bvar)
    let sbvar=get(a:bvar, 'sbvar', a:bvar)
    let sbuf=get(a:bvar, 'sbuf', -1)
    if sbuf isnot 0 && bufexists(sbuf)
        unlet sbvar.bwfunc
        execute 'bwipeout!' sbuf
    endif
endfunction
"▶1 getcontents :: mergedict, file, type → [line]
" type is one of "local", "base", "other"
function s:F.getcontents(repo, mergedict, file, type)
    if !has_key(a:mergedict, a:file)
        return readfile(s:_r.os.path.join(a:repo.path, a:file), 'b')
    endif
    let descr=a:mergedict[a:file][a:type]
    if type(descr)==type(0)
        return []
    elseif type(descr)==type('')
        return readfile(desrc, 'b')
    elseif type(descr)==type([])
        return desrc
    endif
endfunction
"▶1 Methods
let s:F.methods={}
let common
for [s:name, s:tabdesc] in [
            \['2way', {
            \      'top': ['AuIntegrateCurrent', 'AuIntegrateOther'],
            \   'bottom': 'AuIntegrateStatus',
            \  'oprefix': 'int',
            \   'unload': s:F.unload,
            \}],
            \['3way', {
            \      'top': ['AuIntegrateCurrent', 'AuIntegrateBase',
            \              'AuIntegrateOther'],
            \   'bottom': 'AuIntegrateStatus',
            \  'oprefix': 'int',
            \   'unload': s:F.unload,
            \}],
            \['markers', {
            \      'top': ['AuIntegrateCurrent', 'AuIntegrateOther'],
            \   'bottom': 'AuIntegrateStatus',
            \  'oprefix': 'int',
            \   'unload': s:F.unload,
            \}],
        \]
    call s:_f.tab.new('AuIntegrate_'.s:name, s:tabdesc)
endfor
unlet s:name s:tabdesc
"▶2 2way
let s:F.methods.2way={}
function s:F.methods.2way.open(bvar, file)
endfunction
"▶2 3way
let s:F.methods.3way={}
function s:F.methods.3way.open(bvar, file)
endfunction
"▶2 markers
let s:F.methods.markers={}
function s:F.methods.markers.open(bvar, file)
endfunction
"▶1 resetlines
function s:F.resetlines(bvar)
    for idx in range(len(a:bvar.lines))
        call setline(idx+1, s:statchars[a:bvar.statuses[idx]].a:bvar.lines[idx])
    endfor
endfunction
"▶1 run
let s:statchars='UR r'
function s:F.run(cmd, opts)
    let usemarkers=(a:opts.method is# 'markers')
    let [repo, rev] = s:_r.cmdutils.getrrf({}, 'norev', 'getrr')[1:2]
    let mergedict=repo.functions.merge(repo, rev, usemarkers)
    let cs=repo.functions.getcs(repo, rev)
    let sopts={'prefix': 'U'}
    call s:_r.run(a:cmd, 'status', repo, sopts)
    setlocal nomodifiable
    let bvar=s:_r.bufvars[bufnr('%')]
    let bvar.foreignactions=s:foreignactions
    let bvar.foreignmap=s:F.runstatmap
    let bvar.method=a:opts.method
    let bvar.mergedict=mergedict
    let bvar.statuses=map(copy(bvar.files), '1-get(mergedict, v:val, -1)')
    let bvar.copts={}
    if has_key(a:opts, 'message')
        let bvar.copts.message=a:opts.message
    else
        " TODO Include all commit messages from merged revisions
        let bvar.copts.message='Merge revision '.
                    \(repo.hasrevisions ? (cs.rev.' ('.cs.hex.')') : cs.hex)
        let bvar.copts.amend=1
    endif
    call s:F.resetlines(a:bvar)
    call s:_r.undo.setup(bvar, s:_f.getoption('fullundo'))
endfunction
"▶1 AuIntegrate
let s:_aufunctions.cmd={'@FWC': ['-onlystrings '.
            \'{ ?repo    '.s:_r.cmdutils.comp.repo.
            \'  ?rev     '.s:_r.cmdutils.comp.rev.
            \'  ?method  :"2way" key F.methods'.
            \'  ?message type""'.
            \' !?commit'.
            \'}', 'filter']}
let s:_aufunctions.comp=s:_r.cmdutils.gencompfunc(s:_aufunctions.cmd['@FWC'][0],
            \                                     [], s:_f.fwc.compile)
function s:_aufunctions.cmd.function(opts)
    let layout='AuIntegrate_'.a:opts.method
    call s:_f.tab.create(layout, run, [a:opts])
endfunction
"▶1 runstatmap
let s:foreignactions={
            \ 'track': 1,
            \'commit': 1,
            \'forget': 1,
        \}
function s:F.runstatmap(action)
    "▶2 buf, bvar
    let buf=get(a:000, 0, bufnr('%'))
    let bvar=s:_r.bufvars[buf]
    if !a:0
        if !s:_r.undo.preaction(bvar)
            return
        endif
    endif
    "▶2 undo
    let isundo=has_key(s:uactions, a:action)
    if isundo
        if !s:_r.undo.preundoaction(bvar, s:uactions[a:action])
            return
        endif
    endif
    "▶2 open action
    if a:action is# 'open'
        " return s:F.methods[]
    "▶2 commit action
    elseif a:actios is# 'commit'
        if filter(copy(bvar.statuses), '!v:val')
            call s:_f.throw('unresolved')
        endif
        call bvar.repo.functions.resolve(bvar.repo)
        let winview=winsaveview()
        " TODO Include information about conflicts into bvar.copts.message
        " Note: decide what to do if bvar.copts.message was populated from 
        " command-line
        let r=s:_f.tab.copen(a:bvar, a:buf, s:ntypeskeys, {})
        if r
            call s:F.unload(bvar)
        endif
    endif
endfunction
"▶1 runleftmap
function s:F.runleftmap(action, ...)
    let wnrs=s:_f.tab.getwnrs()
    let swnr=wnrs[-1]
    let sbuf=winbufnr(swnr)
    let sbvar=s:_r.bufvars[sbuf]
    if a:action is# 'discard'
    elseif a:action is# 'exit'
    elseif a:action is# 'diffget'
        let wnr=wnrs[1+(a:1 is# 'other')]
        let buf=winbufnr(wnr)
        execute 'diffget' buf
    endif
endfunction
"▶1 AuIntegrate mappings
function s:F.gm(...)
    return ':<C-u>call call(<SID>Eval("s:F.runstatmap"),'.string(a:000).','.
                \          '{})<CR>'
endfunction
function s:F.gml(...)
    return ':<C-u>call call(<SID>Eval("s:F.runleftmap"),'.string(a:000).','.
                \          '{})<CR>'
endfunction
call s:_f.mapgroup.add('AuIntegrateLeft3Way', {
            \'DiffGetOther': {'lhs': 'do', 'rhs': s:F.gml('diffget', 'other')},
            \'DiffGetBase':  {'lhs': 'dO', 'rhs': s:F.gml('diffget', 'base' )},
        \}, {'silent': 1, 'mode': 'n', 'dontmap': 1,})
call s:_f.mapgroup.add('AuIntegrateLeft', {
            \'Discard': {'lhs': 'x', 'rhs': s:F.gml('discard')},
            \'Exit':    {'lhs': 'X', 'rhs': s:F.gml('exit')},
        \}, {'silent': 1, 'mode': 'n', 'dontmap': 1, 'leader': '<Leader>'})
call s:_f.mapgroup.add('AuIntegrate', {
            \   'Edit': {'lhs': 'O',     'rhs': s:F.gm('edit')   },
            \   'Undo': {'lhs': 'u',     'rhs': s:F.gm('undo')   },
            \   'Redo': {'lhs': '<C-r>', 'rhs': s:F.gm('redo')   },
            \'Earlier': {'lhs': 'g-',    'rhs': s:F.gm('earlier')},
            \  'Later': {'lhs': 'g+',    'rhs': s:F.gm('later')  },
        \}, {'silent': 1})
"▶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.