Commits

ZyX_I  committed 335674f

@aurum/drivers/git, @aurum/repo: Added rf-diffname()
@aurum/repo: Made default rf-getstats() use rf-diffname()
@aurum/cmdutils: Made getdifffile() use rf-diffname()
@aurum/drivers/git: Added rf-diffre function

  • Participants
  • Parent commits 95f1462

Comments (0)

Files changed (5)

File doc/aurum.txt

     headers (normally lines starting with ^diff) and obtaining file names from 
     them. Is used by a number of command for obtaining current file name while 
     in diff buffer and also by |aurum-rf-getstats| function.
-    This function must return regex that captures filename into the first 
-    capturing group.
+  diffname :: line, regex, diffopts -> fname               *aurum-rf-diffname*
+    Given {line} that matches {regex} returned by |aurum-rf-diffre|, return 
+    a filename.
   getstats :: diff, diffopts -> stats                      *aurum-rf-getstats*
     Returns a dictionary describing summary of changes described in {diff} (it 
     is what |aurum-rf-diff| returns). Dictionary will contain the following 
                          calls |aurum-rf-setcsprop|.
   |aurum-rf-reltorepo|     Uses |aurum-repo.path| to get requested path.
   |aurum-rf-difftobuffer|  Wrapper around |aurum-rf-diff|.
+  |aurum-rf-diffname|      Uses value of first capturing group of given 
+                         regular expression.
   |aurum-rf-getstats|      Parses git-like unified diff, depends on 
-                         |aurum-rf-diffre|. For this function to work, first 
-                         eight characters of the expression returned by 
-                         |aurum-rf-diffre| must be equal to "\m^diff ".
+                         |aurum-rf-diffre| and |aurum-rf-diffname|.
   |aurum-rf-copy|          Copies file to destination (using command-line “cp” 
                          (cp -- source target), “copy” (copy source target) or 
                          |readfile()| + |writefile()| (in last case 
     1.0: Instead of depending on drivers, make drivers depend on @aurum/repo
     1.1: Added repo.branch and repo.label
     1.2: Added setlines function, default implementations of |aurum-rf-copy|, 
-         |aurum-rf-getstats| and |aurum-rf-getcsprop|.
+         |aurum-rf-getstats|, |aurum-rf-getcsprop| and |aurum-rf-diffname|.
 @aurum:
     0.1: Added :AuBranch and :AuName
 @aurum/edit:

File plugin/aurum/cmdutils.vim

 if !exists('s:_pluginloaded')
     execute frawor#Setup('0.0', {'@/resources': '0.0',
                 \                       '@/os': '0.0',
-                \                '@aurum/repo': '1.0',
+                \                '@aurum/repo': '1.2',
                 \                '@aurum/edit': '1.0',
                 \               '@aurum/cache': '0.0',
                 \             '@aurum/bufvars': '0.0',}, 0)
         return a:bvar.files[0]
     endif
     let diffre=a:bvar.repo.functions.diffre(a:bvar.repo, a:bvar.opts)
-    let lnum=search(diffre, 'bcnW')
-    if !lnum
+    let lnr=search(diffre, 'bcnW')
+    if !lnr
         return 0
     endif
-    return get(matchlist(getline(lnum), diffre), 1, 0)
+    return a:bvar.repo.functions.diffname(a:bvar.repo, getline(lnr), diffre,
+                \                         a:bvar.opts)
 endfunction
 "▶1 getfile :: [path] → path
 function s:F.getfile(files)

File plugin/aurum/drivers/git.vim

     return s:F.git(a:repo, 'cat-file', ['blob', a:rev.':'.a:file], {}, 1,
                 \  'filef', a:rev, a:file)
 endfunction
-"▶1 git.diff :: repo, rev, rev, files, diffopts → [String]
-let s:diffopts={
+"▶1 git.diff :: repo, rev, rev, files, opts → [String]
+let s:difftrans={
             \  'reverse': 'R',
             \ 'ignorews': 'ignore-all-space',
             \'iwsamount': 'ignore-space-change',
             \  'alltext': 'text',
         \}
 function s:git.diff(repo, rev1, rev2, files, opts)
-    let opts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:diffopts)
-    if has_key(opts, 'unified')
-        let opts.unified=''.opts.unified
+    let diffopts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:difftrans)
+    if has_key(diffopts, 'unified')
+        let diffopts.unified=''.diffopts.unified
     endif
-    let kwargs=copy(opts)
+    let kwargs=copy(diffopts)
     let args=[]
     if empty(a:rev2)
         if !empty(a:rev1)
                 \ 'difff', a:rev1, a:rev2, join(a:files, ', '))
     return r+['']
 endfunction
+"▶1 git.diffre :: _, opts → Regex
+let s:diffre='\m^diff --git \v((\")?%s\/.{-}\2) \2%s\/'
+function s:git.diffre(repo, opts)
+    if get(a:opts, 'reverse', 0)
+        return printf(s:diffre, 'b', 'a')
+    else
+        return printf(s:diffre, 'a', 'b')
+    endif
+endfunction
+"▶1 diffname :: _, line, diffre, _ → rpath
+function s:git.diffname(repo, line, diffre, opts)
+    return s:F.refile(get(matchlist(a:line, a:diffre), 1, 0))[2:]
+endfunction
 "▶1 nullnl :: [String] → [String]
 " Convert between lines (NL separated strings with NULLs represented as NLs) and 
 " NULL separated strings with NLs represented by NLs.

File plugin/aurum/drivers/mercurial.vim

     endif
 endfunction
 "▶1 hg.diff :: repo, rev1, rev2, [path], opts → diff::[String]
-"▶2 s:diffopts
-let s:diffopts={
+"▶2 s:difftrans
+let s:difftrans={
             \      'git': 'git',
             \  'reverse': 'reverse',
             \ 'ignorews': 'ignore_all_space',
 if s:usepythondriver "▶2
 function s:hg.diff(repo, rev1, rev2, files, opts)
     let r=[]
-    let opts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:diffopts)
+    let diffopts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:difftrans)
     try
         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("opts"))'
+                    \                  'vim.eval("diffopts"))'
     endtry
     return r
 endfunction
 else "▶2
 "▶3 getdiffcmd
 function s:F.getdiffcmd(repo, rev1, rev2, files, opts)
-    let opts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:diffopts)
+    let diffopts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:difftrans)
     let rev1=((empty(a:rev1))?(0):(shellescape(a:rev1, 1)))
     let rev2=((empty(a:rev2))?(0):(shellescape(a:rev2, 1)))
     let cmd='diff '
             let cmd.='-r '.rev1.' '
         endif
     endif
-    for [o, v] in items(opts)
+    for [o, v] in items(diffopts)
         if o is# 'unified'
             let cmd.='--'.o.' '.v.' '
         elseif v
         execute 'buffer' a:buf
     endif
     try
-        let opts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:diffopts)
+        let diffopts=s:_r.utils.diffopts(a:opts, a:repo.diffopts, s:difftrans)
         execute s:_r.py.cmd 'aurum.diffToBuffer(vim.eval("a:repo.path"), '.
                     \                          'vim.eval("a:rev1"), '.
                     \                          'vim.eval("a:rev2"), '.
                     \                          'vim.eval("a:files"), '.
-                    \                          'vim.eval("opts"))'
+                    \                          'vim.eval("diffopts"))'
     finally
         if oldbuf!=a:buf
             execute 'buffer' oldbuf
     endtry
 endfunction
 endif
-"▶1 diffre :: _, diffopts → regex
-function s:hg.diffre(repo, diffopts)
+"▶1 diffre :: _, opts → regex
+function s:hg.diffre(repo, opts)
     " XXX first characters must be identical for hg.getstats(), but it must not 
     " match lines not containing filename for getdifffile()
-    if get(a:diffopts, 'git', 0)
+    if get(a:opts, 'git', 0)
         return '\m^diff \V--git a/\(\.\{-}\) b/'
     else
         return '\m^diff \v.*\-r\ \w+\s(.*)$'

File plugin/aurum/repo.vim

         execute 'buffer' oldbuf
     endif
 endfunction
+"▶1 diffname :: _, line, diffre, _ → rpath
+function s:deffuncs.diffname(repo, line, diffre, opts)
+    return get(matchlist(a:line, a:diffre), 1, 0)
+endfunction
 "▶1 getstats :: _, diff, diffopts → stats
 " stats :: { ( "insertions" | "deletions" ): UInt,
 "            "files": { ( "insertions" | "deletions" ): UInt } }
-function s:deffuncs.getstats(repo, diff, diffopts)
-    let diffre=a:repo.functions.diffre(a:repo, a:diffopts)
+function s:deffuncs.getstats(repo, diff, opts)
+    let diffre=a:repo.functions.diffre(a:repo, a:opts)
     let i=0
     let llines=len(a:diff)
     let stats={'files': {}, 'insertions': 0, 'deletions': 0}
     while i<llines
         let line=a:diff[i]
         if line[:3] is# 'diff'
-            let file=get(matchlist(line, diffre[8:], 5), 1, 0)
+            let file=a:repo.functions.diffname(a:repo, line, diffre, a:opts)
             if file isnot 0
                 let stats.files[file]={'insertions': 0, 'deletions': 0,}
                 let i+=1