--- 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