ed22ce1f3057

o Daemonized the hg incoming/outgoing calls to increase responsiveness;
o Added zero option to incoming and outgoing that will expand 0 counts.
[view raw] [browse files]
author Chris <doktorstick@gmail.com>
date Fri, 01 Jul 2016 17:52:18 -0500
parents a410d2232772
children 996d64681e55
branches/tags (none)
files .hgignore prompt.py

Changes

--- a/.hgignore	Fri Jul 01 17:47:27 2016 -0500
+++ b/.hgignore	Fri Jul 01 17:52:18 2016 -0500
@@ -2,5 +2,7 @@
 
 .DS_Store
 *.pyc
+.idea/
 docs/.html
 docs/.tmp
+
--- a/prompt.py	Fri Jul 01 17:47:27 2016 -0500
+++ b/prompt.py	Fri Jul 01 17:52:18 2016 -0500
@@ -14,6 +14,7 @@
 import os
 import subprocess
 from datetime import datetime, timedelta
+from contextlib import closing
 from os import path
 from mercurial import extensions, commands, cmdutil, help
 from mercurial.i18n import _
@@ -34,15 +35,54 @@
 
 FILTER_ARG = re.compile(r'\|.+\((.*)\)')
 
+
+def _daemon_spawn (fn):
+    """
+    Daemonize the function `fn`. The calling process will not be
+    terminated; the daemon will terminate after `fn` completes.
+    """
+
+    pid = os.fork()
+    if pid == 0:
+        pid = os.fork()
+        if pid == 0:
+            for fd in range(0,subprocess.MAXFD):
+                try: os.close(fd)
+                except OSError: pass
+
+            os.open(os.devnull, os.O_RDWR)
+            os.dup2(0,1)
+            os.dup2(0,2)
+
+            try:
+                fn()
+            finally:
+                # We are done with this subprocess, so exit.
+                os._exit(0)
+        else:
+            # Close the parent (the first child) of the second child.
+            os._exit(0)
+
 def _cache_remote(repo, kind):
     cache = path.join(repo.root, CACHE_PATH, kind)
     c_tmp = cache + '.temp'
 
-    # This is kind of a hack and I feel a little bit dirty for doing it.
-    IGNORE = open('NUL:','w') if subprocess.mswindows else open('/dev/null','w')
+    devnull = 'NUL:' if subprocess.mswindows else os.devnull
+    spawn = lambda fn: fn() if subprocess.mswindows else _daemon_spawn
 
-    subprocess.call(['hg', kind, '--quiet'], stdout=file(c_tmp, 'w'), stderr=IGNORE)
-    os.rename(c_tmp, cache)
+    def _update_cache():
+        # This is kind of a hack and I feel a little bit dirty for doing it.
+        with closing(open(devnull, 'w')) as IGNORE:
+            subprocess.call(
+                ['hg', kind, '--quiet'],
+                stdout=file(c_tmp, 'w'),
+                stderr=IGNORE
+            )
+            os.rename(c_tmp, cache)
+
+    # Spawn the update in a daemon process so it doesn't slow
+    # down the prompt return.
+    spawn (_update_cache)
     return
 
 def _with_groups(groups, out):
@@ -285,10 +325,12 @@
             if cache_exists:
                 with open(cache) as c:
                     count = len(c.readlines())
-                    if g[1]:
-                        return _with_groups(g, str(count)) if count else ''
+                    if g[1] and count > 0:
+                        return _with_groups(g, str(count))
+                    elif g[2]:
+                        return _with_groups(g, '0') if not count else ''
                     else:
-                        return _with_groups(g, '') if count else ''
+                        return _with_groups(g, '')
             else:
                 return ''
         return _r
@@ -428,8 +470,14 @@
             ')*': _tip,
         'update': _update,
 
-        'incoming(\|count)?': _remote('incoming'),
-        'outgoing(\|count)?': _remote('outgoing'),
+        'incoming(?:'
+            '(\|count)'
+            '|(\|zero)'
+            ')*': _remote('incoming'),
+        'outgoing(?:'
+            '(\|count)'
+            '|(\|zero)'
+            ')*': _remote('outgoing')
     }
 
     if opts.get("cache_incoming"):
@@ -508,6 +556,8 @@
 
      |count
          Display the number of incoming changesets (if greater than 0).
+     |zero
+         Display 0 if there are no incoming changesets.
 
 node
      Display the (full) changeset hash of the current parent.
@@ -531,6 +581,8 @@
 
      |count
          Display the number of outgoing changesets (if greater than 0).
+     |zero
+         Display 0 if there are no incoming changesets.
 
 patch
      Display the topmost currently-applied patch (requires the mq