Commits

ZyX_I committed 88db3a5

Added :AuGrep (untested, with some known bugs)
Fixed :AuLog highlighting: first line was not recognized when marker was not the first character

Comments (0)

Files changed (4)

     call FraworLoad('@/commands')
     call FraworLoad('@/functions')
     " TODO improve files completion
-    " TODO :AuGrep
     " TODO :AuMerge ?
     " TODO :AuExplore
     " TODO aurum#changeset(), aurum#repository() and aurum#status()
     let s:addargs={'Update': {'bang': 1}, 'Move': {'bang': 1}}
-    for s:cmd in ['Diff', 'File', 'Update', 'Move', 'Junk', 'Track', 'Hyperlink']
+    for s:cmd in ['Diff', 'File', 'Update', 'Move', 'Junk', 'Track',
+                \ 'Hyperlink', 'Grep']
         let s:part=tolower(s:cmd[:3])
         if len(s:cmd)>4 && stridx('aeiouy', s:part[-1:])!=-1
             let s:part=s:part[:-2]
             \substitute(s:tracfunc['@FWC'][0],
             \'\V+ type ""', '+ (path)', ''))
 "▶1 hypfunc
-" TODO urlescape file
 function s:hypfunc.function(opts)
     let [hasbuf, repo, rev, file]=s:_r.cmdutils.getrrf(a:opts, 'nocurf', 0)
     call s:_r.cmdutils.checkrepo(repo)
             \'\Vfile\s\+type ""', 'file path',           ''),
             \'\Vcmd\s\+type ""',  'cmd '.s:_r.comp.cmd,  ''),
             \'\Vrev\s\+type ""',  'rev '.s:_r.comp.rev,  ''))
+"▶1 grepfunc
+function s:grepfunc.function(pattern, opts, ...)
+    if a:opts.repo is# ':' && a:0
+        let repo=s:_r.repo.get(a:1)
+    else
+        let repo=s:_r.repo.get(a:opts.repo)
+    endif
+    call s:_r.cmdutils.checkrepo(repo)
+    let revisions=copy(get(a:opts, 'rev', []))
+    call map(revisions, 'repo.functions.getrevhex(repo, v:val)')
+    let revrange=get(a:opts, 'revrange', [])
+    while !empty(revrange)
+        let [rev1, rev2; revrange]=revrange
+        let cs1=repo.functions.getcs(repo, rev1)
+        let cs2=repo.functions.getcs(repo, rev2)
+        if cs1.rev>cs2.rev
+            let [cs1, cs2]=[cs2, cs1]
+        elseif cs1 is cs2
+            let revisions+=[cs1.hex]
+            continue
+        endif
+        " TODO Put only ancestors of cs1 or cs2 here
+        let revisions+=map(range(cs1.rev, cs2.rev),
+                    \      'repo.functions.getrevhex(repo, v:val)')
+    endwhile
+    let files=[]
+    if a:0
+        let allfiless=map(copy(revisions),
+                    \'repo.functions.getcsprop(repo, '.
+                    \                         'repo.functions.getcs(v:val), '.
+                    \                         '"allfiles")')
+        for pattern in map(copy(a:000), 's:_r.cmdutils.globtopat('.
+                    \                   'repo.functions.reltorepo(repo, v:val))')
+            for allfiles in allfiless
+                let files+=filter(copy(allfiles),
+                            \     'v:val=~#pattern && index(files, v:val)==-1')
+            endfor
+        endfor
+    endif
+    let qf=repo.functions.grep(repo, a:pattern, files, revisions,
+                \              get(a:opts, 'ignore_case', 0))
+    " FIXME <CR> in qflist does not jump to desired line number
+    call setqflist(qf)
+endfunction
+let s:grepfunc['@FWC']=['-onlystrings '.
+            \           'type "" '.
+            \           '{?   !ignorecase '.
+            \           ' ?*+2 revrange   type "" type ""'.
+            \           ' ?*   rev        type ""'.
+            \           '      repo '.s:_r.cmdutils.nogetrepoarg.
+            \           '} + type ""', 'filter']
+call add(s:grepcomp,
+            \substitute(s:grepfunc['@FWC'][0],
+            \'\V+ type ""', '+ (path)', ''))
 "▶1
 call frawor#Lockvar(s:, '_pluginloaded,_r')
 " vim: ft=vim ts=4 sts=4 et fmr=▶,▲

plugin/aurum/drivers/mercurial.vim

     let hgignore=s:_r.os.path.join(a:repo.path, '.hgignore')
     return s:F.addtosection(a:repo, hgignore, 'glob', a:glob)
 endfunction
+"▶1 hg.grep :: repo, pattern, files, revisions, ignore_case → qflist
+function s:hg.grep(repo, pattern, files, revisions, ignore_case)
+    let r=[]
+    execute s:_r.py.cmd 'aurum.grep(vim.eval("a:repo.path"), '.
+                \                  'vim.eval("a:pattern"), '.
+                \                  'vim.eval("a:files"), '.
+                \                  'vim.eval("a:revisions"), '.
+                \                  'bool(int(vim.eval("a:ignore_case"))))'
+    return r
+endfunction
 "▶1 Post resource
 call s:_f.postresource('mercurial', s:hg)
 "▶1
         let r+=['syn match auLogNextLineStart @\v'.s:schs.'+@ skipwhite '.
                     \' nextgroup='.join(nlgroups, ',')]
     endif
+    call add(r, remove(r, 0))
     let s:syncache[cid]=r
     return r
 endfunction
 import vim
 import os
 import json
+import re
 
 def nonutf_dumps(obj):
     todump=[('dump', obj)]
             vim_throw('upduns', repo.path)
         rev=g_cs(repo, rev).hex()
         args=[PrintUI(), repo, rev]
-        kwargs={'clean': not not force}
+        kwargs={'clean': bool(force)}
         run_in_dir(repo.root, commands.update, *args, **kwargs)
     except AurumError:
         pass
     try:
         repo=g_repo(path)
         if 'force' in kwargs:
-            kwargs['force']=not not kwargs['force']
+            kwargs['force']=bool(kwargs['force'])
         else:
             kwargs['force']=False
         cargs=[PrintUI(), repo]
     except AurumError:
         pass
 
+grepre=re.compile('^(.*?):(0|[1-9]\d*):([1-9]\d*):(.*)$')
+def grep(path, pattern, files, revisions=[], ignore_case=False):
+    try:
+        repo=g_repo(path)
+        ui=CaptureUI()
+        args=[ui, repo, pattern]
+        args.extend(files)
+        kwargs={'rev': revisions, 'ignore_case': bool(ignore_case),
+                'line_number': True}
+        run_in_dir(repo.root, commands.grep, *args, **kwargs)
+        lines=ui._getCaptured()
+        r_vim=[]
+        clean=repo.status(ignored=False, unknown=False, clean=True)[6]
+        for line in lines:
+            match=grepre.match(line)
+            if not match:
+                continue
+            (file, rev, lnum, text)=match.groups()
+            rev=repo[int(rev)].hex()
+            if rev == repo['.'].hex() and file in clean:
+                file=os.path.join(repo.path, file)
+            else:
+                file='aurum://file:'+\
+                        repo.path.replace('\\', '\\\\').replace(':', '\\:')+\
+                        ':'+rev+':'+file
+            r_vim.append({'filename': file, 'lnum': int(lnum), 'text': line})
+        vim.eval('extend(r, '+nonutf_dumps(r_vim)+')')
+    except AurumError:
+        pass
+