mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-11 11:09:16 +02:00
Move the action parsing code into options_types
This commit is contained in:
@@ -19,11 +19,7 @@ from .child import cached_process_data, cwd_of_process, default_env
|
||||
from .cli import create_opts, parse_args
|
||||
from .cli_stub import CLIOptions
|
||||
from .conf.utils import BadLine, to_cmdline
|
||||
from .config import (
|
||||
KeyAction, SubSequenceMap, common_opts_as_dict,
|
||||
prepare_config_file_for_editing
|
||||
)
|
||||
from .options_types import MINIMUM_FONT_SIZE
|
||||
from .config import common_opts_as_dict, prepare_config_file_for_editing
|
||||
from .constants import (
|
||||
appname, config_dir, is_macos, kitty_exe, supports_primary_selection
|
||||
)
|
||||
@@ -42,6 +38,7 @@ from .keys import get_shortcut, shortcut_matches
|
||||
from .layout.base import set_layout_options
|
||||
from .notify import notification_activated
|
||||
from .options_stub import Options
|
||||
from .options_types import MINIMUM_FONT_SIZE, KeyAction, SubSequenceMap
|
||||
from .os_window_size import initial_window_size_func
|
||||
from .rgb import Color, color_from_int
|
||||
from .session import Session, create_sessions, get_os_window_sizing_data
|
||||
|
||||
@@ -13,7 +13,7 @@ from typing import (
|
||||
|
||||
from .cli_stub import CLIOptions
|
||||
from .conf.utils import resolve_config
|
||||
from .config import KeyAction, MouseMap
|
||||
from .options_types import KeyAction, MouseMap
|
||||
from .constants import appname, defconf, is_macos, is_wayland, str_version
|
||||
from .options_stub import Options as OptionsStub
|
||||
from .types import MouseEvent, SingleKey
|
||||
|
||||
198
kitty/config.py
198
kitty/config.py
@@ -9,40 +9,26 @@ from contextlib import contextmanager, suppress
|
||||
from functools import partial
|
||||
from typing import (
|
||||
Any, Callable, Dict, FrozenSet, Generator, Iterable, List, NamedTuple,
|
||||
Optional, Sequence, Set, Tuple, Type, Union
|
||||
Optional, Sequence, Tuple, Type, Union
|
||||
)
|
||||
|
||||
from . import fast_data_types as defines
|
||||
from .conf.definition import as_conf_file, config_lines
|
||||
from .conf.utils import (
|
||||
BadLine, init_config, key_func, load_config as _load_config, merge_dicts,
|
||||
BadLine, init_config, load_config as _load_config, merge_dicts,
|
||||
parse_config_base, python_string, to_bool, to_cmdline
|
||||
)
|
||||
from .config_data import all_options
|
||||
from .constants import cache_dir, defconf, is_macos
|
||||
from .options_stub import Options as OptionsStub
|
||||
from .options_types import (
|
||||
InvalidMods, env, font_features, parse_mods, parse_shortcut, symbol_map
|
||||
FuncArgsType, KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap,
|
||||
env, font_features, func_with_args, parse_key, parse_key_action,
|
||||
parse_mouse_action, symbol_map
|
||||
)
|
||||
from .types import MouseEvent, SingleKey
|
||||
from .typing import TypedDict
|
||||
from .utils import log_error
|
||||
|
||||
KeyMap = Dict[SingleKey, 'KeyAction']
|
||||
MouseMap = Dict[MouseEvent, 'KeyAction']
|
||||
KeySequence = Tuple[SingleKey, ...]
|
||||
SubSequenceMap = Dict[KeySequence, 'KeyAction']
|
||||
SequenceMap = Dict[SingleKey, SubSequenceMap]
|
||||
|
||||
|
||||
class KeyAction(NamedTuple):
|
||||
func: str
|
||||
args: Sequence[str] = ()
|
||||
|
||||
|
||||
func_with_args, args_funcs = key_func()
|
||||
FuncArgsType = Tuple[str, Sequence[Any]]
|
||||
|
||||
|
||||
@func_with_args(
|
||||
'pass_selection_to_program', 'new_window', 'new_tab', 'new_os_window',
|
||||
@@ -341,176 +327,6 @@ def mouse_selection(func: str, rest: str) -> FuncArgsType:
|
||||
return func, [cmap[rest]]
|
||||
|
||||
|
||||
def parse_key_action(action: str) -> Optional[KeyAction]:
|
||||
parts = action.strip().split(maxsplit=1)
|
||||
func = parts[0]
|
||||
if len(parts) == 1:
|
||||
return KeyAction(func, ())
|
||||
rest = parts[1]
|
||||
parser = args_funcs.get(func)
|
||||
if parser is not None:
|
||||
try:
|
||||
func, args = parser(func, rest)
|
||||
except Exception as err:
|
||||
log_error('Ignoring invalid key action: {} with err: {}'.format(action, err))
|
||||
else:
|
||||
return KeyAction(func, args)
|
||||
return None
|
||||
|
||||
|
||||
all_key_actions: Set[str] = set()
|
||||
sequence_sep = '>'
|
||||
|
||||
|
||||
class BaseDefinition:
|
||||
action: KeyAction
|
||||
|
||||
def resolve_kitten_aliases(self, aliases: Dict[str, Sequence[str]]) -> None:
|
||||
if not self.action.args:
|
||||
return
|
||||
kitten = self.action.args[0]
|
||||
rest = self.action.args[1] if len(self.action.args) > 1 else ''
|
||||
changed = False
|
||||
for key, expanded in aliases.items():
|
||||
if key == kitten:
|
||||
changed = True
|
||||
kitten = expanded[0]
|
||||
if len(expanded) > 1:
|
||||
rest = expanded[1] + ' ' + rest
|
||||
if changed:
|
||||
self.action = self.action._replace(args=[kitten, rest.rstrip()])
|
||||
|
||||
|
||||
class MouseMapping(BaseDefinition):
|
||||
|
||||
def __init__(self, button: int, mods: int, repeat_count: int, grabbed: bool, action: KeyAction):
|
||||
self.button = button
|
||||
self.mods = mods
|
||||
self.repeat_count = repeat_count
|
||||
self.grabbed = grabbed
|
||||
self.action = action
|
||||
|
||||
def resolve(self, kitty_mod: int) -> None:
|
||||
self.mods = defines.resolve_key_mods(kitty_mod, self.mods)
|
||||
|
||||
@property
|
||||
def trigger(self) -> MouseEvent:
|
||||
return MouseEvent(self.button, self.mods, self.repeat_count, self.grabbed)
|
||||
|
||||
|
||||
class KeyDefinition(BaseDefinition):
|
||||
|
||||
def __init__(self, is_sequence: bool, action: KeyAction, mods: int, is_native: bool, key: int, rest: Tuple[SingleKey, ...] = ()):
|
||||
self.is_sequence = is_sequence
|
||||
self.action = action
|
||||
self.trigger = SingleKey(mods, is_native, key)
|
||||
self.rest = rest
|
||||
|
||||
def resolve(self, kitty_mod: int) -> None:
|
||||
|
||||
def r(k: SingleKey) -> SingleKey:
|
||||
mods = defines.resolve_key_mods(kitty_mod, k.mods)
|
||||
key = k.key
|
||||
is_native = k.is_native
|
||||
return SingleKey(mods, is_native, key)
|
||||
|
||||
self.trigger = r(self.trigger)
|
||||
self.rest = tuple(map(r, self.rest))
|
||||
|
||||
|
||||
def parse_key(val: str, key_definitions: List[KeyDefinition]) -> None:
|
||||
parts = val.split(maxsplit=1)
|
||||
if len(parts) != 2:
|
||||
return
|
||||
sc, action = parts
|
||||
sc, action = sc.strip().strip(sequence_sep), action.strip()
|
||||
if not sc or not action:
|
||||
return
|
||||
is_sequence = sequence_sep in sc
|
||||
if is_sequence:
|
||||
trigger: Optional[SingleKey] = None
|
||||
restl: List[SingleKey] = []
|
||||
for part in sc.split(sequence_sep):
|
||||
try:
|
||||
mods, is_native, key = parse_shortcut(part)
|
||||
except InvalidMods:
|
||||
return
|
||||
if key == 0:
|
||||
if mods is not None:
|
||||
log_error('Shortcut: {} has unknown key, ignoring'.format(sc))
|
||||
return
|
||||
if trigger is None:
|
||||
trigger = SingleKey(mods, is_native, key)
|
||||
else:
|
||||
restl.append(SingleKey(mods, is_native, key))
|
||||
rest = tuple(restl)
|
||||
else:
|
||||
try:
|
||||
mods, is_native, key = parse_shortcut(sc)
|
||||
except InvalidMods:
|
||||
return
|
||||
if key == 0:
|
||||
if mods is not None:
|
||||
log_error('Shortcut: {} has unknown key, ignoring'.format(sc))
|
||||
return
|
||||
try:
|
||||
paction = parse_key_action(action)
|
||||
except Exception:
|
||||
log_error('Invalid shortcut action: {}. Ignoring.'.format(
|
||||
action))
|
||||
else:
|
||||
if paction is not None:
|
||||
all_key_actions.add(paction.func)
|
||||
if is_sequence:
|
||||
if trigger is not None:
|
||||
key_definitions.append(KeyDefinition(True, paction, trigger[0], trigger[1], trigger[2], rest))
|
||||
else:
|
||||
assert key is not None
|
||||
key_definitions.append(KeyDefinition(False, paction, mods, is_native, key))
|
||||
|
||||
|
||||
def parse_mouse_action(val: str, mouse_mappings: List[MouseMapping]) -> None:
|
||||
parts = val.split(maxsplit=3)
|
||||
if len(parts) != 4:
|
||||
log_error(f'Ignoring invalid mouse action: {val}')
|
||||
return
|
||||
xbutton, event, modes, action = parts
|
||||
kparts = xbutton.split('+')
|
||||
if len(kparts) > 1:
|
||||
mparts, obutton = kparts[:-1], kparts[-1].lower()
|
||||
mods = parse_mods(mparts, obutton)
|
||||
if mods is None:
|
||||
return
|
||||
else:
|
||||
obutton = parts[0].lower()
|
||||
mods = 0
|
||||
try:
|
||||
b = {'left': 'b1', 'middle': 'b3', 'right': 'b2'}.get(obutton, obutton)[1:]
|
||||
button = getattr(defines, f'GLFW_MOUSE_BUTTON_{b}')
|
||||
except Exception:
|
||||
log_error(f'Mouse button: {xbutton} not recognized, ignoring')
|
||||
return
|
||||
try:
|
||||
count = {'doubleclick': -3, 'click': -2, 'release': -1, 'press': 1, 'doublepress': 2, 'triplepress': 3}[event.lower()]
|
||||
except KeyError:
|
||||
log_error(f'Mouse event type: {event} not recognized, ignoring')
|
||||
return
|
||||
specified_modes = frozenset(modes.lower().split(','))
|
||||
if specified_modes - {'grabbed', 'ungrabbed'}:
|
||||
log_error(f'Mouse modes: {modes} not recognized, ignoring')
|
||||
return
|
||||
try:
|
||||
paction = parse_key_action(action)
|
||||
except Exception:
|
||||
log_error(f'Invalid mouse action: {action}. Ignoring.')
|
||||
return
|
||||
if paction is None:
|
||||
log_error(f'Ignoring unknown mouse action: {action}')
|
||||
return
|
||||
for mode in specified_modes:
|
||||
mouse_mappings.append(MouseMapping(button, mods, count, mode == 'grabbed', paction))
|
||||
|
||||
|
||||
def parse_send_text_bytes(text: str) -> bytes:
|
||||
return python_string(text).encode('utf-8')
|
||||
|
||||
@@ -663,10 +479,6 @@ def parse_defaults(lines: Iterable[str], check_keys: bool = False) -> Dict[str,
|
||||
xc = init_config(config_lines(all_options), parse_defaults)
|
||||
Options: Type[OptionsStub] = xc[0]
|
||||
defaults: OptionsStub = xc[1]
|
||||
actions = frozenset(all_key_actions) | frozenset(
|
||||
'run_simple_kitten combine send_text goto_tab goto_layout set_font_size new_tab_with_cwd new_window_with_cwd new_os_window_with_cwd'.
|
||||
split()
|
||||
)
|
||||
no_op_actions = frozenset({'noop', 'no-op', 'no_op'})
|
||||
|
||||
|
||||
|
||||
@@ -4,15 +4,14 @@
|
||||
|
||||
from typing import Optional, Union
|
||||
|
||||
from .config import KeyAction, KeyMap, SequenceMap, SubSequenceMap
|
||||
from .fast_data_types import (
|
||||
GLFW_MOD_ALT, GLFW_MOD_CAPS_LOCK, GLFW_MOD_CONTROL, GLFW_MOD_HYPER,
|
||||
GLFW_MOD_META, GLFW_MOD_NUM_LOCK, GLFW_MOD_SHIFT, GLFW_MOD_SUPER, KeyEvent
|
||||
)
|
||||
from .options_types import KeyAction, KeyMap, SequenceMap, SubSequenceMap
|
||||
from .types import SingleKey
|
||||
from .typing import ScreenType
|
||||
|
||||
|
||||
mod_mask = GLFW_MOD_ALT | GLFW_MOD_CONTROL | GLFW_MOD_SHIFT | GLFW_MOD_SUPER | GLFW_MOD_META | GLFW_MOD_HYPER
|
||||
lock_mask = GLFW_MOD_NUM_LOCK | GLFW_MOD_CAPS_LOCK
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ from typing import (
|
||||
from urllib.parse import ParseResult, unquote, urlparse
|
||||
|
||||
from .conf.utils import to_cmdline_implementation
|
||||
from .config import KeyAction, parse_key_action
|
||||
from .constants import config_dir
|
||||
from .guess_mime_type import guess_type
|
||||
from .options_types import KeyAction, parse_key_action
|
||||
from .types import run_once
|
||||
from .typing import MatchType
|
||||
from .utils import expandvars, log_error
|
||||
|
||||
@@ -17,7 +17,7 @@ def generate_stub():
|
||||
all_options,
|
||||
preamble_lines=(
|
||||
'from kitty.types import SingleKey',
|
||||
'from kitty.config import KeyAction, KeyMap, SequenceMap, MouseMap',
|
||||
'from kitty.options_types import KeyAction, KeyMap, SequenceMap, MouseMap',
|
||||
'from kitty.fonts import FontFeature',
|
||||
),
|
||||
extra_fields=(
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
import os
|
||||
import sys
|
||||
from typing import (
|
||||
Callable, Dict, FrozenSet, Iterable, List, Optional, Tuple, Union
|
||||
Any, Callable, Dict, FrozenSet, Iterable, List, NamedTuple, Optional,
|
||||
Sequence, Tuple, Union
|
||||
)
|
||||
|
||||
import kitty.fast_data_types as defines
|
||||
from kitty.fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE
|
||||
|
||||
from .conf.utils import (
|
||||
positive_float, positive_int, to_bool, to_color, uniq, unit_float
|
||||
key_func, positive_float, positive_int, to_bool, to_color, uniq, unit_float
|
||||
)
|
||||
from .constants import config_dir
|
||||
from .fonts import FontFeature
|
||||
@@ -23,9 +24,14 @@ from .key_names import (
|
||||
)
|
||||
from .layout.interface import all_layouts
|
||||
from .rgb import Color, color_as_int
|
||||
from .types import FloatEdges, SingleKey
|
||||
from .types import FloatEdges, MouseEvent, SingleKey
|
||||
from .utils import expandvars, log_error
|
||||
|
||||
KeyMap = Dict[SingleKey, 'KeyAction']
|
||||
MouseMap = Dict[MouseEvent, 'KeyAction']
|
||||
KeySequence = Tuple[SingleKey, ...]
|
||||
SubSequenceMap = Dict[KeySequence, 'KeyAction']
|
||||
SequenceMap = Dict[SingleKey, SubSequenceMap]
|
||||
MINIMUM_FONT_SIZE = 4
|
||||
default_tab_separator = ' ┇'
|
||||
mod_map = {'CTRL': 'CONTROL', 'CMD': 'SUPER', '⌘': 'SUPER',
|
||||
@@ -33,6 +39,14 @@ mod_map = {'CTRL': 'CONTROL', 'CMD': 'SUPER', '⌘': 'SUPER',
|
||||
character_key_name_aliases_with_ascii_lowercase: Dict[str, str] = character_key_name_aliases.copy()
|
||||
for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
|
||||
character_key_name_aliases_with_ascii_lowercase[x] = x.lower()
|
||||
sequence_sep = '>'
|
||||
func_with_args, args_funcs = key_func()
|
||||
FuncArgsType = Tuple[str, Sequence[Any]]
|
||||
|
||||
|
||||
class KeyAction(NamedTuple):
|
||||
func: str
|
||||
args: Sequence[str] = ()
|
||||
|
||||
|
||||
class InvalidMods(ValueError):
|
||||
@@ -400,3 +414,168 @@ def symbol_map(val: str) -> Iterable[Tuple[Tuple[int, int], str]]:
|
||||
if b < a or max(a, b) > sys.maxunicode or min(a, b) < 1:
|
||||
return abort()
|
||||
yield (a, b), family
|
||||
|
||||
|
||||
def parse_key_action(action: str) -> Optional[KeyAction]:
|
||||
parts = action.strip().split(maxsplit=1)
|
||||
func = parts[0]
|
||||
if len(parts) == 1:
|
||||
return KeyAction(func, ())
|
||||
rest = parts[1]
|
||||
parser = args_funcs.get(func)
|
||||
if parser is not None:
|
||||
try:
|
||||
func, args = parser(func, rest)
|
||||
except Exception as err:
|
||||
log_error('Ignoring invalid key action: {} with err: {}'.format(action, err))
|
||||
else:
|
||||
return KeyAction(func, args)
|
||||
return None
|
||||
|
||||
|
||||
class BaseDefinition:
|
||||
action: KeyAction
|
||||
|
||||
def resolve_kitten_aliases(self, aliases: Dict[str, Sequence[str]]) -> None:
|
||||
if not self.action.args:
|
||||
return
|
||||
kitten = self.action.args[0]
|
||||
rest = self.action.args[1] if len(self.action.args) > 1 else ''
|
||||
changed = False
|
||||
for key, expanded in aliases.items():
|
||||
if key == kitten:
|
||||
changed = True
|
||||
kitten = expanded[0]
|
||||
if len(expanded) > 1:
|
||||
rest = expanded[1] + ' ' + rest
|
||||
if changed:
|
||||
self.action = self.action._replace(args=[kitten, rest.rstrip()])
|
||||
|
||||
|
||||
class MouseMapping(BaseDefinition):
|
||||
|
||||
def __init__(self, button: int, mods: int, repeat_count: int, grabbed: bool, action: KeyAction):
|
||||
self.button = button
|
||||
self.mods = mods
|
||||
self.repeat_count = repeat_count
|
||||
self.grabbed = grabbed
|
||||
self.action = action
|
||||
|
||||
def resolve(self, kitty_mod: int) -> None:
|
||||
self.mods = defines.resolve_key_mods(kitty_mod, self.mods)
|
||||
|
||||
@property
|
||||
def trigger(self) -> MouseEvent:
|
||||
return MouseEvent(self.button, self.mods, self.repeat_count, self.grabbed)
|
||||
|
||||
|
||||
class KeyDefinition(BaseDefinition):
|
||||
|
||||
def __init__(self, is_sequence: bool, action: KeyAction, mods: int, is_native: bool, key: int, rest: Tuple[SingleKey, ...] = ()):
|
||||
self.is_sequence = is_sequence
|
||||
self.action = action
|
||||
self.trigger = SingleKey(mods, is_native, key)
|
||||
self.rest = rest
|
||||
|
||||
def resolve(self, kitty_mod: int) -> None:
|
||||
|
||||
def r(k: SingleKey) -> SingleKey:
|
||||
mods = defines.resolve_key_mods(kitty_mod, k.mods)
|
||||
key = k.key
|
||||
is_native = k.is_native
|
||||
return SingleKey(mods, is_native, key)
|
||||
|
||||
self.trigger = r(self.trigger)
|
||||
self.rest = tuple(map(r, self.rest))
|
||||
|
||||
|
||||
def parse_key(val: str, key_definitions: List[KeyDefinition]) -> None:
|
||||
parts = val.split(maxsplit=1)
|
||||
if len(parts) != 2:
|
||||
return
|
||||
sc, action = parts
|
||||
sc, action = sc.strip().strip(sequence_sep), action.strip()
|
||||
if not sc or not action:
|
||||
return
|
||||
is_sequence = sequence_sep in sc
|
||||
if is_sequence:
|
||||
trigger: Optional[SingleKey] = None
|
||||
restl: List[SingleKey] = []
|
||||
for part in sc.split(sequence_sep):
|
||||
try:
|
||||
mods, is_native, key = parse_shortcut(part)
|
||||
except InvalidMods:
|
||||
return
|
||||
if key == 0:
|
||||
if mods is not None:
|
||||
log_error('Shortcut: {} has unknown key, ignoring'.format(sc))
|
||||
return
|
||||
if trigger is None:
|
||||
trigger = SingleKey(mods, is_native, key)
|
||||
else:
|
||||
restl.append(SingleKey(mods, is_native, key))
|
||||
rest = tuple(restl)
|
||||
else:
|
||||
try:
|
||||
mods, is_native, key = parse_shortcut(sc)
|
||||
except InvalidMods:
|
||||
return
|
||||
if key == 0:
|
||||
if mods is not None:
|
||||
log_error('Shortcut: {} has unknown key, ignoring'.format(sc))
|
||||
return
|
||||
try:
|
||||
paction = parse_key_action(action)
|
||||
except Exception:
|
||||
log_error('Invalid shortcut action: {}. Ignoring.'.format(
|
||||
action))
|
||||
else:
|
||||
if paction is not None:
|
||||
if is_sequence:
|
||||
if trigger is not None:
|
||||
key_definitions.append(KeyDefinition(True, paction, trigger[0], trigger[1], trigger[2], rest))
|
||||
else:
|
||||
assert key is not None
|
||||
key_definitions.append(KeyDefinition(False, paction, mods, is_native, key))
|
||||
|
||||
|
||||
def parse_mouse_action(val: str, mouse_mappings: List[MouseMapping]) -> None:
|
||||
parts = val.split(maxsplit=3)
|
||||
if len(parts) != 4:
|
||||
log_error(f'Ignoring invalid mouse action: {val}')
|
||||
return
|
||||
xbutton, event, modes, action = parts
|
||||
kparts = xbutton.split('+')
|
||||
if len(kparts) > 1:
|
||||
mparts, obutton = kparts[:-1], kparts[-1].lower()
|
||||
mods = parse_mods(mparts, obutton)
|
||||
if mods is None:
|
||||
return
|
||||
else:
|
||||
obutton = parts[0].lower()
|
||||
mods = 0
|
||||
try:
|
||||
b = {'left': 'b1', 'middle': 'b3', 'right': 'b2'}.get(obutton, obutton)[1:]
|
||||
button = getattr(defines, f'GLFW_MOUSE_BUTTON_{b}')
|
||||
except Exception:
|
||||
log_error(f'Mouse button: {xbutton} not recognized, ignoring')
|
||||
return
|
||||
try:
|
||||
count = {'doubleclick': -3, 'click': -2, 'release': -1, 'press': 1, 'doublepress': 2, 'triplepress': 3}[event.lower()]
|
||||
except KeyError:
|
||||
log_error(f'Mouse event type: {event} not recognized, ignoring')
|
||||
return
|
||||
specified_modes = frozenset(modes.lower().split(','))
|
||||
if specified_modes - {'grabbed', 'ungrabbed'}:
|
||||
log_error(f'Mouse modes: {modes} not recognized, ignoring')
|
||||
return
|
||||
try:
|
||||
paction = parse_key_action(action)
|
||||
except Exception:
|
||||
log_error(f'Invalid mouse action: {action}. Ignoring.')
|
||||
return
|
||||
if paction is None:
|
||||
log_error(f'Ignoring unknown mouse action: {action}')
|
||||
return
|
||||
for mode in specified_modes:
|
||||
mouse_mappings.append(MouseMapping(button, mods, count, mode == 'grabbed', paction))
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
from asyncio import AbstractEventLoop as AbstractEventLoop
|
||||
from socket import AddressFamily as AddressFamily, socket as Socket
|
||||
from subprocess import (
|
||||
CompletedProcess as CompletedProcess, Popen as PopenType
|
||||
)
|
||||
from typing import (
|
||||
Literal, Protocol as Protocol, TypedDict as TypedDict
|
||||
)
|
||||
from subprocess import CompletedProcess as CompletedProcess, Popen as PopenType
|
||||
from typing import Literal, Protocol as Protocol, TypedDict as TypedDict
|
||||
|
||||
from kittens.hints.main import Mark as MarkType
|
||||
from kittens.tui.handler import Handler as HandlerType
|
||||
@@ -21,16 +17,16 @@ from kitty.conf.utils import KittensKeyAction as KittensKeyActionType
|
||||
from .boss import Boss as BossType
|
||||
from .child import Child as ChildType
|
||||
from .conf.utils import BadLine as BadLineType
|
||||
from .config import (
|
||||
KeyAction as KeyActionType, KeyMap as KeyMap,
|
||||
KittyCommonOpts as KittyCommonOpts, SequenceMap as SequenceMap
|
||||
)
|
||||
from .config import KittyCommonOpts
|
||||
from .fast_data_types import (
|
||||
CoreTextFont as CoreTextFont, FontConfigPattern as FontConfigPattern,
|
||||
Screen as ScreenType, StartupCtx as StartupCtx
|
||||
)
|
||||
from .key_encoding import KeyEvent as KeyEventType
|
||||
from .layout.base import Layout as LayoutType
|
||||
from .options_types import (
|
||||
KeyAction as KeyActionType, KeyMap as KeyMap, SequenceMap as SequenceMap
|
||||
)
|
||||
from .rc.base import RemoteCommand as RemoteCommandType
|
||||
from .session import Session as SessionType, Tab as SessionTab
|
||||
from .tabs import (
|
||||
|
||||
Reference in New Issue
Block a user