Commits

ZyX_I committed cecd946

Finished aurum://diff

  • Participants
  • Parent commits 3d5a6c3

Comments (0)

Files changed (2)

     let s:repos[a:path]=repo
     return repo
 endfunction
-"▶3 hg.getrevhex :: rev, repo → rev(hex)
-function s:F.hg.getrevhex(rev, repo)
+"▶3 hg.getrevhex :: repo, rev → rev(hex)
+function s:F.hg.getrevhex(repo, rev)
     execute s:_r.py.cmd
                 \ 'vim.command(''return "''+'.
                 \    'aurum.get_repo(vim.eval("a:repo.path"))'.
                 \                      'vim.eval("a:file"))'
     return r
 endfunction
+"▶3 hg.diff :: repo, rev1, rev2, [path], opts → [String]
+function s:F.hg.diff(repo, rev1, rev2, files, opts)
+    let r=[]
+    execute s:_r.py.cmd 'aurum.diff(vim.eval("a:repo.path"), '.
+                \                  'vim.eval("a:rev1"), '.
+                \                  'vim.eval("a:rev2"), '.
+                \                  'vim.eval("a:files"), '.
+                \                  'vim.eval("a:opts"))'
+    echom string(a:files)
+    return r
+endfunction
 "▶2 comm
 "▶3 comm.hasrepo
 function s:F.comm.hasrepo(path)
 endfunction
 "▶3 auefunc
 let s:bufvars={}
-"▶4 comm.repotuplesplit :: str → (repo, String, ...)
+"▶4 comm.repotuplesplit :: str, UInt → (repo, String, ...)
 function s:F.comm.repotuplesplit(str, num)
     let file=a:str
     let repopath=matchstr(file, '\v^(\\.|[^\\:]+)')
     call add(r, file)
     return r
 endfunction
+"▶4 comm.repotupleoptssplit :: str, UInt → (repo, ..., opts::Dictionary)
+function s:F.comm.repotupleoptssplit(str, num)
+    let [repo; strings]=s:F.comm.repotuplesplit(a:str, a:num+1)
+    let ostr=remove(strings, -1)
+    let opts={}
+    for o in split(ostr, '\v%(\\@<!\\%(\\\\)*)@<!,')
+        let colonidx=stridx(o, ':')
+        if colonidx==-1
+            continue
+        endif
+        let opts[o[:(colonidx-1)]]=o[(colonidx+1):]
+    endfor
+    return [repo]+strings+[opts]
+endfunction
 "▲4
 function s:auefunc.function()
+    "▶4 Split <amatch> into command and arguments
     let tail=substitute(expand('<amatch>'), '\V\^aurum://', '', '')
     let command=matchstr(tail, '\v^\w+')
     let tail=tail[len(command)+1:]
+    "▶4 glog command
     if command is# 'glog'
         let repo=s:F.comm.getrepo(tail)
         let s:bufvars[bufnr('%')]={'repo': repo}
         setlocal buftype=nofile filetype=aurumgraphlog bufhidden=wipe
+        runtime ftplugin/aurumgraphlog.vim
+    "▶4 file command
     elseif command is# 'file'
         let [repo, rev, file]=s:F.comm.repotuplesplit(tail, 2)
         setlocal buftype=nofile
         call setline('.', repo.functions.readfile(repo, rev, file))
+    "▶4 annotate command
     elseif command is# 'annotate'
         let [repo, rev, file]=s:F.comm.repotuplesplit(tail, 2)
         let s:bufvars[bufnr('%')]={'repo': repo, 'rev': rev, 'file': file}
         setlocal buftype=nofile filetype=aurumannotate bufhidden=wipe
+        runtime ftplugin/aurumannotate.vim
+    "▶4 diff command
     elseif command is# 'diff'
-        let [repo, rev1, rev2, files]=s:F.comm.repotuplesplit(tail, 3)
+        let [repo, rev1, rev2, files, opts]=s:F.comm.repotupleoptssplit(tail, 3)
+        "▶5 Get revisions and file list
         if empty(rev1) && empty(rev2)
             let rev2=repo.work_hex
         endif
         if !empty(rev1)
-            let rev1=repo.functions.gethex(repo, rev1)
+            let rev1=repo.functions.getrevhex(repo, rev1)
             let csfiles=repo.changesets[rev1].files
         endif
         if !empty(rev2)
-            let rev2=repo.functions.gethex(repo, rev2)
+            let rev2=repo.functions.getrevhex(repo, rev2)
             let csfiles=repo.changesets[rev2].files
         endif
         if !empty(rev1) && !empty(rev2)
             let cs1files=repo.changesets[rev1].files
             let cs2files=repo.changesets[rev2].files
-            let csfiles=filter(cs1files, 'index(cs2files, v:val)!=-1')
+            let csfiles=filter(cs1files, 'index(cs2files, v:val)!=-1')+cs2files
         endif
+        "▶5 Add directories to the list of files
+        for file in csfiles
+            while file isnot# '.'
+                let file=fnamemodify(file, ':h')
+                if file is# '.' || index(csfiles, file)!=-1
+                    break
+                endif
+                call add(csfiles, file)
+            endwhile
+        endfor
+        "▶5 Filter out requested files
         let filelist=[]
         for glob in split(files, '\v%(\\@<!\\%(\\\\)*)@<!,')
             let pattern='\V\^'.substitute(substitute(substitute(substitute(
                         \substitute(substitute(substitute(glob,
                         \'\v\\(.)', '\="\\{".char2nr(submatch(1))."}"', 'g'),
-                        \'\V**',    '\.\*',    'g'),
-                        \'\V*',     '\[^/]\*', 'g'),
-                        \'\V?',     '\.',      'g'),
-                        \'\V[',     '\\[',     'g'),
+                        \'\V**',    '\\.\\\\{42}',    'g'),
+                        \'\V*',     '\\\\{91}^/]\\*', 'g'),
+                        \'\V?',     '\\.',            'g'),
+                        \'\V[',     '\\[',            'g'),
                         \'\V\\{'.char2nr('\').'}', '\\\\', 'g'),
                         \'\V\\{\(\d\+\)}', '\=nr2char(submatch(1))', 'g').'\$'
             let filelist+=filter(csfiles, 'v:val=~#pattern && '.
                         \                 'index(filelist, v:val)==-1')
         endfor
-        echom string(filelist)
+        "▲5
         let s:bufvars[bufnr('%')]={'repo': repo, 'rev1': rev1, 'rev2': rev2,
                     \             'files': filelist,}
+        setlocal buftype=nofile filetype=diff
+        call setline('.', repo.functions.diff(repo, rev1, rev2, filelist, opts))
     endif
 endfunction
 "▶3 aubwfunc
 
-from mercurial import hg, ui
+from mercurial import hg, ui, commands
 import vim
 import json
 
-ui=ui.ui()
+vim_dumps=json.dumps
+
+class CaptureUI(ui.ui):
+    def __init__(self):
+        self._captured=[]
+        super(CaptureUI, self).__init__()
+
+    def write(self, *args, **kwargs):
+        target=self._buffers[-1] if self._buffers else self._captured
+        target.extend([str(a) for a in args])
+
+    def _getCaptured(self):
+        r=[s.replace("\0", "\n") for s in ("".join(self._captured)).split("\n")]
+        self._captured=[]
+        return r
 
 def get_repo(path):
-    return hg.repository(ui, path)
+    return hg.repository(ui.ui(), path)
 
 def set_rev_dict(cs, cs_vim):
     cs_vim['hex']=cs.hex()
         set_rev_dict(repo[curcsnum], cs_vim)
         css_vim.append(cs_vim)
         curcsnum+=1
-    vim.eval('extend(d, {"css": '+json.dumps(css_vim)+', '+
+    vim.eval('extend(d, {"css": '+vim_dumps(css_vim)+', '+
                         '"tip_hex": "'+tipcs.hex()+'", '+
                         '"work_hex": "'+repo['.'].hex()+'", '+
                         '"startrev": '+str(startrev)+'})')
     while curcsnum<=cscount:
         set_rev_dict(repo[curcsnum], repo_vim['cslist'][curcsnum])
         curcsnum+=1
-    vim.eval('extend(repo, '+json.dumps(repo_vim)+')')
+    vim.eval('extend(repo, '+vim_dumps(repo_vim)+')')
 
 def get_file(path, rev, filepath):
     fctx=get_repo(path)[rev].filectx(filepath)
     vim.eval('extend(r, '+
-            json.dumps(
+            vim_dumps(
                 [line.replace("\0", "\n") for line in fctx.data().split("\n")])+
                    ')')
 
     vim.eval('extend(r, ['+",".join(['"'+line[0].hex()+'"' for line in ann])+
                        '])')
 
+def diff(path, rev1, rev2, files, opts):
+    repo=get_repo(path)
+    ui=CaptureUI()
+    args=[ui, repo]+files
+    kwargs=opts
+    if rev1:
+        kwargs["change"]=rev1
+    elif rev2:
+        kwargs["rev"]=[rev2]
+    else:
+        kwargs["rev"]=[rev1, rev2]
+    commands.diff(*args, **kwargs)
+    vim.eval('extend(r, '+vim_dumps(ui._getCaptured())+')')