mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-11-14 22:57:37 +03:00
611 lines
21 KiB
Python
611 lines
21 KiB
Python
#!/usr/bin/env python3
|
|
# vim:fileencoding=utf-8
|
|
#
|
|
# Configuration file for the Sphinx documentation builder.
|
|
#
|
|
# This file does only contain a selection of the most common options. For a
|
|
# full list see the documentation:
|
|
# https://www.sphinx-doc.org/en/master/config
|
|
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
from functools import partial
|
|
from typing import (
|
|
Any, Callable, Dict, Iterable, List, Match, Optional, Sequence, Tuple,
|
|
Union
|
|
)
|
|
|
|
from docutils import nodes
|
|
from docutils.parsers.rst.roles import set_classes
|
|
from pygments.lexer import RegexLexer, bygroups # type: ignore
|
|
from pygments.token import ( # type: ignore
|
|
Comment, Keyword, Literal, Name, Number, String, Whitespace
|
|
)
|
|
from sphinx import addnodes, version_info # type: ignore
|
|
from sphinx.environment.adapters.toctree import TocTree # type: ignore
|
|
from sphinx.util.logging import getLogger # type: ignore
|
|
|
|
kitty_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
if kitty_src not in sys.path:
|
|
sys.path.insert(0, kitty_src)
|
|
|
|
from kitty.conf.definition import Option, Shortcut # noqa
|
|
from kitty.constants import str_version # noqa
|
|
|
|
|
|
# config {{{
|
|
# -- Project information -----------------------------------------------------
|
|
|
|
project = 'kitty'
|
|
copyright = time.strftime('%Y, Kovid Goyal')
|
|
author = 'Kovid Goyal'
|
|
building_man_pages = 'man' in sys.argv
|
|
|
|
# The short X.Y version
|
|
version = str_version
|
|
# The full version, including alpha/beta/rc tags
|
|
release = str_version
|
|
logger = getLogger(__name__)
|
|
|
|
|
|
# -- General configuration ---------------------------------------------------
|
|
|
|
# If your documentation needs a minimal Sphinx version, state it here.
|
|
#
|
|
needs_sphinx = '1.7'
|
|
|
|
# Add any Sphinx extension module names here, as strings. They can be
|
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
# ones.
|
|
extensions = [
|
|
'sphinx.ext.ifconfig',
|
|
'sphinx.ext.viewcode',
|
|
'sphinx.ext.githubpages',
|
|
]
|
|
|
|
# Add any paths that contain templates here, relative to this directory.
|
|
templates_path = ['_templates']
|
|
|
|
# The suffix(es) of source filenames.
|
|
# You can specify multiple suffix as a list of string:
|
|
#
|
|
# source_suffix = ['.rst', '.md']
|
|
source_suffix = '.rst'
|
|
|
|
# The master toctree document.
|
|
master_doc = 'index'
|
|
|
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
# for a list of supported languages.
|
|
#
|
|
# This is also used if you do content translation via gettext catalogs.
|
|
# Usually you set "language" from the command line for these cases.
|
|
language: Optional[str] = None
|
|
|
|
# List of patterns, relative to source directory, that match files and
|
|
# directories to ignore when looking for source files.
|
|
# This pattern also affects html_static_path and html_extra_path .
|
|
exclude_patterns = [
|
|
'_build', 'Thumbs.db', '.DS_Store',
|
|
'generated/cli-*.rst', 'generated/conf-*.rst'
|
|
]
|
|
|
|
# The name of the Pygments (syntax highlighting) style to use.
|
|
pygments_style = 'sphinx'
|
|
|
|
rst_prolog = '''
|
|
.. |kitty| replace:: *kitty*
|
|
.. |version| replace:: VERSION
|
|
.. _tarball: https://github.com/kovidgoyal/kitty/releases/download/vVERSION/kitty-VERSION.tar.xz
|
|
.. role:: green
|
|
.. role:: italic
|
|
.. role:: bold
|
|
.. role:: cyan
|
|
.. role:: title
|
|
.. role:: env
|
|
|
|
'''.replace('VERSION', str_version)
|
|
|
|
|
|
# -- Options for HTML output -------------------------------------------------
|
|
|
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
# a list of builtin themes.
|
|
#
|
|
html_theme = 'alabaster'
|
|
|
|
# Theme options are theme-specific and customize the look and feel of a theme
|
|
# further. For a list of options available for each theme, see the
|
|
# documentation.
|
|
#
|
|
html_theme_options = {
|
|
'logo': 'kitty.png',
|
|
'show_powered_by': False,
|
|
'fixed_sidebar': True,
|
|
'sidebar_collapse': True,
|
|
'github_button': False,
|
|
'github_banner': True,
|
|
'github_user': 'kovidgoyal',
|
|
'github_repo': 'kitty',
|
|
# increase contrast of link color with text color
|
|
'link': '#00587d',
|
|
'link_hover': 'green',
|
|
}
|
|
|
|
|
|
# Add any paths that contain custom static files (such as style sheets) here,
|
|
# relative to this directory. They are copied after the builtin static files,
|
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
html_static_path = ['_static', '../logo/kitty.png']
|
|
html_favicon = '../logo/kitty.png'
|
|
|
|
# Custom sidebar templates, must be a dictionary that maps document names
|
|
# to template names.
|
|
#
|
|
# The default sidebars (for documents that don't match any pattern) are
|
|
# defined by theme itself. Builtin themes are using these templates by
|
|
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
|
|
# 'searchbox.html']``.
|
|
#
|
|
html_sidebars = {
|
|
'**': [
|
|
'about.html',
|
|
'support.html',
|
|
'searchbox.html',
|
|
'localtoc.html',
|
|
'relations.html',
|
|
]
|
|
}
|
|
html_show_sourcelink = False
|
|
|
|
|
|
# -- Options for manual page output ------------------------------------------
|
|
|
|
# One entry per manual page. List of tuples
|
|
# (source start file, name, description, authors, manual section).
|
|
man_pages = [
|
|
('invocation', 'kitty', 'kitty Documentation', [author], 1),
|
|
('conf', 'kitty.conf', 'kitty.conf Documentation', [author], 5)
|
|
]
|
|
|
|
|
|
# -- Options for Texinfo output ----------------------------------------------
|
|
|
|
# Grouping the document tree into Texinfo files. List of tuples
|
|
# (source start file, target name, title, author,
|
|
# dir menu entry, description, category)
|
|
texinfo_documents = [
|
|
(master_doc, 'kitty', 'kitty Documentation',
|
|
author, 'kitty', 'Cross-platform, fast, feature-rich, GPU based terminal',
|
|
'Miscellaneous'),
|
|
]
|
|
# }}}
|
|
|
|
|
|
# GitHub linking inline roles {{{
|
|
|
|
def num_role(which: str, name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
|
|
' Link to a github issue '
|
|
try:
|
|
issue_num = int(text)
|
|
if issue_num <= 0:
|
|
raise ValueError
|
|
except ValueError:
|
|
msg = inliner.reporter.error(
|
|
'GitHub issue number must be a number greater than or equal to 1; '
|
|
'"%s" is invalid.' % text, line=lineno)
|
|
prb = inliner.problematic(rawtext, rawtext, msg)
|
|
return [prb], [msg]
|
|
url = f'https://github.com/kovidgoyal/kitty/{which}/{issue_num}'
|
|
set_classes(options)
|
|
node = nodes.reference(rawtext, f'#{issue_num}', refuri=url, **options)
|
|
return [node], []
|
|
|
|
|
|
def commit_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
|
|
' Link to a github commit '
|
|
try:
|
|
commit_id = subprocess.check_output(
|
|
f'git rev-list --max-count=1 --skip=# {text}'.split()).decode('utf-8').strip()
|
|
except Exception:
|
|
msg = inliner.reporter.error(
|
|
f'GitHub commit id "{text}" not recognized.', line=lineno)
|
|
prb = inliner.problematic(rawtext, rawtext, msg)
|
|
return [prb], [msg]
|
|
url = f'https://github.com/kovidgoyal/kitty/commit/{commit_id}'
|
|
set_classes(options)
|
|
short_id = subprocess.check_output(
|
|
f'git rev-list --max-count=1 --abbrev-commit --skip=# {commit_id}'.split()).decode('utf-8').strip()
|
|
node = nodes.reference(rawtext, f'commit: {short_id}', refuri=url, **options)
|
|
return [node], []
|
|
# }}}
|
|
|
|
|
|
# Sidebar ToC {{{
|
|
def create_toc(app: Any, pagename: str) -> Optional[Any]:
|
|
tt = TocTree(app.env)
|
|
toctree = tt.get_toc_for(pagename, app.builder)
|
|
if toctree is not None:
|
|
subtree = toctree[toctree.first_child_matching_class(nodes.list_item)]
|
|
bl = subtree.first_child_matching_class(nodes.bullet_list)
|
|
if bl is None:
|
|
return None # Empty ToC
|
|
subtree = subtree[bl]
|
|
# for li in subtree.traverse(nodes.list_item):
|
|
# modify_li(li)
|
|
# subtree['ids'] = [ID]
|
|
return app.builder.render_partial(subtree)['fragment']
|
|
|
|
|
|
def add_html_context(app: Any, pagename: str, templatename: str, context: Any, *args: Any) -> None:
|
|
if 'toc' in context:
|
|
context['toc'] = create_toc(app, pagename) or context['toc']
|
|
# }}}
|
|
|
|
|
|
# CLI docs {{{
|
|
def write_cli_docs(all_kitten_names: Iterable[str]) -> None:
|
|
from kitty.launch import options_spec as launch_options_spec
|
|
from kitty.cli import option_spec_as_rst
|
|
with open('generated/launch.rst', 'w') as f:
|
|
f.write(option_spec_as_rst(
|
|
appname='launch', ospec=launch_options_spec, heading_char='_',
|
|
message='''\
|
|
Launch an arbitrary program in a new kitty window/tab. Note that
|
|
if you specify a program-to-run you can use the special placeholder
|
|
:code:`@selection` which will be replaced by the current selection.
|
|
'''
|
|
))
|
|
with open('generated/cli-kitty.rst', 'w') as f:
|
|
f.write(option_spec_as_rst(appname='kitty').replace(
|
|
'kitty --to', 'kitty @ --to'))
|
|
as_rst = partial(option_spec_as_rst, heading_char='_')
|
|
from kitty.rc.base import all_command_names, command_for_name
|
|
from kitty.remote_control import global_options_spec, cli_msg
|
|
with open('generated/cli-kitty-at.rst', 'w') as f:
|
|
p = partial(print, file=f)
|
|
p('kitty @\n' + '-' * 80)
|
|
p('.. program::', 'kitty @')
|
|
p('\n\n' + as_rst(
|
|
global_options_spec, message=cli_msg, usage='command ...', appname='kitty @'))
|
|
from kitty.rc.base import cli_params_for
|
|
for cmd_name in sorted(all_command_names()):
|
|
func = command_for_name(cmd_name)
|
|
p(f'.. _at_{func.name}:\n')
|
|
p('kitty @', func.name + '\n' + '-' * 120)
|
|
p('.. program::', 'kitty @', func.name)
|
|
p('\n\n' + as_rst(*cli_params_for(func)))
|
|
from kittens.runner import get_kitten_cli_docs
|
|
for kitten in all_kitten_names:
|
|
data = get_kitten_cli_docs(kitten)
|
|
if data:
|
|
with open(f'generated/cli-kitten-{kitten}.rst', 'w') as f:
|
|
p = partial(print, file=f)
|
|
p('.. program::', f'kitty +kitten {kitten}')
|
|
p('\n\n' + option_spec_as_rst(
|
|
data['options'], message=data['help_text'], usage=data['usage'], appname=f'kitty +kitten {kitten}',
|
|
heading_char='^'))
|
|
|
|
# }}}
|
|
|
|
|
|
def write_remote_control_protocol_docs() -> None: # {{{
|
|
from kitty.rc.base import all_command_names, command_for_name, RemoteCommand
|
|
field_pat = re.compile(r'\s*([a-zA-Z0-9_+]+)\s*:\s*(.+)')
|
|
|
|
def format_cmd(p: Callable, name: str, cmd: RemoteCommand) -> None:
|
|
p(name)
|
|
p('-' * 80)
|
|
lines = (cmd.__doc__ or '').strip().splitlines()
|
|
fields = []
|
|
for line in lines:
|
|
m = field_pat.match(line)
|
|
if m is None:
|
|
p(line)
|
|
else:
|
|
fields.append((m.group(1), m.group(2)))
|
|
if fields:
|
|
p('\nFields are:\n')
|
|
for (name, desc) in fields:
|
|
if '+' in name:
|
|
title = name.replace('+', ' (required)')
|
|
else:
|
|
title = name
|
|
defval = cmd.get_default(name.replace('-', '_'), cmd)
|
|
if defval is not cmd:
|
|
title = f'{title} (default: {defval})'
|
|
else:
|
|
title = f'{title} (optional)'
|
|
p(f':code:`{title}`')
|
|
p(' ', desc), p()
|
|
p(), p()
|
|
|
|
with open('generated/rc.rst', 'w') as f:
|
|
p = partial(print, file=f)
|
|
for name in sorted(all_command_names()):
|
|
cmd = command_for_name(name)
|
|
if not cmd.__doc__:
|
|
continue
|
|
name = name.replace('_', '-')
|
|
format_cmd(p, name, cmd)
|
|
# }}}
|
|
|
|
|
|
# config file docs {{{
|
|
|
|
class ConfLexer(RegexLexer):
|
|
name = 'Conf'
|
|
aliases = ['conf']
|
|
filenames = ['*.conf']
|
|
|
|
tokens = {
|
|
'root': [
|
|
(r'#.*?$', Comment.Single),
|
|
(r'\s+$', Whitespace),
|
|
(r'\s+', Whitespace),
|
|
(r'(include)(\s+)(.+?)$', bygroups(Comment.Preproc, Whitespace, Name.Namespace)),
|
|
(r'(map)(\s+)(\S+)(\s+)', bygroups(
|
|
Keyword.Declaration, Whitespace, String, Whitespace), 'action'),
|
|
(r'(symbol_map)(\s+)(\S+)(\s+)(.+?)$', bygroups(
|
|
Keyword.Declaration, Whitespace, String, Whitespace, Literal)),
|
|
(r'([a-zA-Z_0-9]+)(\s+)', bygroups(
|
|
Name.Variable, Whitespace), 'args'),
|
|
],
|
|
'action': [
|
|
(r'[a-z_0-9]+$', Name.Function, 'root'),
|
|
(r'[a-z_0-9]+', Name.Function, 'args'),
|
|
],
|
|
'args': [
|
|
(r'\s+', Whitespace, 'args'),
|
|
(r'\b(yes|no)\b$', Number.Bin, 'root'),
|
|
(r'\b(yes|no)\b', Number.Bin, 'args'),
|
|
(r'[+-]?[0-9]+\s*$', Number.Integer, 'root'),
|
|
(r'[+-]?[0-9.]+\s*$', Number.Float, 'root'),
|
|
(r'[+-]?[0-9]+', Number.Integer, 'args'),
|
|
(r'[+-]?[0-9.]+', Number.Float, 'args'),
|
|
(r'#[a-fA-F0-9]{3,6}\s*$', String, 'root'),
|
|
(r'#[a-fA-F0-9]{3,6}\s*', String, 'args'),
|
|
(r'.+', String, 'root'),
|
|
],
|
|
}
|
|
|
|
|
|
class SessionLexer(RegexLexer):
|
|
name = 'Session'
|
|
aliases = ['session']
|
|
filenames = ['*.session']
|
|
|
|
tokens = {
|
|
'root': [
|
|
(r'#.*?$', Comment.Single),
|
|
(r'[a-z][a-z0-9_]+', Name.Function, 'args'),
|
|
],
|
|
'args': [
|
|
(r'.*?$', Literal, 'root'),
|
|
]
|
|
}
|
|
|
|
|
|
def link_role(name: str, rawtext: str, text: str, lineno: int, inliner: Any, options: Any = {}, content: Any = []) -> Tuple[List, List]:
|
|
m = re.match(r'(.+)\s+<(.+?)>', text)
|
|
if m is None:
|
|
msg = inliner.reporter.error(f'link "{text}" not recognized', line=lineno)
|
|
prb = inliner.problematic(rawtext, rawtext, msg)
|
|
return [prb], [msg]
|
|
text, url = m.group(1, 2)
|
|
set_classes(options)
|
|
node = nodes.reference(rawtext, text, refuri=url, **options)
|
|
return [node], []
|
|
|
|
|
|
def expand_opt_references(conf_name: str, text: str) -> str:
|
|
conf_name += '.'
|
|
|
|
def expand(m: Match) -> str:
|
|
ref = m.group(1)
|
|
if '<' not in ref and '.' not in ref:
|
|
full_ref = conf_name + ref
|
|
return ':opt:`{} <{}>`'.format(ref, full_ref)
|
|
return str(m.group())
|
|
|
|
return re.sub(r':opt:`(.+?)`', expand, text)
|
|
|
|
|
|
opt_aliases: Dict[str, str] = {}
|
|
shortcut_slugs: Dict[str, Tuple[str, str]] = {}
|
|
|
|
|
|
def parse_opt_node(env: Any, sig: str, signode: Any) -> str:
|
|
"""Transform an option description into RST nodes."""
|
|
count = 0
|
|
firstname = ''
|
|
for potential_option in sig.split(', '):
|
|
optname = potential_option.strip()
|
|
if count:
|
|
signode += addnodes.desc_addname(', ', ', ')
|
|
text = optname.split('.', 1)[-1]
|
|
signode += addnodes.desc_name(text, text)
|
|
if not count:
|
|
firstname = optname
|
|
signode['allnames'] = [optname]
|
|
else:
|
|
signode['allnames'].append(optname)
|
|
opt_aliases[optname] = firstname
|
|
count += 1
|
|
if not firstname:
|
|
raise ValueError('{} is not a valid opt'.format(sig))
|
|
return firstname
|
|
|
|
|
|
def parse_shortcut_node(env: Any, sig: str, signode: Any) -> str:
|
|
"""Transform a shortcut description into RST nodes."""
|
|
conf_name, text = sig.split('.', 1)
|
|
signode += addnodes.desc_name(text, text)
|
|
return sig
|
|
|
|
|
|
def render_conf(conf_name: str, all_options: Iterable[Union['Option', Sequence['Shortcut']]]) -> str:
|
|
from kitty.conf.definition import merged_opts, Option, Group
|
|
ans = ['.. default-domain:: conf', '']
|
|
a = ans.append
|
|
current_group: Optional[Group] = None
|
|
all_options_ = list(all_options)
|
|
kitty_mod = 'kitty_mod'
|
|
|
|
def render_group(group: Group) -> None:
|
|
a('')
|
|
a(f'.. _conf-{conf_name}-{group.name}:')
|
|
a('')
|
|
a(group.short_text)
|
|
heading_level = '+' if '.' in group.name else '^'
|
|
a(heading_level * (len(group.short_text) + 20))
|
|
a('')
|
|
if group.start_text:
|
|
a(group.start_text)
|
|
a('')
|
|
|
|
def handle_group_end(group: Group) -> None:
|
|
if group.end_text:
|
|
assert current_group is not None
|
|
a(''), a(current_group.end_text)
|
|
|
|
def handle_group(new_group: Group, new_group_is_shortcut: bool = False) -> None:
|
|
nonlocal current_group
|
|
if new_group is not current_group:
|
|
if current_group:
|
|
handle_group_end(current_group)
|
|
current_group = new_group
|
|
render_group(current_group)
|
|
|
|
def handle_option(i: int, opt: Option) -> None:
|
|
nonlocal kitty_mod
|
|
if not opt.long_text or not opt.add_to_docs:
|
|
return
|
|
handle_group(opt.group)
|
|
if opt.name == 'kitty_mod':
|
|
kitty_mod = opt.defval_as_string
|
|
mopts = list(merged_opts(all_options_, opt, i))
|
|
a('.. opt:: ' + ', '.join(conf_name + '.' + mo.name for mo in mopts))
|
|
a('.. code-block:: conf')
|
|
a('')
|
|
sz = max(len(x.name) for x in mopts)
|
|
for mo in mopts:
|
|
a((' {:%ds} {}' % sz).format(mo.name, mo.defval_as_string))
|
|
a('')
|
|
if opt.long_text:
|
|
a(expand_opt_references(conf_name, opt.long_text))
|
|
a('')
|
|
|
|
def handle_shortcuts(shortcuts: Sequence[Shortcut]) -> None:
|
|
sc = shortcuts[0]
|
|
handle_group(sc.group, True)
|
|
sc_text = f'{conf_name}.{sc.short_text}'
|
|
a('.. shortcut:: ' + sc_text)
|
|
shortcuts = [s for s in shortcuts if s.add_to_default]
|
|
shortcut_slugs[f'{conf_name}.{sc.name}'] = (sc_text, sc.key.replace('kitty_mod', kitty_mod))
|
|
if shortcuts:
|
|
a('.. code-block:: conf')
|
|
a('')
|
|
for x in shortcuts:
|
|
if x.add_to_default:
|
|
a(' map {} {}'.format(x.key.replace('kitty_mod', kitty_mod), x.action_def))
|
|
a('')
|
|
if sc.long_text:
|
|
a(expand_opt_references(conf_name, sc.long_text))
|
|
a('')
|
|
|
|
for i, opt in enumerate(all_options_):
|
|
if isinstance(opt, Option):
|
|
handle_option(i, opt)
|
|
else:
|
|
handle_shortcuts(opt)
|
|
|
|
if current_group:
|
|
handle_group_end(current_group)
|
|
return '\n'.join(ans)
|
|
|
|
|
|
def process_opt_link(env: Any, refnode: Any, has_explicit_title: bool, title: str, target: str) -> Tuple[str, str]:
|
|
conf_name, opt = target.partition('.')[::2]
|
|
if not opt:
|
|
conf_name, opt = 'kitty', conf_name
|
|
full_name = conf_name + '.' + opt
|
|
return title, opt_aliases.get(full_name, full_name)
|
|
|
|
|
|
def process_shortcut_link(env: Any, refnode: Any, has_explicit_title: bool, title: str, target: str) -> Tuple[str, str]:
|
|
conf_name, slug = target.partition('.')[::2]
|
|
if not slug:
|
|
conf_name, slug = 'kitty', conf_name
|
|
full_name = conf_name + '.' + slug
|
|
try:
|
|
target, stitle = shortcut_slugs[full_name]
|
|
except KeyError:
|
|
logger.warning('Unknown shortcut: {}'.format(target), location=refnode)
|
|
else:
|
|
if not has_explicit_title:
|
|
title = stitle
|
|
return title, target
|
|
|
|
|
|
def write_conf_docs(app: Any, all_kitten_names: Iterable[str]) -> None:
|
|
app.add_lexer('conf', ConfLexer() if version_info[0] < 3 else ConfLexer)
|
|
app.add_object_type(
|
|
'opt', 'opt',
|
|
indextemplate="pair: %s; Config Setting",
|
|
parse_node=parse_opt_node,
|
|
)
|
|
# Warn about opt references that could not be resolved
|
|
opt_role = app.registry.domain_roles['std']['opt']
|
|
opt_role.warn_dangling = True
|
|
opt_role.process_link = process_opt_link
|
|
|
|
app.add_object_type(
|
|
'shortcut', 'sc',
|
|
indextemplate="pair: %s; Keyboard Shortcut",
|
|
parse_node=parse_shortcut_node,
|
|
)
|
|
sc_role = app.registry.domain_roles['std']['sc']
|
|
sc_role.warn_dangling = True
|
|
sc_role.process_link = process_shortcut_link
|
|
|
|
def generate_default_config(all_options: Dict[str, Union[Option, Sequence[Shortcut]]], name: str) -> None:
|
|
from kitty.conf.definition import as_conf_file
|
|
with open(f'generated/conf-{name}.rst', 'w', encoding='utf-8') as f:
|
|
print('.. highlight:: conf\n', file=f)
|
|
f.write(render_conf(name, all_options.values()))
|
|
|
|
conf_name = re.sub(r'^kitten-', '', name) + '.conf'
|
|
with open(f'generated/conf/{conf_name}', 'w', encoding='utf-8') as f:
|
|
text = '\n'.join(as_conf_file(all_options.values()))
|
|
print(text, file=f)
|
|
|
|
from kitty.config_data import all_options
|
|
generate_default_config(all_options, 'kitty')
|
|
|
|
from kittens.runner import get_kitten_conf_docs
|
|
for kitten in all_kitten_names:
|
|
all_options = get_kitten_conf_docs(kitten)
|
|
if all_options:
|
|
generate_default_config(all_options, f'kitten-{kitten}')
|
|
# }}}
|
|
|
|
|
|
def setup(app: Any) -> None:
|
|
os.makedirs('generated/conf', exist_ok=True)
|
|
from kittens.runner import all_kitten_names
|
|
kn = all_kitten_names()
|
|
write_cli_docs(kn)
|
|
write_remote_control_protocol_docs()
|
|
write_conf_docs(app, kn)
|
|
app.add_css_file('custom.css')
|
|
app.add_lexer('session', SessionLexer() if version_info[0] < 3 else SessionLexer)
|
|
app.add_role('link', link_role)
|
|
app.add_role('iss', partial(num_role, 'issues'))
|
|
app.add_role('pull', partial(num_role, 'pull'))
|
|
app.add_role('commit', commit_role)
|
|
app.connect('html-page-context', add_html_context)
|