ZyX_I avatar ZyX_I committed e7f25e0

@aurum/drivers/mercurial: Made it always use s:_r.utils.getcmd to create commands

Comments (0)

Files changed (3)

 test/dummy.in
 test/*repo
 test/svntestreposerver
+testother

plugin/aurum/drivers/git.vim

 endfunction
 "▶1 gitcmd :: repo, cmd, args, kwargs, esc → String
 function s:F.gitcmd(repo, ...)
-    let cmd = 'git --git-dir='.  shellescape(a:repo.path.'/.git', a:4).
+    return 'git --git-dir='.  shellescape(a:repo.path.'/.git', a:4).
                 \' --work-tree='.shellescape(a:repo.path,         a:4).
                 \' '.call(s:_r.utils.getcmd, a:000, {})
-    return cmd
 endfunction
 "▶1 git :: repo, cmd, args, kwargs, has0[, msgid[, marg1[, …]]] → [String] + ?
 function s:F.git(repo, cmd, args, kwargs, hasnulls, ...)

plugin/aurum/drivers/mercurial.vim

             \'reponwr': 'Unable to write to repository root (%s)',
             \  'nocfg': 'Failed to get property %s of repository %s',
             \'nlocbms': 'Bookmarks can’t be local',
+            \'parsefail': 'Failed to parse changeset information',
+            \ 'filefail': 'Failed to get file %s '.
+            \             'from the repository %s: %s',
+            \ 'difffail': 'Failed to get diff between %s and %s '.
+            \             'for files %s from the repository %s: %s',
+            \ 'statfail': 'Failed to obtain status information '.
+            \             'for the repository %s: %s',
+            \  'annfail': 'Failed to annotate revision %s of file %s '.
+            \             'in the repository %s: %s',
+            \  'cspfail': 'Failed to get property %s for changeset %s '.
+            \             'in the repository %s: %s',
+            \  'logfail': 'Failed to get log for the repository %s: %s',
+            \  'keyfail': 'Failed to get %s for the repository %s: %s',
+            \   'csfail': 'Failed to get changeset %s '.
+            \             'from the repository %s: %s',
+            \  'renfail': 'Failed to get renames list for revision %s '.
+            \             'in the repository %s: %s',
+            \  'cmdfail': 'Failure while running command %s '.
+            \             'for the repository %s: %s',
+            \ 'grepfail': 'Failed to search through the repository %s: %s',
+            \   'scfail': 'Failed to show [paths] section '.
+            \             'for the repository %s: %s',
+            \ 'stat1mis': 'You must specify first revision as well',
         \}
-if !s:usepythondriver
-    call extend(s:_messages, {
-                \'parsefail': 'Failed to parse changeset information',
-                \ 'filefail': 'Failed to get file %s '.
-                \             'from the repository %s: %s',
-                \ 'difffail': 'Failed to get diff between %s and %s '.
-                \             'for files %s from the repository %s: %s',
-                \ 'statfail': 'Failed to obtain status information '.
-                \             'for the repository %s: %s',
-                \  'annfail': 'Failed to annotate revision %s of file %s '.
-                \             'in the repository %s: %s',
-                \  'cspfail': 'Failed to get property %s for changeset %s '.
-                \             'in the repository %s: %s',
-                \  'logfail': 'Failed to get log for the repository %s: %s',
-                \  'keyfail': 'Failed to get %s for the repository %s: %s',
-                \   'csfail': 'Failed to get changeset %s '.
-                \             'from the repository %s: %s',
-                \  'renfail': 'Failed to get renames list for revision %s '.
-                \             'in the repository %s: %s',
-                \  'cmdfail': 'Failure while running command %s '.
-                \             'for the repository %s: %s',
-                \ 'grepfail': 'Failed to search through the repository %s: %s',
-                \   'scfail': 'Failed to show [paths] section '.
-                \             'for the repository %s: %s',
-                \ 'stat1mis': 'You must specify first revision as well',
-            \})
-    let s:nullrev=repeat('0', 40)
-endif
+let s:nullrev=repeat('0', 40)
 "▶1 s:hypsites
 let s:hypsites=[]
 let s:gitrev='((!empty(cs.bookmarks))?'.
         endfor
     endfor
 endfunction
+"▶1 hgcmd :: repo, cmd, args, kwargs, esc → String
+function s:F.hgcmd(repo, ...)
+    return 'hg -R '.shellescape(a:repo.path, a:4).' '.
+                \call(s:_r.utils.getcmd, a:000, {})
+endfunction
+"▶1 hg :: repo, cmd, args, kwargs, esc, msgid[, throwarg1[, …]] → [String]
+function s:F.hg(repo, cmd, args, kwargs, hasnulls, ...)
+    let cmd=s:F.hgcmd(a:repo, a:cmd, a:args, a:kwargs, a:hasnulls)
+    let r=s:_r.utils.run(cmd, a:hasnulls, a:repo.path)
+    if v:shell_error && a:0
+        let args=copy(a:000)
+        let args[0].='fail'
+        call call(s:_f.throw, args+[a:repo.path, join(r[:-1-(a:hasnulls)],
+                    \                                 "\n")], {})
+    endif
+    return r
+endfunction
 if s:usepythondriver "▶1
 "▶2 addchangesets :: repo, [cs] → _ + repo
 function s:F.addchangesets(repo, css)
         endfor
     endfor
 endfunction
-"▶2 hg :: repo, cmd, hasnulls, msgid[, throwarg1[, …]] → [String]
-function s:F.hg(repo, cmd, hasnulls, msgid, ...)
-    let cmd='hg -R '.shellescape(a:repo.path, a:hasnulls).' '.a:cmd
-    let r=s:_r.utils.run(cmd, a:hasnulls, a:repo.path)
-    if v:shell_error
-        if a:msgid isnot 0
-            call call(s:_f.throw, [a:msgid.'fail']+a:000+[a:repo.path,
-                        \                              join(r[:-1-(a:hasnulls)],
-                        \                                      "\n")], {})
-        endif
-    endif
-    return r
-endfunction
 "▶2 unesc :: String → String
 let s:F.unesc=function('eval')
 "▶2 refile :: path → path
     return join(s:_r.os.path.split(a:path)[1:], '/')
 endfunction
 "▶2 parsecs :: csdata, lstart::UInt → (cs, line::UInt)
-let s:stylefile=shellescape(s:_r.os.path.join(s:_frawor.runtimepath,
-                \                             'misc', 'map-cmdline.csinfo'))
+let s:stylefile=s:_r.os.path.join(s:_frawor.runtimepath,
+                \                 'misc', 'map-cmdline.csinfo')
 let s:chars = [['P', 'parents'  ],
             \  ['T', 'tags'     ],
             \  ['B', 'bookmarks']]
 endfunction
 "▶2 getcslist :: repo, start, end
 function s:F.getcslist(repo, start, end)
-    let logbeg='log --style '.s:stylefile.' '
-    let lines=s:F.hg(a:repo, logbeg.'-r '.a:start.'..'.a:end, 0, 'log')[:-2]
+    let kwargs={'style': s:stylefile}
+    let lines=s:F.hg(a:repo, 'log', [],
+                \    extend({'rev': a:start.'..'.a:end}, kwargs), 0, 'log')[:-2]
     let css=[]
     if has_key(a:repo.changesets, s:nullrev)
         let cs0=a:repo.changesets[s:nullrev]
     else
-        let lines0=s:F.hg(a:repo, logbeg.'-r '.s:nullrev, 0, 'log')
+        let lines0=s:F.hg(a:repo, 'log', [], extend({'rev': s:nullrev}, kwargs),
+                    \     0, 'log')
         let cs0=s:F.parsecs(lines0, 0)[0]
     endif
     let llines=len(lines)
         let [cs, line]=s:F.parsecs(lines, line)
         if cs.rev-prevrev!=1
             let css+=map(range(prevrev+1, cs.rev-1),
-                        \'s:F.parsecs(s:F.hg(a:repo, logbeg."-r".v:val, 0, '.
-                        \                   '"log"), 0)[0]')
+                        \'s:F.parsecs(s:F.hg(a:repo, "log", [], '.
+                        \            'extend({"rev": "".v:val}, kwargs), 0, '.
+                        \            '"log"), 0)[0]')
         endif
         let css+=[cs]
         let prevrev=cs.rev
 endfunction
 "▶2 getkeylist :: repo, key → [(name, rev)]
 function s:F.getkeylist(repo, key)
-    let lines=s:F.hg(a:repo, a:key, 0, 'key', a:key)[:-2]
+    let lines=s:F.hg(a:repo, a:key, [], {}, 0, 'key', a:key)[:-2]
     if len(lines)==1 && lines[0]!~#'\v\ [1-9]\d*\:\x{12}$'
         return []
     endif
     endtry
 endfunction
 else "▶2
-let s:getrevhextemplate=shellescape('{node}')
+let s:getrevhextemplate='{node}'
 function s:hg.getrevhex(repo, rev)
     if type(a:rev)==type('') && (has_key(a:repo.changesets, a:rev) ||
                 \                a:rev=~#'\v^[0-9a-f]{40}$')
     elseif type(a:rev)==type(0) && a:rev<len(a:repo.cslist)
         return a:repo.cslist[a:rev].hex
     endif
-    let hex=get(s:F.hg(a:repo, 'log --template '.s:getrevhextemplate.' '.
-                \                  '-r '.shellescape(a:rev), 0, 'log'), 0, 0)
+    let hex=get(s:F.hg(a:repo, 'log', [], {'template': s:getrevhextemplate,
+                \                               'rev': ''.a:rev}, 0, 'log'),0,0)
     if hex is 0
         call s:_f.throw('norev', a:rev, a:repo.path)
     endif
 endfunction
 else "▶2
 function s:hg.readfile(repo, rev, file)
-    return s:F.hg(a:repo, 'cat -r '.shellescape(a:rev, 1).' -- '.
-                \                   shellescape(a:file, 1), 1, 'file', a:file)
+    return s:F.hg(a:repo, 'cat', ['--',a:file], {'rev': ''.a:rev}, 1,
+                \ 'file', a:file)
 endfunction
 endif
 "▶1 hg.annotate :: repo, rev, file → [(file, rev, linenumber)]
 endfunction
 else "▶2
 function s:hg.annotate(repo, rev, file)
-    let cmd='annotate -r '.shellescape(a:rev,1).' -fnl -- '.
-                \     shellescape(a:file,1)
     let r=[]
-    let lines=s:F.hg(a:repo, cmd, 1, 'ann', a:rev, a:file)
+    let lines=s:F.hg(a:repo, 'annotate', ['--', a:file],
+                \    {'rev': ''.a:rev, 'file':1, 'number':1, 'line-number':1},
+                \    1, 'ann', a:rev, a:file)
     for line in lines
         " XXX This won't work for files that start with spaces and also with 
         " some other unusual filenames that can be present in a repository
 else "▶2
 function s:hg.setcsprop(repo, cs, prop)
     if a:prop is# 'allfiles'
-        let r=s:F.hg(a:repo, 'manifest -r '.a:cs.rev, 0,
+        let r=s:F.hg(a:repo, 'manifest', [], {'rev': a:cs.hex}, 0,
                     \'csp', a:prop, a:cs.rev)[:-2]
     elseif a:prop is# 'children'
         " XXX str2nr('123:1f6de') will return number 123
-        let r=map(split(s:F.hg(a:repo, 'log -r '.a:cs.rev.' --template '.
-                    \                       shellescape('{children}'), 0,
-                    \          'csp', a:prop, a:cs.rev)[0]),
-                    \    'str2nr(v:val)')
+        let r=map(split(s:F.hg(a:repo, 'log', [],
+                    \          {'rev': a:cs.hex, 'template': '{children}'},
+                    \          0, 'csp', a:prop, a:cs.rev)[0]), 'str2nr(v:val)')
         if empty(a:repo.cslist)
             call map(r, 'a:repo.functions.getrevhex(a:repo, v:val)')
         else
 "▶1 hg.getcs :: repo, rev → cs
 "▶2 getcs
 if s:usepythondriver "▶3
-function s:F.getcs(repo, hex)
+function s:F.getcs(repo, rev)
     let cs={}
     try
-        execute s:_r.py.cmd 'aurum.get_cs(vim.eval("a:repo.path"), "'.a:hex.'")'
+        execute s:_r.py.cmd 'aurum.get_cs(vim.eval("a:repo.path"), '.
+                    \                    'vim.eval("a:rev"))'
     endtry
     return cs
 endfunction
 else "▶3
-function s:F.getcs(repo, hex)
-    let csdata=s:F.hg(a:repo, 'log -r '.a:hex.' --style '.s:stylefile, 0,
-                \     'cs', a:hex)
+function s:F.getcs(repo, rev)
+    let csdata=s:F.hg(a:repo, 'log', [], {'rev': a:rev, 'style': s:stylefile},0,
+                \     'cs', a:rev)
     let cs=s:F.parsecs(csdata, 0)[0]
     call map(cs.parents,
                 \'type(v:val)=='.type(0).'? '.
     return r
 endfunction
 else "▶2
-"▶3 getdiffcmd
-function s:F.getdiffcmd(repo, rev1, rev2, files, opts)
+"▶3 getdiffargs
+function s:F.getdiffargs(repo, rev1, rev2, files, opts)
     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 args=[]
+    let kwargs={}
+    let rev1=((empty(a:rev1))?(0):(''.a:rev1))
+    let rev2=((empty(a:rev2))?(0):(''.a:rev2))
     if rev2 is 0
         if rev1 isnot 0
-            let cmd.='-c '.rev1.' '
+            let kwargs.change=''.rev1
         endif
+    elseif rev1 isnot 0
+        let args+=['--rev', rev2, '--rev', rev1]
     else
-        let cmd.='-r '.rev2.' '
-        if rev1 isnot 0
-            let cmd.='-r '.rev1.' '
-        endif
+        let kwargs.rev=rev2
     endif
     for [o, v] in items(diffopts)
         if o is# 'unified'
-            let cmd.='--'.o.' '.v.' '
+            let kwargs[o]=''.v
         elseif v
-            let cmd.='--'.tr(o, '_', '-').' '
+            let kwargs[tr(o, '_', '-')]=1
         endif
     endfor
-    let cmd.='-- '.join(map(copy(a:files), 'shellescape(v:val, 1)'))
-    return cmd
+    if !empty(a:files)
+        let args+=['--']+a:files
+    endif
+    return [a:repo, 'diff', args, kwargs, 1]
 endfunction
 "▲3
 function s:hg.diff(repo, rev1, rev2, files, opts)
-    let cmd=s:F.getdiffcmd(a:repo, a:rev1, a:rev2, a:files, a:opts)
-    let r=s:F.hg(a:repo, cmd, 1, 'diff', string(a:rev1), string(a:rev2),
-                \                        join(a:files, ', '))
-    return r+['']
+    let args=s:F.getdiffargs(a:repo, a:rev1, a:rev2, a:files, a:opts)
+    return call(s:F.hg, args+['diff', a:rev1, a:rev2, join(a:files, ', ')], {})
+                \+['']
 endfunction
 endif
 "▶1 hg.difftobuffer :: repo, buf, rev1, rev2, [path], opts → [String]
 endfunction
 else "▶2
 function s:hg.difftobuffer(repo, buf, rev1, rev2, files, opts)
-    let cmd=s:F.getdiffcmd(a:repo, a:rev1, a:rev2, a:files, a:opts)
+    let args=s:F.getdiffargs(a:repo, a:rev1, a:rev2, a:files, a:opts)
+    let cmd=call(s:F.hgcmd, args, {})
     let oldbuf=bufnr('%')
     if oldbuf!=a:buf
         execute 'buffer' a:buf
     endif
     try
-        execute '%!hg -R '.shellescape(a:repo.path, 1).' '.cmd
+        execute '%!'.cmd
     finally
         if oldbuf!=a:buf
             execute 'buffer' oldbuf
 call map(values(s:statchars), 'extend(s:initstatdct, {v:val : []})')
 " TODO test whether zero revision may cause bugs in some commands
 function s:hg.status(repo, ...)
-    let cmd='status -marduic'
+    let args=[]
+    let kwargs={'modified': 1,
+                \  'added': 1,
+                \'removed': 1,
+                \'deleted': 1,
+                \'unknown': 1,
+                \'ignored': 1,
+                \  'clean': 1}
     let reverse=0
     if a:0
         if a:1 is 0
                 let reverse=1
             endif
         else
-            let cmd.=' --rev '.shellescape(a:1)
+            let args+=['--rev', a:1]
         endif
         if a:0>1 && a:2 isnot 0
-            let cmd.=' --rev '.shellescape(a:2)
+            let args+=['--rev', a:2]
         endif
         if a:0>2 && !empty(a:3)
-            let cmd.=' -- '.join(map(copy(a:3),
-                        \'shellescape(s:_r.os.path.join(a:repo.path, v:val))'))
+            let args+=['--']+a:3
         endif
     endif
-    let slines=s:F.hg(a:repo, cmd, 0, 'stat')[:-2]
+    let slines=s:F.hg(a:repo, 'status', args, kwargs, 0, 'stat')[:-2]
     if !empty(filter(copy(slines), '!has_key(s:statchars, v:val[0])'))
         call s:_f.throw('statfail', a:repo.path, join(slines, "\n"))
     endif
                 \               a:prop is# 'bookmarkslist'
         return map(copy(s:F.getkeylist(a:repo, a:prop[:-5])), 'v:val[0]')
     elseif a:prop is# 'url'
-        let lines=s:F.hg(a:repo, 'showconfig paths', 0, 'sc')[:-2]
+        let lines=s:F.hg(a:repo, 'showconfig', ['paths'], {}, 0, 'sc')[:-2]
         let confs={}
         call map(lines, 'matchlist(v:val, ''\v^paths\.([^=]+)\=(.*)$'')[1:2]')
         call map(copy(lines), 'extend(confs, {v:val[0]: v:val[1]})')
                 \                      '**vim.eval("a:kwargs"))'
 endfunction
 else "▶2
-" XXX Here all args must be paths unless attr is listed in nopathattrs
-let s:nopathattrs=['branch', 'tag', 'bookmark']
 function s:F.runcmd(repo, attr, args, kwargs, ...)
     let e=(a:0 && a:1)
     let args=copy(a:args)
     if !empty(args)
         call insert(args, '--')
     endif
-    let cmd=s:_r.utils.getcmd(a:attr, args, a:kwargs, e)
-    return s:_r.utils.printm(s:F.hg(a:repo, cmd, e, 'cmd', cmd)[:-2+e])
+    return s:_r.utils.printm(s:F.hg(a:repo, a:attr, args, a:kwargs, e)[:-2+e])
 endfunction
 endif
 "▶1 hg.move :: repo, force, source, target → + FS
 endfunction
 "▲3
 function s:hg.grep(repo, pattern, files, revisions, ignore_case, wdfiles)
-    let cmd='grep '.join(map(copy(a:revisions),
+    let args=map(copy(a:revisions),
             \                '((type(v:val)=='.type([]).')?'.
-            \                   '("-r".shellescape(join(v:val, ".."), 1)):'.
-            \                   '("-r".shellescape(v:val, 1)))')).' '
+            \                   '("--rev=".join(v:val, "..")):'.
+            \                   '("--rev=".v:val))')+
+            \['--', a:pattern]+a:files
+    let kwargs={'follow': 1, 'line-number': 1}
     if a:ignore_case
-        let cmd.='--ignore-case '
+        let kwargs['ignore-case']=1
     endif
-    let cmd.='--follow --line-number '
-    let cmd.='-- '.join(map(copy([a:pattern]+a:files), 'shellescape(v:val, 1)'))
-    let lines=s:F.hg(a:repo, cmd, 1, 0)
+    let lines=s:F.hg(a:repo, 'grep', args, kwargs, 1)
     if v:shell_error
+        " Grep failed because it has found nothing
         if lines ==# ['']
             return []
+        " Grep failed for another reason
         else
             call s:_f.throw('grepfail', a:repo.path, join(lines, "\n"))
         endif
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.