Commits

ZyX_I committed 7c0dda9

@aurum/log: Now function that checks changesets is compiled

  • Participants
  • Parent commits 9de8bb0

Comments (0)

Files changed (2)

File README.markdown

 
   - Partially committing changes ([:AuRecord](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line385-0)).
 
-  - Viewing file state at particular revision ([aurum://file](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line627-0), [:AuFile](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line160-0)).
+  - Viewing file state at particular revision ([aurum://file](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line628-0), [:AuFile](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line160-0)).
 
   - Viewing uncommited changes in a vimdiff, as well as changes between 
     specific revisions ([:AuVimDiff](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line428-0)). It is also possible to open multiple 
   - Viewing working directory status ([:AuStatus](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line389-0)).
 
   - Commiting changes ([:AuCommit](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line101-0)), commit messages are remembered in case of 
-    rollback ([g:aurum_remembermsg](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line921-0)).
+    rollback ([g:aurum_remembermsg](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line922-0)).
 
   - Obtaining various URL’s out of remote repository URL (like URL of the HTML 
     version of the current file with URL fragment pointing to the current line 
     supports git and subversion revisions (in case you are using hg-git and 
     hgsubversion respectively).
 
-  - [aurum#changeset()](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line476-0), [aurum#repository()](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line472-0) and [aurum#status()](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line480-0) functions 
+  - [aurum#changeset()](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line477-0), [aurum#repository()](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line473-0) and [aurum#status()](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line481-0) functions 
     that are to be used from modeline.
 
   - Frontends for various other VCS commands.
 
-Most commands can be reached with a set of mappings (see [aurum-mappings](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line782-0)), 
+Most commands can be reached with a set of mappings (see [aurum-mappings](http://vimpluginloader.sourceforge.net/doc/aurum.txt.html#line783-0)), 
 all mappings are customizable.
 
 

File plugin/aurum/log.vim

     "▶3 Initialize iterator functions
     let ld=literfuncs.start(a:repo,a:opts,[a:repo.functions.getworkhex(a:repo)])
     let csd=a:csiterfuncs.start(a:repo, a:opts)
-    let checkd=s:iterfuncs.check.start(a:repo, a:opts)
+    let checkd=s:iterfuncs.check.generate(a:repo, a:opts)
     "▲3
     while 1 && (!haslimit || limit)
         let cs=a:csiterfuncs.next(csd)
         if cs is 0 "▶3
             return r
         endif "▲3
-        let skip=!s:iterfuncs.check.check(checkd, cs)
+        let skip=!checkd.check(cs)
         "▶3 Add cs to skipchangesets or get its properties
         if skip
             let a:opts.skipchangesets[cs.hex]=cs
     let text.special.bullet=[0, 0, char]
     return [text.text, text.block_r, text.special]
 endfunction
-"▶1 comparedates :: datesel, time → -1|0|1
-let s:datechars='YmdHM'
-function s:F.comparedates(datesel, time)
-    let j=0
-    for selnum in a:datesel
-        if selnum isnot# '*'
-            let spec='%'.s:datechars[j]
-            if selnum is# '.'
-                let selnum=str2nr(strftime(spec))
-            endif
-            let actnum=str2nr(strftime(spec, a:time))
-            if actnum!=selnum
-                if actnum<selnum
-                    return -1
-                else
-                    return 1
-                endif
-            endif
-        endif
-        let j+=1
-    endfor
-    return 0
-endfunction
 "▶1 iterfuncs.check
 " startfunc (here)  :: repo, opts → d
 let s:fcheckpropslist=['renames', 'copies', 'changes', 'files']
 let s:iterfuncs.check={}
-"▶2 iterfuncs.check.start
+"▶2 getcid :: opts → cid
+function s:F.getcid(opts)
+    let r    =   get(a:opts, 'merges', 2).
+                \get(a:opts, 'date', '').'D'
+    for o in ['branch', 'search', 'user']
+        let r.=has_key(a:opts, o) ? string(a:opts[o]) : '-'
+    endfor
+    let r.=has_key(a:opts, 'files') ? '+' : '-'
+    return r
+endfunction
+"▶2 iterfuncs.check.generate
 "▶3 addcentury
 function s:F.addcentury(year)
-    if type(a:year)==type(0) && a:year<100
+    if a:year=~#'\v^\d\d?$'
+        let year=str2nr(a:year)
         let curyear=str2nr(strftime('%y'))
         let century=str2nr(strftime('%Y')[:-3])
-        if a:year<=curyear
-            let r=((century*100)+a:year)
+        if year<=curyear
+            let r=((century*100)+year)
         else
-            let r=(((century-1)*100)+a:year)
+            let r=(((century-1)*100)+year)
         endif
-        return r
+        return string(r)
     endif
     return a:year
 endfunction
 "▶3 redate
 function s:F.redate(datespec)
     let date=map(split(a:datespec, '\v[^0-9*.]+'),
-                \'v:val=~#"\\d" ? str2nr(v:val) : v:val')
+                \'v:val=~#"\\d" ? string(str2nr(v:val)) : '.
+                \'v:val is# "." ? ''str2nr(strftime("%".s:datechars[v:key]))'''.
+                \              ': -1')
     let date[0]=s:F.addcentury(date[0])
     return date
 endfunction
 "▲3
+let s:checkcache={}
 let s:keytoexpr={
             \'branch': '"a:cs.branch isnot# ".string(v:val)',
             \'merges': '(v:val)?("len(a:cs.parents)<=1"):'.
             \'search': '"a:cs.description!~#".string(v:val)',
             \  'user':        '"a:cs.user!~#".string(v:val)',
         \}
-function s:iterfuncs.check.start(repo, opts)
-    let r={'repo': a:repo, 'hasfiles': 0, 'hasdaterange': 0, 'hasdate': 0}
-    "▶3 Define variables for files filtering
+let s:datechars='YmdHM'
+function s:iterfuncs.check.generate(repo, opts)
+    let cid=s:F.getcid(a:opts)
+    let r={}
     if has_key(a:opts, 'files')
-        let r.hasfiles=1
         let r.csfiles={}
+        let r.tocheck={}
+        let r.repo=a:repo
         let r.filepats=a:opts.filepats
-        let r.tocheck={}
         let a:opts.csfiles=r.csfiles
     endif
-    "▶3 Define variables for date filtering
+    if has_key(s:checkcache, cid)
+        let r.check=s:checkcache[cid]
+        return r
+    endif
+    let function=['function r.check(cs)']
+    let precond=join(values(map(filter(copy(a:opts),
+                \                      'has_key(s:keytoexpr, v:key)'),
+                \               'eval(s:keytoexpr[v:key])')), '||')
+    if !empty(precond)
+        let function+=['    if '.precond, '        return 0', '    endif']
+    endif
+    "▶3 Date filtering
     if has_key(a:opts, 'date')
         let idx=match(a:opts.date, '\V<=\?>')
+        let function+=['    let time=a:cs.time']
+        "▶4 One border
         if idx==-1
-            let r.hasdate=1
-            let r.selector=(stridx('<>', a:opts.date[0])==-1)?(''):
-                        \                                     (a:opts.date[0])
-            let r.acceptexact=(empty(r.selector) || a:opts.date[1] is# '=')
-            let r.date=s:F.redate(a:opts.date[empty(r.selector)?(0):
-                        \                     (len(r.selector)+r.acceptexact):])
+            let selector=(stridx('<>', a:opts.date[0])==-1)?(''):
+                      \                                     (a:opts.date[0])
+            let acceptexact=(empty(selector) || a:opts.date[1] is# '=')
+            let date=s:F.redate(a:opts.date[empty(selector)?(0):
+                        \                     (len(selector)+acceptexact):])
+            if empty(selector)
+                let selector='!='
+            endif
+            let j=0
+            if !acceptexact
+                let function+=['    let matched=0']
+            endif
+            let function+=[
+                        \'    for [spec, sel] in ['.join(
+                        \     map(filter(map(copy(date),
+                        \                    '["%".s:datechars[v:key], v:val]'),
+                        \                'v:val[1] isnot# -1'),
+                        \         '"[''".v:val[0]."'', ".v:val[1]."]"'), ', ').
+                        \                       ']',
+                        \'        let actnum=str2nr(strftime(spec, time))',
+                        \'        if actnum'.selector.'sel',
+                        \]
+            if !acceptexact
+                let function+=['            let matched=1']
+            endif
+            if selector isnot# '!='
+                let function+=['            break',
+                            \  '        else']
+                if acceptexact
+                    let function[-1].='if actnum!=sel'
+                endif
+            endif
+            let function+=['            return 0',
+                        \  '        endif']
+            let function+=['    endfor']
+            if !acceptexact
+                let function+=['    if !matched',
+                            \  '        return 0',
+                            \  '    endif']
+            endif
+        "▶4 Range
         else
-            let r.hasdaterange=1
-            let r.date1=s:F.redate(a:opts.date[:(idx-1)])
-            let r.acceptexact=(a:opts.date[idx+1] is# '=')
-            let r.date2=s:F.redate(a:opts.date[(idx+2+r.acceptexact):])
+            let date1=s:F.redate(a:opts.date[:(idx-1)])
+            let acceptexact=(a:opts.date[idx+1] is# '=')
+            let date2=s:F.redate(a:opts.date[(idx+2+acceptexact):])
+            let selnum=max([len(date1), len(date2)])
+            let selector='<'.((acceptexact)?('='):(''))
+            let j=0
+            if !acceptexact
+                let function+=['    let matched=0']
+            endif
+            let function+=[
+                        \'    for [spec, sel1, sel2] in ['.join(
+                        \     map(filter(map(range(selnum),
+                        \                    '["%".s:datechars[v:val], '.
+                        \                     'get(date1, v:val, -1), '.
+                        \                     'get(date2, v:val, -1)]'),
+                        \                'v:val[1] isnot# -1 || '.
+                        \                'v:val[2] isnot# -1'),
+                        \         '"[''".v:val[0]."'', ".'.
+                        \           'join(v:val[1:], ", ")."]"'), ', ').']',
+                        \
+                        \'        let actnum=str2nr(strftime(spec, time))',
+                        \'        if ((sel1 is# -1 ? '.
+                        \                '1 : '.
+                        \                'sel1<actnum) && '.
+                        \            '(sel2 is# -1 ? '.
+                        \                '1 : '.
+                        \                'actnum<sel2))',
+                        \'            break',]
+            if acceptexact
+                let function+=['        elseif !((sel1 is# -1 ? '.
+                            \                       '1 : '.
+                            \                       'sel1==actnum) || '.
+                            \                   '(sel2 is# -1 ? '.
+                            \                       '1 : '.
+                            \                       'actnum==sel2))']
+            else
+                let function+=['        else']
+            endif
+            let function+=['            return 0',
+                        \  '        endif',
+                        \  '    endfor']
         endif
     endif
-    "▶3 Determine other filters
-    let r.expr=join(values(map(filter(copy(a:opts),
-                \                     'has_key(s:keytoexpr, v:key)'),
-                \              'eval(s:keytoexpr[v:key])')), '||')
-    "▲3
-    return r
-endfunction
-"▶2 iterfuncs.check.check
-function s:iterfuncs.check.check(d, cs)
-    "▶3 Check simple cases
-    if !empty(a:d.expr) && eval(a:d.expr)
-        return 0
-    endif
-    "▶3 Check files
-    if a:d.hasfiles
-        let copies =a:d.repo.functions.getcsprop(a:d.repo, a:cs, 'copies' )
-        let renames=a:d.repo.functions.getcsprop(a:d.repo, a:cs, 'renames')
-        let changes=a:d.repo.functions.getcsprop(a:d.repo, a:cs, 'changes')[:]
-        let csfiles=[]
-        let tcfiles=[]
-        let a:d.csfiles[a:cs.hex]=csfiles
-        if has_key(a:d.tocheck,a:cs.hex)
-            let tc=a:d.tocheck[a:cs.hex]
-            call filter(changes, '(index(tc, v:val)==-1)?(1):'.
-                        \           '([0, add(csfiles, v:val)][0])')
-            call filter(tc, 'index(csfiles, v:val)==-1')
-            if !empty(tc)
-                let allfiles=a:d.repo.functions.getcsprop(a:d.repo, a:cs,
-                            \                             'allfiles')
-                let tcfiles+=filter(copy(allfiles), 'index(tc, v:val)!=-1')
-            endif
-        endif
-        for pattern in a:d.filepats
-            let newchanges=[]
-            call map(copy(changes), 'add(((v:val=~#'.string(pattern).')?'.
-                        \                   '(csfiles):'.
-                        \                   '(newchanges)), v:val)')
-            if empty(newchanges)
-                break
-            endif
-            let changes=newchanges
-        endfor
-        for file in csfiles
-            let tcfiles+=map(filter(['renames', 'copies'],
-                        \           'has_key({v:val}, file) && '.
-                        \           '{v:val}[file] isnot 0'),
-                        \    '{v:val}[file]')
-        endfor
-        if !empty(tcfiles)
-            call map(copy(a:cs.parents), 'extend(a:d.tocheck, '.
-                        \'{v:val : get(a:d.tocheck, v:val, [])+tcfiles})')
-        endif
-        if empty(csfiles)
-            return 0
-        endif
-    endif
-    "▶3 Check date
-    if a:d.hasdate
-        let cmpresult=s:F.comparedates(a:d.date, a:cs.time)
-        if !((a:d.acceptexact && cmpresult==0) ||
-                    \(a:d.selector is# '<' && cmpresult==-1) ||
-                    \(a:d.selector is# '>' && cmpresult==1))
-            return 0
-        endif
-    elseif a:d.hasdaterange
-        let cmp1result=s:F.comparedates(a:d.date1, a:cs.time)
-        let cmp2result=s:F.comparedates(a:d.date2, a:cs.time)
-        if !((cmp1result==1 && cmp2result==-1) ||
-                    \(a:d.acceptexact && (cmp1result==0 ||
-                    \                     cmp2result==0)))
-            return 0
-        endif
+    "▶3 File filtering
+    if has_key(a:opts, 'files')
+        " XXX Keep “changes” last
+        let function+=map(['copies', 'renames', 'changes'],
+                    \'"    let ".v:val."=self.repo.functions.getcsprop('.
+                    \                        'self.repo, a:cs, ''".v:val."'')"')
+        let function[-1].='[:]'
+        let function+=map(['cs', 'tc'], '"    let ".v:val."files=[]"')
+        let function+=['    let self.csfiles[a:cs.hex]=csfiles']
+        let function+=['    if has_key(self.tocheck,a:cs.hex)',
+                    \  '        let tc=self.tocheck[a:cs.hex]',
+                    \  '        call filter(changes, '.
+                    \                      '"(index(tc, v:val)==-1)?'.
+                    \                         '(1):'.
+                    \                         '([0, add(csfiles, v:val)][0])")',
+                    \  '        call filter(tc, "index(csfiles, v:val)==-1")',
+                    \  '        if !empty(tc)',
+                    \ '            let allfiles=self.repo.functions.getcsprop('.
+                    \                            'self.repo, a:cs, "allfiles")',
+                    \  '            let tcfiles+=filter(copy(allfiles), '.
+                    \                                  '"index(tc,v:val)!=-1")',
+                    \  '        endif',
+                    \  '    endif',
+                    \  '    for pattern in self.filepats',
+                    \  '        let newchanges=[]',
+                    \  '        call map(copy(changes), '.
+                    \                   '"add(((v:val=~#".string(pattern).")?'.
+                    \                              '(csfiles):'.
+                    \                              '(newchanges)), v:val)")',
+                    \  '        if empty(newchanges)',
+                    \  '            break',
+                    \  '        endif',
+                    \  '        let changes=newchanges',
+                    \  '    endfor',
+                    \  '    for file in csfiles',
+                    \  '        let tcfiles+=map(filter(["renames","copies"], '.
+                    \                             '"has_key({v:val}, file) && '.
+                    \                              '{v:val}[file] isnot 0"), '.
+                    \                            '"{v:val}[file]")',
+                    \  '    endfor',
+                    \  '    if !empty(tcfiles)',
+                    \  '        call map(copy(a:cs.parents), '.
+                    \                   '"extend(self.tocheck, '.
+                    \                           '{v:val : get(self.tocheck, '.
+                    \                                        'v:val, [])+'.
+                    \                                    'tcfiles})")',
+                    \  '    endif',
+                    \  '    if empty(csfiles)',
+                    \  '        return 0',
+                    \  '    endif',
+                    \]
     endif
     "▲3
-    return 1
+    let function+=['    return 1', 'endfunction']
+    execute join(function, "\n")
+    let s:checkcache[cid]=r.check
+    return r
 endfunction
 "▶1 getblock :: bvar + cursor, bvar → block
 "▶2 bisect :: [a], function + self → a
             \'requiresbvar': 1,
             \})
 "▶1
-call frawor#Lockvar(s:, '_r')
+call frawor#Lockvar(s:, '_r,checkcache')
 " vim: ft=vim ts=4 sts=4 et fmr=▶,▲