Move cli spec parsing code into simple module

This commit is contained in:
Kovid Goyal 2025-04-27 09:34:51 +05:30
parent 62699f6799
commit e42d410ee4
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
13 changed files with 362 additions and 326 deletions

View file

@ -29,11 +29,9 @@ from kittens.tui.operations import Mode
from kittens.tui.spinners import spinners
from kitty.actions import get_all_actions
from kitty.cli import (
CompletionSpec,
GoOption,
go_options_for_seq,
parse_option_spec,
serialize_as_go_string,
)
from kitty.conf.generate import gen_go_code
from kitty.conf.types import Definition
@ -45,6 +43,7 @@ from kitty.options.types import Options
from kitty.rc.base import RemoteCommand, all_command_names, command_for_name
from kitty.remote_control import global_options_spec
from kitty.rgb import color_names
from kitty.simple_cli_definitions import CompletionSpec, serialize_as_go_string
if __name__ == '__main__' and not __package__:
import __main__

View file

@ -82,7 +82,7 @@ usage = '[files to copy to/from]'
if __name__ == '__main__':
raise SystemExit('This should be run as kitten clipboard')
elif __name__ == '__doc__':
from kitty.cli import CompletionSpec
from kitty.simple_cli_definitions import CompletionSpec
cd = sys.cli_docs # type: ignore
cd['usage'] = usage
cd['options'] = OPTIONS

View file

@ -4,9 +4,9 @@
import sys
from functools import partial
from kitty.cli import CONFIG_HELP, CompletionSpec
from kitty.conf.types import Definition
from kitty.constants import appname
from kitty.simple_cli_definitions import CONFIG_HELP, CompletionSpec
def main(args: list[str]) -> None:

View file

@ -179,7 +179,7 @@ if __name__ == '__main__':
elif __name__ == '__doc__':
import sys
from kitty.cli import CompletionSpec
from kitty.simple_cli_definitions import CompletionSpec
cd = sys.cli_docs # type: ignore
cd['usage'] = usage
cd['options'] = lambda: OPTIONS.format()

View file

@ -4,7 +4,7 @@
import sys
from kitty.cli import CompletionSpec
from kitty.simple_cli_definitions import CompletionSpec
OPTIONS = '''
--role

View file

@ -7,7 +7,7 @@ from contextlib import suppress
from functools import partial
from typing import Any, Mapping, Sequence
from kitty.cli import listen_on_defn, parse_args
from kitty.cli import parse_args
from kitty.cli_stub import PanelCLIOptions
from kitty.constants import appname, is_macos, is_wayland, kitten_exe
from kitty.fast_data_types import (
@ -29,6 +29,7 @@ from kitty.fast_data_types import (
toggle_os_window_visibility,
)
from kitty.os_window_size import WindowSizeData, edge_spacing
from kitty.simple_cli_definitions import listen_on_defn
from kitty.types import LayerShellConfig
from kitty.typing import BossType, EdgeLiteral
from kitty.utils import log_error

View file

@ -3,7 +3,7 @@
import sys
from kitty.cli import CompletionSpec
from kitty.simple_cli_definitions import CompletionSpec
help_text = (
'Change the kitty theme. If no theme name is supplied, run interactively, otherwise'

View file

@ -127,7 +127,7 @@ def main(args: list[str]) -> None:
if __name__ == '__main__':
main(sys.argv)
elif __name__ == '__doc__':
from kitty.cli import CompletionSpec
from kitty.simple_cli_definitions import CompletionSpec
cd = sys.cli_docs # type: ignore
cd['usage'] = usage
cd['options'] = option_text

View file

@ -5,8 +5,6 @@ import os
import re
import sys
from collections.abc import Callable, Iterator, Sequence
from dataclasses import dataclass
from enum import Enum, auto
from re import Match
from typing import Any, NoReturn, TypeVar, Union, cast
@ -15,104 +13,11 @@ from .conf.utils import resolve_config
from .constants import appname, clear_handled_signals, config_dir, default_pager_for_help, defconf, is_macos, str_version, website_url
from .fast_data_types import parse_cli_from_spec, wcswidth
from .options.types import Options as KittyOpts
from .simple_cli_definitions import CompletionSpec, CompletionType, OptionDict, kitty_options_spec, serialize_as_go_string
from .types import run_once
from .typing import BadLineType, TypedDict
from .utils import shlex_split
class CompletionType(Enum):
file = auto()
directory = auto()
keyword = auto()
special = auto()
none = auto()
class CompletionRelativeTo(Enum):
cwd = auto()
config_dir = auto()
@dataclass
class CompletionSpec:
type: CompletionType = CompletionType.none
kwds: tuple[str,...] = ()
extensions: tuple[str,...] = ()
mime_patterns: tuple[str,...] = ()
group: str = ''
relative_to: CompletionRelativeTo = CompletionRelativeTo.cwd
@staticmethod
def from_string(raw: str) -> 'CompletionSpec':
self = CompletionSpec()
for x in shlex_split(raw):
ck, vv = x.split(':', 1)
if ck == 'type':
self.type = getattr(CompletionType, vv)
elif ck == 'kwds':
self.kwds += tuple(vv.split(','))
elif ck == 'ext':
self.extensions += tuple(vv.split(','))
elif ck == 'group':
self.group = vv
elif ck == 'mime':
self.mime_patterns += tuple(vv.split(','))
elif ck == 'relative':
if vv == 'conf':
self.relative_to = CompletionRelativeTo.config_dir
else:
raise ValueError(f'Unknown completion relative to value: {vv}')
else:
raise KeyError(f'Unknown completion property: {ck}')
return self
def as_go_code(self, go_name: str, sep: str = ': ') -> Iterator[str]:
completers = []
if self.kwds:
kwds = (f'"{serialize_as_go_string(x)}"' for x in self.kwds)
g = (self.group if self.type is CompletionType.keyword else '') or "Keywords"
completers.append(f'cli.NamesCompleter("{serialize_as_go_string(g)}", ' + ', '.join(kwds) + ')')
relative_to = 'CONFIG' if self.relative_to is CompletionRelativeTo.config_dir else 'CWD'
if self.type is CompletionType.file:
g = serialize_as_go_string(self.group or 'Files')
added = False
if self.extensions:
added = True
pats = (f'"*.{ext}"' for ext in self.extensions)
completers.append(f'cli.FnmatchCompleter("{g}", cli.{relative_to}, ' + ', '.join(pats) + ')')
if self.mime_patterns:
added = True
completers.append(f'cli.MimepatCompleter("{g}", cli.{relative_to}, ' + ', '.join(f'"{p}"' for p in self.mime_patterns) + ')')
if not added:
completers.append(f'cli.FnmatchCompleter("{g}", cli.{relative_to}, "*")')
if self.type is CompletionType.directory:
g = serialize_as_go_string(self.group or 'Directories')
completers.append(f'cli.DirectoryCompleter("{g}", cli.{relative_to})')
if self.type is CompletionType.special:
completers.append(self.group)
if len(completers) > 1:
yield f'{go_name}{sep}cli.ChainCompleters(' + ', '.join(completers) + ')'
elif completers:
yield f'{go_name}{sep}{completers[0]}'
class OptionDict(TypedDict):
dest: str
name: str
aliases: tuple[str, ...]
help: str
choices: tuple[str, ...]
type: str
default: str | None
condition: bool
completion: CompletionSpec
def serialize_as_go_string(x: str) -> str:
return x.replace('\\', '\\\\').replace('\n', '\\n').replace('"', '\\"')
from .typing import BadLineType
is_macos
go_type_map = {
'bool-set': 'bool', 'bool-reset': 'bool', 'bool-unset': 'bool', 'int': 'int', 'float': 'float64',
'': 'string', 'list': '[]string', 'choices': 'string', 'str': 'string'}
@ -201,31 +106,6 @@ def go_options_for_seq(seq: 'OptionSpecSeq') -> Iterator[GoOption]:
yield GoOption(x)
CONFIG_HELP = '''\
Specify a path to the configuration file(s) to use. All configuration files are
merged onto the builtin :file:`{conf_name}.conf`, overriding the builtin values.
This option can be specified multiple times to read multiple configuration files
in sequence, which are merged. Use the special value :code:`NONE` to not load
any config file.
If this option is not specified, config files are searched for in the order:
:file:`$XDG_CONFIG_HOME/{appname}/{conf_name}.conf`,
:file:`~/.config/{appname}/{conf_name}.conf`,{macos_confpath}
:file:`$XDG_CONFIG_DIRS/{appname}/{conf_name}.conf`. The first one that exists
is used as the config file.
If the environment variable :envvar:`KITTY_CONFIG_DIRECTORY` is specified, that
directory is always used and the above searching does not happen.
If :file:`/etc/xdg/{appname}/{conf_name}.conf` exists, it is merged before (i.e.
with lower priority) than any user config files. It can be used to specify
system-wide defaults for all users. You can use either :code:`-` or
:file:`/dev/stdin` to read the config from STDIN.
'''.replace(
'{macos_confpath}',
(' :file:`~/Library/Preferences/{appname}/{conf_name}.conf`,' if is_macos else ''), 1
)
def surround(x: str, start: int, end: int) -> str:
if sys.stdout.isatty():
@ -399,7 +279,7 @@ OptionSpecSeq = list[Union[str, OptionDict]]
def parse_option_spec(spec: str | None = None) -> tuple[OptionSpecSeq, OptionSpecSeq]:
if spec is None:
spec = options_spec()
spec = kitty_options_spec()
NORMAL, METADATA, HELP = 'NORMAL', 'METADATA', 'HELP'
state = NORMAL
lines = spec.splitlines()
@ -867,202 +747,15 @@ def parse_cmdline(oc: Options, disabled: OptionSpecSeq, ans: Any, args: list[str
return leftover_args
listen_on_defn = f'''\
--listen-on
completion=type:special group:complete_kitty_listen_on
Listen on the specified socket address for control messages. For example,
:option:`{appname} --listen-on`=unix:/tmp/mykitty or :option:`{appname}
--listen-on`=tcp:localhost:12345. On Linux systems, you can also use abstract
UNIX sockets, not associated with a file, like this: :option:`{appname}
--listen-on`=unix:@mykitty. Environment variables are expanded and relative
paths are resolved with respect to the temporary directory. To control kitty,
you can send commands to it with :italic:`kitten @` using the
:option:`kitten @ --to` option to specify this address. Note that if you run
:italic:`kitten @` within a kitty window, there is no need to specify the
:option:`kitten @ --to` option as it will automatically read from the
environment. Note that this will be ignored unless :opt:`allow_remote_control`
is set to either: :code:`yes`, :code:`socket` or :code:`socket-only`. This can
also be specified in :file:`kitty.conf`.
'''
def options_spec() -> str:
if not hasattr(options_spec, 'ans'):
OPTIONS = '''
--class --app-id
dest=cls
default={appname}
condition=not is_macos
Set the class part of the :italic:`WM_CLASS` window property. On Wayland, it
sets the app id.
--name
condition=not is_macos
Set the name part of the :italic:`WM_CLASS` property. Defaults to using the
value from :option:`{appname} --class`.
--title -T
Set the OS window title. This will override any title set by the program running
inside kitty, permanently fixing the OS window's title. So only use this if you
are running a program that does not set titles.
--config -c
type=list
completion=type:file ext:conf group:"Config files" kwds:none,NONE
{config_help}
--override -o
type=list
completion=type:special group:complete_kitty_override
Override individual configuration options, can be specified multiple times.
Syntax: :italic:`name=value`. For example: :option:`{appname} -o` font_size=20
--directory --working-directory -d
default=.
completion=type:directory
Change to the specified directory when launching.
--detach
type=bool-set
Detach from the controlling terminal, if any. On macOS
use :code:`open -a kitty.app -n` instead.
--detached-log
Path to a log file to store STDOUT/STDERR when using :option:`--detach`
--session
completion=type:file ext:session relative:conf group:"Session files"
Path to a file containing the startup :italic:`session` (tabs, windows, layout,
programs). Use - to read from STDIN. See :ref:`sessions` for details and
an example. Environment variables in the file name are expanded,
relative paths are resolved relative to the kitty configuration directory.
The special value :code:`none` means no session will be used, even if
the :opt:`startup_session` option has been specified in kitty.conf.
Note that using this option means the command line arguments to kitty specifying
a program to run are ignored.
--hold
type=bool-set
Remain open, at a shell prompt, after child process exits. Note that this only
affects the first window. You can quit by either using the close window
shortcut or running the exit command.
--single-instance -1
type=bool-set
If specified only a single instance of :italic:`{appname}` will run. New
invocations will instead create a new top-level window in the existing
:italic:`{appname}` instance. This allows :italic:`{appname}` to share a single
sprite cache on the GPU and also reduces startup time. You can also have
separate groups of :italic:`{appname}` instances by using the :option:`{appname}
--instance-group` option.
--instance-group
Used in combination with the :option:`{appname} --single-instance` option. All
:italic:`{appname}` invocations with the same :option:`{appname}
--instance-group` will result in new windows being created in the first
:italic:`{appname}` instance within that group.
--wait-for-single-instance-window-close
type=bool-set
Normally, when using :option:`{appname} --single-instance`, :italic:`{appname}`
will open a new window in an existing instance and quit immediately. With this
option, it will not quit till the newly opened window is closed. Note that if no
previous instance is found, then :italic:`{appname}` will wait anyway,
regardless of this option.
{listen_on_defn} To start in headless mode,
without an actual window, use :option:`{appname} --start-as`=hidden.
--start-as
type=choices
default=normal
choices=normal,fullscreen,maximized,minimized,hidden
Control how the initial kitty window is created.
# Debugging options
--version -v
type=bool-set
The current {appname} version.
--dump-commands
type=bool-set
Output commands received from child process to STDOUT.
--replay-commands
Replay previously dumped commands. Specify the path to a dump file previously
created by :option:`{appname} --dump-commands`. You
can open a new kitty window to replay the commands with::
{appname} sh -c "{appname} --replay-commands /path/to/dump/file; read"
--dump-bytes
Path to file in which to store the raw bytes received from the child process.
--debug-rendering --debug-gl
type=bool-set
Debug rendering commands. This will cause all OpenGL calls to check for errors
instead of ignoring them. Also prints out miscellaneous debug information.
Useful when debugging rendering problems.
--debug-input --debug-keyboard
dest=debug_keyboard
type=bool-set
Print out key and mouse events as they are received.
--debug-font-fallback
type=bool-set
Print out information about the selection of fallback fonts for characters not
present in the main font.
--watcher
completion=type:file ext:py relative:conf group:"Watcher files"
This option is deprecated in favor of the :opt:`watcher` option in
:file:`{conf_name}.conf` and should not be used.
--execute -e
type=bool-set
!
'''
setattr(options_spec, 'ans', OPTIONS.format(
appname=appname, conf_name=appname, listen_on_defn=listen_on_defn,
config_help=CONFIG_HELP.format(appname=appname, conf_name=appname),
))
ans: str = getattr(options_spec, 'ans')
return ans
def options_for_completion() -> OptionSpecSeq:
raw = '--help -h\ntype=bool-set\nShow help for {appname} command line options\n\n{raw}'.format(
appname=appname, raw=options_spec())
appname=appname, raw=kitty_options_spec())
return parse_option_spec(raw)[0]
def option_spec_as_rst(
ospec: Callable[[], str] = options_spec,
ospec: Callable[[], str] = kitty_options_spec,
usage: str | None = None, message: str | None = None, appname: str | None = None,
heading_char: str = '-'
) -> str:
@ -1077,7 +770,7 @@ T = TypeVar('T')
def parse_args(
args: list[str] | None = None,
ospec: Callable[[], str] = options_spec,
ospec: Callable[[], str] = kitty_options_spec,
usage: str | None = None,
message: str | None = None,
appname: str | None = None,

View file

@ -10,6 +10,7 @@ from collections.abc import Callable, Iterator
from typing import Any, get_type_hints
from kitty.conf.types import Definition, MultiOption, Option, ParserFuncType, unset
from kitty.simple_cli_definitions import serialize_as_go_string
from kitty.types import _T
@ -579,7 +580,6 @@ def gen_go_code(defn: Definition) -> str:
a('func NewConfig() *Config {')
a('return &Config{')
from kitty.cli import serialize_as_go_string
from kitty.fast_data_types import Color
for name, pname in go_parsers.items():
if name in multiopts:

View file

@ -2,12 +2,12 @@ import termios
from typing import Any, Callable, Dict, Iterator, List, Literal, NewType, Optional, Tuple, TypedDict, Union, overload
from kitty.boss import Boss
from kitty.cli import OptionDict
from kitty.fonts import VariableData
from kitty.fonts.render import FontObject
from kitty.marks import MarkerFunc
from kitty.notifications import MacOSNotificationCategory
from kitty.options.types import Options
from kitty.simple_cli_definitions import OptionDict
from kitty.types import LayerShellConfig, SignalInfo
from kitty.typing import EdgeLiteral, NotRequired, ReadableBuffer, WriteableBuffer

View file

@ -7,9 +7,10 @@ from dataclasses import dataclass, field
from io import BytesIO
from typing import TYPE_CHECKING, Any, NoReturn, Optional, Union, cast
from kitty.cli import CompletionSpec, get_defaults_from_seq, parse_args, parse_option_spec
from kitty.cli import get_defaults_from_seq, parse_args, parse_option_spec
from kitty.cli_stub import RCOptions as R
from kitty.constants import list_kitty_resources, running_in_kitty
from kitty.simple_cli_definitions import CompletionSpec
from kitty.types import AsyncResponse
if TYPE_CHECKING:

View file

@ -0,0 +1,342 @@
#!/usr/bin/env python
# License: GPLv3 Copyright: 2025, Kovid Goyal <kovid at kovidgoyal.net>
# This module must be runnable by a vanilla python interperter
# as it is used to generate C code when building kitty
import os
import sys
from dataclasses import dataclass
from enum import Enum, auto
from typing import Iterator, TypedDict
try:
from kitty.constants import appname, is_macos
except ImportError:
is_macos = 'darwin' in sys.platform.lower()
try:
appname
except NameError:
appname = os.environ['KITTY_APPNAME']
try:
from kitty.utils import shlex_split as ksplit
def shlex_split(text: str) -> Iterator[str]:
yield from ksplit(text)
except ImportError:
from shlex import split as psplit
def shlex_split(text: str) -> Iterator[str]:
yield from psplit(text)
def serialize_as_go_string(x: str) -> str:
return x.replace('\\', '\\\\').replace('\n', '\\n').replace('"', '\\"')
class CompletionType(Enum):
file = auto()
directory = auto()
keyword = auto()
special = auto()
none = auto()
class CompletionRelativeTo(Enum):
cwd = auto()
config_dir = auto()
@dataclass
class CompletionSpec:
type: CompletionType = CompletionType.none
kwds: tuple[str,...] = ()
extensions: tuple[str,...] = ()
mime_patterns: tuple[str,...] = ()
group: str = ''
relative_to: CompletionRelativeTo = CompletionRelativeTo.cwd
@staticmethod
def from_string(raw: str) -> 'CompletionSpec':
self = CompletionSpec()
for x in shlex_split(raw):
ck, vv = x.split(':', 1)
if ck == 'type':
self.type = getattr(CompletionType, vv)
elif ck == 'kwds':
self.kwds += tuple(vv.split(','))
elif ck == 'ext':
self.extensions += tuple(vv.split(','))
elif ck == 'group':
self.group = vv
elif ck == 'mime':
self.mime_patterns += tuple(vv.split(','))
elif ck == 'relative':
if vv == 'conf':
self.relative_to = CompletionRelativeTo.config_dir
else:
raise ValueError(f'Unknown completion relative to value: {vv}')
else:
raise KeyError(f'Unknown completion property: {ck}')
return self
def as_go_code(self, go_name: str, sep: str = ': ') -> Iterator[str]:
completers = []
if self.kwds:
kwds = (f'"{serialize_as_go_string(x)}"' for x in self.kwds)
g = (self.group if self.type is CompletionType.keyword else '') or "Keywords"
completers.append(f'cli.NamesCompleter("{serialize_as_go_string(g)}", ' + ', '.join(kwds) + ')')
relative_to = 'CONFIG' if self.relative_to is CompletionRelativeTo.config_dir else 'CWD'
if self.type is CompletionType.file:
g = serialize_as_go_string(self.group or 'Files')
added = False
if self.extensions:
added = True
pats = (f'"*.{ext}"' for ext in self.extensions)
completers.append(f'cli.FnmatchCompleter("{g}", cli.{relative_to}, ' + ', '.join(pats) + ')')
if self.mime_patterns:
added = True
completers.append(f'cli.MimepatCompleter("{g}", cli.{relative_to}, ' + ', '.join(f'"{p}"' for p in self.mime_patterns) + ')')
if not added:
completers.append(f'cli.FnmatchCompleter("{g}", cli.{relative_to}, "*")')
if self.type is CompletionType.directory:
g = serialize_as_go_string(self.group or 'Directories')
completers.append(f'cli.DirectoryCompleter("{g}", cli.{relative_to})')
if self.type is CompletionType.special:
completers.append(self.group)
if len(completers) > 1:
yield f'{go_name}{sep}cli.ChainCompleters(' + ', '.join(completers) + ')'
elif completers:
yield f'{go_name}{sep}{completers[0]}'
class OptionDict(TypedDict):
dest: str
name: str
aliases: tuple[str, ...]
help: str
choices: tuple[str, ...]
type: str
default: str | None
condition: bool
completion: CompletionSpec
listen_on_defn = f'''\
--listen-on
completion=type:special group:complete_kitty_listen_on
Listen on the specified socket address for control messages. For example,
:option:`{appname} --listen-on`=unix:/tmp/mykitty or :option:`{appname}
--listen-on`=tcp:localhost:12345. On Linux systems, you can also use abstract
UNIX sockets, not associated with a file, like this: :option:`{appname}
--listen-on`=unix:@mykitty. Environment variables are expanded and relative
paths are resolved with respect to the temporary directory. To control kitty,
you can send commands to it with :italic:`kitten @` using the
:option:`kitten @ --to` option to specify this address. Note that if you run
:italic:`kitten @` within a kitty window, there is no need to specify the
:option:`kitten @ --to` option as it will automatically read from the
environment. Note that this will be ignored unless :opt:`allow_remote_control`
is set to either: :code:`yes`, :code:`socket` or :code:`socket-only`. This can
also be specified in :file:`kitty.conf`.
'''
CONFIG_HELP = '''\
Specify a path to the configuration file(s) to use. All configuration files are
merged onto the builtin :file:`{conf_name}.conf`, overriding the builtin values.
This option can be specified multiple times to read multiple configuration files
in sequence, which are merged. Use the special value :code:`NONE` to not load
any config file.
If this option is not specified, config files are searched for in the order:
:file:`$XDG_CONFIG_HOME/{appname}/{conf_name}.conf`,
:file:`~/.config/{appname}/{conf_name}.conf`,{macos_confpath}
:file:`$XDG_CONFIG_DIRS/{appname}/{conf_name}.conf`. The first one that exists
is used as the config file.
If the environment variable :envvar:`KITTY_CONFIG_DIRECTORY` is specified, that
directory is always used and the above searching does not happen.
If :file:`/etc/xdg/{appname}/{conf_name}.conf` exists, it is merged before (i.e.
with lower priority) than any user config files. It can be used to specify
system-wide defaults for all users. You can use either :code:`-` or
:file:`/dev/stdin` to read the config from STDIN.
'''.replace(
'{macos_confpath}',
(' :file:`~/Library/Preferences/{appname}/{conf_name}.conf`,' if is_macos else ''), 1
)
def kitty_options_spec() -> str:
if not hasattr(kitty_options_spec, 'ans'):
OPTIONS = '''
--class --app-id
dest=cls
default={appname}
condition=not is_macos
Set the class part of the :italic:`WM_CLASS` window property. On Wayland, it
sets the app id.
--name
condition=not is_macos
Set the name part of the :italic:`WM_CLASS` property. Defaults to using the
value from :option:`{appname} --class`.
--title -T
Set the OS window title. This will override any title set by the program running
inside kitty, permanently fixing the OS window's title. So only use this if you
are running a program that does not set titles.
--config -c
type=list
completion=type:file ext:conf group:"Config files" kwds:none,NONE
{config_help}
--override -o
type=list
completion=type:special group:complete_kitty_override
Override individual configuration options, can be specified multiple times.
Syntax: :italic:`name=value`. For example: :option:`{appname} -o` font_size=20
--directory --working-directory -d
default=.
completion=type:directory
Change to the specified directory when launching.
--detach
type=bool-set
Detach from the controlling terminal, if any. On macOS
use :code:`open -a kitty.app -n` instead.
--detached-log
Path to a log file to store STDOUT/STDERR when using :option:`--detach`
--session
completion=type:file ext:session relative:conf group:"Session files"
Path to a file containing the startup :italic:`session` (tabs, windows, layout,
programs). Use - to read from STDIN. See :ref:`sessions` for details and
an example. Environment variables in the file name are expanded,
relative paths are resolved relative to the kitty configuration directory.
The special value :code:`none` means no session will be used, even if
the :opt:`startup_session` option has been specified in kitty.conf.
Note that using this option means the command line arguments to kitty specifying
a program to run are ignored.
--hold
type=bool-set
Remain open, at a shell prompt, after child process exits. Note that this only
affects the first window. You can quit by either using the close window
shortcut or running the exit command.
--single-instance -1
type=bool-set
If specified only a single instance of :italic:`{appname}` will run. New
invocations will instead create a new top-level window in the existing
:italic:`{appname}` instance. This allows :italic:`{appname}` to share a single
sprite cache on the GPU and also reduces startup time. You can also have
separate groups of :italic:`{appname}` instances by using the :option:`{appname}
--instance-group` option.
--instance-group
Used in combination with the :option:`{appname} --single-instance` option. All
:italic:`{appname}` invocations with the same :option:`{appname}
--instance-group` will result in new windows being created in the first
:italic:`{appname}` instance within that group.
--wait-for-single-instance-window-close
type=bool-set
Normally, when using :option:`{appname} --single-instance`, :italic:`{appname}`
will open a new window in an existing instance and quit immediately. With this
option, it will not quit till the newly opened window is closed. Note that if no
previous instance is found, then :italic:`{appname}` will wait anyway,
regardless of this option.
{listen_on_defn} To start in headless mode,
without an actual window, use :option:`{appname} --start-as`=hidden.
--start-as
type=choices
default=normal
choices=normal,fullscreen,maximized,minimized,hidden
Control how the initial kitty window is created.
# Debugging options
--version -v
type=bool-set
The current {appname} version.
--dump-commands
type=bool-set
Output commands received from child process to STDOUT.
--replay-commands
Replay previously dumped commands. Specify the path to a dump file previously
created by :option:`{appname} --dump-commands`. You
can open a new kitty window to replay the commands with::
{appname} sh -c "{appname} --replay-commands /path/to/dump/file; read"
--dump-bytes
Path to file in which to store the raw bytes received from the child process.
--debug-rendering --debug-gl
type=bool-set
Debug rendering commands. This will cause all OpenGL calls to check for errors
instead of ignoring them. Also prints out miscellaneous debug information.
Useful when debugging rendering problems.
--debug-input --debug-keyboard
dest=debug_keyboard
type=bool-set
Print out key and mouse events as they are received.
--debug-font-fallback
type=bool-set
Print out information about the selection of fallback fonts for characters not
present in the main font.
--watcher
completion=type:file ext:py relative:conf group:"Watcher files"
This option is deprecated in favor of the :opt:`watcher` option in
:file:`{conf_name}.conf` and should not be used.
--execute -e
type=bool-set
!
'''
setattr(kitty_options_spec, 'ans', OPTIONS.format(
appname=appname, conf_name=appname, listen_on_defn=listen_on_defn,
config_help=CONFIG_HELP.format(appname=appname, conf_name=appname),
))
ans: str = getattr(kitty_options_spec, 'ans')
return ans
if __name__ == '__main__':
print(111111111, appname)