# HG changeset patch # User Pierre-Yves David # Date 1725532092 -7200 # Node ID 76387080f238b008ca5ead62640993547835b418 # Parent fe08a0bfa9fde2138e51e0f0901d06dec89cd7d4 help: add :config-doc:`section.key` shorthand to insert documentation The config items defined in the configitems.toml file can already hold their documentation. Having some way to automatically insert it was a long standing low hanging fruit. So I did a first implementation on that. It fairly simple, but it open the door to more. It will be used in the next changeset. diff -r fe08a0bfa9fd -r 76387080f238 doc/gendoc.py --- a/doc/gendoc.py Wed Sep 11 20:52:51 2024 +0200 +++ b/doc/gendoc.py Thu Sep 05 12:28:12 2024 +0200 @@ -156,7 +156,8 @@ for extensionname in sorted(allextensionnames()): mod = extensions.load(ui, extensionname, None) ui.write(minirst.subsection(extensionname)) - ui.write(b"%s\n\n" % gettext(pycompat.getdoc(mod))) + ext_doc = help.ext_help(ui, mod) + ui.write(b"%s\n\n" % ext_doc) cmdtable = getattr(mod, 'cmdtable', None) if cmdtable: ui.write(minirst.subsubsection(_(b'Commands'))) diff -r fe08a0bfa9fd -r 76387080f238 mercurial/help.py --- a/mercurial/help.py Wed Sep 11 20:52:51 2024 +0200 +++ b/mercurial/help.py Thu Sep 05 12:28:12 2024 +0200 @@ -159,6 +159,15 @@ return rst +def ext_help(ui: uimod.ui, ext) -> bytes: + doc = pycompat.getdoc(ext) + if doc is None: + return b"" + assert doc is not None + doc = gettext(doc) + return sub_config_item_help(ui, doc) + + def extshelp(ui: uimod.ui) -> bytes: rst = loaddoc(b'extensions')(ui).splitlines(True) rst.extend( @@ -365,6 +374,7 @@ doc = gettext(fp.read()) for rewriter in helphooks.get(topic, []): doc = rewriter(ui, topic, doc) + doc = sub_config_item_help(ui, doc) return doc return loader @@ -695,6 +705,44 @@ return re.sub(br'( *)%s' % re.escape(marker), sub, doc) +_CONFIG_DOC_RE = re.compile(b'(^ *)?:config-doc:`([^`]+)`', flags=re.MULTILINE) + + +def sub_config_item_help(ui: uimod.ui, doc: bytes) -> bytes: + """replace :config-doc:`foo.bar` markup with the item documentation + + This allow grouping config item declaration and help without having to + repeat it in the help text file and keep that in sync. + """ + pieces = [] + last_match_end = 0 + for match in _CONFIG_DOC_RE.finditer(doc): + # finditer is expected to yield result in order + start = match.start() + assert last_match_end <= match.start() + pieces.append(doc[last_match_end:start]) + item_name = match.group(2) + section, key = item_name.split(b'.', 1) + section_items = ui._knownconfig.get(section) + if section_items is None: + item = None + else: + item = section_items.get(key) + if item is None or not item.documentation: + item_doc = b'' % item_name + else: + item_doc = gettext(item.documentation) + item_doc = sub_config_item_help(ui, item_doc) + indent = match.group(1) + if indent: # either None or 0 should be ignored + indent = indent + item_doc = indent + item_doc.replace(b'\n', b'\n' + indent) + pieces.append(item_doc) + last_match_end = match.end() + pieces.append(doc[last_match_end:]) + return b''.join(pieces) + + def _getcategorizedhelpcmds( ui: uimod.ui, cmdtable, name: bytes, select: Optional[_SelectFn] = None ) -> Tuple[Dict[bytes, List[bytes]], Dict[bytes, bytes], _SynonymTable]: @@ -822,6 +870,7 @@ doc, source, ) + doc = sub_config_item_help(ui, doc) doc = doc.splitlines(True) if ui.quiet or not full: rst.append(doc[0]) @@ -1042,12 +1091,15 @@ def helpext(name: bytes, subtopic: Optional[bytes] = None) -> List[bytes]: try: mod = extensions.find(name) - doc = gettext(pycompat.getdoc(mod)) or _(b'no help text available') + doc = ext_help(ui, mod) + if not doc: + doc = _(b'no help text available') except KeyError: mod = None doc = extensions.disabled_help(name) if not doc: raise error.UnknownCommand(name) + doc = sub_config_item_help(ui, doc) if b'\n' not in doc: head, tail = doc, b""