author |
Steve Losh <steve@stevelosh.com> |
date |
Tue, 14 Jul 2009 20:28:50 -0400 |
parents |
894fbbeb6e6d |
children |
d7e61ff5eced |
#!/usr/bin/env python
'''get repository information for use in a shell prompt
Take a string, parse any special variables inside, and output the result.
Useful mostly for putting information about the current repository into
a shell prompt.
'''
import re
from os import path
from mercurial import extensions, hg, cmdutil
def _with_groups(g, out):
if any(g) and not all(g):
print 'ERROR'
return ("%s" + out + "%s") % (g[0][:-1] if g[0] else '',
g[1][1:] if g[1] else '')
def prompt(ui, repo, fs):
'''get repository information for use in a shell prompt
Take a string and output it for use in a shell prompt. You can use
keywords in curly braces:
$ hg prompt "currently on {branch}"
currently on default
You can also use an extended form of any keyword:
{optional text here{keyword}more optional text}
This will expand the inner {keyword} and output it along with the extra
text only if the {keyword} expands successfully. This is useful if you
have a keyword that may not always apply to the current state and you
have some text that you would like to see only if it is appropriate:
$ hg prompt "currently at {bookmark}"
currently at
$ hg prompt "{currently at {bookmark}}"
$ hg bookmark my-bookmark
$ hg prompt "{currently at {bookmark}}"
currently at my-bookmark
The following keywords are available:
- bookmark: the current bookmark
- branch: the current branch
- incoming: this keyword prints nothing on its own. If the default
path contains incoming changesets the extra text will be expanded.
For example:
'{incoming changes{incoming}}' will expand to
'incoming changes' if there are changes, '' otherwise.
- incoming|count: the number of incoming changesets if greater than 0
- outgoing: this keyword prints nothing on its own. If the current
repository contains outgoing changesets (to default) the extra text
will be expanded. For example:
'{outgoing changes{outgoing}}' will expand to
'outgoing changes' if there are changes, '' otherwise.
- outgoing|count: the number of outgoing changesets if greater than 0
- root: the full path to the root of the current repository, without a
trailing slash
- root|basename: the directory name of the root of the current
repository. For example, if the repository is in '/home/u/myrepo'
then this keyword would expand to 'myrepo'.
- status: "!" if the current repository contains files that have been
modified, added, removed, or deleted, otherwise "?" if it contains
untracked (and not ignored) files, otherwise nothing.
'''
def _branch(m):
branch = repo.dirstate.branch()
return _with_groups(m.groups(), branch) if branch else ''
def _status(m):
st = repo.status(unknown=True)[:5]
flag = '!' if any(st[:4]) else '?' if st[-1] else ''
return _with_groups(m.groups(), flag) if flag else ''
def _bookmark(m):
try:
book = extensions.find('bookmarks').current(repo)
return _with_groups(m.groups(), book) if book else ''
except KeyError:
return ''
def _root(m):
return _with_groups(m.groups(), repo.root) if repo.root else ''
def _basename(m):
return _with_groups(m.groups(), path.basename(repo.root)) if repo.root else ''
def _incoming(m):
source = "default"
ui.quiet = True
source, revs, checkout = hg.parseurl(ui.expandpath(source))
other = hg.repository(cmdutil.remoteui(repo, {}), source)
o = other.changelog.nodesbetween(repo.findincoming(other), revs)[0]
count = len(o) if o else 0
ui.quiet = False
g = m.groups()
out_g = (g[0],) + (g[-1],)
if g[1]:
output = _with_groups(out_g, str(count)) if count else ''
else:
output = _with_groups(out_g, '') if count else ''
return output
def _outgoing(m):
dest = "default"
ui.quiet = True
dest, revs, checkout = hg.parseurl(
ui.expandpath(dest or 'default-push', dest or 'default'))
other = hg.repository(cmdutil.remoteui(repo, {}), dest)
o = repo.changelog.nodesbetween(repo.findoutgoing(other), revs)[0]
count = len(o) if o else 0
ui.quiet = False
g = m.groups()
out_g = (g[0],) + (g[-1],)
if g[1]:
output = _with_groups(out_g, str(count)) if count else ''
else:
output = _with_groups(out_g, '') if count else ''
return output
tag_start = r'\{([^{}]*?\{)?'
tag_end = r'(\}[^{}]*?)?\}'
patterns = {
'branch': _branch,
'status': _status,
'bookmark': _bookmark,
'root': _root,
'root\|basename': _basename,
'incoming(\|count)?': _incoming,
'outgoing(\|count)?': _outgoing,
}
for tag, repl in patterns.items():
fs = re.sub(tag_start + tag + tag_end, repl, fs)
ui.status(fs)
cmdtable = {
"prompt": (prompt, [], 'hg prompt STRING')
}