Parse actions on demand

This removes the startup cost of parsing hundreds of default actions
when action_alias or kitten_alias are used. Although the cost is on the
order of 1ms, this design feels cleaner and gives nicer debug config
output.
This commit is contained in:
Kovid Goyal 2021-11-29 21:51:42 +05:30
parent 0e5f51f195
commit 0c274a9a0b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
13 changed files with 288 additions and 269 deletions

View File

@ -238,7 +238,7 @@ class Boss:
self.current_visual_select: Optional[VisualSelect] = None
self.startup_cursor_text_color = opts.cursor_text_color
self.pending_sequences: Optional[SubSequenceMap] = None
self.default_pending_action: Tuple[KeyAction, ...] = ()
self.default_pending_action: str = ''
self.cached_values = cached_values
self.os_window_map: Dict[int, TabManager] = {}
self.os_window_death_actions: Dict[int, Callable[[], None]] = {}
@ -259,7 +259,7 @@ class Boss:
)
set_boss(self)
self.args = args
self.global_shortcuts_map: KeyMap = {v: (KeyAction(k),) for k, v in global_shortcuts.items()}
self.global_shortcuts_map: KeyMap = {v: k for k, v in global_shortcuts.items()}
self.global_shortcuts = global_shortcuts
self.mouse_handler: Optional[Callable[[WindowSystemMouseEvent], None]] = None
self.update_keymap()
@ -895,7 +895,7 @@ class Boss:
t = self.active_tab
return None if t is None else t.active_window
def set_pending_sequences(self, sequences: SubSequenceMap, default_pending_action: Tuple[KeyAction, ...] = ()) -> None:
def set_pending_sequences(self, sequences: SubSequenceMap, default_pending_action: str = '') -> None:
self.pending_sequences = sequences
self.default_pending_action = default_pending_action
set_in_sequence_mode(True)
@ -905,18 +905,18 @@ class Boss:
key_action = get_shortcut(self.keymap, ev)
if key_action is None:
sequences = get_shortcut(get_options().sequence_map, ev)
if sequences and not isinstance(sequences, tuple):
if sequences and not isinstance(sequences, str):
self.set_pending_sequences(sequences)
return True
if self.global_shortcuts_map and get_shortcut(self.global_shortcuts_map, ev):
return True
elif isinstance(key_action, tuple):
elif isinstance(key_action, str):
return self.combine(key_action)
return False
def clear_pending_sequences(self) -> None:
self.pending_sequences = None
self.default_pending_action = ()
self.default_pending_action = ''
set_in_sequence_mode(False)
def process_sequence(self, ev: KeyEvent) -> None:
@ -976,18 +976,18 @@ class Boss:
for idx, window in tab.windows.iter_windows_with_number(only_visible=True):
if only_window_ids and window.id not in only_window_ids:
continue
ac = KeyAction('visual_window_select_action_trigger', (window.id,))
ac = f'visual_window_select_action_trigger {window.id}'
if idx >= len(alphanumerics):
break
ch = alphanumerics[idx]
window.screen.set_window_char(ch)
self.current_visual_select.window_ids.append(window.id)
for mods in (0, GLFW_MOD_CONTROL, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT, GLFW_MOD_SUPER, GLFW_MOD_ALT, GLFW_MOD_SHIFT):
pending_sequences[(SingleKey(mods=mods, key=ord(ch.lower())),)] = (ac,)
pending_sequences[(SingleKey(mods=mods, key=ord(ch.lower())),)] = ac
if ch in string.digits:
pending_sequences[(SingleKey(mods=mods, key=fmap[f'KP_{ch}']),)] = (ac,)
pending_sequences[(SingleKey(mods=mods, key=fmap[f'KP_{ch}']),)] = ac
if len(self.current_visual_select.window_ids) > 1:
self.set_pending_sequences(pending_sequences, default_pending_action=(KeyAction('visual_window_select_action_trigger', (0,)),))
self.set_pending_sequences(pending_sequences, default_pending_action='visual_window_select_action_trigger 0')
redirect_mouse_handling(True)
self.mouse_handler = self.visual_window_select_mouse_handler
else:
@ -997,7 +997,7 @@ class Boss:
def visual_window_select_action_trigger(self, window_id: int = 0) -> None:
if self.current_visual_select:
self.current_visual_select.trigger(window_id)
self.current_visual_select.trigger(int(window_id))
self.current_visual_select = None
def visual_window_select_mouse_handler(self, ev: WindowSystemMouseEvent) -> None:
@ -1131,17 +1131,25 @@ class Boss:
map kitty_mod+e combine : new_window : next_layout
''')
def combine(self, actions: Tuple[KeyAction, ...], window_for_dispatch: Optional[Window] = None, dispatch_type: str = 'KeyPress') -> bool:
def combine(self, action_definition: str, window_for_dispatch: Optional[Window] = None, dispatch_type: str = 'KeyPress') -> bool:
consumed = False
if actions:
if action_definition:
try:
if self.dispatch_action(actions[0], window_for_dispatch, dispatch_type):
consumed = True
if len(actions) > 1:
self.drain_actions(list(actions[1:]), window_for_dispatch, dispatch_type)
actions = get_options().alias_map.resolve_aliases(action_definition, 'map' if dispatch_type == 'KeyPress' else 'mouse_map')
except Exception as e:
self.show_error('Key action failed', f'{actions[0].pretty()}\n{e}')
consumed = True
import traceback
traceback.print_exc()
self.show_error('Failed to parse action', f'{action_definition}\n{e}')
return True
for action in actions:
try:
if self.dispatch_action(actions[0], window_for_dispatch, dispatch_type):
consumed = True
if len(actions) > 1:
self.drain_actions(list(actions[1:]), window_for_dispatch, dispatch_type)
except Exception as e:
self.show_error('Key action failed', f'{actions[0].pretty()}\n{e}')
consumed = True
return consumed
def on_focus(self, os_window_id: int, focused: bool) -> None:

View File

@ -165,7 +165,8 @@ def generate_class(defn: Definition, loc: str) -> Tuple[str, str]:
resolve_import(imp)
for fname, ftype in action.fields.items():
ftype = resolve_import(ftype)
a(f' {fname}: {ftype} = ' '{}')
fval = f'{ftype}()' if ftype == 'AliasMap' else '{}'
a(f' {fname}: {ftype} = {fval}')
parser_function_declaration(aname)
t(f' for k in {func.__name__}(val):')
t(f' ans[{aname!r}].append(k)')
@ -269,11 +270,6 @@ def generate_class(defn: Definition, loc: str) -> Tuple[str, str]:
a('if not is_macos:')
a(f' defaults.{option_name}.update({mval["linux"]!r}')
def resolve_action(a: Any) -> Any:
if hasattr(a, 'resolve_aliases_and_parse'):
a.resolve_aliases_and_parse({})
return a
for aname, func in action_parsers.items():
a(f'defaults.{aname} = [')
only: Dict[str, List[Tuple[str, Callable[..., Any]]]] = {}
@ -286,7 +282,7 @@ def generate_class(defn: Definition, loc: str) -> Tuple[str, str]:
else:
for val in func(text):
a(f' # {sc.name}')
a(f' {resolve_action(val)!r}, # noqa')
a(f' {val!r}, # noqa')
a(']')
if only:
imports.add(('kitty.constants', 'is_macos'))
@ -295,7 +291,7 @@ def generate_class(defn: Definition, loc: str) -> Tuple[str, str]:
a(f'if {cond}:')
for (text, func) in items:
for val in func(text):
a(f' defaults.{aname}.append({resolve_action(val)!r}) # noqa')
a(f' defaults.{aname}.append({val!r}) # noqa')
t('')
t('')

View File

@ -11,7 +11,7 @@ from .conf.utils import BadLine, load_config as _load_config, parse_config_base
from .constants import cache_dir, defconf
from .options.types import Options, defaults, option_names
from .options.utils import (
ActionAlias, KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap,
KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap,
build_action_aliases
)
from .typing import TypedDict
@ -91,17 +91,17 @@ def prepare_config_file_for_editing() -> str:
return defconf
def finalize_keys(opts: Options, alias_map: Dict[str, List[ActionAlias]], accumulate_bad_lines: Optional[List[BadLine]] = None) -> None:
def finalize_keys(opts: Options, accumulate_bad_lines: Optional[List[BadLine]] = None) -> None:
defns: List[KeyDefinition] = []
for d in opts.map:
if d is None: # clear_all_shortcuts
defns = [] # type: ignore
else:
try:
defns.append(d.resolve_and_copy(opts.kitty_mod, alias_map))
defns.append(d.resolve_and_copy(opts.kitty_mod))
except Exception as err:
if accumulate_bad_lines is None:
log_error(f'Ignoring map with invalid action: {d.original_definition}. Error: {err}')
log_error(f'Ignoring map with invalid action: {d.definition}. Error: {err}')
else:
accumulate_bad_lines.append(BadLine(d.definition_location.number, d.definition_location.line, err, d.definition_location.file))
@ -118,28 +118,28 @@ def finalize_keys(opts: Options, alias_map: Dict[str, List[ActionAlias]], accumu
if not s:
del sequence_map[defn.trigger]
else:
s[defn.rest] = defn.actions
s[defn.rest] = defn.definition
else:
sequence_map.pop(defn.trigger, None)
if is_no_op:
keymap.pop(defn.trigger, None)
else:
keymap[defn.trigger] = defn.actions
keymap[defn.trigger] = defn.definition
opts.keymap = keymap
opts.sequence_map = sequence_map
def finalize_mouse_mappings(opts: Options, alias_map: Dict[str, List[ActionAlias]], accumulate_bad_lines: Optional[List[BadLine]] = None) -> None:
def finalize_mouse_mappings(opts: Options, accumulate_bad_lines: Optional[List[BadLine]] = None) -> None:
defns: List[MouseMapping] = []
for d in opts.mouse_map:
if d is None: # clear_all_mouse_actions
defns = [] # type: ignore
else:
try:
defns.append(d.resolve_and_copy(opts.kitty_mod, alias_map))
defns.append(d.resolve_and_copy(opts.kitty_mod))
except Exception as err:
if accumulate_bad_lines is None:
log_error(f'Ignoring mouse_map with invalid action: {d.original_definition}. Error: {err}')
log_error(f'Ignoring mouse_map with invalid action: {d.definition}. Error: {err}')
else:
accumulate_bad_lines.append(BadLine(d.definition_location.number, d.definition_location.line, err, d.definition_location.file))
mousemap: MouseMap = {}
@ -149,7 +149,7 @@ def finalize_mouse_mappings(opts: Options, alias_map: Dict[str, List[ActionAlias
if is_no_op:
mousemap.pop(defn.trigger, None)
else:
mousemap[defn.trigger] = defn.actions
mousemap[defn.trigger] = defn.definition
opts.mousemap = mousemap
@ -172,10 +172,10 @@ def load_config(*paths: str, overrides: Optional[Iterable[str]] = None, accumula
opts_dict, paths = _load_config(defaults, partial(parse_config, accumulate_bad_lines=accumulate_bad_lines), merge_result_dicts, *paths, overrides=overrides)
opts = Options(opts_dict)
alias_map = build_action_aliases(opts.kitten_alias, 'kitten')
alias_map.update(build_action_aliases(opts.action_alias))
finalize_keys(opts, alias_map, accumulate_bad_lines)
finalize_mouse_mappings(opts, alias_map, accumulate_bad_lines)
opts.alias_map = build_action_aliases(opts.kitten_alias, 'kitten')
opts.alias_map.update(build_action_aliases(opts.action_alias))
finalize_keys(opts, accumulate_bad_lines)
finalize_mouse_mappings(opts, accumulate_bad_lines)
# delete no longer needed definitions, replacing with empty placeholders
opts.kitten_alias = {}
opts.action_alias = {}

View File

@ -16,7 +16,6 @@ from typing import (
from kittens.tui.operations import colored, styled
from .cli import version
from .conf.utils import KeyAction
from .constants import (
extensions_dir, is_macos, is_wayland, kitty_base_dir, kitty_exe, shell_path
)
@ -27,7 +26,7 @@ from .rgb import color_as_sharp
from .types import MouseEvent, SingleKey
from .typing import SequenceMap
ShortcutMap = Dict[Tuple[SingleKey, ...], Tuple[KeyAction, ...]]
ShortcutMap = Dict[Tuple[SingleKey, ...], str]
def green(x: str) -> str:
@ -54,7 +53,7 @@ def mod_to_names(mods: int) -> Generator[str, None, None]:
yield name
def print_shortcut(key_sequence: Iterable[SingleKey], actions: Iterable[KeyAction], print: Callable[..., None]) -> None:
def print_shortcut(key_sequence: Iterable[SingleKey], defn: str, print: Callable[..., None]) -> None:
from .fast_data_types import glfw_get_key_name
keys = []
for key_spec in key_sequence:
@ -66,8 +65,7 @@ def print_shortcut(key_sequence: Iterable[SingleKey], actions: Iterable[KeyActio
names.append(kname or f'{key}')
keys.append('+'.join(names))
for action in actions:
print('\t' + ' > '.join(keys), action)
print('\t' + ' > '.join(keys), defn)
def print_shortcut_changes(defns: ShortcutMap, text: str, changes: Set[Tuple[SingleKey, ...]], print: Callable[..., None]) -> None:
@ -100,12 +98,11 @@ def compare_mousemaps(final: MouseMap, initial: MouseMap, print: Callable[..., N
removed = set(initial) - set(final)
changed = {k for k in set(final) & set(initial) if final[k] != initial[k]}
def print_mouse_action(trigger: MouseEvent, actions: Tuple[KeyAction, ...]) -> None:
def print_mouse_action(trigger: MouseEvent, defn: str) -> None:
names = list(mod_to_names(trigger.mods)) + [f'b{trigger.button+1}']
when = {-1: 'repeat', 1: 'press', 2: 'doublepress', 3: 'triplepress'}.get(trigger.repeat_count, trigger.repeat_count)
grabbed = 'grabbed' if trigger.grabbed else 'ungrabbed'
for action in actions:
print('\t', '+'.join(names), when, grabbed, action)
print('\t', '+'.join(names), when, grabbed, defn)
def print_changes(defns: MouseMap, changes: Set[MouseEvent], text: str) -> None:
if changes:

View File

@ -1,9 +1,8 @@
#!/usr/bin/env python3
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
from typing import Optional, Union, Tuple
from typing import Union
from .conf.utils import KeyAction
from .fast_data_types import (
GLFW_MOD_ALT, GLFW_MOD_CONTROL, GLFW_MOD_HYPER, GLFW_MOD_META,
GLFW_MOD_SHIFT, GLFW_MOD_SUPER, KeyEvent
@ -22,7 +21,7 @@ def keyboard_mode_name(screen: ScreenType) -> str:
return 'application' if screen.cursor_key_mode else 'normal'
def get_shortcut(keymap: Union[KeyMap, SequenceMap], ev: KeyEvent) -> Optional[Union[Tuple[KeyAction, ...], SubSequenceMap]]:
def get_shortcut(keymap: Union[KeyMap, SequenceMap], ev: KeyEvent) -> Union[str, SubSequenceMap, None]:
mods = ev.mods & mod_mask
ans = keymap.get(SingleKey(mods, False, ev.key))
if ans is None and ev.shifted_key and mods & GLFW_MOD_SHIFT:

View File

@ -6,7 +6,7 @@ import os
import shutil
import sys
from contextlib import contextmanager, suppress
from typing import Any, Dict, Generator, List, Optional, Sequence, Tuple
from typing import Dict, Generator, List, Optional, Sequence, Tuple
from .borders import load_borders_program
from .boss import Boss
@ -108,14 +108,17 @@ def init_glfw(opts: Options, debug_keyboard: bool = False, debug_rendering: bool
return glfw_module
def get_macos_shortcut_for(opts: Options, function: str = 'new_os_window', args: Tuple[Any, ...] = (), lookup_name: str = '') -> Optional[SingleKey]:
def get_macos_shortcut_for(
func_map: Dict[Tuple[str, ...], List[SingleKey]], defn: str = 'new_os_window', lookup_name: str = ''
) -> Optional[SingleKey]:
# for maximum robustness we should use opts.alias_map to resolve
# aliases however this requires parsing everything on startup which could
# be potentially slow. Lets just hope the user doesnt alias these
# fucntions.
ans = None
candidates = []
for k, v in opts.keymap.items():
if len(v) == 1:
q = v[0]
if q.func == function and q.args == args:
candidates.append(k)
qkey = tuple(defn.split())
candidates = func_map[qkey]
if candidates:
from .fast_data_types import cocoa_set_global_shortcut
alt_mods = GLFW_MOD_ALT, GLFW_MOD_ALT | GLFW_MOD_SHIFT
@ -126,7 +129,7 @@ def get_macos_shortcut_for(opts: Options, function: str = 'new_os_window', args:
# presumably because Apple reserves them for IME, see
# https://github.com/kovidgoyal/kitty/issues/3515
continue
if cocoa_set_global_shortcut(lookup_name or function, candidate[0], candidate[2]):
if cocoa_set_global_shortcut(lookup_name or qkey[0], candidate[0], candidate[2]):
ans = candidate
break
return ans
@ -141,15 +144,21 @@ def set_x11_window_icon() -> None:
def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ()) -> None:
global_shortcuts: Dict[str, SingleKey] = {}
if is_macos:
from collections import defaultdict
func_map = defaultdict(list)
for k, v in opts.keymap.items():
parts = tuple(v.split())
func_map[parts].append(k)
for ac in ('new_os_window', 'close_os_window', 'close_tab', 'edit_config_file', 'previous_tab',
'next_tab', 'new_tab', 'new_window', 'close_window'):
val = get_macos_shortcut_for(opts, ac)
val = get_macos_shortcut_for(func_map, ac)
if val is not None:
global_shortcuts[ac] = val
val = get_macos_shortcut_for(opts, 'clear_terminal', args=('reset', True), lookup_name='reset_terminal')
val = get_macos_shortcut_for(func_map, 'clear_terminal reset active', lookup_name='reset_terminal')
if val is not None:
global_shortcuts['reset_terminal'] = val
val = get_macos_shortcut_for(opts, 'load_config_file', args=(), lookup_name='reload_config')
val = get_macos_shortcut_for(func_map, 'load_config_file', lookup_name='reload_config')
if val is not None:
global_shortcuts['reload_config'] = val
if is_macos and opts.macos_custom_beam_cursor:

View File

@ -9,9 +9,9 @@ from kitty.conf.types import Action, Definition
definition = Definition(
'kitty',
Action('map', 'parse_map', {'keymap': 'KeyMap', 'sequence_map': 'SequenceMap'},
['KeyDefinition', 'kitty.conf.utils.KeyAction', 'kitty.types.SingleKey']),
Action('mouse_map', 'parse_mouse_map', {'mousemap': 'MouseMap'}, ['MouseMapping', 'kitty.conf.utils.KeyAction']),
Action('map', 'parse_map', {'keymap': 'KeyMap', 'sequence_map': 'SequenceMap', 'alias_map': 'AliasMap'},
['KeyDefinition', 'kitty.types.SingleKey']),
Action('mouse_map', 'parse_mouse_map', {'mousemap': 'MouseMap'}, ['MouseMapping']),
has_color_table=True,
)
definition.add_deprecation('deprecated_hide_window_decorations_aliases', 'x11_hide_window_decorations', 'macos_hide_titlebar')

291
kitty/options/types.py generated
View File

@ -2,13 +2,11 @@
import typing
from array import array
from kitty.conf.utils import KeyAction
import kitty.conf.utils
from kitty.constants import is_macos
import kitty.constants
from kitty.fast_data_types import Color
import kitty.fast_data_types
from kitty.options.utils import KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap, TabBarMarginHeight
from kitty.options.utils import AliasMap, KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap, TabBarMarginHeight
import kitty.options.utils
from kitty.types import FloatEdges, SingleKey
import kitty.types
@ -593,6 +591,7 @@ class Options:
map: typing.List[kitty.options.utils.KeyDefinition] = []
keymap: KeyMap = {}
sequence_map: SequenceMap = {}
alias_map: AliasMap = AliasMap()
mouse_map: typing.List[kitty.options.utils.MouseMapping] = []
mousemap: MouseMap = {}
color_table: "array[int]" = array("L", (
@ -708,252 +707,252 @@ defaults.symbol_map = {}
defaults.watcher = {}
defaults.map = [
# copy_to_clipboard
KeyDefinition(actions=(KeyAction('copy_to_clipboard'),), trigger=SingleKey(mods=1024, key=99), original_definition='copy_to_clipboard'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=99), definition='copy_to_clipboard'), # noqa
# paste_from_clipboard
KeyDefinition(actions=(KeyAction('paste_from_clipboard'),), trigger=SingleKey(mods=1024, key=118), original_definition='paste_from_clipboard'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=118), definition='paste_from_clipboard'), # noqa
# paste_from_selection
KeyDefinition(actions=(KeyAction('paste_from_selection'),), trigger=SingleKey(mods=1024, key=115), original_definition='paste_from_selection'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=115), definition='paste_from_selection'), # noqa
# paste_from_selection
KeyDefinition(actions=(KeyAction('paste_from_selection'),), trigger=SingleKey(mods=1, key=57348), original_definition='paste_from_selection'), # noqa
KeyDefinition(trigger=SingleKey(mods=1, key=57348), definition='paste_from_selection'), # noqa
# pass_selection_to_program
KeyDefinition(actions=(KeyAction('pass_selection_to_program'),), trigger=SingleKey(mods=1024, key=111), original_definition='pass_selection_to_program'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=111), definition='pass_selection_to_program'), # noqa
# scroll_line_up
KeyDefinition(actions=(KeyAction('scroll_line_up'),), trigger=SingleKey(mods=1024, key=57352), original_definition='scroll_line_up'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57352), definition='scroll_line_up'), # noqa
# scroll_line_up
KeyDefinition(actions=(KeyAction('scroll_line_up'),), trigger=SingleKey(mods=1024, key=107), original_definition='scroll_line_up'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=107), definition='scroll_line_up'), # noqa
# scroll_line_down
KeyDefinition(actions=(KeyAction('scroll_line_down'),), trigger=SingleKey(mods=1024, key=57353), original_definition='scroll_line_down'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57353), definition='scroll_line_down'), # noqa
# scroll_line_down
KeyDefinition(actions=(KeyAction('scroll_line_down'),), trigger=SingleKey(mods=1024, key=106), original_definition='scroll_line_down'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=106), definition='scroll_line_down'), # noqa
# scroll_page_up
KeyDefinition(actions=(KeyAction('scroll_page_up'),), trigger=SingleKey(mods=1024, key=57354), original_definition='scroll_page_up'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57354), definition='scroll_page_up'), # noqa
# scroll_page_down
KeyDefinition(actions=(KeyAction('scroll_page_down'),), trigger=SingleKey(mods=1024, key=57355), original_definition='scroll_page_down'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57355), definition='scroll_page_down'), # noqa
# scroll_home
KeyDefinition(actions=(KeyAction('scroll_home'),), trigger=SingleKey(mods=1024, key=57356), original_definition='scroll_home'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57356), definition='scroll_home'), # noqa
# scroll_end
KeyDefinition(actions=(KeyAction('scroll_end'),), trigger=SingleKey(mods=1024, key=57357), original_definition='scroll_end'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57357), definition='scroll_end'), # noqa
# scroll_to_previous_prompt
KeyDefinition(actions=(KeyAction('scroll_to_prompt', (-1,)),), trigger=SingleKey(mods=1024, key=122), original_definition='scroll_to_prompt -1'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=122), definition='scroll_to_prompt -1'), # noqa
# scroll_to_next_prompt
KeyDefinition(actions=(KeyAction('scroll_to_prompt', (1,)),), trigger=SingleKey(mods=1024, key=120), original_definition='scroll_to_prompt 1'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=120), definition='scroll_to_prompt 1'), # noqa
# show_scrollback
KeyDefinition(actions=(KeyAction('show_scrollback'),), trigger=SingleKey(mods=1024, key=104), original_definition='show_scrollback'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=104), definition='show_scrollback'), # noqa
# show_last_command_output
KeyDefinition(actions=(KeyAction('show_last_command_output'),), trigger=SingleKey(mods=1024, key=103), original_definition='show_last_command_output'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=103), definition='show_last_command_output'), # noqa
# new_window
KeyDefinition(actions=(KeyAction('new_window'),), trigger=SingleKey(mods=1024, key=57345), original_definition='new_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57345), definition='new_window'), # noqa
# new_os_window
KeyDefinition(actions=(KeyAction('new_os_window'),), trigger=SingleKey(mods=1024, key=110), original_definition='new_os_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=110), definition='new_os_window'), # noqa
# close_window
KeyDefinition(actions=(KeyAction('close_window'),), trigger=SingleKey(mods=1024, key=119), original_definition='close_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=119), definition='close_window'), # noqa
# next_window
KeyDefinition(actions=(KeyAction('next_window'),), trigger=SingleKey(mods=1024, key=93), original_definition='next_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=93), definition='next_window'), # noqa
# previous_window
KeyDefinition(actions=(KeyAction('previous_window'),), trigger=SingleKey(mods=1024, key=91), original_definition='previous_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=91), definition='previous_window'), # noqa
# move_window_forward
KeyDefinition(actions=(KeyAction('move_window_forward'),), trigger=SingleKey(mods=1024, key=102), original_definition='move_window_forward'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=102), definition='move_window_forward'), # noqa
# move_window_backward
KeyDefinition(actions=(KeyAction('move_window_backward'),), trigger=SingleKey(mods=1024, key=98), original_definition='move_window_backward'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=98), definition='move_window_backward'), # noqa
# move_window_to_top
KeyDefinition(actions=(KeyAction('move_window_to_top'),), trigger=SingleKey(mods=1024, key=96), original_definition='move_window_to_top'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=96), definition='move_window_to_top'), # noqa
# start_resizing_window
KeyDefinition(actions=(KeyAction('start_resizing_window'),), trigger=SingleKey(mods=1024, key=114), original_definition='start_resizing_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=114), definition='start_resizing_window'), # noqa
# first_window
KeyDefinition(actions=(KeyAction('first_window'),), trigger=SingleKey(mods=1024, key=49), original_definition='first_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=49), definition='first_window'), # noqa
# second_window
KeyDefinition(actions=(KeyAction('second_window'),), trigger=SingleKey(mods=1024, key=50), original_definition='second_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=50), definition='second_window'), # noqa
# third_window
KeyDefinition(actions=(KeyAction('third_window'),), trigger=SingleKey(mods=1024, key=51), original_definition='third_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=51), definition='third_window'), # noqa
# fourth_window
KeyDefinition(actions=(KeyAction('fourth_window'),), trigger=SingleKey(mods=1024, key=52), original_definition='fourth_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=52), definition='fourth_window'), # noqa
# fifth_window
KeyDefinition(actions=(KeyAction('fifth_window'),), trigger=SingleKey(mods=1024, key=53), original_definition='fifth_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=53), definition='fifth_window'), # noqa
# sixth_window
KeyDefinition(actions=(KeyAction('sixth_window'),), trigger=SingleKey(mods=1024, key=54), original_definition='sixth_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=54), definition='sixth_window'), # noqa
# seventh_window
KeyDefinition(actions=(KeyAction('seventh_window'),), trigger=SingleKey(mods=1024, key=55), original_definition='seventh_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=55), definition='seventh_window'), # noqa
# eighth_window
KeyDefinition(actions=(KeyAction('eighth_window'),), trigger=SingleKey(mods=1024, key=56), original_definition='eighth_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=56), definition='eighth_window'), # noqa
# ninth_window
KeyDefinition(actions=(KeyAction('ninth_window'),), trigger=SingleKey(mods=1024, key=57), original_definition='ninth_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57), definition='ninth_window'), # noqa
# tenth_window
KeyDefinition(actions=(KeyAction('tenth_window'),), trigger=SingleKey(mods=1024, key=48), original_definition='tenth_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=48), definition='tenth_window'), # noqa
# focus_visible_window
KeyDefinition(actions=(KeyAction('focus_visible_window'),), trigger=SingleKey(mods=1024, key=57370), original_definition='focus_visible_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57370), definition='focus_visible_window'), # noqa
# swap_with_window
KeyDefinition(actions=(KeyAction('swap_with_window'),), trigger=SingleKey(mods=1024, key=57371), original_definition='swap_with_window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57371), definition='swap_with_window'), # noqa
# next_tab
KeyDefinition(actions=(KeyAction('next_tab'),), trigger=SingleKey(mods=1024, key=57351), original_definition='next_tab'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57351), definition='next_tab'), # noqa
# next_tab
KeyDefinition(actions=(KeyAction('next_tab'),), trigger=SingleKey(mods=4, key=57346), original_definition='next_tab'), # noqa
KeyDefinition(trigger=SingleKey(mods=4, key=57346), definition='next_tab'), # noqa
# previous_tab
KeyDefinition(actions=(KeyAction('previous_tab'),), trigger=SingleKey(mods=1024, key=57350), original_definition='previous_tab'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57350), definition='previous_tab'), # noqa
# previous_tab
KeyDefinition(actions=(KeyAction('previous_tab'),), trigger=SingleKey(mods=5, key=57346), original_definition='previous_tab'), # noqa
KeyDefinition(trigger=SingleKey(mods=5, key=57346), definition='previous_tab'), # noqa
# new_tab
KeyDefinition(actions=(KeyAction('new_tab'),), trigger=SingleKey(mods=1024, key=116), original_definition='new_tab'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=116), definition='new_tab'), # noqa
# close_tab
KeyDefinition(actions=(KeyAction('close_tab'),), trigger=SingleKey(mods=1024, key=113), original_definition='close_tab'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=113), definition='close_tab'), # noqa
# move_tab_forward
KeyDefinition(actions=(KeyAction('move_tab_forward'),), trigger=SingleKey(mods=1024, key=46), original_definition='move_tab_forward'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=46), definition='move_tab_forward'), # noqa
# move_tab_backward
KeyDefinition(actions=(KeyAction('move_tab_backward'),), trigger=SingleKey(mods=1024, key=44), original_definition='move_tab_backward'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=44), definition='move_tab_backward'), # noqa
# set_tab_title
KeyDefinition(actions=(KeyAction('set_tab_title'),), trigger=SingleKey(mods=1026, key=116), original_definition='set_tab_title'), # noqa
KeyDefinition(trigger=SingleKey(mods=1026, key=116), definition='set_tab_title'), # noqa
# next_layout
KeyDefinition(actions=(KeyAction('next_layout'),), trigger=SingleKey(mods=1024, key=108), original_definition='next_layout'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=108), definition='next_layout'), # noqa
# increase_font_size
KeyDefinition(actions=(KeyAction('change_font_size', (True, '+', 2.0)),), trigger=SingleKey(mods=1024, key=61), original_definition='change_font_size all +2.0'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=61), definition='change_font_size all +2.0'), # noqa
# increase_font_size
KeyDefinition(actions=(KeyAction('change_font_size', (True, '+', 2.0)),), trigger=SingleKey(mods=1024, key=43), original_definition='change_font_size all +2.0'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=43), definition='change_font_size all +2.0'), # noqa
# increase_font_size
KeyDefinition(actions=(KeyAction('change_font_size', (True, '+', 2.0)),), trigger=SingleKey(mods=1024, key=57413), original_definition='change_font_size all +2.0'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57413), definition='change_font_size all +2.0'), # noqa
# decrease_font_size
KeyDefinition(actions=(KeyAction('change_font_size', (True, '-', 2.0)),), trigger=SingleKey(mods=1024, key=45), original_definition='change_font_size all -2.0'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=45), definition='change_font_size all -2.0'), # noqa
# decrease_font_size
KeyDefinition(actions=(KeyAction('change_font_size', (True, '-', 2.0)),), trigger=SingleKey(mods=1024, key=57412), original_definition='change_font_size all -2.0'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57412), definition='change_font_size all -2.0'), # noqa
# reset_font_size
KeyDefinition(actions=(KeyAction('change_font_size', (True, None, 0.0)),), trigger=SingleKey(mods=1024, key=57347), original_definition='change_font_size all 0'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57347), definition='change_font_size all 0'), # noqa
# open_url
KeyDefinition(actions=(KeyAction('open_url_with_hints'),), trigger=SingleKey(mods=1024, key=101), original_definition='open_url_with_hints'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=101), definition='open_url_with_hints'), # noqa
# insert_selected_path
KeyDefinition(is_sequence=True, actions=(KeyAction('kitten', ('hints', '--type', 'path', '--program', '-')),), trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=102),), original_definition='kitten hints --type path --program -'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=102),), definition='kitten hints --type path --program -'), # noqa
# open_selected_path
KeyDefinition(is_sequence=True, actions=(KeyAction('kitten', ('hints', '--type', 'path')),), trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(mods=1, key=102),), original_definition='kitten hints --type path'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(mods=1, key=102),), definition='kitten hints --type path'), # noqa
# insert_selected_line
KeyDefinition(is_sequence=True, actions=(KeyAction('kitten', ('hints', '--type', 'line', '--program', '-')),), trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=108),), original_definition='kitten hints --type line --program -'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=108),), definition='kitten hints --type line --program -'), # noqa
# insert_selected_word
KeyDefinition(is_sequence=True, actions=(KeyAction('kitten', ('hints', '--type', 'word', '--program', '-')),), trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=119),), original_definition='kitten hints --type word --program -'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=119),), definition='kitten hints --type word --program -'), # noqa
# insert_selected_hash
KeyDefinition(is_sequence=True, actions=(KeyAction('kitten', ('hints', '--type', 'hash', '--program', '-')),), trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=104),), original_definition='kitten hints --type hash --program -'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=104),), definition='kitten hints --type hash --program -'), # noqa
# goto_file_line
KeyDefinition(is_sequence=True, actions=(KeyAction('kitten', ('hints', '--type', 'linenum')),), trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=110),), original_definition='kitten hints --type linenum'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=110),), definition='kitten hints --type linenum'), # noqa
# open_selected_hyperlink
KeyDefinition(is_sequence=True, actions=(KeyAction('kitten', ('hints', '--type', 'hyperlink')),), trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=121),), original_definition='kitten hints --type hyperlink'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=112), rest=(SingleKey(key=121),), definition='kitten hints --type hyperlink'), # noqa
# toggle_fullscreen
KeyDefinition(actions=(KeyAction('toggle_fullscreen'),), trigger=SingleKey(mods=1024, key=57374), original_definition='toggle_fullscreen'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57374), definition='toggle_fullscreen'), # noqa
# toggle_maximized
KeyDefinition(actions=(KeyAction('toggle_maximized'),), trigger=SingleKey(mods=1024, key=57373), original_definition='toggle_maximized'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57373), definition='toggle_maximized'), # noqa
# input_unicode_character
KeyDefinition(actions=(KeyAction('kitten', ('unicode_input',)),), trigger=SingleKey(mods=1024, key=117), original_definition='kitten unicode_input'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=117), definition='kitten unicode_input'), # noqa
# edit_config_file
KeyDefinition(actions=(KeyAction('edit_config_file'),), trigger=SingleKey(mods=1024, key=57365), original_definition='edit_config_file'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57365), definition='edit_config_file'), # noqa
# kitty_shell
KeyDefinition(actions=(KeyAction('kitty_shell', ('window',)),), trigger=SingleKey(mods=1024, key=57344), original_definition='kitty_shell window'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57344), definition='kitty_shell window'), # noqa
# increase_background_opacity
KeyDefinition(is_sequence=True, actions=(KeyAction('set_background_opacity', ('+0.1',)),), trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=109),), original_definition='set_background_opacity +0.1'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=109),), definition='set_background_opacity +0.1'), # noqa
# decrease_background_opacity
KeyDefinition(is_sequence=True, actions=(KeyAction('set_background_opacity', ('-0.1',)),), trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=108),), original_definition='set_background_opacity -0.1'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=108),), definition='set_background_opacity -0.1'), # noqa
# full_background_opacity
KeyDefinition(is_sequence=True, actions=(KeyAction('set_background_opacity', ('1',)),), trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=49),), original_definition='set_background_opacity 1'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=49),), definition='set_background_opacity 1'), # noqa
# reset_background_opacity
KeyDefinition(is_sequence=True, actions=(KeyAction('set_background_opacity', ('default',)),), trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=100),), original_definition='set_background_opacity default'), # noqa
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=1024, key=97), rest=(SingleKey(key=100),), definition='set_background_opacity default'), # noqa
# reset_terminal
KeyDefinition(actions=(KeyAction('clear_terminal', ('reset', True)),), trigger=SingleKey(mods=1024, key=57349), original_definition='clear_terminal reset active'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57349), definition='clear_terminal reset active'), # noqa
# reload_config_file
KeyDefinition(actions=(KeyAction('load_config_file'),), trigger=SingleKey(mods=1024, key=57368), original_definition='load_config_file'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57368), definition='load_config_file'), # noqa
# debug_config
KeyDefinition(actions=(KeyAction('debug_config'),), trigger=SingleKey(mods=1024, key=57369), original_definition='debug_config'), # noqa
KeyDefinition(trigger=SingleKey(mods=1024, key=57369), definition='debug_config'), # noqa
]
if is_macos:
defaults.map.append(KeyDefinition(actions=(KeyAction('copy_to_clipboard'),), trigger=SingleKey(mods=8, key=99), original_definition='copy_to_clipboard')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('paste_from_clipboard'),), trigger=SingleKey(mods=8, key=118), original_definition='paste_from_clipboard')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_line_up'),), trigger=SingleKey(mods=10, key=57354), original_definition='scroll_line_up')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_line_up'),), trigger=SingleKey(mods=8, key=57352), original_definition='scroll_line_up')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_line_down'),), trigger=SingleKey(mods=10, key=57355), original_definition='scroll_line_down')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_line_down'),), trigger=SingleKey(mods=8, key=57353), original_definition='scroll_line_down')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_page_up'),), trigger=SingleKey(mods=8, key=57354), original_definition='scroll_page_up')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_page_down'),), trigger=SingleKey(mods=8, key=57355), original_definition='scroll_page_down')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_home'),), trigger=SingleKey(mods=8, key=57356), original_definition='scroll_home')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('scroll_end'),), trigger=SingleKey(mods=8, key=57357), original_definition='scroll_end')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('new_window'),), trigger=SingleKey(mods=8, key=57345), original_definition='new_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('new_os_window'),), trigger=SingleKey(mods=8, key=110), original_definition='new_os_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('close_window'),), trigger=SingleKey(mods=9, key=100), original_definition='close_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('start_resizing_window'),), trigger=SingleKey(mods=8, key=114), original_definition='start_resizing_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('first_window'),), trigger=SingleKey(mods=8, key=49), original_definition='first_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('second_window'),), trigger=SingleKey(mods=8, key=50), original_definition='second_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('third_window'),), trigger=SingleKey(mods=8, key=51), original_definition='third_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('fourth_window'),), trigger=SingleKey(mods=8, key=52), original_definition='fourth_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('fifth_window'),), trigger=SingleKey(mods=8, key=53), original_definition='fifth_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('sixth_window'),), trigger=SingleKey(mods=8, key=54), original_definition='sixth_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('seventh_window'),), trigger=SingleKey(mods=8, key=55), original_definition='seventh_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('eighth_window'),), trigger=SingleKey(mods=8, key=56), original_definition='eighth_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('ninth_window'),), trigger=SingleKey(mods=8, key=57), original_definition='ninth_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('next_tab'),), trigger=SingleKey(mods=9, key=93), original_definition='next_tab')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('previous_tab'),), trigger=SingleKey(mods=9, key=91), original_definition='previous_tab')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('new_tab'),), trigger=SingleKey(mods=8, key=116), original_definition='new_tab')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('close_tab'),), trigger=SingleKey(mods=8, key=119), original_definition='close_tab')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('close_os_window'),), trigger=SingleKey(mods=9, key=119), original_definition='close_os_window')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('set_tab_title'),), trigger=SingleKey(mods=9, key=105), original_definition='set_tab_title')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('change_font_size', (True, '+', 2.0)),), trigger=SingleKey(mods=8, key=43), original_definition='change_font_size all +2.0')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('change_font_size', (True, '+', 2.0)),), trigger=SingleKey(mods=8, key=61), original_definition='change_font_size all +2.0')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('change_font_size', (True, '+', 2.0)),), trigger=SingleKey(mods=9, key=61), original_definition='change_font_size all +2.0')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('change_font_size', (True, '-', 2.0)),), trigger=SingleKey(mods=8, key=45), original_definition='change_font_size all -2.0')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('change_font_size', (True, '-', 2.0)),), trigger=SingleKey(mods=9, key=45), original_definition='change_font_size all -2.0')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('change_font_size', (True, None, 0.0)),), trigger=SingleKey(mods=8, key=48), original_definition='change_font_size all 0')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('kitten', ('unicode_input',)),), trigger=SingleKey(mods=12, key=32), original_definition='kitten unicode_input')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('edit_config_file'),), trigger=SingleKey(mods=8, key=44), original_definition='edit_config_file')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('clear_terminal', ('reset', True)),), trigger=SingleKey(mods=10, key=114), original_definition='clear_terminal reset active')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('load_config_file'),), trigger=SingleKey(mods=12, key=44), original_definition='load_config_file')) # noqa
defaults.map.append(KeyDefinition(actions=(KeyAction('debug_config'),), trigger=SingleKey(mods=10, key=44), original_definition='debug_config')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=99), definition='copy_to_clipboard')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=118), definition='paste_from_clipboard')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=57354), definition='scroll_line_up')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57352), definition='scroll_line_up')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=57355), definition='scroll_line_down')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57353), definition='scroll_line_down')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57354), definition='scroll_page_up')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57355), definition='scroll_page_down')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57356), definition='scroll_home')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57357), definition='scroll_end')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57345), definition='new_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=110), definition='new_os_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=100), definition='close_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=114), definition='start_resizing_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=49), definition='first_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=50), definition='second_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=51), definition='third_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=52), definition='fourth_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=53), definition='fifth_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=54), definition='sixth_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=55), definition='seventh_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=56), definition='eighth_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57), definition='ninth_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=93), definition='next_tab')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=91), definition='previous_tab')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=116), definition='new_tab')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=119), definition='close_tab')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=119), definition='close_os_window')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=105), definition='set_tab_title')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=43), definition='change_font_size all +2.0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=61), definition='change_font_size all +2.0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=61), definition='change_font_size all +2.0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=45), definition='change_font_size all -2.0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=45), definition='change_font_size all -2.0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=48), definition='change_font_size all 0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=12, key=32), definition='kitten unicode_input')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=44), definition='edit_config_file')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=114), definition='clear_terminal reset active')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=12, key=44), definition='load_config_file')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=44), definition='debug_config')) # noqa
defaults.mouse_map = [
# click_url_or_select
MouseMapping(repeat_count=-2, actions=(KeyAction('mouse_handle_click', ('selection', 'link', 'prompt')),), original_definition='mouse_handle_click selection link prompt'), # noqa
MouseMapping(repeat_count=-2, definition='mouse_handle_click selection link prompt'), # noqa
# click_url_or_select_grabbed
MouseMapping(mods=1, repeat_count=-2, grabbed=True, actions=(KeyAction('mouse_handle_click', ('selection', 'link', 'prompt')),), original_definition='mouse_handle_click selection link prompt'), # noqa
MouseMapping(mods=1, repeat_count=-2, grabbed=True, definition='mouse_handle_click selection link prompt'), # noqa
# click_url_or_select_grabbed
MouseMapping(mods=1, repeat_count=-2, actions=(KeyAction('mouse_handle_click', ('selection', 'link', 'prompt')),), original_definition='mouse_handle_click selection link prompt'), # noqa
MouseMapping(mods=1, repeat_count=-2, definition='mouse_handle_click selection link prompt'), # noqa
# click_url
MouseMapping(mods=5, repeat_count=-1, grabbed=True, actions=(KeyAction('mouse_handle_click', ('link',)),), original_definition='mouse_handle_click link'), # noqa
MouseMapping(mods=5, repeat_count=-1, grabbed=True, definition='mouse_handle_click link'), # noqa
# click_url
MouseMapping(mods=5, repeat_count=-1, actions=(KeyAction('mouse_handle_click', ('link',)),), original_definition='mouse_handle_click link'), # noqa
MouseMapping(mods=5, repeat_count=-1, definition='mouse_handle_click link'), # noqa
# click_url_discard
MouseMapping(mods=5, grabbed=True, actions=(KeyAction('discard_event'),), original_definition='discard_event'), # noqa
MouseMapping(mods=5, grabbed=True, definition='discard_event'), # noqa
# paste_selection
MouseMapping(button=2, repeat_count=-1, actions=(KeyAction('paste_from_selection'),), original_definition='paste_from_selection'), # noqa
MouseMapping(button=2, repeat_count=-1, definition='paste_from_selection'), # noqa
# start_simple_selection
MouseMapping(actions=(KeyAction('mouse_selection', (0,)),), original_definition='mouse_selection normal'), # noqa
MouseMapping(definition='mouse_selection normal'), # noqa
# start_rectangle_selection
MouseMapping(mods=6, actions=(KeyAction('mouse_selection', (2,)),), original_definition='mouse_selection rectangle'), # noqa
MouseMapping(mods=6, definition='mouse_selection rectangle'), # noqa
# select_word
MouseMapping(repeat_count=2, actions=(KeyAction('mouse_selection', (3,)),), original_definition='mouse_selection word'), # noqa
MouseMapping(repeat_count=2, definition='mouse_selection word'), # noqa
# select_line
MouseMapping(repeat_count=3, actions=(KeyAction('mouse_selection', (4,)),), original_definition='mouse_selection line'), # noqa
MouseMapping(repeat_count=3, definition='mouse_selection line'), # noqa
# select_line_from_point
MouseMapping(mods=6, repeat_count=3, actions=(KeyAction('mouse_selection', (5,)),), original_definition='mouse_selection line_from_point'), # noqa
MouseMapping(mods=6, repeat_count=3, definition='mouse_selection line_from_point'), # noqa
# extend_selection
MouseMapping(button=1, actions=(KeyAction('mouse_selection', (1,)),), original_definition='mouse_selection extend'), # noqa
MouseMapping(button=1, definition='mouse_selection extend'), # noqa
# paste_selection_grabbed
MouseMapping(button=2, mods=1, repeat_count=-1, grabbed=True, actions=(KeyAction('paste_selection'),), original_definition='paste_selection'), # noqa
MouseMapping(button=2, mods=1, repeat_count=-1, grabbed=True, definition='paste_selection'), # noqa
# paste_selection_grabbed
MouseMapping(button=2, mods=1, repeat_count=-1, actions=(KeyAction('paste_selection'),), original_definition='paste_selection'), # noqa
MouseMapping(button=2, mods=1, repeat_count=-1, definition='paste_selection'), # noqa
# paste_selection_grabbed
MouseMapping(button=2, mods=1, grabbed=True, actions=(KeyAction('discard_event'),), original_definition='discard_event'), # noqa
MouseMapping(button=2, mods=1, grabbed=True, definition='discard_event'), # noqa
# start_simple_selection_grabbed
MouseMapping(mods=1, grabbed=True, actions=(KeyAction('mouse_selection', (0,)),), original_definition='mouse_selection normal'), # noqa
MouseMapping(mods=1, grabbed=True, definition='mouse_selection normal'), # noqa
# start_simple_selection_grabbed
MouseMapping(mods=1, actions=(KeyAction('mouse_selection', (0,)),), original_definition='mouse_selection normal'), # noqa
MouseMapping(mods=1, definition='mouse_selection normal'), # noqa
# start_rectangle_selection_grabbed
MouseMapping(mods=7, grabbed=True, actions=(KeyAction('mouse_selection', (2,)),), original_definition='mouse_selection rectangle'), # noqa
MouseMapping(mods=7, grabbed=True, definition='mouse_selection rectangle'), # noqa
# start_rectangle_selection_grabbed
MouseMapping(mods=7, actions=(KeyAction('mouse_selection', (2,)),), original_definition='mouse_selection rectangle'), # noqa
MouseMapping(mods=7, definition='mouse_selection rectangle'), # noqa
# select_word_grabbed
MouseMapping(mods=1, repeat_count=2, grabbed=True, actions=(KeyAction('mouse_selection', (3,)),), original_definition='mouse_selection word'), # noqa
MouseMapping(mods=1, repeat_count=2, grabbed=True, definition='mouse_selection word'), # noqa
# select_word_grabbed
MouseMapping(mods=1, repeat_count=2, actions=(KeyAction('mouse_selection', (3,)),), original_definition='mouse_selection word'), # noqa
MouseMapping(mods=1, repeat_count=2, definition='mouse_selection word'), # noqa
# select_line_grabbed
MouseMapping(mods=1, repeat_count=3, grabbed=True, actions=(KeyAction('mouse_selection', (4,)),), original_definition='mouse_selection line'), # noqa
MouseMapping(mods=1, repeat_count=3, grabbed=True, definition='mouse_selection line'), # noqa
# select_line_grabbed
MouseMapping(mods=1, repeat_count=3, actions=(KeyAction('mouse_selection', (4,)),), original_definition='mouse_selection line'), # noqa
MouseMapping(mods=1, repeat_count=3, definition='mouse_selection line'), # noqa
# select_line_from_point_grabbed
MouseMapping(mods=7, repeat_count=3, grabbed=True, actions=(KeyAction('mouse_selection', (5,)),), original_definition='mouse_selection line_from_point'), # noqa
MouseMapping(mods=7, repeat_count=3, grabbed=True, definition='mouse_selection line_from_point'), # noqa
# select_line_from_point_grabbed
MouseMapping(mods=7, repeat_count=3, actions=(KeyAction('mouse_selection', (5,)),), original_definition='mouse_selection line_from_point'), # noqa
MouseMapping(mods=7, repeat_count=3, definition='mouse_selection line_from_point'), # noqa
# extend_selection_grabbed
MouseMapping(button=1, mods=1, grabbed=True, actions=(KeyAction('mouse_selection', (1,)),), original_definition='mouse_selection extend'), # noqa
MouseMapping(button=1, mods=1, grabbed=True, definition='mouse_selection extend'), # noqa
# extend_selection_grabbed
MouseMapping(button=1, mods=1, actions=(KeyAction('mouse_selection', (1,)),), original_definition='mouse_selection extend'), # noqa
MouseMapping(button=1, mods=1, definition='mouse_selection extend'), # noqa
# show_clicked_cmd_output_ungrabbed
MouseMapping(button=1, mods=5, actions=(KeyAction('mouse_show_command_output'),), original_definition='mouse_show_command_output'), # noqa
MouseMapping(button=1, mods=5, definition='mouse_show_command_output'), # noqa
]

View File

@ -5,6 +5,7 @@
import os
import re
import sys
from functools import lru_cache
from typing import (
Any, Callable, Container, Dict, FrozenSet, Iterable, Iterator, List,
NamedTuple, Optional, Sequence, Tuple, Union
@ -29,10 +30,10 @@ from kitty.rgb import color_as_int
from kitty.types import FloatEdges, MouseEvent, SingleKey
from kitty.utils import expandvars, log_error
KeyMap = Dict[SingleKey, Tuple[KeyAction, ...]]
MouseMap = Dict[MouseEvent, Tuple[KeyAction, ...]]
KeyMap = Dict[SingleKey, str]
MouseMap = Dict[MouseEvent, str]
KeySequence = Tuple[SingleKey, ...]
SubSequenceMap = Dict[KeySequence, Tuple[KeyAction, ...]]
SubSequenceMap = Dict[KeySequence, str]
SequenceMap = Dict[SingleKey, SubSequenceMap]
MINIMUM_FONT_SIZE = 4
default_tab_separator = ''
@ -249,7 +250,7 @@ def remote_control(func: str, rest: str) -> FuncArgsType:
return func, args
@func_with_args('nth_window', 'scroll_to_prompt')
@func_with_args('nth_window', 'scroll_to_prompt', 'visual_window_select_action_trigger')
def single_integer_arg(func: str, rest: str) -> FuncArgsType:
try:
num = int(rest)
@ -831,14 +832,30 @@ class ActionAlias(NamedTuple):
replace_second_arg: bool = False
def build_action_aliases(raw: Dict[str, str], first_arg_replacement: str = '') -> Dict[str, List[ActionAlias]]:
ans: Dict[str, List[ActionAlias]] = {}
class AliasMap:
def __init__(self) -> None:
self.aliases: Dict[str, List[ActionAlias]] = {}
def append(self, name: str, aa: ActionAlias) -> None:
self.aliases.setdefault(name, []).append(aa)
def update(self, aa: 'AliasMap') -> None:
self.aliases.update(aa.aliases)
@lru_cache(maxsize=256)
def resolve_aliases(self, definition: str, map_type: str = 'map') -> Tuple[KeyAction, ...]:
return tuple(resolve_aliases_and_parse_actions(definition, self.aliases, map_type))
def build_action_aliases(raw: Dict[str, str], first_arg_replacement: str = '') -> AliasMap:
ans = AliasMap()
if first_arg_replacement:
for alias_name, rest in raw.items():
ans.setdefault(first_arg_replacement, []).append(ActionAlias(alias_name, rest, True))
ans.append(first_arg_replacement, ActionAlias(alias_name, rest, True))
else:
for alias_name, rest in raw.items():
ans[alias_name] = [ActionAlias(alias_name, rest)]
ans.append(alias_name, ActionAlias(alias_name, rest))
return ans
@ -882,23 +899,17 @@ def resolve_aliases_and_parse_actions(
class BaseDefinition:
actions: Tuple[KeyAction, ...] = ()
no_op_actions = frozenset(('noop', 'no-op', 'no_op'))
map_type: str = 'map'
definition_location: CurrentlyParsing
def __init__(self, original_definition: str = '') -> None:
self.original_definition = original_definition
def __init__(self, definition: str = '') -> None:
self.definition = definition
self.definition_location = currently_parsing.__copy__()
@property
def is_no_op(self) -> bool:
return self.original_definition in self.no_op_actions
def resolve_aliases_and_parse(self, aliases: Dict[str, List[ActionAlias]]) -> None:
if self.original_definition and (aliases or not self.actions):
self.actions = tuple(resolve_aliases_and_parse_actions(
self.original_definition, aliases, self.map_type))
return self.definition in self.no_op_actions
def pretty_repr(self, *fields: str) -> str:
kwds = []
@ -907,8 +918,8 @@ class BaseDefinition:
val = getattr(self, f)
if val != getattr(defaults, f):
kwds.append(f'{f}={val!r}')
if self.original_definition:
kwds.append(f'original_definition={self.original_definition!r}')
if self.definition:
kwds.append(f'definition={self.definition!r}')
return f'{self.__class__.__name__}({", ".join(kwds)})'
@ -917,24 +928,22 @@ class MouseMapping(BaseDefinition):
def __init__(
self, button: int = 0, mods: int = 0, repeat_count: int = 1, grabbed: bool = False,
actions: Tuple[KeyAction, ...] = (), original_definition: str = ''
definition: str = ''
):
super().__init__(original_definition)
super().__init__(definition)
self.button = button
self.mods = mods
self.actions = actions
self.repeat_count = repeat_count
self.grabbed = grabbed
def __repr__(self) -> str:
return self.pretty_repr('button', 'mods', 'repeat_count', 'grabbed', 'actions')
return self.pretty_repr('button', 'mods', 'repeat_count', 'grabbed')
def resolve_and_copy(self, kitty_mod: int, aliases: Dict[str, List[ActionAlias]]) -> 'MouseMapping':
def resolve_and_copy(self, kitty_mod: int) -> 'MouseMapping':
ans = MouseMapping(
self.button, defines.resolve_key_mods(kitty_mod, self.mods), self.repeat_count, self.grabbed,
self.actions, self.original_definition)
self.definition)
ans.definition_location = self.definition_location
ans.resolve_aliases_and_parse(aliases)
return ans
@property
@ -945,28 +954,26 @@ class MouseMapping(BaseDefinition):
class KeyDefinition(BaseDefinition):
def __init__(
self, is_sequence: bool = False, actions: Tuple[KeyAction, ...] = (), trigger: SingleKey = SingleKey(),
rest: Tuple[SingleKey, ...] = (), original_definition: str = ''
self, is_sequence: bool = False, trigger: SingleKey = SingleKey(),
rest: Tuple[SingleKey, ...] = (), definition: str = ''
):
super().__init__(original_definition)
super().__init__(definition)
self.is_sequence = is_sequence
self.actions = actions
self.trigger = trigger
self.rest = rest
def __repr__(self) -> str:
return self.pretty_repr('is_sequence', 'actions', 'trigger', 'rest')
return self.pretty_repr('is_sequence', 'trigger', 'rest')
def resolve_and_copy(self, kitty_mod: int, aliases: Dict[str, List[ActionAlias]]) -> 'KeyDefinition':
def resolve_and_copy(self, kitty_mod: int) -> 'KeyDefinition':
def r(k: SingleKey) -> SingleKey:
mods = defines.resolve_key_mods(kitty_mod, k.mods)
return k._replace(mods=mods)
ans = KeyDefinition(
self.is_sequence, self.actions, r(self.trigger), tuple(map(r, self.rest)),
self.original_definition
self.is_sequence, r(self.trigger), tuple(map(r, self.rest)),
self.definition
)
ans.definition_location = self.definition_location
ans.resolve_aliases_and_parse(aliases)
return ans
@ -1007,10 +1014,10 @@ def parse_map(val: str) -> Iterable[KeyDefinition]:
return
if is_sequence:
if trigger is not None:
yield KeyDefinition(True, (), trigger, rest, original_definition=action)
yield KeyDefinition(True, trigger, rest, definition=action)
else:
assert key is not None
yield KeyDefinition(False, (), SingleKey(mods, is_native, key), original_definition=action)
yield KeyDefinition(False, SingleKey(mods, is_native, key), definition=action)
def parse_mouse_map(val: str) -> Iterable[MouseMapping]:
@ -1044,7 +1051,7 @@ def parse_mouse_map(val: str) -> Iterable[MouseMapping]:
log_error(f'Mouse modes: {modes} not recognized, ignoring')
return
for mode in sorted(specified_modes):
yield MouseMapping(button, mods, count, mode == 'grabbed', original_definition=action)
yield MouseMapping(button, mods, count, mode == 'grabbed', definition=action)
def deprecated_hide_window_decorations_aliases(key: str, val: str, ans: Dict[str, Any]) -> None:

View File

@ -5,7 +5,7 @@ from typing import Tuple
BossType = ChildType = TabType = WindowType = ScreenType = None
BadLineType = SequenceMap = KeyActionType = None
BadLineType = SequenceMap = KeyActionType = AliasMap = None
AddressFamily = PopenType = Socket = StartupCtx = None
SessionTab = SessionType = LayoutType = SpecialWindowInstance = None
MarkType = RemoteCommandType = CoreTextFont = FontConfigPattern = None

View File

@ -23,7 +23,7 @@ from .fast_data_types import (
)
from .key_encoding import KeyEvent as KeyEventType
from .layout.base import Layout as LayoutType
from .options.utils import KeyMap as KeyMap, SequenceMap as SequenceMap
from .options.utils import KeyMap as KeyMap, SequenceMap as SequenceMap, AliasMap as AliasMap
from .rc.base import RemoteCommand as RemoteCommandType
from .session import Session as SessionType, Tab as SessionTab
from .tabs import (

View File

@ -69,11 +69,11 @@ class Callbacks:
def on_mouse_event(self, event):
ev = MouseEvent(**event)
actions = self.opts.mousemap.get(ev)
if not actions:
action_def = self.opts.mousemap.get(ev)
if not action_def:
return False
self.current_mouse_button = ev.button
for action in actions:
for action in self.opts.alias_map.resolve_aliases(action_def, 'mouse_map'):
getattr(self, action.func)(*action.args)
self.current_mouse_button = 0
return True

View File

@ -34,8 +34,8 @@ class TestConfParsing(BaseTest):
return ans
def keys_for_func(opts, name):
for key, actions in opts.keymap.items():
for action in actions:
for key, defn in opts.keymap.items():
for action in opts.alias_map.resolve_aliases(defn):
if action.func == name:
yield key
@ -57,48 +57,52 @@ class TestConfParsing(BaseTest):
# test the aliasing options
opts = p('env A=1', 'env B=x$A', 'env C=', 'env D', 'clear_all_shortcuts y', 'kitten_alias a b --moo', 'map f1 kitten a arg')
self.ae(opts.env, {'A': '1', 'B': 'x1', 'C': '', 'D': DELETE_ENV_VAR})
ka = tuple(opts.keymap.values())[0][0]
def ac(which=0):
ka = tuple(opts.keymap.values())[0]
acs = opts.alias_map.resolve_aliases(ka)
return acs[which]
ka = ac()
self.ae(ka.func, 'kitten')
self.ae(ka.args, ('b', '--moo', 'arg'))
opts = p('clear_all_shortcuts y', 'kitten_alias hints hints --hi', 'map f1 kitten hints XXX')
ka = tuple(opts.keymap.values())[0][0]
ka = ac()
self.ae(ka.func, 'kitten')
self.ae(ka.args, ('hints', '--hi', 'XXX'))
opts = p('clear_all_shortcuts y', 'action_alias la launch --moo', 'map f1 la XXX')
ka = tuple(opts.keymap.values())[0][0]
ka = ac()
self.ae(ka.func, 'launch')
self.ae(ka.args, ('--moo', 'XXX'))
opts = p('clear_all_shortcuts y', 'action_alias one launch --moo', 'action_alias two one recursive', 'map f1 two XXX')
ka = tuple(opts.keymap.values())[0][0]
ka = ac()
self.ae(ka.func, 'launch')
self.ae(ka.args, ('--moo', 'recursive', 'XXX'))
opts = p('clear_all_shortcuts y', 'action_alias launch two 1', 'action_alias two launch 2', 'map f1 launch 3')
ka = tuple(opts.keymap.values())[0][0]
ka = ac()
self.ae(ka.func, 'launch')
self.ae(ka.args, ('2', '1', '3'))
opts = p('clear_all_shortcuts y', 'action_alias launch launch --moo', 'map f1 launch XXX')
ka = tuple(opts.keymap.values())[0][0]
ka = ac()
self.ae(ka.func, 'launch')
self.ae(ka.args, ('--moo', 'XXX'))
opts = p('clear_all_shortcuts y', 'action_alias cfs change_font_size current', 'map f1 cfs +2')
ka = tuple(opts.keymap.values())[0][0]
ka = ac()
self.ae(ka.func, 'change_font_size')
self.ae(ka.args, (False, '+', 2.0))
opts = p('clear_all_shortcuts y', 'action_alias la launch --moo', 'map f1 combine : new_window : la ')
ka = tuple(opts.keymap.values())[0]
self.ae((ka[0].func, ka[1].func), ('new_window', 'launch'))
self.ae((ac().func, ac(1).func), ('new_window', 'launch'))
opts = p('clear_all_shortcuts y', 'action_alias cc combine : new_window : launch --moo', 'map f1 cc XXX')
ka = tuple(opts.keymap.values())[0]
self.ae((ka[0].func, ka[1].func), ('new_window', 'launch'))
self.ae(ka[1].args, ('--moo', 'XXX'))
self.ae((ac().func, ac(1).func), ('new_window', 'launch'))
self.ae(ac(1).args, ('--moo', 'XXX'))
opts = p('kitty_mod alt')
self.ae(opts.kitty_mod, to_modifiers('alt'))