Commits

ZyX_I committed 8049b63

Some speed improvements: replaced vim_dumps with utf_dumps (uses fast json.dumps) and nonutf_dumps (slower own implementation that does not care whether string is unicode)

Comments (0)

Files changed (3)

ftplugin/aurumgraphlog.vim

         let text+=newtext
     endfor
     "▶3 Add files
-    if get(a:opts, 'showfiles', 0) && !empty(a:cs.files)
+    if get(a:opts, 'showfiles', 0) &&
+                \!empty(a:opts.repo.functions.getcsprop(a:opts.repo, a:cs,
+                \                                       'files'))
         let curline=len(text)
         let ftext=['Files: ']
         let ww=winwidth(0)-10
                     \               'crrestrict:date')
     "▶3 file: view file
     elseif spname=~#'\v^file\d+$'
+        " XXX If fileN special exists, then files property was definitely added, 
+        " so no need to use getcsprop()
         let file=cs.files[+spname[4:]]
         let cmd='edit '.fnameescape('aurum://file:'.epath.':'.hex.':'.file)
     "▶3 diff: view diff between changeset and current state
     let cs=bvar.repo.changesets[hex]
     let file=0
     if spname=~#'\v^file\d+$'
+        " XXX If fileN special exists, then files property was definitely added, 
+        " so no need to use getcsprop()
         let file=cs.files[+spname[4:]]
-    elseif !empty(cs.files)
+    " Above is not applicable if we don't know exactly whether such special 
+    " exists
+    elseif !empty(bvar.repo.functions.getcsprop(bvar.repo, cs, 'files'))
         if len(cs.files)==1
             let file=cs.files[0]
         else
     endif
     let repo={}
     try
+        " execute s:_r.py.cmd 'import cProfile as profile'
+        " execute s:_r.py.cmd 'profile.run("aurum.new_repo(vim.eval(''a:path''))", "python.profile")'
         execute s:_r.py.cmd 'aurum.new_repo(vim.eval("a:path"))'
     catch
         return 0
                 \                      'vim.eval("a:file"))'
     return r
 endfunction
+"▶3 hg.getcsprop :: repo, cs, propname → a
+function s:F.hg.getcsprop(repo, cs, propname)
+    if has_key(a:cs, a:propname)
+        return a:cs[a:propname]
+    endif
+    execute s:_r.py.cmd 'aurum.get_cs_prop(vim.eval("a:repo.path"), '.
+                \                         'vim.eval("a:cs.hex"), '.
+                \                         'vim.eval("a:propname"))'
+    " XXX There is much code relying on the fact that after getcsprop property 
+    " with given name is added to changeset dictionary
+    return a:cs[a:propname]
+endfunction
 "▶3 hg.diff :: repo, rev1, rev2, [path], opts → [String]
 function s:F.hg.diff(repo, rev1, rev2, files, opts)
     let r=[]
         endif
         if !empty(rev1)
             let rev1=repo.functions.getrevhex(repo, rev1)
-            let csfiles=repo.changesets[rev1].files
+            let csfiles=repo.functions.getcsprop(repo, repo.changesets[rev1],
+                        \                        'files')
         endif
         if !empty(rev2)
             let rev2=repo.functions.getrevhex(repo, rev2)
-            let csfiles=repo.changesets[rev2].files
+            let csfiles=repo.functions.getcsprop(repo, repo.changesets[rev2],
+                        \                        'files')
         endif
         if !empty(rev1) && !empty(rev2)
             let cs1files=repo.changesets[rev1].files
 from mercurial import hg, ui, commands
 import vim
 import os
+import json
 
-def vim_dumps(obj):
+def nonutf_dumps(obj):
     todump=[('dump', obj)]
     r=''
     while todump:
                 r+='{'
                 todump.insert(0, ('inject', '}'))
                 for key, value in obj.items():
-                    todump.insert(0, ('inject', ','))
-                    todump.insert(0, ('dump', value))
-                    todump.insert(0, ('inject', ':'))
-                    todump.insert(0, ('dump', key))
+                    todump[:0]=[('dump', key),
+                                ('inject', ':'),
+                                ('dump', value),
+                                ('inject', ',')]
             elif tobj is list:
                 r+='['
                 todump.insert(0, ('inject', ']'))
                 for value in reversed(obj):
-                    todump.insert(0, ('inject', ','))
-                    todump.insert(0, ('dump', value))
+                    todump[:0]=[('dump', value), ('inject', ',')]
             elif tobj is int:
                 r+=str(obj)
             elif tobj is float:
                 r+='"'+str(obj).replace('\\', '\\\\').replace('"', '\\"')+'"'
     return r
 
+def utf_dumps(obj):
+    return json.dumps(obj, encoding='utf8')
+
+class VIMEncode(json.JSONEncoder):
+    def encode(self, obj, *args, **kwargs):
+        if isinstance(obj, (dict, list, int)):
+            return super(VIMEncode, self).encode(obj, *args, **kwargs)
+        return '"'+str(obj).replace('\\', '\\\\').replace('"', '\\"')+'"'
+
 class CaptureUI(ui.ui):
     def __init__(self):
         self._captured=[]
     cs_vim['time']=int(cs.date()[0])
     cs_vim['description']=cs.description()
     cs_vim['user']=cs.user()
+    cs_vim['parents']=[parent.hex() for parent in cs.parents()]
     try:
         branch=cs.branch()
         cs_vim['branch']=branch
         cs_vim['bookmarks']=cs.bookmarks()
     except AttributeError:
         pass
-    for parent in cs.parents():
-        cs_vim['parents'].append(parent.hex())
-    for file in cs.files():
-        cs_vim['files'].append(file)
     return cs_vim
 
 def get_updates(path, oldtip):
         return
     startrev=cs.rev()
     r=get_revlist(repo, startrev)
-    vim.eval('extend(d, {"css": '+vim_dumps(r)+', '+
+    vim.eval('extend(d, {"css": '+utf_dumps(r)+', '+
                         '"tip_hex": "'+tipcs.hex()+'", '+
                         '"work_hex": "'+repo['.'].hex()+'", '+
                         '"startrev": '+str(startrev)+'})')
     cscount=repo['tip'].rev()+1
     r=[set_rev_dict(repo[i], {'rev': i,
                           'parents': [],
-                         'children': [],
-                            'files': [],}) for i in range(0, cscount+1)]
+                         'children': [],}) for i in range(0, cscount+1)]
     return r
 
 def new_repo(path):
     repo_vim['work_hex']=repo['.'].hex()
     repo_vim['tip_hex']=repo['tip'].hex()
     repo_vim['cslist']=get_revlist(repo)
-    vim.eval('extend(repo, '+vim_dumps(repo_vim)+')')
+    vim.eval('extend(repo, '+utf_dumps(repo_vim)+')')
 
 def get_file(path, rev, filepath):
     fctx=get_repo(path)[rev].filectx(filepath)
     vim.eval('extend(r, '+
-            vim_dumps(
+            nonutf_dumps(
                 [line.replace("\0", "\n") for line in fctx.data().split("\n")])+
                    ')')
 
 def diff(*args, **kwargs):
     ui=CaptureUI()
     dodiff(ui, *args, **kwargs)
-    vim.eval('extend(r, '+vim_dumps(ui._getCaptured())+')')
+    vim.eval('extend(r, '+nonutf_dumps(ui._getCaptured())+')')
 
 def diffToBuffer(*args, **kwargs):
     ui=CaptureToBuf(vim.current.buffer)
     dodiff(ui, *args, **kwargs)
+
+def get_cs_prop(path, rev, prop):
+    vim.eval('extend(a:cs, {"'+prop+'": '+
+             nonutf_dumps(get_repo(path)[rev].__getattribute__(prop)())+'})')