Start work on documenting the conf file
This commit is contained in:
parent
3ce9e1932c
commit
9dc9fb2012
61
docs/conf.py
61
docs/conf.py
@ -6,6 +6,7 @@
|
|||||||
# full list see the documentation:
|
# full list see the documentation:
|
||||||
# http://www.sphinx-doc.org/en/master/config
|
# http://www.sphinx-doc.org/en/master/config
|
||||||
|
|
||||||
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@ -80,7 +81,7 @@ language = None
|
|||||||
# List of patterns, relative to source directory, that match files and
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# directories to ignore when looking for source files.
|
||||||
# This pattern also affects html_static_path and html_extra_path .
|
# This pattern also affects html_static_path and html_extra_path .
|
||||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'generated/cli-*']
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'generated/cli-*', 'generated/conf-*']
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
pygments_style = 'sphinx'
|
pygments_style = 'sphinx'
|
||||||
@ -298,8 +299,66 @@ def write_cli_docs():
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
|
# config file docs {{{
|
||||||
|
|
||||||
|
def render_group(a, group):
|
||||||
|
a(group.short_text)
|
||||||
|
a('^' * (len(group.short_text) + 20))
|
||||||
|
a('')
|
||||||
|
if group.start_text:
|
||||||
|
a(group.start_text)
|
||||||
|
a('')
|
||||||
|
|
||||||
|
|
||||||
|
def render_conf(ref_prefix, all_options):
|
||||||
|
from kitty.conf.definition import merged_opts
|
||||||
|
ans = []
|
||||||
|
a = ans.append
|
||||||
|
current_group = None
|
||||||
|
all_options = list(all_options)
|
||||||
|
for i, opt in enumerate(all_options):
|
||||||
|
if not opt.short_text:
|
||||||
|
continue
|
||||||
|
if opt.group is not current_group:
|
||||||
|
if current_group and current_group.end_text:
|
||||||
|
a(''), a(current_group.end_text)
|
||||||
|
current_group = opt.group
|
||||||
|
render_group(a, current_group)
|
||||||
|
mopts = list(merged_opts(all_options, opt, i))
|
||||||
|
for mo in mopts:
|
||||||
|
a('.. _conf_{}_{}:'.format(ref_prefix, mo.name))
|
||||||
|
a('')
|
||||||
|
a(opt.short_text)
|
||||||
|
a('_' * (len(opt.short_text) + 20))
|
||||||
|
a('')
|
||||||
|
a('.. code-block:: ini')
|
||||||
|
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(opt.long_text)
|
||||||
|
a('')
|
||||||
|
|
||||||
|
return '\n'.join(ans)
|
||||||
|
|
||||||
|
|
||||||
|
def write_conf_docs():
|
||||||
|
from kitty.config_data import all_options
|
||||||
|
with open('generated/conf-kitty.rst', 'w', encoding='utf-8') as f:
|
||||||
|
print('.. highlight:: ini\n', file=f)
|
||||||
|
f.write(render_conf('kitty', all_options.values()))
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
try:
|
||||||
|
os.mkdir('generated')
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
write_cli_docs()
|
write_cli_docs()
|
||||||
|
write_conf_docs()
|
||||||
app.add_role('iss', partial(num_role, 'issues'))
|
app.add_role('iss', partial(num_role, 'issues'))
|
||||||
app.add_role('pull', partial(num_role, 'pull'))
|
app.add_role('pull', partial(num_role, 'pull'))
|
||||||
app.add_role('commit', commit_role)
|
app.add_role('commit', commit_role)
|
||||||
|
|||||||
@ -1,25 +1,32 @@
|
|||||||
|
:tocdepth: 2
|
||||||
|
|
||||||
Configuring kitty
|
Configuring kitty
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
|
.. highlight:: ini
|
||||||
|
|
||||||
|kitty| is highly customizable, everything from keyboard shortcuts, to painting
|
|kitty| is highly customizable, everything from keyboard shortcuts, to painting
|
||||||
frames-per-second. See the heavily commented default config file below for an
|
frames-per-second. See below for an overview of all customization
|
||||||
overview of all customization possibilities.
|
possibilities.
|
||||||
|
|
||||||
You can open the config file within kitty by pressing |sc_edit_config_file|.
|
You can open the config file within kitty by pressing |sc_edit_config_file|.
|
||||||
You can also display the current configuration by running ``kitty
|
You can also display the current configuration by running ``kitty
|
||||||
--debug-config``.
|
--debug-config``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. literalinclude:: ../kitty/kitty.conf
|
|
||||||
:language: ini
|
|
||||||
|
|
||||||
|
|
||||||
.. _confloc:
|
.. _confloc:
|
||||||
|
|
||||||
|kitty| looks for a config file in the OS config directories (usually
|
|kitty| looks for a config file in the OS config directories (usually
|
||||||
:file:`~/.config/kitty/kitty.conf` and additionally
|
:file:`~/.config/kitty/kitty.conf`) but you can pass a specific path via the
|
||||||
:file:`~/Library/Preferences/kitty/kitty.conf` on macOS) but you can pass a
|
:option:`kitty --config` option or use the ``KITTY_CONFIG_DIRECTORY``
|
||||||
specific path via the :option:`kitty --config` option or use the ``KITTY_CONFIG_DIRECTORY``
|
environment variable. See the :option:`kitty --config` option for full details.
|
||||||
environment variable. See the :option:`kitty --config` option
|
|
||||||
for full details.
|
You can include secondary config files via the :code:`include` directive. If
|
||||||
|
you use a relative path for include, it is resolved with respect to the
|
||||||
|
location of the current config file. Note that environment variables are
|
||||||
|
expanded, so :code:`${USER}.conf` becomes :file:`name.conf` if
|
||||||
|
:code:`USER=name`. For example::
|
||||||
|
|
||||||
|
include other.conf
|
||||||
|
|
||||||
|
|
||||||
|
.. include:: /generated/conf-kitty.rst
|
||||||
|
|||||||
@ -12,10 +12,8 @@ from weakref import WeakValueDictionary
|
|||||||
|
|
||||||
from .cli import create_opts, parse_args
|
from .cli import create_opts, parse_args
|
||||||
from .conf.utils import to_cmdline
|
from .conf.utils import to_cmdline
|
||||||
from .config import (
|
from .config import initial_window_size_func, prepare_config_file_for_editing
|
||||||
MINIMUM_FONT_SIZE, initial_window_size_func,
|
from .config_data import MINIMUM_FONT_SIZE
|
||||||
prepare_config_file_for_editing
|
|
||||||
)
|
|
||||||
from .constants import (
|
from .constants import (
|
||||||
appname, config_dir, set_boss, supports_primary_selection
|
appname, config_dir, set_boss, supports_primary_selection
|
||||||
)
|
)
|
||||||
|
|||||||
137
kitty/conf/definition.py
Normal file
137
kitty/conf/definition.py
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import re
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
from .utils import to_bool
|
||||||
|
|
||||||
|
|
||||||
|
def to_string(x):
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
class Group:
|
||||||
|
|
||||||
|
__slots__ = 'name', 'short_text', 'start_text', 'end_text'
|
||||||
|
|
||||||
|
def __init__(self, name, short_text, start_text='', end_text=''):
|
||||||
|
self.name, self.short_text = name, short_text.strip()
|
||||||
|
self.start_text, self.end_text = start_text.strip(), end_text.strip()
|
||||||
|
|
||||||
|
|
||||||
|
class Option:
|
||||||
|
|
||||||
|
__slots__ = 'name', 'group', 'short_text', 'long_text', 'option_type', 'defval_as_string', 'defval', 'add_to_default'
|
||||||
|
|
||||||
|
def __init__(self, name, group, defval, option_type, short_text, long_text, add_to_default):
|
||||||
|
self.name, self.group, self.short_text = name, group, short_text
|
||||||
|
self.long_text, self.option_type = long_text.strip(), option_type
|
||||||
|
self.defval_as_string, self.defval = defval, option_type(defval)
|
||||||
|
self.add_to_default = add_to_default
|
||||||
|
|
||||||
|
|
||||||
|
def option(
|
||||||
|
all_options,
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
defval,
|
||||||
|
short_text='',
|
||||||
|
long_text='',
|
||||||
|
option_type=to_string,
|
||||||
|
add_to_default=True
|
||||||
|
):
|
||||||
|
is_multiple = name.startswith('+')
|
||||||
|
if is_multiple:
|
||||||
|
name = name[1:]
|
||||||
|
defval_type = type(defval)
|
||||||
|
if defval_type is not str:
|
||||||
|
if option_type is to_string:
|
||||||
|
if defval_type is bool:
|
||||||
|
option_type = to_bool
|
||||||
|
else:
|
||||||
|
option_type = defval_type
|
||||||
|
if defval_type is bool:
|
||||||
|
defval = 'yes' if defval else 'no'
|
||||||
|
else:
|
||||||
|
defval = str(defval)
|
||||||
|
|
||||||
|
key = name
|
||||||
|
if is_multiple:
|
||||||
|
key = name + ' ' + defval.partition(' ')[0]
|
||||||
|
ans = Option(name, group[0], defval, option_type, short_text, long_text, add_to_default)
|
||||||
|
all_options[key] = ans
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def option_func(all_options, all_groups):
|
||||||
|
all_groups = {k: Group(k, *v) for k, v in all_groups.items()}
|
||||||
|
group = [None]
|
||||||
|
|
||||||
|
def change_group(name):
|
||||||
|
group[0] = all_groups[name]
|
||||||
|
|
||||||
|
return partial(option, all_options, group), change_group, all_groups
|
||||||
|
|
||||||
|
|
||||||
|
def merged_opts(all_options, opt, i):
|
||||||
|
yield opt
|
||||||
|
for k in range(i + 1, len(all_options)):
|
||||||
|
q = all_options[k]
|
||||||
|
if not q.short_text:
|
||||||
|
yield q
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def remove_markup(text):
|
||||||
|
return re.sub(r':(.+?):`(.+?)`', r'\2', text, flags=re.DOTALL)
|
||||||
|
|
||||||
|
|
||||||
|
def render_block(text):
|
||||||
|
text = remove_markup(text)
|
||||||
|
lines = text.splitlines()
|
||||||
|
return '\n'.join('#: ' + line for line in lines)
|
||||||
|
|
||||||
|
|
||||||
|
def render_group(a, group):
|
||||||
|
a('# ' + group.short_text + ' {{{')
|
||||||
|
a('')
|
||||||
|
if group.start_text:
|
||||||
|
a(render_block(group.start_text))
|
||||||
|
a('')
|
||||||
|
|
||||||
|
|
||||||
|
def as_conf_file(all_options):
|
||||||
|
ans = []
|
||||||
|
a = ans.append
|
||||||
|
current_group = None
|
||||||
|
all_options = list(all_options)
|
||||||
|
for i, opt in enumerate(all_options):
|
||||||
|
if not opt.short_text:
|
||||||
|
continue
|
||||||
|
if opt.group is not current_group:
|
||||||
|
if current_group:
|
||||||
|
if current_group.end_text:
|
||||||
|
a(''), a(current_group.end_text)
|
||||||
|
a('# }}}')
|
||||||
|
|
||||||
|
current_group = opt.group
|
||||||
|
render_group(a, current_group)
|
||||||
|
mopts = list(merged_opts(all_options, opt, i))
|
||||||
|
a(render_block(opt.short_text))
|
||||||
|
a('')
|
||||||
|
if opt.long_text:
|
||||||
|
a(render_block(opt.long_text))
|
||||||
|
a('')
|
||||||
|
sz = max(len(x.name) for x in mopts)
|
||||||
|
for mo in mopts:
|
||||||
|
prefix = '' if mo.add_to_default else '# '
|
||||||
|
a(('{}{:%ds} {}' % sz).format(prefix, mo.name, mo.defval_as_string))
|
||||||
|
a('')
|
||||||
|
if current_group:
|
||||||
|
if current_group.end_text:
|
||||||
|
a(''), a(current_group.end_text)
|
||||||
|
a('# }}}')
|
||||||
|
return ans
|
||||||
@ -10,24 +10,19 @@ from collections import namedtuple
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from . import fast_data_types as defines
|
from . import fast_data_types as defines
|
||||||
|
from .conf.definition import as_conf_file
|
||||||
from .conf.utils import (
|
from .conf.utils import (
|
||||||
init_config, key_func, load_config as _load_config, merge_dicts,
|
init_config, key_func, load_config as _load_config, merge_dicts,
|
||||||
parse_config_base, positive_float, positive_int, python_string, to_bool,
|
parse_config_base, positive_float, positive_int, python_string, to_bool,
|
||||||
to_cmdline, to_color, unit_float
|
to_cmdline, to_color, unit_float
|
||||||
)
|
)
|
||||||
|
from .config_data import all_options
|
||||||
from .constants import cache_dir, defconf
|
from .constants import cache_dir, defconf
|
||||||
from .fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE
|
from .fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE
|
||||||
from .layout import all_layouts
|
from .layout import all_layouts
|
||||||
from .rgb import color_as_int, color_from_int
|
from .rgb import color_as_int, color_from_int
|
||||||
from .utils import log_error
|
from .utils import log_error
|
||||||
|
|
||||||
MINIMUM_FONT_SIZE = 4
|
|
||||||
|
|
||||||
|
|
||||||
def to_font_size(x):
|
|
||||||
return max(MINIMUM_FONT_SIZE, float(x))
|
|
||||||
|
|
||||||
|
|
||||||
cshapes = {
|
cshapes = {
|
||||||
'block': CURSOR_BLOCK,
|
'block': CURSOR_BLOCK,
|
||||||
'beam': CURSOR_BEAM,
|
'beam': CURSOR_BEAM,
|
||||||
@ -378,7 +373,6 @@ type_map = {
|
|||||||
'scrollback_lines': positive_int,
|
'scrollback_lines': positive_int,
|
||||||
'scrollback_pager': to_cmdline,
|
'scrollback_pager': to_cmdline,
|
||||||
'open_url_with': to_cmdline,
|
'open_url_with': to_cmdline,
|
||||||
'font_size': to_font_size,
|
|
||||||
'focus_follows_mouse': to_bool,
|
'focus_follows_mouse': to_bool,
|
||||||
'cursor_shape': to_cursor_shape,
|
'cursor_shape': to_cursor_shape,
|
||||||
'open_url_modifiers': to_modifiers,
|
'open_url_modifiers': to_modifiers,
|
||||||
@ -587,15 +581,12 @@ def initial_window_size_func(opts, cached_values):
|
|||||||
|
|
||||||
|
|
||||||
def commented_out_default_config():
|
def commented_out_default_config():
|
||||||
with open(default_config_path, encoding='utf-8', errors='replace') as f:
|
ans = []
|
||||||
config = f.read()
|
for line in as_conf_file(all_options.values()):
|
||||||
lines = []
|
if line and line[0] != '#':
|
||||||
for line in config.splitlines():
|
|
||||||
if line.strip() and not line.startswith('#'):
|
|
||||||
line = '# ' + line
|
line = '# ' + line
|
||||||
lines.append(line)
|
ans.append(line)
|
||||||
config = '\n'.join(lines)
|
return '\n'.join(ans)
|
||||||
return config
|
|
||||||
|
|
||||||
|
|
||||||
def prepare_config_file_for_editing():
|
def prepare_config_file_for_editing():
|
||||||
@ -605,7 +596,7 @@ def prepare_config_file_for_editing():
|
|||||||
os.makedirs(d)
|
os.makedirs(d)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
pass
|
pass
|
||||||
with open(defconf, 'w') as f:
|
with open(defconf, 'w', encoding='utf-8') as f:
|
||||||
f.write(commented_out_default_config())
|
f.write(commented_out_default_config())
|
||||||
return defconf
|
return defconf
|
||||||
|
|
||||||
|
|||||||
69
kitty/config_data.py
Normal file
69
kitty/config_data.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
|
||||||
|
from gettext import gettext as _
|
||||||
|
|
||||||
|
from .conf.definition import option_func
|
||||||
|
|
||||||
|
MINIMUM_FONT_SIZE = 4
|
||||||
|
|
||||||
|
|
||||||
|
def to_font_size(x):
|
||||||
|
return max(MINIMUM_FONT_SIZE, float(x))
|
||||||
|
|
||||||
|
|
||||||
|
all_options = {}
|
||||||
|
|
||||||
|
o, g, all_groups = option_func(all_options, {
|
||||||
|
'fonts': [
|
||||||
|
_('Fonts'),
|
||||||
|
_('kitty has very powerful font management. You can configure individual\n'
|
||||||
|
'font faces and even specify special fonts for particular characters.')
|
||||||
|
],
|
||||||
|
})
|
||||||
|
type_map = {o.name: o.option_type for o in all_options.values()}
|
||||||
|
|
||||||
|
|
||||||
|
g('fonts') # {{{
|
||||||
|
|
||||||
|
o(
|
||||||
|
'font_family',
|
||||||
|
'monospace',
|
||||||
|
_('Font family'),
|
||||||
|
long_text=_('''
|
||||||
|
You can specify different fonts for the bold/italic/bold-italic variants.
|
||||||
|
By default they are derived automatically, by the OSes font system. Setting
|
||||||
|
them manually is useful for font families that have many weight variants like
|
||||||
|
Book, Medium, Thick, etc. For example::
|
||||||
|
|
||||||
|
font_family Operator Mono Book
|
||||||
|
bold_font Operator Mono Medium
|
||||||
|
italic_font Operator Mono Book Italic
|
||||||
|
bold_italic_font Operator Mono Medium Italic
|
||||||
|
''')
|
||||||
|
)
|
||||||
|
o('bold_font', 'auto')
|
||||||
|
o('italic_font', 'auto')
|
||||||
|
o('bold_italic_font', 'auto')
|
||||||
|
|
||||||
|
o('font_size', 11.0, _('Font size (in pts)'), option_type=to_font_size)
|
||||||
|
|
||||||
|
o(
|
||||||
|
'+symbol_map',
|
||||||
|
'U+E0A0-U+E0A2,U+E0B0-U+E0B3 PowerlineSymbols',
|
||||||
|
_('Font character mapping'),
|
||||||
|
add_to_default=False,
|
||||||
|
long_text=_('''
|
||||||
|
Map the specified unicode codepoints to a particular font. Useful if you need
|
||||||
|
special rendering for some symbols, such as for Powerline. Avoids the need for
|
||||||
|
patched fonts. Each unicode code point is specified in the form :code:`U+<code point
|
||||||
|
in hexadecimal>`. You can specify multiple code points, separated by commas and
|
||||||
|
ranges separated by hyphens. :code:`symbol_map` itself can be specified multiple times.
|
||||||
|
Syntax is::
|
||||||
|
|
||||||
|
symbol_map codepoints Font Family Name
|
||||||
|
|
||||||
|
'''))
|
||||||
|
# }}}
|
||||||
Loading…
x
Reference in New Issue
Block a user