help: basic support for showing only specified topic sections
authorMatt Mackall <mpm@selenic.com>
Tue, 30 Sep 2014 16:40:10 -0500
changeset 22587 c3c3dd31fe1c
parent 22586 6e5657ce9e8c
child 22588 cd1b43226b34
help: basic support for showing only specified topic sections For instance, 'hg help config.files' will show only the Files section.
mercurial/commands.py
mercurial/minirst.py
tests/test-help.t
--- a/mercurial/commands.py	Tue Sep 30 15:55:30 2014 -0500
+++ b/mercurial/commands.py	Tue Sep 30 16:40:10 2014 -0500
@@ -3834,14 +3834,23 @@
         keep.append('unix')
         keep.append(sys.platform.lower())
 
+    section = None
+    if name and '.' in name:
+        name, section = name.split('.')
+
     text = help.help_(ui, name, **opts)
 
-    formatted, pruned = minirst.format(text, textwidth, keep=keep)
+    formatted, pruned = minirst.format(text, textwidth, keep=keep,
+                                       section=section)
+    if section and not formatted:
+        raise util.Abort(_("help section not found"))
+
     if 'verbose' in pruned:
         keep.append('omitted')
     else:
         keep.append('notomitted')
-    formatted, pruned = minirst.format(text, textwidth, keep=keep)
+    formatted, pruned = minirst.format(text, textwidth, keep=keep,
+                                       section=section)
     ui.write(formatted)
 
 
--- a/mercurial/minirst.py	Tue Sep 30 15:55:30 2014 -0500
+++ b/mercurial/minirst.py	Tue Sep 30 16:40:10 2014 -0500
@@ -648,9 +648,15 @@
     text = ''.join(formatblock(b, width) for b in blocks)
     return text
 
-def format(text, width=80, indent=0, keep=None, style='plain'):
+def format(text, width=80, indent=0, keep=None, style='plain', section=None):
     """Parse and format the text according to width."""
     blocks, pruned = parse(text, indent, keep or [])
+    if section:
+        sections = getsections(blocks)
+        blocks = []
+        for name, nest, b in sections:
+            if name == section:
+                blocks = b
     if style == 'html':
         text = formathtml(blocks)
     else:
@@ -665,6 +671,14 @@
     nest = ""
     level = 0
     secs = []
+
+    def getname(b):
+        x = b['lines'][0]
+        x = x.lower().strip('"')
+        if '(' in x:
+            x = x.split('(')[0]
+        return x
+
     for b in blocks:
         if b['type'] == 'section':
             i = b['underline']
@@ -672,7 +686,14 @@
                 nest += i
             level = nest.index(i) + 1
             nest = nest[:level]
-            secs.append((b['lines'][0], level, [b]))
+            secs.append((getname(b), level, [b]))
+        if b['type'] == 'definition':
+            i = ' '
+            if i not in nest:
+                nest += i
+            level = nest.index(i) + 1
+            nest = nest[:level]
+            secs.append((getname(b), level, [b]))
         else:
             if not secs:
                 # add an initial empty section
--- a/tests/test-help.t	Tue Sep 30 15:55:30 2014 -0500
+++ b/tests/test-help.t	Tue Sep 30 16:40:10 2014 -0500
@@ -1046,6 +1046,25 @@
   
       This paragraph is never omitted, too (for topic)
 
+Test section lookup
+
+  $ hg help revset.merge
+      "merge()"
+        Changeset is a merge changeset.
+  
+  $ hg help glossary.dag
+      DAG
+          The repository of changesets of a distributed version control system
+          (DVCS) can be described as a directed acyclic graph (DAG), consisting
+          of nodes and edges, where nodes correspond to changesets and edges
+          imply a parent -> child relation. This graph can be visualized by
+          graphical tools such as "hg log --graph". In Mercurial, the DAG is
+          limited by the requirement for children to have at most two parents.
+  
+  $ hg help glossary.mcguffin
+  abort: help section not found
+  [255]
+
 Test usage of section marks in help documents
 
   $ cd "$TESTDIR"/../doc