aboutsummaryrefslogtreecommitdiff
path: root/scripts/gen_vimdoc.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/gen_vimdoc.py')
-rwxr-xr-xscripts/gen_vimdoc.py81
1 files changed, 64 insertions, 17 deletions
diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py
index a61690e99f..b1a7f92854 100755
--- a/scripts/gen_vimdoc.py
+++ b/scripts/gen_vimdoc.py
@@ -39,6 +39,7 @@ Each function :help block is formatted as follows:
parameter is marked as [out].
- Each function documentation is separated by a single line.
"""
+import argparse
import os
import re
import sys
@@ -57,7 +58,6 @@ if sys.version_info < MIN_PYTHON_VERSION:
sys.exit(1)
DEBUG = ('DEBUG' in os.environ)
-TARGET = os.environ.get('TARGET', None)
INCLUDE_C_DECL = ('INCLUDE_C_DECL' in os.environ)
INCLUDE_DEPRECATED = ('INCLUDE_DEPRECATED' in os.environ)
@@ -68,6 +68,7 @@ base_dir = os.path.dirname(os.path.dirname(script_path))
out_dir = os.path.join(base_dir, 'tmp-{target}-doc')
filter_cmd = '%s %s' % (sys.executable, script_path)
seen_funcs = set()
+msgs = [] # Messages to show on exit.
lua2dox_filter = os.path.join(base_dir, 'scripts', 'lua2dox_filter')
CONFIG = {
@@ -112,10 +113,12 @@ CONFIG = {
'section_order': [
'vim.lua',
'shared.lua',
+ 'uri.lua',
],
'files': ' '.join([
os.path.join(base_dir, 'src/nvim/lua/vim.lua'),
os.path.join(base_dir, 'runtime/lua/vim/shared.lua'),
+ os.path.join(base_dir, 'runtime/lua/vim/uri.lua'),
]),
'file_patterns': '*.lua',
'fn_name_prefix': '',
@@ -128,6 +131,7 @@ CONFIG = {
'module_override': {
# `shared` functions are exposed on the `vim` module.
'shared': 'vim',
+ 'uri': 'vim',
},
'append_only': [
'shared.lua',
@@ -139,12 +143,13 @@ CONFIG = {
'section_start_token': '*lsp-core*',
'section_order': [
'lsp.lua',
- 'protocol.lua',
'buf.lua',
- 'callbacks.lua',
+ 'diagnostic.lua',
+ 'handlers.lua',
+ 'util.lua',
'log.lua',
'rpc.lua',
- 'util.lua'
+ 'protocol.lua',
],
'files': ' '.join([
os.path.join(base_dir, 'runtime/lua/vim/lsp'),
@@ -191,7 +196,7 @@ xrefs = set()
# Raises an error with details about `o`, if `cond` is in object `o`,
# or if `cond()` is callable and returns True.
-def debug_this(cond, o):
+def debug_this(o, cond=True):
name = ''
if not isinstance(o, str):
try:
@@ -205,6 +210,23 @@ def debug_this(cond, o):
raise RuntimeError('xxx: {}\n{}'.format(name, o))
+# Appends a message to a list which will be printed on exit.
+def msg(s):
+ msgs.append(s)
+
+
+# Print all collected messages.
+def msg_report():
+ for m in msgs:
+ print(f' {m}')
+
+
+# Print collected messages, then throw an exception.
+def fail(s):
+ msg_report()
+ raise RuntimeError(s)
+
+
def find_first(parent, name):
"""Finds the first matching node within parent."""
sub = parent.getElementsByTagName(name)
@@ -426,7 +448,7 @@ def render_node(n, text, prefix='', indent='', width=62):
indent=indent, width=width))
i = i + 1
elif n.nodeName == 'simplesect' and 'note' == n.getAttribute('kind'):
- text += 'Note:\n '
+ text += '\nNote:\n '
for c in n.childNodes:
text += render_node(c, text, indent=' ', width=width)
text += '\n'
@@ -440,6 +462,8 @@ def render_node(n, text, prefix='', indent='', width=62):
text += ind(' ')
for c in n.childNodes:
text += render_node(c, text, indent=' ', width=width)
+ elif n.nodeName == 'computeroutput':
+ return get_text(n)
else:
raise RuntimeError('unhandled node type: {}\n{}'.format(
n.nodeName, n.toprettyxml(indent=' ', newl='\n')))
@@ -505,6 +529,7 @@ def para_as_map(parent, indent='', width=62):
and is_inline(self_or_child(prev))
and is_inline(self_or_child(child))
and '' != get_text(self_or_child(child)).strip()
+ and text
and ' ' != text[-1]):
text += ' '
@@ -684,7 +709,7 @@ def extract_from_xml(filename, target, width):
if len(prefix) + len(suffix) > lhs:
signature = vimtag.rjust(width) + '\n'
- signature += doc_wrap(suffix, width=width-8, prefix=prefix,
+ signature += doc_wrap(suffix, width=width, prefix=prefix,
func=True)
else:
signature = prefix + suffix
@@ -841,7 +866,7 @@ def delete_lines_below(filename, tokenstr):
fp.writelines(lines[0:i])
-def main(config):
+def main(config, args):
"""Generates:
1. Vim :help docs
@@ -850,7 +875,7 @@ def main(config):
Doxygen is called and configured through stdin.
"""
for target in CONFIG:
- if TARGET is not None and target != TARGET:
+ if args.target is not None and target != args.target:
continue
mpack_file = os.path.join(
base_dir, 'runtime', 'doc',
@@ -915,9 +940,10 @@ def main(config):
filename = get_text(find_first(compound, 'name'))
if filename.endswith('.c') or filename.endswith('.lua'):
+ xmlfile = os.path.join(base,
+ '{}.xml'.format(compound.getAttribute('refid')))
# Extract unformatted (*.mpack).
- fn_map, _ = extract_from_xml(os.path.join(base, '{}.xml'.format(
- compound.getAttribute('refid'))), target, width=9999)
+ fn_map, _ = extract_from_xml(xmlfile, target, width=9999)
# Extract formatted (:help).
functions_text, deprecated_text = fmt_doxygen_xml_as_vimhelp(
os.path.join(base, '{}.xml'.format(
@@ -950,7 +976,8 @@ def main(config):
sections[filename] = (title, helptag, doc)
fn_map_full.update(fn_map)
- assert sections
+ if len(sections) == 0:
+ fail(f'no sections for target: {target}')
if len(sections) > len(CONFIG[target]['section_order']):
raise RuntimeError(
'found new modules "{}"; update the "section_order" map'.format(
@@ -960,7 +987,11 @@ def main(config):
i = 0
for filename in CONFIG[target]['section_order']:
- title, helptag, section_doc = sections.pop(filename)
+ try:
+ title, helptag, section_doc = sections.pop(filename)
+ except KeyError:
+ msg(f'warning: empty docs, skipping (target={target}): {filename}')
+ continue
i += 1
if filename not in CONFIG[target]['append_only']:
docs += sep
@@ -983,7 +1014,10 @@ def main(config):
with open(mpack_file, 'wb') as fp:
fp.write(msgpack.packb(fn_map_full, use_bin_type=True))
- shutil.rmtree(output_dir)
+ if not args.keep_tmpfiles:
+ shutil.rmtree(output_dir)
+
+ msg_report()
def filter_source(filename):
@@ -1001,6 +1035,18 @@ def filter_source(filename):
fp.read(), flags=re.M))
+def parse_args():
+ targets = ', '.join(CONFIG.keys())
+ ap = argparse.ArgumentParser()
+ ap.add_argument('source_filter', nargs='*',
+ help="Filter source file(s)")
+ ap.add_argument('-k', '--keep-tmpfiles', action='store_true',
+ help="Keep temporary files")
+ ap.add_argument('-t', '--target',
+ help=f'One of ({targets}), defaults to "all"')
+ return ap.parse_args()
+
+
Doxyfile = textwrap.dedent('''
OUTPUT_DIRECTORY = {output}
INPUT = {input}
@@ -1037,9 +1083,10 @@ Doxyfile = textwrap.dedent('''
''')
if __name__ == "__main__":
- if len(sys.argv) > 1:
- filter_source(sys.argv[1])
+ args = parse_args()
+ if len(args.source_filter) > 0:
+ filter_source(args.source_filter[0])
else:
- main(Doxyfile)
+ main(Doxyfile, args)
# vim: set ft=python ts=4 sw=4 tw=79 et :