WIP: support keywords topic, revtopic, stackidx
1 files changed, 99 insertions(+), 1 deletions(-)

M prompt.py
M prompt.py +99 -1
@@ 16,7 16,7 @@ import subprocess
 from datetime import datetime, timedelta
 from contextlib import closing
 from os import path
-from mercurial import extensions, commands, cmdutil, help
+from mercurial import extensions, commands, cmdutil, help, error
 from mercurial.i18n import _
 from mercurial.node import hex, short
 

          
@@ 129,6 129,74 @@ def prompt(ui, repo, fs='', **opts):
         else:
             return ''
 
+    def _topic(m):
+        # topic -- The active topic
+        # topic|if_empty -- only display if the active topic contains no commits
+        # topic|if_nonempty -- only display if the active topic contains commits
+        g = m.groups()
+        topic = getattr(repo, 'currenttopic', None)
+        empty = not bool(repo.revs("stack()"))
+        if_empty = '|if_empty' in g
+        if_nonempty = '|if_nonempty' in g
+
+        if not topic:
+            return ''
+
+        out = _with_groups(m.groups(), topic)
+
+        # If neither flag is set, or both flags are set:
+        if (if_empty + if_nonempty) in (0, 2):
+            return out
+        # just the if_empty flag
+        if if_empty:
+            return out if empty else ''
+        # just the if_nonempty flag
+        if if_nonempty:
+            return out if not empty else ''
+
+    def _revtopic(m):
+        # Return early if the topic extension isn't active
+        try:
+            rev_topic = repo['.'].topic()
+        except AttributeError:
+            return ''
+        current_topic = getattr(repo, 'currenttopic', None)
+
+        # Return early if the changeset has no topic set
+        if not rev_topic:
+            return ''
+        # Return early if the topic must be active, and isn't.
+        if ('|if_active' in m.groups() and not rev_topic == current_topic):
+            return ''
+        # The changeset has a topic, and we want its number
+        if '|idx' in m.groups():
+            rev_idx = str(repo['.'].topicidx())
+            return _with_groups(m.groups(), rev_idx)
+        # The changeset has a topic, and we want its name
+        return _with_groups(m.groups(), rev_topic)
+
+    def _stackidx(m):
+        # Return early if the topic extension isn't active
+        try:
+            rev_topic = repo['.'].topic()
+        except AttributeError:
+            return ''
+        # Return early if there is no active topic
+        if repo.currenttopic == '':
+            return ''
+        # Return success if the changeset is in the current topic
+        if rev_topic == repo.currenttopic:
+            return _with_groups(m.groups(), 's%d' % repo['.'].topicidx())
+        # Return success if the changeset is s0
+        try:
+            is_s0 = repo['.'].rev() == list(repo.revs('s0'))[0]
+            if is_s0:
+                return _with_groups(m.groups(), 's0')
+        except error.Abort:
+            pass
+        # Not s0, not part of the current topic
+        return ''
+
     def _branch(m):
         g = m.groups()
 

          
@@ 400,6 468,15 @@ def prompt(ui, repo, fs='', **opts):
             '(\|node)'
             '|(\|short)'
             ')*': _tip,
+        'topic(?:'
+            '(\|if_empty)'
+            '|(\|if_nonempty)'
+            ')*': _topic,
+        'revtopic(?:'
+            '(\|idx)'
+            '|(\|if_active)'
+            ')*': _revtopic,
+        'stackidx': _stackidx,
         'update': _update
     }
 

          
@@ 515,6 592,16 @@ rev
          Display the repository-local changeset number of the changeset you're
          merging with.
 
+revtopic
+     Display the topic of the current changeset. E.g.
+
+     |idx
+         Display the topic index of the current changeset as 1, 2, 3, ...
+
+     |if_active
+        Only display something if the changeset's topic is the active topic.
+
+
 root
      Display the full path to the root of the current repository, without a
      trailing slash.

          
@@ 524,6 611,9 @@ root
          example, if the repository is in `/home/u/myrepo` then this keyword
          would expand to `myrepo`.
 
+stackidx
+     Display the stack alias of the current changeset. E.g. s0, s1, ...
+
 status
      Display `!` if the repository has any changed/added/removed files,
      otherwise `?` if it has any untracked (but not ignored) files, otherwise

          
@@ 559,6 649,14 @@ tip
          Display a short form of the changeset hash of the current tip (must be
          used with the **|node** filter)
 
+topic
+     Display the active topic, whether or not it contains changesets.
+
+     |if_empty
+         Only display something if the topic is empty.
+     |if_nonempty
+         Only display something if the topic contains changesets.
+
 update
      Display `^` if the current parent is not the tip of the current branch,
      otherwise nothing.  In effect, this lets you see if running `hg update`