Commits

ZyX_I committed 6bf72b1

@%aurum/drivers/utils: Changed _r.utils.run() so that it accepts a list of
arguments and returns pair (output, exit_code)
Replaced _r.utils.kwargstostr with _r.utils.kwargstolst
Made _r.utils.getcmd return a list of arguments
@%aurum/drivers/*: Made them respect changes in utils

  • Participants
  • Parent commits 433e831

Comments (0)

Files changed (5)

File autoload/aurum/drivers/common/utils.vim

 "▶1
 scriptencoding utf-8
-execute frawor#Setup('0.4', {'@/resources': '0.0',
+execute frawor#Setup('1.0', {'@/resources': '0.0',
             \                       '@/os': '0.2'})
 let s:utils={}
-"▶1 utils.kwargstostr :: kwargs → str
-let s:prefexpr='repeat("-", 1+(len(v:val[0])>1)).v:val[0]." ="[len(v:val[0])>1]'
-function s:utils.kwargstostr(kwargs, esc)
-    return join(map(filter(items(a:kwargs), 'v:val[1] isnot 0'),
-                \   '((v:val[1] is 1)?'.
-                \     '(repeat("-", 1+(len(v:val[0])>1)).v:val[0]):'.
-                \   '((v:val[1] is 0)?'.
-                \     '(""):'.
-                \   '((type(v:val[1])=='.type([]).')?'.
-                \     '(join(map(copy(v:val[1]), '.
-                \               '"\"".'.s:prefexpr.'."\".'.
-                \                     'shellescape(v:val,    a:esc)"))):'.
-                \     '('.s:prefexpr.'.shellescape(v:val[1], a:esc)))))'
-                \  ))
+"▶1 utils.kwargstolst :: kwargs → [str]
+function s:utils.kwargstolst(kwargs)
+    let r=[]
+    for [key, value] in filter(items(a:kwargs), 'v:val[1] isnot 0')
+        let long=(len(key)>1)
+        let r+=[repeat('-', 1+long).key]
+        if value is 1
+            continue
+        elseif type(value)==type([])
+            let k=remove(r, -1)
+            let r+=map(copy(value), 'k.'.(long? '"=".': '').'v:val')
+        else
+            let r[-1].=(long? '=': '').value
+        endif
+        unlet value
+    endfor
+    return r
 endfunction
-"▶1 utils.getcmd :: cmd, args, kwargs, esc → sh
-function s:utils.getcmd(cmd, args, kwargs, esc)
-    let cmd=a:cmd
+"▶1 utils.getcmd :: cmd, args, kwargs → sh
+function s:utils.getcmd(cmd, args, kwargs)
+    let cmd=[a:cmd]
     if !empty(a:kwargs)
-        let cmd.=' '.s:utils.kwargstostr(a:kwargs, a:esc)
+        let cmd+=s:utils.kwargstolst(a:kwargs)
     endif
     if !empty(a:args)
-        let cmd.=' '.join(map(copy(a:args), 'shellescape(v:val, a:esc)'))
+        let cmd+=a:args
     endif
     return cmd
 endfunction
+"▶1 readsystem :: cmd[, cdpath] → [String]
+if has('python') && exists('*pyeval')
+    python import aurum.utils
+    function s:F.readsystem(...)
+        return pyeval('aurum.utils.readsystem(*vim.eval("a:000"))')
+    endfunction
+endif
 "▶1 utils.run :: cmd, hasnulls::0|1|2, path → [String] + shell
 function s:utils.run(cmd, hasnulls, cdpath)
-    if a:hasnulls==2 && !empty(&shellredir)
-        return call(s:_r.os.readsystem, [a:cmd]+(empty(a:cdpath)?
-                    \                               ([]):
-                    \                               ([a:cdpath])), {})
-    elseif a:hasnulls
+    if a:hasnulls==2
+        if has_key(s:F, 'readsystem')
+            return s:F.readsystem(a:cmd, a:cdpath)
+        elseif !empty(&shellredir)
+            let lines=call(s:F.readsystem, [a:cmd]+(empty(a:cdpath)?
+                        \                               ([]):
+                        \                               ([a:cdpath])), {})
+            return [lines, v:shell_error]
+        endif
+    endif
+    if a:hasnulls
         let savedlazyredraw=&lazyredraw
         let savedeventignore=&eventignore
         set eventignore=all
             endif
             " XXX this is not able to distinguish between output with and 
             " without trailing newline, and also is “smart” about lineendings
-            silent execute '%!'.a:cmd
+            silent execute '%!'.join(map(copy(a:cmd), 'shellescape(v:val, 1)'))
             let r=getline(1, '$')
             bwipeout!
         finally
             let &eventignore=savedeventignore
         endtry
     else
-        let cmd=a:cmd
+        let cmd=join(map(copy(a:cmd), 'shellescape(v:val, 0)'))
         if !empty(a:cdpath)
             let cmd='cd '.shellescape(a:cdpath).' && '.cmd
         endif
         let r=split(system(cmd), "\n", 1)
     endif
-    return r
+    return [r, v:shell_error]
 endfunction
 "▶1 utils.diffopts :: opts, opts, difftrans → diffopts
 function s:utils.diffopts(opts, defaultdiffopts, difftrans)

File autoload/aurum/drivers/git.vim

 scriptencoding utf-8
 execute frawor#Setup('0.1', {'@%aurum/drivers/common/hypsites': '0.0',
             \                                   '@%aurum/repo': '5.0',
-            \                   '@%aurum/drivers/common/utils': '0.4',
+            \                   '@%aurum/drivers/common/utils': '1.0',
             \                                           '@/os': '0.1',
             \                                      '@/options': '0.0',})
 let s:_messages={
 function s:F.refile(fname)
     return a:fname[0] is# '"' ? eval(a:fname) : a:fname
 endfunction
-"▶1 gitcmd :: repo, cmd, args, kwargs, esc → String
-function s:F.gitcmd(repo, ...)
-    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, {})
+"▶1 gitcmd :: cmd, args, kwargs → String
+function s:F.gitcmd(...)
+    return ['git']+call(s:_r.utils.getcmd, a:000, {})
 endfunction
 "▶1 git :: repo, cmd, args, kwargs, has0[, msgid[, marg1[, …]]] → [String] + ?
 function s:F.git(repo, cmd, args, kwargs, hasnulls, ...)
-    let cmd=s:F.gitcmd(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
-        call call(s:_f.throw, a:000+[a:repo.path, join(r[:-1-(a:hasnulls)],
-                    \                                  "\n")], {})
+    let cmd=s:F.gitcmd(a:cmd, a:args, a:kwargs)
+    let [r, exit_code]=s:_r.utils.run(cmd, a:hasnulls, a:repo.path)
+    if a:0
+        if a:1 is 0
+            return [r, exit_code]
+        elseif exit_code
+            call call(s:_f.throw, a:000+[a:repo.path, join(r[:-1-(a:hasnulls)],
+                        \                                  "\n")], {})
+        endif
     endif
     return r
 endfunction
 function s:git.grep(repo, pattern, files, revisions, ic, wdfiles)
     let args=['-e', a:pattern, '--']+a:files
     let kwargs={'full-name': 1, 'extended-regexp': 1, 'n': 1, 'z': 1}
-    let gitargs=[a:repo, 'grep', args, kwargs, 1, 0]
+    let gitargs=[a:repo, 'grep', args, kwargs, 1]
     let r=[]
     if !empty(a:revisions)
         let revs=[]
                     \        'branchf')[:-2]
         return get(filter(branches, 'v:val[0] is# "*"'), 0, '')[2:]
     elseif a:prop is# 'url'
-        let r=get(s:F.git(a:repo, 'config', ['remote.origin.pushurl'], {}, 0),
-                    \0, 0)
-        if v:shell_error || r is 0
+        let [r, exit_code]=get(s:F.git(a:repo, 'config',
+                    \                  ['remote.origin.pushurl'], {}, 0),
+                    \          0, 0)
+        if exit_code || r is 0
             let r=get(s:F.git(a:repo, 'config', ['remote.origin.url'], {}, 0),
                         \0, 0)
         endif

File autoload/aurum/drivers/mercurial.vim

 scriptencoding utf-8
 execute frawor#Setup('0.2', {'@%aurum/drivers/common/hypsites': '0.0',
             \                                   '@%aurum/repo': '5.0',
-            \                   '@%aurum/drivers/common/utils': '0.4',
+            \                   '@%aurum/drivers/common/utils': '1.0',
             \                                       '@/python': '0.0',
             \                                           '@/os': '0.0',
             \                                      '@/options': '0.0',})
         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, {})
+"▶1 hgcmd :: cmd, args, kwargs → String
+function s:F.hgcmd(...)
+    return ['hg']+call(s:_r.utils.getcmd, a:000, {})
 endfunction
 "▶1 runshellcmd :: repo, attr, args, kwargs → + ?
 function s:F.runshellcmd(repo, attr, args, kwargs, ...)
 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")], {})
+    let cmd=s:F.hgcmd(a:cmd, a:args, a:kwargs)
+    let [r, exit_code]=s:_r.utils.run(cmd, a:hasnulls, a:repo.path)
+    if a:0
+        if a:1 is 0
+            return [r, exit_code]
+        elseif exit_code
+            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
     endif
     return r
 endfunction
 "▶2 trycmd :: repo, attr → Bool
 function s:F.trycmd(repo, cmd)
     try
-        call s:F.hg(a:repo, 'help', [a:cmd], {}, 0)
-        return !v:shell_error
+        call s:F.hg(a:repo, 'help', [a:cmd], {}, 0, 'f')
+        return 1
     catch
         return 0
     endtry
     endfunction
 else "▶2
     function s:F.getcs(repo, rev)
-        let csdata=s:F.hg(a:repo, 'log', [], {'rev': a:rev, 'style': s:stylefile},0,
+        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,
         let kwargs['ignore-case']=1
     endif
     let kwargs.print0=1
-    let lines=s:F.hg(a:repo, 'grep', args, kwargs, 2)
-    if v:shell_error
+    let [lines, exit_code]=s:F.hg(a:repo, 'grep', args, kwargs, 2, 0)
+    if exit_code
         " Grep failed because it has found nothing
         if lines ==# ['']
             return []
             let kwargs[tr(o, '_', '-')]=1
         endif
     endfor
-    if has_key(kwargs, 'reverse') &&
-                \(!has_key(a:repo.mutable, 'noreverse') ||
-                \ empty(filter(s:F.hg(a:repo, 'help', 'diff', [], {}, 0, 0),
-                \              'stridx(v:val, "--reverse")!=-1')))
-        let a:repo.mutable.noreverse=1
-        unlet kwargs.reverse
+    if has_key(kwargs, 'reverse')
+        if (has_key(a:repo.mutable, 'noreverse')?
+                \(a:repo.mutable.noreverse):
+                \(empty(filter(s:F.hg(a:repo, 'help', ['diff'], {}, 0),
+                \              'stridx(v:val, "--reverse")!=-1'))))
+            let a:repo.mutable.noreverse=1
+            unlet kwargs.reverse
+        else
+            let a:repo.mutable.noreverse=0
+        endif
     endif
     if !empty(a:files)
         let args+=['--']+a:files
     endif
-    return [a:repo, 'diff', args, kwargs, 1]
+    return ['diff', args, kwargs]
 endfunction
 "▲3
 function s:hg.diff(repo, rev1, rev2, files, opts)
     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, ', ')], {})
+    return call(s:F.hg, [a:repo]+args+[1, 'diff', a:rev1, a:rev2,
+                \                      join(a:files, ', ')], {})
                 \+['']
 endfunction
 endif
         execute 'buffer' a:buf
     endif
     try
-        execute '%!'.cmd
+        execute 'lcd' fnameescape(a:repo.path)
+        execute '%!'.join(map(copy(cmd), 'shellescape(v:val, 1)'))
+        lcd -
     finally
         if oldbuf!=a:buf
             execute 'buffer' oldbuf

File autoload/aurum/drivers/subversion.vim

 scriptencoding utf-8
 execute frawor#Setup('0.1', {'@%aurum/drivers/common/hypsites': '0.0',
             \                                   '@%aurum/repo': '5.0',
-            \                   '@%aurum/drivers/common/utils': '0.4',
+            \                   '@%aurum/drivers/common/utils': '1.0',
             \                     '@%aurum/drivers/common/xml': '0.0',
             \                                           '@/os': '0.0',})
 let s:_messages={
 let s:iterfuncs={}
 "▶1 s:hypsites
 let s:hypsites=s:_r.hypsites.svn
-"▶1 svncmd :: repo, cmd, args, kwargs, esc → String
-function s:F.svncmd(repo, ...)
-    return 'svn '.call(s:_r.utils.getcmd, a:000, {})
+"▶1 svncmd :: cmd, args, kwargs → String
+function s:F.svncmd(...)
+    return ['svn']+call(s:_r.utils.getcmd, a:000, {})
 endfunction
 "▶1 svn :: repo, cmd, args, kwargs, has0[, msgid[, marg1[, …]]] → [String] + ?
 function s:F.svn(repo, cmd, args, kwargs, hasnulls, ...)
-    let cmd=s:F.svncmd(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 cmd=s:F.svncmd(a:cmd, a:args, a:kwargs)
+    let [r, exit_code]=s:_r.utils.run(cmd, a:hasnulls, a:repo.path)
+    if exit_code && a:0
         call call(s:_f.throw, a:000+[a:repo.path, join(r[:-1-(a:hasnulls)],
                     \                                  "\n")], {})
     endif

File doc/aurum.txt

     0.2: Added _r.utils.using_ansi_esc_echo
     0.3: Added _r.utils.nullnl and _r.utils.kwargstostr
     0.4: Added _r.utils.emptystatdct
+    1.0: Made _r.utils.getcmd return a list,
+         replaced _r.utils.kwargstostr with _r.utils.kwargstolst,
+         made _r.utils.run return a pair (output, exit_code)
 
 vim: ft=help:tw=78