Allow defining aliases for more general actions, not just kittens
Fixes #4260
This commit is contained in:
parent
727c69ffdd
commit
aa4fa4cc85
@ -210,6 +210,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
--program` option work when using the ``self``
|
||||
:option:`kitty +kitten hints --linenum-action` (:iss:`3931`)
|
||||
|
||||
- Allow defining aliases for more general actions, not just kittens
|
||||
(:pull:`4260`)
|
||||
|
||||
|
||||
0.22.2 [2021-08-02]
|
||||
----------------------
|
||||
|
||||
@ -38,6 +38,18 @@ To pass the contents of the current screen and scrollback to the started process
|
||||
|
||||
There are many more powerful options, refer to the complete list below.
|
||||
|
||||
.. note::
|
||||
To avoid duplicating launch actions with frequently used parameters, you can
|
||||
use :opt:`action_alias` to define launch action aliases. For example::
|
||||
|
||||
action_alias launch_tab launch --cwd=current --type=tab
|
||||
map f1 launch_tab vim
|
||||
map f2 launch_tab emacs
|
||||
|
||||
The :kbd:`F1` key will now open vim in a new tab with the current windows
|
||||
working directory
|
||||
|
||||
|
||||
The piping environment
|
||||
--------------------------
|
||||
|
||||
|
||||
@ -58,6 +58,12 @@ some special variables, documented below:
|
||||
``FRAGMENT``
|
||||
The fragment (unquoted), if any of the URL or the empty string.
|
||||
|
||||
|
||||
.. note::
|
||||
You can use the :opt:`action_alias` option just as in kitty.conf to
|
||||
define aliases for frequently used actions.
|
||||
|
||||
|
||||
.. _matching_criteria:
|
||||
|
||||
Matching criteria
|
||||
|
||||
@ -46,7 +46,7 @@ from .keys import get_shortcut, shortcut_matches
|
||||
from .layout.base import set_layout_options
|
||||
from .notify import notification_activated
|
||||
from .options.types import Options
|
||||
from .options.utils import MINIMUM_FONT_SIZE, SubSequenceMap
|
||||
from .options.utils import MINIMUM_FONT_SIZE, KeyMap, SubSequenceMap
|
||||
from .os_window_size import initial_window_size_func
|
||||
from .rgb import color_from_int
|
||||
from .session import Session, create_sessions, get_os_window_sizing_data
|
||||
@ -62,7 +62,7 @@ from .utils import (
|
||||
remove_socket_file, safe_print, set_primary_selection, single_instance,
|
||||
startup_notification_handler
|
||||
)
|
||||
from .window import MatchPatternType, Window, CommandOutput
|
||||
from .window import CommandOutput, MatchPatternType, Window
|
||||
|
||||
|
||||
class OSWindowDict(TypedDict):
|
||||
@ -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: Optional[KeyAction] = None
|
||||
self.default_pending_action: Tuple[KeyAction, ...] = ()
|
||||
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 = {v: KeyAction(k) for k, v in global_shortcuts.items()}
|
||||
self.global_shortcuts_map: KeyMap = {v: (KeyAction(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: Optional[KeyAction] = None) -> None:
|
||||
def set_pending_sequences(self, sequences: SubSequenceMap, default_pending_action: Tuple[KeyAction, ...] = ()) -> None:
|
||||
self.pending_sequences = sequences
|
||||
self.default_pending_action = default_pending_action
|
||||
set_in_sequence_mode(True)
|
||||
@ -905,17 +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, KeyAction):
|
||||
if sequences and not isinstance(sequences, tuple):
|
||||
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, KeyAction):
|
||||
return self.dispatch_action(key_action)
|
||||
elif isinstance(key_action, tuple):
|
||||
return self.combine(key_action)
|
||||
return False
|
||||
|
||||
def clear_pending_sequences(self) -> None:
|
||||
self.pending_sequences = self.default_pending_action = None
|
||||
self.pending_sequences = None
|
||||
self.default_pending_action = ()
|
||||
set_in_sequence_mode(False)
|
||||
|
||||
def process_sequence(self, ev: KeyEvent) -> None:
|
||||
@ -939,7 +940,7 @@ class Boss:
|
||||
matched_action = matched_action or self.default_pending_action
|
||||
self.clear_pending_sequences()
|
||||
if matched_action is not None:
|
||||
self.dispatch_action(matched_action)
|
||||
self.combine(matched_action)
|
||||
|
||||
def cancel_current_visual_select(self) -> None:
|
||||
if self.current_visual_select:
|
||||
@ -982,11 +983,11 @@ class Boss:
|
||||
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=(KeyAction('visual_window_select_action_trigger', (0,)),))
|
||||
redirect_mouse_handling(True)
|
||||
self.mouse_handler = self.visual_window_select_mouse_handler
|
||||
else:
|
||||
@ -1130,9 +1131,12 @@ class Boss:
|
||||
|
||||
map kitty_mod+e combine : new_window : next_layout
|
||||
''')
|
||||
def combine(self, *actions: KeyAction) -> None:
|
||||
def combine(self, actions: Tuple[KeyAction, ...], window_for_dispatch: Optional[Window] = None, dispatch_type: str = 'KeyPress') -> bool:
|
||||
consumed = False
|
||||
for key_action in actions:
|
||||
self.dispatch_action(key_action)
|
||||
if self.dispatch_action(key_action, window_for_dispatch, dispatch_type):
|
||||
consumed = True
|
||||
return consumed
|
||||
|
||||
def on_focus(self, os_window_id: int, focused: bool) -> None:
|
||||
tm = self.os_window_map.get(os_window_id)
|
||||
@ -1363,10 +1367,7 @@ class Boss:
|
||||
return overlay_window
|
||||
|
||||
@ac('misc', 'Run the specified kitten. See :doc:`/kittens/custom` for details')
|
||||
def kitten(self, kitten: str, *args: str) -> None:
|
||||
import shlex
|
||||
cmdline = args[0] if args else ''
|
||||
kargs = shlex.split(cmdline) if cmdline else []
|
||||
def kitten(self, kitten: str, *kargs: str) -> None:
|
||||
self._run_kitten(kitten, kargs)
|
||||
|
||||
def run_kitten(self, kitten: str, *args: str) -> None:
|
||||
|
||||
@ -11,7 +11,8 @@ 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 (
|
||||
KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap
|
||||
ActionAlias, KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap,
|
||||
build_action_aliases
|
||||
)
|
||||
from .typing import TypedDict
|
||||
from .utils import log_error
|
||||
@ -21,9 +22,6 @@ def option_names_for_completion() -> Tuple[str, ...]:
|
||||
return option_names
|
||||
|
||||
|
||||
no_op_actions = frozenset({'noop', 'no-op', 'no_op'})
|
||||
|
||||
|
||||
def build_ansi_color_table(opts: Optional[Options] = None) -> int:
|
||||
if opts is None:
|
||||
opts = defaults
|
||||
@ -93,18 +91,18 @@ def prepare_config_file_for_editing() -> str:
|
||||
return defconf
|
||||
|
||||
|
||||
def finalize_keys(opts: Options) -> None:
|
||||
def finalize_keys(opts: Options, alias_map: Dict[str, ActionAlias]) -> None:
|
||||
defns: List[KeyDefinition] = []
|
||||
for d in opts.map:
|
||||
if d is None: # clear_all_shortcuts
|
||||
defns = [] # type: ignore
|
||||
else:
|
||||
defns.append(d.resolve_and_copy(opts.kitty_mod, opts.kitten_alias))
|
||||
defns.append(d.resolve_and_copy(opts.kitty_mod, alias_map))
|
||||
keymap: KeyMap = {}
|
||||
sequence_map: SequenceMap = {}
|
||||
|
||||
for defn in defns:
|
||||
is_no_op = defn.action.func in no_op_actions
|
||||
is_no_op = defn.is_no_op
|
||||
if defn.is_sequence:
|
||||
keymap.pop(defn.trigger, None)
|
||||
s = sequence_map.setdefault(defn.trigger, {})
|
||||
@ -113,32 +111,32 @@ def finalize_keys(opts: Options) -> None:
|
||||
if not s:
|
||||
del sequence_map[defn.trigger]
|
||||
else:
|
||||
s[defn.rest] = defn.action
|
||||
s[defn.rest] = defn.actions
|
||||
else:
|
||||
sequence_map.pop(defn.trigger, None)
|
||||
if is_no_op:
|
||||
keymap.pop(defn.trigger, None)
|
||||
else:
|
||||
keymap[defn.trigger] = defn.action
|
||||
keymap[defn.trigger] = defn.actions
|
||||
opts.keymap = keymap
|
||||
opts.sequence_map = sequence_map
|
||||
|
||||
|
||||
def finalize_mouse_mappings(opts: Options) -> None:
|
||||
def finalize_mouse_mappings(opts: Options, alias_map: Dict[str, ActionAlias]) -> None:
|
||||
defns: List[MouseMapping] = []
|
||||
for d in opts.mouse_map:
|
||||
if d is None: # clear_all_mouse_actions
|
||||
defns = [] # type: ignore
|
||||
else:
|
||||
defns.append(d.resolve_and_copy(opts.kitty_mod, opts.kitten_alias))
|
||||
defns.append(d.resolve_and_copy(opts.kitty_mod, alias_map))
|
||||
mousemap: MouseMap = {}
|
||||
|
||||
for defn in defns:
|
||||
is_no_op = defn.action.func in no_op_actions
|
||||
is_no_op = defn.is_no_op
|
||||
if is_no_op:
|
||||
mousemap.pop(defn.trigger, None)
|
||||
else:
|
||||
mousemap[defn.trigger] = defn.action
|
||||
mousemap[defn.trigger] = defn.actions
|
||||
opts.mousemap = mousemap
|
||||
|
||||
|
||||
@ -161,10 +159,13 @@ 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)
|
||||
|
||||
finalize_keys(opts)
|
||||
finalize_mouse_mappings(opts)
|
||||
alias_map = build_action_aliases(opts.kitten_alias, 'kitten')
|
||||
alias_map.update(build_action_aliases(opts.action_alias))
|
||||
finalize_keys(opts, alias_map)
|
||||
finalize_mouse_mappings(opts, alias_map)
|
||||
# delete no longer needed definitions, replacing with empty placeholders
|
||||
opts.kitten_alias = {}
|
||||
opts.action_alias = {}
|
||||
opts.mouse_map = []
|
||||
opts.map = []
|
||||
if opts.background_opacity < 1.0 and opts.macos_titlebar_color:
|
||||
|
||||
@ -27,7 +27,7 @@ from .rgb import color_as_sharp
|
||||
from .types import MouseEvent, SingleKey
|
||||
from .typing import SequenceMap
|
||||
|
||||
ShortcutMap = Dict[Tuple[SingleKey, ...], KeyAction]
|
||||
ShortcutMap = Dict[Tuple[SingleKey, ...], Tuple[KeyAction, ...]]
|
||||
|
||||
|
||||
def green(x: str) -> str:
|
||||
@ -54,7 +54,7 @@ def mod_to_names(mods: int) -> Generator[str, None, None]:
|
||||
yield name
|
||||
|
||||
|
||||
def print_shortcut(key_sequence: Iterable[SingleKey], action: KeyAction, print: Callable[..., None]) -> None:
|
||||
def print_shortcut(key_sequence: Iterable[SingleKey], actions: Iterable[KeyAction], print: Callable[..., None]) -> None:
|
||||
from .fast_data_types import glfw_get_key_name
|
||||
keys = []
|
||||
for key_spec in key_sequence:
|
||||
@ -66,6 +66,7 @@ def print_shortcut(key_sequence: Iterable[SingleKey], action: KeyAction, print:
|
||||
names.append(kname or f'{key}')
|
||||
keys.append('+'.join(names))
|
||||
|
||||
for action in actions:
|
||||
print('\t' + ' > '.join(keys), action)
|
||||
|
||||
|
||||
@ -87,7 +88,7 @@ def compare_keymaps(final: ShortcutMap, initial: ShortcutMap, print: Callable[..
|
||||
|
||||
|
||||
def flatten_sequence_map(m: SequenceMap) -> ShortcutMap:
|
||||
ans: Dict[Tuple[SingleKey, ...], KeyAction] = {}
|
||||
ans = {}
|
||||
for key_spec, rest_map in m.items():
|
||||
for r, action in rest_map.items():
|
||||
ans[(key_spec,) + (r)] = action
|
||||
@ -99,10 +100,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, action: KeyAction) -> None:
|
||||
def print_mouse_action(trigger: MouseEvent, actions: Tuple[KeyAction, ...]) -> 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)
|
||||
|
||||
def print_changes(defns: MouseMap, changes: Set[MouseEvent], text: str) -> None:
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from typing import Optional, Union
|
||||
from typing import Optional, Union, Tuple
|
||||
|
||||
from .conf.utils import KeyAction
|
||||
from .fast_data_types import (
|
||||
@ -22,7 +22,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[KeyAction, SubSequenceMap]]:
|
||||
def get_shortcut(keymap: Union[KeyMap, SequenceMap], ev: KeyEvent) -> Optional[Union[Tuple[KeyAction, ...], SubSequenceMap]]:
|
||||
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:
|
||||
|
||||
@ -112,7 +112,9 @@ def get_macos_shortcut_for(opts: Options, function: str = 'new_os_window', args:
|
||||
ans = None
|
||||
candidates = []
|
||||
for k, v in opts.keymap.items():
|
||||
if v.func == function and v.args == args:
|
||||
if len(v) == 1:
|
||||
q = v[0]
|
||||
if q.func == function and q.args == args:
|
||||
candidates.append(k)
|
||||
if candidates:
|
||||
from .fast_data_types import cocoa_set_global_shortcut
|
||||
|
||||
@ -6,14 +6,16 @@ import os
|
||||
import posixpath
|
||||
from contextlib import suppress
|
||||
from typing import (
|
||||
Any, Generator, Iterable, List, NamedTuple, Optional, Tuple, cast
|
||||
Any, Dict, Iterable, Iterator, List, NamedTuple, Optional, Tuple, cast
|
||||
)
|
||||
from urllib.parse import ParseResult, unquote, urlparse
|
||||
|
||||
from .conf.utils import KeyAction, to_cmdline_implementation
|
||||
from .constants import config_dir
|
||||
from .guess_mime_type import guess_type
|
||||
from .options.utils import parse_key_action
|
||||
from .options.utils import (
|
||||
ActionAlias, action_alias, parse_key_actions, resolve_aliases_in_action
|
||||
)
|
||||
from .types import run_once
|
||||
from .typing import MatchType
|
||||
from .utils import expandvars, log_error
|
||||
@ -29,9 +31,11 @@ class OpenAction(NamedTuple):
|
||||
actions: Tuple[KeyAction, ...]
|
||||
|
||||
|
||||
def parse(lines: Iterable[str]) -> Generator[OpenAction, None, None]:
|
||||
def parse(lines: Iterable[str]) -> Iterator[OpenAction]:
|
||||
match_criteria: List[MatchCriteria] = []
|
||||
actions: List[KeyAction] = []
|
||||
alias_map: Dict[str, ActionAlias] = {}
|
||||
entries = []
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
@ -39,7 +43,7 @@ def parse(lines: Iterable[str]) -> Generator[OpenAction, None, None]:
|
||||
continue
|
||||
if not line:
|
||||
if match_criteria and actions:
|
||||
yield OpenAction(tuple(match_criteria), tuple(actions))
|
||||
entries.append((tuple(match_criteria), tuple(actions)))
|
||||
match_criteria = []
|
||||
actions = []
|
||||
continue
|
||||
@ -50,18 +54,22 @@ def parse(lines: Iterable[str]) -> Generator[OpenAction, None, None]:
|
||||
key = key.lower()
|
||||
if key == 'action':
|
||||
with to_cmdline_implementation.filter_env_vars('URL', 'FILE_PATH', 'FILE', 'FRAGMENT'):
|
||||
x = parse_key_action(rest)
|
||||
if x is not None:
|
||||
for x in parse_key_actions(rest):
|
||||
actions.append(x)
|
||||
elif key in ('mime', 'ext', 'protocol', 'file', 'path', 'url', 'fragment_matches'):
|
||||
if key != 'url':
|
||||
rest = rest.lower()
|
||||
match_criteria.append(MatchCriteria(cast(MatchType, key), rest))
|
||||
elif key == 'action_alias':
|
||||
for (alias_name, args) in action_alias(rest):
|
||||
alias_map[alias_name] = ActionAlias(args[0], args=tuple(args[1:]))
|
||||
else:
|
||||
log_error(f'Ignoring malformed open actions line: {line}')
|
||||
|
||||
for (mc, ac) in entries:
|
||||
yield OpenAction(mc, tuple(resolve_aliases_in_action(a, alias_map) for a in ac))
|
||||
if match_criteria and actions:
|
||||
yield OpenAction(tuple(match_criteria), tuple(actions))
|
||||
yield OpenAction(tuple(match_criteria), tuple(resolve_aliases_in_action(a, alias_map) for a in actions))
|
||||
|
||||
|
||||
def url_matches_criterion(purl: 'ParseResult', url: str, unquoted_path: str, mc: MatchCriteria) -> bool:
|
||||
@ -142,7 +150,7 @@ def url_matches_criteria(purl: 'ParseResult', url: str, unquoted_path: str, crit
|
||||
return True
|
||||
|
||||
|
||||
def actions_for_url_from_list(url: str, actions: Iterable[OpenAction]) -> Generator[KeyAction, None, None]:
|
||||
def actions_for_url_from_list(url: str, actions: Iterable[OpenAction]) -> Iterator[KeyAction]:
|
||||
try:
|
||||
purl = urlparse(url)
|
||||
except Exception:
|
||||
@ -184,7 +192,7 @@ def load_open_actions() -> Tuple[OpenAction, ...]:
|
||||
return tuple(parse(f))
|
||||
|
||||
|
||||
def actions_for_url(url: str, actions_spec: Optional[str] = None) -> Generator[KeyAction, None, None]:
|
||||
def actions_for_url(url: str, actions_spec: Optional[str] = None) -> Iterator[KeyAction]:
|
||||
if actions_spec is None:
|
||||
actions = load_open_actions()
|
||||
else:
|
||||
|
||||
@ -2870,15 +2870,23 @@ for instance, to remove the default shortcuts.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('+action_alias', 'launch_tab launch --type=tab --cwd=current',
|
||||
option_type='action_alias',
|
||||
add_to_default=False,
|
||||
long_text='''
|
||||
Define aliases to avoid repeating the same options in multiple mappings. Aliases
|
||||
can be defined for the :ref:`launch <action-launch>`, :ref:`kitten <action-kitten>`
|
||||
and :ref:`action-remote_control` actions. For example, the above alias allows you
|
||||
to create mappings to launch a new tab without duplication::
|
||||
|
||||
map f1 launch_tab vim
|
||||
map f2 launch_tab emacs
|
||||
''')
|
||||
|
||||
opt('+kitten_alias', 'hints hints --hints-offset=0',
|
||||
option_type='kitten_alias',
|
||||
add_to_default=False,
|
||||
long_text='''
|
||||
You can create aliases for kitten names, this allows overriding the defaults for
|
||||
kitten options and can also be used to shorten repeated mappings of the same
|
||||
kitten with a specific group of options. For example, the above alias changes
|
||||
the default value of :option:`kitty +kitten hints --hints-offset` to zero for
|
||||
all mappings, including the builtin ones.
|
||||
long_text='''Deprecated, use :opt:`action_alias` instead.
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
13
kitty/options/parse.py
generated
13
kitty/options/parse.py
generated
@ -6,13 +6,13 @@ from kitty.conf.utils import (
|
||||
unit_float
|
||||
)
|
||||
from kitty.options.utils import (
|
||||
active_tab_title_template, adjust_baseline, adjust_line_height, allow_hyperlinks,
|
||||
action_alias, active_tab_title_template, adjust_baseline, adjust_line_height, allow_hyperlinks,
|
||||
allow_remote_control, box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts,
|
||||
clipboard_control, config_or_absolute_path, copy_on_select, cursor_text_color,
|
||||
deprecated_hide_window_decorations_aliases, deprecated_macos_show_window_title_in_menubar_alias,
|
||||
deprecated_send_text, disable_ligatures, edge_width, env, font_features, hide_window_decorations,
|
||||
kitten_alias, macos_option_as_alt, macos_titlebar_color, optional_edge_width, parse_map,
|
||||
parse_mouse_map, resize_draw_strategy, scrollback_lines, scrollback_pager_history_size, symbol_map,
|
||||
macos_option_as_alt, macos_titlebar_color, optional_edge_width, parse_map, parse_mouse_map,
|
||||
resize_draw_strategy, scrollback_lines, scrollback_pager_history_size, symbol_map,
|
||||
tab_activity_symbol, tab_bar_edge, tab_bar_margin_height, tab_bar_min_tabs, tab_fade,
|
||||
tab_font_style, tab_separator, tab_title_template, to_cursor_shape, to_font_size, to_layout_names,
|
||||
to_modifiers, url_prefixes, url_style, visual_window_select_characters, watcher,
|
||||
@ -22,6 +22,10 @@ from kitty.options.utils import (
|
||||
|
||||
class Parser:
|
||||
|
||||
def action_alias(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
for k, v in action_alias(val):
|
||||
ans["action_alias"][k] = v
|
||||
|
||||
def active_border_color(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['active_border_color'] = to_color_or_none(val)
|
||||
|
||||
@ -1006,7 +1010,7 @@ class Parser:
|
||||
ans['italic_font'] = str(val)
|
||||
|
||||
def kitten_alias(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
for k, v in kitten_alias(val):
|
||||
for k, v in action_alias(val):
|
||||
ans["kitten_alias"][k] = v
|
||||
|
||||
def kitty_mod(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
@ -1309,6 +1313,7 @@ class Parser:
|
||||
|
||||
def create_result_dict() -> typing.Dict[str, typing.Any]:
|
||||
return {
|
||||
'action_alias': {},
|
||||
'env': {},
|
||||
'font_features': {},
|
||||
'kitten_alias': {},
|
||||
|
||||
289
kitty/options/types.py
generated
289
kitty/options/types.py
generated
@ -43,6 +43,7 @@ else:
|
||||
choices_for_tab_switch_strategy = str
|
||||
|
||||
option_names = ( # {{{
|
||||
'action_alias',
|
||||
'active_border_color',
|
||||
'active_tab_background',
|
||||
'active_tab_font_style',
|
||||
@ -583,6 +584,7 @@ class Options:
|
||||
window_padding_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0)
|
||||
window_resize_step_cells: int = 2
|
||||
window_resize_step_lines: int = 2
|
||||
action_alias: typing.Dict[str, typing.List[str]] = {}
|
||||
env: typing.Dict[str, str] = {}
|
||||
font_features: typing.Dict[str, typing.Tuple[kitty.fonts.FontFeature, ...]] = {}
|
||||
kitten_alias: typing.Dict[str, typing.List[str]] = {}
|
||||
@ -698,6 +700,7 @@ class Options:
|
||||
|
||||
|
||||
defaults = Options()
|
||||
defaults.action_alias = {}
|
||||
defaults.env = {}
|
||||
defaults.font_features = {}
|
||||
defaults.kitten_alias = {}
|
||||
@ -705,252 +708,252 @@ defaults.symbol_map = {}
|
||||
defaults.watcher = {}
|
||||
defaults.map = [
|
||||
# copy_to_clipboard
|
||||
KeyDefinition(False, KeyAction('copy_to_clipboard'), 1024, False, 99, ()),
|
||||
KeyDefinition(False, (KeyAction('copy_to_clipboard'),), 1024, False, 99, ()),
|
||||
# paste_from_clipboard
|
||||
KeyDefinition(False, KeyAction('paste_from_clipboard'), 1024, False, 118, ()),
|
||||
KeyDefinition(False, (KeyAction('paste_from_clipboard'),), 1024, False, 118, ()),
|
||||
# paste_from_selection
|
||||
KeyDefinition(False, KeyAction('paste_from_selection'), 1024, False, 115, ()),
|
||||
KeyDefinition(False, (KeyAction('paste_from_selection'),), 1024, False, 115, ()),
|
||||
# paste_from_selection
|
||||
KeyDefinition(False, KeyAction('paste_from_selection'), 1, False, 57348, ()),
|
||||
KeyDefinition(False, (KeyAction('paste_from_selection'),), 1, False, 57348, ()),
|
||||
# pass_selection_to_program
|
||||
KeyDefinition(False, KeyAction('pass_selection_to_program'), 1024, False, 111, ()),
|
||||
KeyDefinition(False, (KeyAction('pass_selection_to_program'),), 1024, False, 111, ()),
|
||||
# scroll_line_up
|
||||
KeyDefinition(False, KeyAction('scroll_line_up'), 1024, False, 57352, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_line_up'),), 1024, False, 57352, ()),
|
||||
# scroll_line_up
|
||||
KeyDefinition(False, KeyAction('scroll_line_up'), 1024, False, 107, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_line_up'),), 1024, False, 107, ()),
|
||||
# scroll_line_down
|
||||
KeyDefinition(False, KeyAction('scroll_line_down'), 1024, False, 57353, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_line_down'),), 1024, False, 57353, ()),
|
||||
# scroll_line_down
|
||||
KeyDefinition(False, KeyAction('scroll_line_down'), 1024, False, 106, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_line_down'),), 1024, False, 106, ()),
|
||||
# scroll_page_up
|
||||
KeyDefinition(False, KeyAction('scroll_page_up'), 1024, False, 57354, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_page_up'),), 1024, False, 57354, ()),
|
||||
# scroll_page_down
|
||||
KeyDefinition(False, KeyAction('scroll_page_down'), 1024, False, 57355, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_page_down'),), 1024, False, 57355, ()),
|
||||
# scroll_home
|
||||
KeyDefinition(False, KeyAction('scroll_home'), 1024, False, 57356, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_home'),), 1024, False, 57356, ()),
|
||||
# scroll_end
|
||||
KeyDefinition(False, KeyAction('scroll_end'), 1024, False, 57357, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_end'),), 1024, False, 57357, ()),
|
||||
# scroll_to_previous_prompt
|
||||
KeyDefinition(False, KeyAction('scroll_to_prompt', (-1,)), 1024, False, 122, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_to_prompt', (-1,)),), 1024, False, 122, ()),
|
||||
# scroll_to_next_prompt
|
||||
KeyDefinition(False, KeyAction('scroll_to_prompt', (1,)), 1024, False, 120, ()),
|
||||
KeyDefinition(False, (KeyAction('scroll_to_prompt', (1,)),), 1024, False, 120, ()),
|
||||
# show_scrollback
|
||||
KeyDefinition(False, KeyAction('show_scrollback'), 1024, False, 104, ()),
|
||||
KeyDefinition(False, (KeyAction('show_scrollback'),), 1024, False, 104, ()),
|
||||
# show_last_command_output
|
||||
KeyDefinition(False, KeyAction('show_last_command_output'), 1024, False, 103, ()),
|
||||
KeyDefinition(False, (KeyAction('show_last_command_output'),), 1024, False, 103, ()),
|
||||
# new_window
|
||||
KeyDefinition(False, KeyAction('new_window'), 1024, False, 57345, ()),
|
||||
KeyDefinition(False, (KeyAction('new_window'),), 1024, False, 57345, ()),
|
||||
# new_os_window
|
||||
KeyDefinition(False, KeyAction('new_os_window'), 1024, False, 110, ()),
|
||||
KeyDefinition(False, (KeyAction('new_os_window'),), 1024, False, 110, ()),
|
||||
# close_window
|
||||
KeyDefinition(False, KeyAction('close_window'), 1024, False, 119, ()),
|
||||
KeyDefinition(False, (KeyAction('close_window'),), 1024, False, 119, ()),
|
||||
# next_window
|
||||
KeyDefinition(False, KeyAction('next_window'), 1024, False, 93, ()),
|
||||
KeyDefinition(False, (KeyAction('next_window'),), 1024, False, 93, ()),
|
||||
# previous_window
|
||||
KeyDefinition(False, KeyAction('previous_window'), 1024, False, 91, ()),
|
||||
KeyDefinition(False, (KeyAction('previous_window'),), 1024, False, 91, ()),
|
||||
# move_window_forward
|
||||
KeyDefinition(False, KeyAction('move_window_forward'), 1024, False, 102, ()),
|
||||
KeyDefinition(False, (KeyAction('move_window_forward'),), 1024, False, 102, ()),
|
||||
# move_window_backward
|
||||
KeyDefinition(False, KeyAction('move_window_backward'), 1024, False, 98, ()),
|
||||
KeyDefinition(False, (KeyAction('move_window_backward'),), 1024, False, 98, ()),
|
||||
# move_window_to_top
|
||||
KeyDefinition(False, KeyAction('move_window_to_top'), 1024, False, 96, ()),
|
||||
KeyDefinition(False, (KeyAction('move_window_to_top'),), 1024, False, 96, ()),
|
||||
# start_resizing_window
|
||||
KeyDefinition(False, KeyAction('start_resizing_window'), 1024, False, 114, ()),
|
||||
KeyDefinition(False, (KeyAction('start_resizing_window'),), 1024, False, 114, ()),
|
||||
# first_window
|
||||
KeyDefinition(False, KeyAction('first_window'), 1024, False, 49, ()),
|
||||
KeyDefinition(False, (KeyAction('first_window'),), 1024, False, 49, ()),
|
||||
# second_window
|
||||
KeyDefinition(False, KeyAction('second_window'), 1024, False, 50, ()),
|
||||
KeyDefinition(False, (KeyAction('second_window'),), 1024, False, 50, ()),
|
||||
# third_window
|
||||
KeyDefinition(False, KeyAction('third_window'), 1024, False, 51, ()),
|
||||
KeyDefinition(False, (KeyAction('third_window'),), 1024, False, 51, ()),
|
||||
# fourth_window
|
||||
KeyDefinition(False, KeyAction('fourth_window'), 1024, False, 52, ()),
|
||||
KeyDefinition(False, (KeyAction('fourth_window'),), 1024, False, 52, ()),
|
||||
# fifth_window
|
||||
KeyDefinition(False, KeyAction('fifth_window'), 1024, False, 53, ()),
|
||||
KeyDefinition(False, (KeyAction('fifth_window'),), 1024, False, 53, ()),
|
||||
# sixth_window
|
||||
KeyDefinition(False, KeyAction('sixth_window'), 1024, False, 54, ()),
|
||||
KeyDefinition(False, (KeyAction('sixth_window'),), 1024, False, 54, ()),
|
||||
# seventh_window
|
||||
KeyDefinition(False, KeyAction('seventh_window'), 1024, False, 55, ()),
|
||||
KeyDefinition(False, (KeyAction('seventh_window'),), 1024, False, 55, ()),
|
||||
# eighth_window
|
||||
KeyDefinition(False, KeyAction('eighth_window'), 1024, False, 56, ()),
|
||||
KeyDefinition(False, (KeyAction('eighth_window'),), 1024, False, 56, ()),
|
||||
# ninth_window
|
||||
KeyDefinition(False, KeyAction('ninth_window'), 1024, False, 57, ()),
|
||||
KeyDefinition(False, (KeyAction('ninth_window'),), 1024, False, 57, ()),
|
||||
# tenth_window
|
||||
KeyDefinition(False, KeyAction('tenth_window'), 1024, False, 48, ()),
|
||||
KeyDefinition(False, (KeyAction('tenth_window'),), 1024, False, 48, ()),
|
||||
# focus_visible_window
|
||||
KeyDefinition(False, KeyAction('focus_visible_window'), 1024, False, 57370, ()),
|
||||
KeyDefinition(False, (KeyAction('focus_visible_window'),), 1024, False, 57370, ()),
|
||||
# swap_with_window
|
||||
KeyDefinition(False, KeyAction('swap_with_window'), 1024, False, 57371, ()),
|
||||
KeyDefinition(False, (KeyAction('swap_with_window'),), 1024, False, 57371, ()),
|
||||
# next_tab
|
||||
KeyDefinition(False, KeyAction('next_tab'), 1024, False, 57351, ()),
|
||||
KeyDefinition(False, (KeyAction('next_tab'),), 1024, False, 57351, ()),
|
||||
# next_tab
|
||||
KeyDefinition(False, KeyAction('next_tab'), 4, False, 57346, ()),
|
||||
KeyDefinition(False, (KeyAction('next_tab'),), 4, False, 57346, ()),
|
||||
# previous_tab
|
||||
KeyDefinition(False, KeyAction('previous_tab'), 1024, False, 57350, ()),
|
||||
KeyDefinition(False, (KeyAction('previous_tab'),), 1024, False, 57350, ()),
|
||||
# previous_tab
|
||||
KeyDefinition(False, KeyAction('previous_tab'), 5, False, 57346, ()),
|
||||
KeyDefinition(False, (KeyAction('previous_tab'),), 5, False, 57346, ()),
|
||||
# new_tab
|
||||
KeyDefinition(False, KeyAction('new_tab'), 1024, False, 116, ()),
|
||||
KeyDefinition(False, (KeyAction('new_tab'),), 1024, False, 116, ()),
|
||||
# close_tab
|
||||
KeyDefinition(False, KeyAction('close_tab'), 1024, False, 113, ()),
|
||||
KeyDefinition(False, (KeyAction('close_tab'),), 1024, False, 113, ()),
|
||||
# move_tab_forward
|
||||
KeyDefinition(False, KeyAction('move_tab_forward'), 1024, False, 46, ()),
|
||||
KeyDefinition(False, (KeyAction('move_tab_forward'),), 1024, False, 46, ()),
|
||||
# move_tab_backward
|
||||
KeyDefinition(False, KeyAction('move_tab_backward'), 1024, False, 44, ()),
|
||||
KeyDefinition(False, (KeyAction('move_tab_backward'),), 1024, False, 44, ()),
|
||||
# set_tab_title
|
||||
KeyDefinition(False, KeyAction('set_tab_title'), 1026, False, 116, ()),
|
||||
KeyDefinition(False, (KeyAction('set_tab_title'),), 1026, False, 116, ()),
|
||||
# next_layout
|
||||
KeyDefinition(False, KeyAction('next_layout'), 1024, False, 108, ()),
|
||||
KeyDefinition(False, (KeyAction('next_layout'),), 1024, False, 108, ()),
|
||||
# increase_font_size
|
||||
KeyDefinition(False, KeyAction('change_font_size', (True, '+', 2.0)), 1024, False, 61, ()),
|
||||
KeyDefinition(False, (KeyAction('change_font_size', (True, '+', 2.0)),), 1024, False, 61, ()),
|
||||
# increase_font_size
|
||||
KeyDefinition(False, KeyAction('change_font_size', (True, '+', 2.0)), 1024, False, 43, ()),
|
||||
KeyDefinition(False, (KeyAction('change_font_size', (True, '+', 2.0)),), 1024, False, 43, ()),
|
||||
# increase_font_size
|
||||
KeyDefinition(False, KeyAction('change_font_size', (True, '+', 2.0)), 1024, False, 57413, ()),
|
||||
KeyDefinition(False, (KeyAction('change_font_size', (True, '+', 2.0)),), 1024, False, 57413, ()),
|
||||
# decrease_font_size
|
||||
KeyDefinition(False, KeyAction('change_font_size', (True, '-', 2.0)), 1024, False, 45, ()),
|
||||
KeyDefinition(False, (KeyAction('change_font_size', (True, '-', 2.0)),), 1024, False, 45, ()),
|
||||
# decrease_font_size
|
||||
KeyDefinition(False, KeyAction('change_font_size', (True, '-', 2.0)), 1024, False, 57412, ()),
|
||||
KeyDefinition(False, (KeyAction('change_font_size', (True, '-', 2.0)),), 1024, False, 57412, ()),
|
||||
# reset_font_size
|
||||
KeyDefinition(False, KeyAction('change_font_size', (True, None, 0.0)), 1024, False, 57347, ()),
|
||||
KeyDefinition(False, (KeyAction('change_font_size', (True, None, 0.0)),), 1024, False, 57347, ()),
|
||||
# open_url
|
||||
KeyDefinition(False, KeyAction('open_url_with_hints'), 1024, False, 101, ()),
|
||||
KeyDefinition(False, (KeyAction('open_url_with_hints'),), 1024, False, 101, ()),
|
||||
# insert_selected_path
|
||||
KeyDefinition(True, KeyAction('kitten', ('hints', '--type path --program -')), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=102),)),
|
||||
KeyDefinition(True, (KeyAction('kitten', ('hints', '--type', 'path', '--program', '-')),), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=102),)),
|
||||
# open_selected_path
|
||||
KeyDefinition(True, KeyAction('kitten', ('hints', '--type path')), 1024, False, 112, (SingleKey(mods=1, is_native=False, key=102),)),
|
||||
KeyDefinition(True, (KeyAction('kitten', ('hints', '--type', 'path')),), 1024, False, 112, (SingleKey(mods=1, is_native=False, key=102),)),
|
||||
# insert_selected_line
|
||||
KeyDefinition(True, KeyAction('kitten', ('hints', '--type line --program -')), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=108),)),
|
||||
KeyDefinition(True, (KeyAction('kitten', ('hints', '--type', 'line', '--program', '-')),), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=108),)),
|
||||
# insert_selected_word
|
||||
KeyDefinition(True, KeyAction('kitten', ('hints', '--type word --program -')), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=119),)),
|
||||
KeyDefinition(True, (KeyAction('kitten', ('hints', '--type', 'word', '--program', '-')),), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=119),)),
|
||||
# insert_selected_hash
|
||||
KeyDefinition(True, KeyAction('kitten', ('hints', '--type hash --program -')), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=104),)),
|
||||
KeyDefinition(True, (KeyAction('kitten', ('hints', '--type', 'hash', '--program', '-')),), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=104),)),
|
||||
# goto_file_line
|
||||
KeyDefinition(True, KeyAction('kitten', ('hints', '--type linenum')), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=110),)),
|
||||
KeyDefinition(True, (KeyAction('kitten', ('hints', '--type', 'linenum')),), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=110),)),
|
||||
# open_selected_hyperlink
|
||||
KeyDefinition(True, KeyAction('kitten', ('hints', '--type hyperlink')), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=121),)),
|
||||
KeyDefinition(True, (KeyAction('kitten', ('hints', '--type', 'hyperlink')),), 1024, False, 112, (SingleKey(mods=0, is_native=False, key=121),)),
|
||||
# toggle_fullscreen
|
||||
KeyDefinition(False, KeyAction('toggle_fullscreen'), 1024, False, 57374, ()),
|
||||
KeyDefinition(False, (KeyAction('toggle_fullscreen'),), 1024, False, 57374, ()),
|
||||
# toggle_maximized
|
||||
KeyDefinition(False, KeyAction('toggle_maximized'), 1024, False, 57373, ()),
|
||||
KeyDefinition(False, (KeyAction('toggle_maximized'),), 1024, False, 57373, ()),
|
||||
# input_unicode_character
|
||||
KeyDefinition(False, KeyAction('kitten', ('unicode_input',)), 1024, False, 117, ()),
|
||||
KeyDefinition(False, (KeyAction('kitten', ('unicode_input',)),), 1024, False, 117, ()),
|
||||
# edit_config_file
|
||||
KeyDefinition(False, KeyAction('edit_config_file'), 1024, False, 57365, ()),
|
||||
KeyDefinition(False, (KeyAction('edit_config_file'),), 1024, False, 57365, ()),
|
||||
# kitty_shell
|
||||
KeyDefinition(False, KeyAction('kitty_shell', ('window',)), 1024, False, 57344, ()),
|
||||
KeyDefinition(False, (KeyAction('kitty_shell', ('window',)),), 1024, False, 57344, ()),
|
||||
# increase_background_opacity
|
||||
KeyDefinition(True, KeyAction('set_background_opacity', ('+0.1',)), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=109),)),
|
||||
KeyDefinition(True, (KeyAction('set_background_opacity', ('+0.1',)),), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=109),)),
|
||||
# decrease_background_opacity
|
||||
KeyDefinition(True, KeyAction('set_background_opacity', ('-0.1',)), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=108),)),
|
||||
KeyDefinition(True, (KeyAction('set_background_opacity', ('-0.1',)),), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=108),)),
|
||||
# full_background_opacity
|
||||
KeyDefinition(True, KeyAction('set_background_opacity', ('1',)), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=49),)),
|
||||
KeyDefinition(True, (KeyAction('set_background_opacity', ('1',)),), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=49),)),
|
||||
# reset_background_opacity
|
||||
KeyDefinition(True, KeyAction('set_background_opacity', ('default',)), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=100),)),
|
||||
KeyDefinition(True, (KeyAction('set_background_opacity', ('default',)),), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=100),)),
|
||||
# reset_terminal
|
||||
KeyDefinition(False, KeyAction('clear_terminal', ('reset', True)), 1024, False, 57349, ()),
|
||||
KeyDefinition(False, (KeyAction('clear_terminal', ('reset', True)),), 1024, False, 57349, ()),
|
||||
# reload_config_file
|
||||
KeyDefinition(False, KeyAction('load_config_file'), 1024, False, 57368, ()),
|
||||
KeyDefinition(False, (KeyAction('load_config_file'),), 1024, False, 57368, ()),
|
||||
# debug_config
|
||||
KeyDefinition(False, KeyAction('debug_config'), 1024, False, 57369, ()),
|
||||
KeyDefinition(False, (KeyAction('debug_config'),), 1024, False, 57369, ()),
|
||||
]
|
||||
if is_macos:
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('copy_to_clipboard'), 8, False, 99, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('paste_from_clipboard'), 8, False, 118, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_line_up'), 10, False, 57354, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_line_up'), 8, False, 57352, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_line_down'), 10, False, 57355, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_line_down'), 8, False, 57353, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_page_up'), 8, False, 57354, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_page_down'), 8, False, 57355, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_home'), 8, False, 57356, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('scroll_end'), 8, False, 57357, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('new_window'), 8, False, 57345, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('new_os_window'), 8, False, 110, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('close_window'), 9, False, 100, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('start_resizing_window'), 8, False, 114, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('first_window'), 8, False, 49, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('second_window'), 8, False, 50, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('third_window'), 8, False, 51, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('fourth_window'), 8, False, 52, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('fifth_window'), 8, False, 53, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('sixth_window'), 8, False, 54, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('seventh_window'), 8, False, 55, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('eighth_window'), 8, False, 56, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('ninth_window'), 8, False, 57, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('next_tab'), 9, False, 93, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('previous_tab'), 9, False, 91, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('new_tab'), 8, False, 116, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('close_tab'), 8, False, 119, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('close_os_window'), 9, False, 119, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('set_tab_title'), 9, False, 105, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('change_font_size', (True, '+', 2.0)), 8, False, 43, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('change_font_size', (True, '+', 2.0)), 8, False, 61, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('change_font_size', (True, '+', 2.0)), 9, False, 61, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('change_font_size', (True, '-', 2.0)), 8, False, 45, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('change_font_size', (True, '-', 2.0)), 9, False, 45, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('change_font_size', (True, None, 0.0)), 8, False, 48, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('kitten', ('unicode_input',)), 12, False, 32, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('edit_config_file'), 8, False, 44, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('clear_terminal', ('reset', True)), 10, False, 114, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('load_config_file'), 12, False, 44, ()))
|
||||
defaults.map.append(KeyDefinition(False, KeyAction('debug_config'), 10, False, 44, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('copy_to_clipboard'),), 8, False, 99, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('paste_from_clipboard'),), 8, False, 118, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_line_up'),), 10, False, 57354, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_line_up'),), 8, False, 57352, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_line_down'),), 10, False, 57355, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_line_down'),), 8, False, 57353, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_page_up'),), 8, False, 57354, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_page_down'),), 8, False, 57355, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_home'),), 8, False, 57356, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('scroll_end'),), 8, False, 57357, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('new_window'),), 8, False, 57345, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('new_os_window'),), 8, False, 110, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('close_window'),), 9, False, 100, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('start_resizing_window'),), 8, False, 114, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('first_window'),), 8, False, 49, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('second_window'),), 8, False, 50, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('third_window'),), 8, False, 51, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('fourth_window'),), 8, False, 52, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('fifth_window'),), 8, False, 53, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('sixth_window'),), 8, False, 54, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('seventh_window'),), 8, False, 55, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('eighth_window'),), 8, False, 56, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('ninth_window'),), 8, False, 57, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('next_tab'),), 9, False, 93, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('previous_tab'),), 9, False, 91, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('new_tab'),), 8, False, 116, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('close_tab'),), 8, False, 119, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('close_os_window'),), 9, False, 119, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('set_tab_title'),), 9, False, 105, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('change_font_size', (True, '+', 2.0)),), 8, False, 43, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('change_font_size', (True, '+', 2.0)),), 8, False, 61, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('change_font_size', (True, '+', 2.0)),), 9, False, 61, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('change_font_size', (True, '-', 2.0)),), 8, False, 45, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('change_font_size', (True, '-', 2.0)),), 9, False, 45, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('change_font_size', (True, None, 0.0)),), 8, False, 48, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('kitten', ('unicode_input',)),), 12, False, 32, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('edit_config_file'),), 8, False, 44, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('clear_terminal', ('reset', True)),), 10, False, 114, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('load_config_file'),), 12, False, 44, ()))
|
||||
defaults.map.append(KeyDefinition(False, (KeyAction('debug_config'),), 10, False, 44, ()))
|
||||
defaults.mouse_map = [
|
||||
# click_url_or_select
|
||||
MouseMapping(0, 0, -2, False, KeyAction('mouse_handle_click', ('selection', 'link', 'prompt'))),
|
||||
MouseMapping(0, 0, -2, False, (KeyAction('mouse_handle_click', ('selection', 'link', 'prompt')),)),
|
||||
# click_url_or_select_grabbed
|
||||
MouseMapping(0, 1, -2, True, KeyAction('mouse_handle_click', ('selection', 'link', 'prompt'))),
|
||||
MouseMapping(0, 1, -2, True, (KeyAction('mouse_handle_click', ('selection', 'link', 'prompt')),)),
|
||||
# click_url_or_select_grabbed
|
||||
MouseMapping(0, 1, -2, False, KeyAction('mouse_handle_click', ('selection', 'link', 'prompt'))),
|
||||
MouseMapping(0, 1, -2, False, (KeyAction('mouse_handle_click', ('selection', 'link', 'prompt')),)),
|
||||
# click_url
|
||||
MouseMapping(0, 5, -1, True, KeyAction('mouse_handle_click', ('link',))),
|
||||
MouseMapping(0, 5, -1, True, (KeyAction('mouse_handle_click', ('link',)),)),
|
||||
# click_url
|
||||
MouseMapping(0, 5, -1, False, KeyAction('mouse_handle_click', ('link',))),
|
||||
MouseMapping(0, 5, -1, False, (KeyAction('mouse_handle_click', ('link',)),)),
|
||||
# click_url_discard
|
||||
MouseMapping(0, 5, 1, True, KeyAction('discard_event')),
|
||||
MouseMapping(0, 5, 1, True, (KeyAction('discard_event'),)),
|
||||
# paste_selection
|
||||
MouseMapping(2, 0, -1, False, KeyAction('paste_from_selection')),
|
||||
MouseMapping(2, 0, -1, False, (KeyAction('paste_from_selection'),)),
|
||||
# start_simple_selection
|
||||
MouseMapping(0, 0, 1, False, KeyAction('mouse_selection', (0,))),
|
||||
MouseMapping(0, 0, 1, False, (KeyAction('mouse_selection', (0,)),)),
|
||||
# start_rectangle_selection
|
||||
MouseMapping(0, 6, 1, False, KeyAction('mouse_selection', (2,))),
|
||||
MouseMapping(0, 6, 1, False, (KeyAction('mouse_selection', (2,)),)),
|
||||
# select_word
|
||||
MouseMapping(0, 0, 2, False, KeyAction('mouse_selection', (3,))),
|
||||
MouseMapping(0, 0, 2, False, (KeyAction('mouse_selection', (3,)),)),
|
||||
# select_line
|
||||
MouseMapping(0, 0, 3, False, KeyAction('mouse_selection', (4,))),
|
||||
MouseMapping(0, 0, 3, False, (KeyAction('mouse_selection', (4,)),)),
|
||||
# select_line_from_point
|
||||
MouseMapping(0, 6, 3, False, KeyAction('mouse_selection', (5,))),
|
||||
MouseMapping(0, 6, 3, False, (KeyAction('mouse_selection', (5,)),)),
|
||||
# extend_selection
|
||||
MouseMapping(1, 0, 1, False, KeyAction('mouse_selection', (1,))),
|
||||
MouseMapping(1, 0, 1, False, (KeyAction('mouse_selection', (1,)),)),
|
||||
# paste_selection_grabbed
|
||||
MouseMapping(2, 1, -1, True, KeyAction('paste_selection')),
|
||||
MouseMapping(2, 1, -1, True, (KeyAction('paste_selection'),)),
|
||||
# paste_selection_grabbed
|
||||
MouseMapping(2, 1, -1, False, KeyAction('paste_selection')),
|
||||
MouseMapping(2, 1, -1, False, (KeyAction('paste_selection'),)),
|
||||
# paste_selection_grabbed
|
||||
MouseMapping(2, 1, 1, True, KeyAction('discard_event')),
|
||||
MouseMapping(2, 1, 1, True, (KeyAction('discard_event'),)),
|
||||
# start_simple_selection_grabbed
|
||||
MouseMapping(0, 1, 1, True, KeyAction('mouse_selection', (0,))),
|
||||
MouseMapping(0, 1, 1, True, (KeyAction('mouse_selection', (0,)),)),
|
||||
# start_simple_selection_grabbed
|
||||
MouseMapping(0, 1, 1, False, KeyAction('mouse_selection', (0,))),
|
||||
MouseMapping(0, 1, 1, False, (KeyAction('mouse_selection', (0,)),)),
|
||||
# start_rectangle_selection_grabbed
|
||||
MouseMapping(0, 7, 1, True, KeyAction('mouse_selection', (2,))),
|
||||
MouseMapping(0, 7, 1, True, (KeyAction('mouse_selection', (2,)),)),
|
||||
# start_rectangle_selection_grabbed
|
||||
MouseMapping(0, 7, 1, False, KeyAction('mouse_selection', (2,))),
|
||||
MouseMapping(0, 7, 1, False, (KeyAction('mouse_selection', (2,)),)),
|
||||
# select_word_grabbed
|
||||
MouseMapping(0, 1, 2, True, KeyAction('mouse_selection', (3,))),
|
||||
MouseMapping(0, 1, 2, True, (KeyAction('mouse_selection', (3,)),)),
|
||||
# select_word_grabbed
|
||||
MouseMapping(0, 1, 2, False, KeyAction('mouse_selection', (3,))),
|
||||
MouseMapping(0, 1, 2, False, (KeyAction('mouse_selection', (3,)),)),
|
||||
# select_line_grabbed
|
||||
MouseMapping(0, 1, 3, True, KeyAction('mouse_selection', (4,))),
|
||||
MouseMapping(0, 1, 3, True, (KeyAction('mouse_selection', (4,)),)),
|
||||
# select_line_grabbed
|
||||
MouseMapping(0, 1, 3, False, KeyAction('mouse_selection', (4,))),
|
||||
MouseMapping(0, 1, 3, False, (KeyAction('mouse_selection', (4,)),)),
|
||||
# select_line_from_point_grabbed
|
||||
MouseMapping(0, 7, 3, True, KeyAction('mouse_selection', (5,))),
|
||||
MouseMapping(0, 7, 3, True, (KeyAction('mouse_selection', (5,)),)),
|
||||
# select_line_from_point_grabbed
|
||||
MouseMapping(0, 7, 3, False, KeyAction('mouse_selection', (5,))),
|
||||
MouseMapping(0, 7, 3, False, (KeyAction('mouse_selection', (5,)),)),
|
||||
# extend_selection_grabbed
|
||||
MouseMapping(1, 1, 1, True, KeyAction('mouse_selection', (1,))),
|
||||
MouseMapping(1, 1, 1, True, (KeyAction('mouse_selection', (1,)),)),
|
||||
# extend_selection_grabbed
|
||||
MouseMapping(1, 1, 1, False, KeyAction('mouse_selection', (1,))),
|
||||
MouseMapping(1, 1, 1, False, (KeyAction('mouse_selection', (1,)),)),
|
||||
# show_clicked_cmd_output_ungrabbed
|
||||
MouseMapping(1, 5, 1, False, KeyAction('mouse_show_command_output')),
|
||||
MouseMapping(1, 5, 1, False, (KeyAction('mouse_show_command_output'),)),
|
||||
]
|
||||
|
||||
@ -6,17 +6,19 @@ import os
|
||||
import re
|
||||
import sys
|
||||
from typing import (
|
||||
Any, Callable, Container, Dict, Iterable, List, NamedTuple, Optional,
|
||||
Sequence, Tuple, Union
|
||||
Any, Callable, Container, Dict, Iterable, Iterator, List, NamedTuple,
|
||||
Optional, Sequence, Tuple, Union
|
||||
)
|
||||
|
||||
import kitty.fast_data_types as defines
|
||||
from kitty.conf.utils import (
|
||||
KeyAction, KeyFuncWrapper, positive_float, positive_int,
|
||||
python_string, to_bool, to_cmdline, to_color, uniq, unit_float
|
||||
KeyAction, KeyFuncWrapper, positive_float, positive_int, python_string,
|
||||
to_bool, to_cmdline, to_color, uniq, unit_float
|
||||
)
|
||||
from kitty.constants import config_dir, is_macos
|
||||
from kitty.fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, Color
|
||||
from kitty.fast_data_types import (
|
||||
CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, Color
|
||||
)
|
||||
from kitty.fonts import FontFeature
|
||||
from kitty.key_names import (
|
||||
character_key_name_aliases, functional_key_name_aliases,
|
||||
@ -26,10 +28,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, KeyAction]
|
||||
MouseMap = Dict[MouseEvent, KeyAction]
|
||||
KeyMap = Dict[SingleKey, Tuple[KeyAction, ...]]
|
||||
MouseMap = Dict[MouseEvent, Tuple[KeyAction, ...]]
|
||||
KeySequence = Tuple[SingleKey, ...]
|
||||
SubSequenceMap = Dict[KeySequence, KeyAction]
|
||||
SubSequenceMap = Dict[KeySequence, Tuple[KeyAction, ...]]
|
||||
SequenceMap = Dict[SingleKey, SubSequenceMap]
|
||||
MINIMUM_FONT_SIZE = 4
|
||||
default_tab_separator = ' ┇'
|
||||
@ -58,14 +60,6 @@ def shlex_parse(func: str, rest: str) -> FuncArgsType:
|
||||
return func, to_cmdline(rest)
|
||||
|
||||
|
||||
@func_with_args('combine')
|
||||
def combine_parse(func: str, rest: str) -> FuncArgsType:
|
||||
sep, rest = rest.split(maxsplit=1)
|
||||
parts = re.split(r'\s*' + re.escape(sep) + r'\s*', rest)
|
||||
args = tuple(map(parse_key_action, filter(None, parts)))
|
||||
return func, args
|
||||
|
||||
|
||||
def parse_send_text_bytes(text: str) -> bytes:
|
||||
return python_string(text).encode('utf-8')
|
||||
|
||||
@ -91,7 +85,7 @@ def kitten_parse(func: str, rest: str) -> FuncArgsType:
|
||||
else:
|
||||
args = rest.split(maxsplit=2)[1:]
|
||||
func = 'kitten'
|
||||
return func, args
|
||||
return func, [args[0]] + (to_cmdline(args[1]) if len(args) > 1 else [])
|
||||
|
||||
|
||||
@func_with_args('goto_tab')
|
||||
@ -772,11 +766,14 @@ def watcher(val: str, current_val: Container[str]) -> Iterable[Tuple[str, str]]:
|
||||
yield val, val
|
||||
|
||||
|
||||
def kitten_alias(val: str) -> Iterable[Tuple[str, List[str]]]:
|
||||
parts = val.split(maxsplit=2)
|
||||
if len(parts) >= 2:
|
||||
name = parts.pop(0)
|
||||
yield name, parts
|
||||
def action_alias(val: str) -> Iterable[Tuple[str, List[str]]]:
|
||||
parts = val.split(maxsplit=1)
|
||||
if len(parts) > 1:
|
||||
alias_name, rest = parts
|
||||
yield alias_name, to_cmdline(rest)
|
||||
|
||||
|
||||
kitten_alias = action_alias
|
||||
|
||||
|
||||
def symbol_map(val: str) -> Iterable[Tuple[Tuple[int, int], str]]:
|
||||
@ -806,12 +803,24 @@ def symbol_map(val: str) -> Iterable[Tuple[Tuple[int, int], str]]:
|
||||
yield (a, b), family
|
||||
|
||||
|
||||
def parse_key_action(action: str, action_type: str = 'map') -> Optional[KeyAction]:
|
||||
def parse_combine(rest: str, action_type: str = 'map') -> Iterator[KeyAction]:
|
||||
sep, rest = rest.split(maxsplit=1)
|
||||
parts = re.split(r'\s*' + re.escape(sep) + r'\s*', rest)
|
||||
for x in parts:
|
||||
if x:
|
||||
yield from parse_key_actions(x, action_type)
|
||||
|
||||
|
||||
def parse_key_actions(action: str, action_type: str = 'map') -> Iterator[KeyAction]:
|
||||
parts = action.strip().split(maxsplit=1)
|
||||
func = parts[0]
|
||||
if len(parts) == 1:
|
||||
return KeyAction(func, ())
|
||||
yield KeyAction(func, ())
|
||||
return
|
||||
rest = parts[1]
|
||||
if func == 'combine':
|
||||
yield from parse_combine(rest, action_type)
|
||||
else:
|
||||
parser = func_with_args.get(func)
|
||||
if parser is not None:
|
||||
try:
|
||||
@ -819,44 +828,64 @@ def parse_key_action(action: str, action_type: str = 'map') -> Optional[KeyActio
|
||||
except Exception as err:
|
||||
log_error(f'Ignoring invalid {action_type} action: {action} with err: {err}')
|
||||
else:
|
||||
return KeyAction(func, tuple(args))
|
||||
yield KeyAction(func, tuple(args))
|
||||
else:
|
||||
log_error(f'Ignoring unknown {action_type} action: {action}')
|
||||
return None
|
||||
|
||||
|
||||
class ActionAlias(NamedTuple):
|
||||
func_name: str
|
||||
args: Tuple[str, ...]
|
||||
second_arg_test: Optional[Callable[[Any], bool]] = None
|
||||
|
||||
|
||||
def build_action_aliases(raw: Dict[str, List[str]], first_arg_replacement: str = '') -> Dict[str, List[ActionAlias]]:
|
||||
ans: Dict[str, List[ActionAlias]] = {}
|
||||
if first_arg_replacement:
|
||||
for alias_name, args in raw.items():
|
||||
ans.setdefault('kitten', []).append(ActionAlias('kitten', tuple(args), alias_name.__eq__))
|
||||
else:
|
||||
for alias_name, args in raw.items():
|
||||
ans[alias_name] = [ActionAlias(args[0], tuple(args[1:]))]
|
||||
return ans
|
||||
|
||||
|
||||
def resolve_aliases_in_action(action: KeyAction, aliases: Dict[str, List[ActionAlias]]) -> KeyAction:
|
||||
for alias in aliases.get(action.func, ()):
|
||||
if alias.second_arg_test is None:
|
||||
return action._replace(func=alias.func_name, args=alias.args)
|
||||
if action.args and alias.second_arg_test(action.args[0]):
|
||||
return action._replace(func=alias.func_name, args=alias.args)
|
||||
return action
|
||||
|
||||
|
||||
class BaseDefinition:
|
||||
action: KeyAction
|
||||
actions: Tuple[KeyAction, ...]
|
||||
no_op_actions = frozenset(('noop', 'no-op', 'no_op'))
|
||||
|
||||
def resolve_kitten_aliases(self, aliases: Dict[str, List[str]]) -> KeyAction:
|
||||
if not self.action.args or not aliases:
|
||||
return self.action
|
||||
kitten = self.action.args[0]
|
||||
rest = str(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
|
||||
return self.action._replace(args=(kitten, rest.rstrip())) if changed else self.action
|
||||
@property
|
||||
def is_no_op(self) -> bool:
|
||||
return len(self.actions) == 1 and self.actions[0].func in self.no_op_actions
|
||||
|
||||
def resolve_aliases(self, aliases: Dict[str, List[ActionAlias]]) -> Tuple[KeyAction, ...]:
|
||||
self.actions = tuple(resolve_aliases_in_action(a, aliases) for a in self.actions)
|
||||
return self.actions
|
||||
|
||||
|
||||
class MouseMapping(BaseDefinition):
|
||||
|
||||
def __init__(self, button: int, mods: int, repeat_count: int, grabbed: bool, action: KeyAction):
|
||||
def __init__(self, button: int, mods: int, repeat_count: int, grabbed: bool, actions: Tuple[KeyAction, ...]):
|
||||
self.button = button
|
||||
self.mods = mods
|
||||
self.repeat_count = repeat_count
|
||||
self.grabbed = grabbed
|
||||
self.action = action
|
||||
self.actions = actions
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'MouseMapping({self.button}, {self.mods}, {self.repeat_count}, {self.grabbed}, {self.action})'
|
||||
return f'MouseMapping({self.button}, {self.mods}, {self.repeat_count}, {self.grabbed}, {self.actions})'
|
||||
|
||||
def resolve_and_copy(self, kitty_mod: int, aliases: Dict[str, List[str]]) -> 'MouseMapping':
|
||||
return MouseMapping(self.button, defines.resolve_key_mods(kitty_mod, self.mods), self.repeat_count, self.grabbed, self.resolve_kitten_aliases(aliases))
|
||||
def resolve_and_copy(self, kitty_mod: int, aliases: Dict[str, List[ActionAlias]]) -> 'MouseMapping':
|
||||
return MouseMapping(self.button, defines.resolve_key_mods(kitty_mod, self.mods), self.repeat_count, self.grabbed, self.resolve_aliases(aliases))
|
||||
|
||||
@property
|
||||
def trigger(self) -> MouseEvent:
|
||||
@ -865,21 +894,21 @@ class MouseMapping(BaseDefinition):
|
||||
|
||||
class KeyDefinition(BaseDefinition):
|
||||
|
||||
def __init__(self, is_sequence: bool, action: KeyAction, mods: int, is_native: bool, key: int, rest: Tuple[SingleKey, ...] = ()):
|
||||
def __init__(self, is_sequence: bool, actions: Tuple[KeyAction, ...], mods: int, is_native: bool, key: int, rest: Tuple[SingleKey, ...] = ()):
|
||||
self.is_sequence = is_sequence
|
||||
self.action = action
|
||||
self.actions = actions
|
||||
self.trigger = SingleKey(mods, is_native, key)
|
||||
self.rest = rest
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'KeyDefinition({self.is_sequence}, {self.action}, {self.trigger.mods}, {self.trigger.is_native}, {self.trigger.key}, {self.rest})'
|
||||
return f'KeyDefinition({self.is_sequence}, {self.actions}, {self.trigger.mods}, {self.trigger.is_native}, {self.trigger.key}, {self.rest})'
|
||||
|
||||
def resolve_and_copy(self, kitty_mod: int, aliases: Dict[str, List[str]]) -> 'KeyDefinition':
|
||||
def resolve_and_copy(self, kitty_mod: int, aliases: Dict[str, List[ActionAlias]]) -> 'KeyDefinition':
|
||||
def r(k: SingleKey) -> SingleKey:
|
||||
mods = defines.resolve_key_mods(kitty_mod, k.mods)
|
||||
return k._replace(mods=mods)
|
||||
return KeyDefinition(
|
||||
self.is_sequence, self.resolve_kitten_aliases(aliases),
|
||||
self.is_sequence, self.resolve_aliases(aliases),
|
||||
defines.resolve_key_mods(kitty_mod, self.trigger.mods),
|
||||
self.trigger.is_native, self.trigger.key, tuple(map(r, self.rest)))
|
||||
|
||||
@ -920,12 +949,11 @@ def parse_map(val: str) -> Iterable[KeyDefinition]:
|
||||
log_error(f'Shortcut: {sc} has unknown key, ignoring')
|
||||
return
|
||||
try:
|
||||
paction = parse_key_action(action)
|
||||
paction = tuple(parse_key_actions(action))
|
||||
except Exception:
|
||||
log_error('Invalid shortcut action: {}. Ignoring.'.format(
|
||||
action))
|
||||
log_error(f'Invalid shortcut action: {action}. Ignoring.')
|
||||
else:
|
||||
if paction is not None:
|
||||
if paction:
|
||||
if is_sequence:
|
||||
if trigger is not None:
|
||||
yield KeyDefinition(True, paction, trigger[0], trigger[1], trigger[2], rest)
|
||||
@ -965,11 +993,11 @@ def parse_mouse_map(val: str) -> Iterable[MouseMapping]:
|
||||
log_error(f'Mouse modes: {modes} not recognized, ignoring')
|
||||
return
|
||||
try:
|
||||
paction = parse_key_action(action, 'mouse_map')
|
||||
paction = tuple(parse_key_actions(action, 'mouse_map'))
|
||||
except Exception:
|
||||
log_error(f'Invalid mouse action: {action}. Ignoring.')
|
||||
return
|
||||
if paction is None:
|
||||
if not paction:
|
||||
return
|
||||
for mode in sorted(specified_modes):
|
||||
yield MouseMapping(button, mods, count, mode == 'grabbed', paction)
|
||||
|
||||
@ -646,7 +646,7 @@ class Window:
|
||||
action = get_options().mousemap.get(ev)
|
||||
if action is None:
|
||||
return False
|
||||
return get_boss().dispatch_action(action, window_for_dispatch=self, dispatch_type='MouseEvent')
|
||||
return get_boss().combine(action, window_for_dispatch=self, dispatch_type='MouseEvent')
|
||||
|
||||
def open_url(self, url: str, hyperlink_id: int, cwd: Optional[str] = None) -> None:
|
||||
opts = get_options()
|
||||
|
||||
@ -69,10 +69,11 @@ class Callbacks:
|
||||
|
||||
def on_mouse_event(self, event):
|
||||
ev = MouseEvent(**event)
|
||||
action = self.opts.mousemap.get(ev)
|
||||
if action is None:
|
||||
actions = self.opts.mousemap.get(ev)
|
||||
if not actions:
|
||||
return False
|
||||
self.current_mouse_button = ev.button
|
||||
for action in actions:
|
||||
getattr(self, action.func)(*action.args)
|
||||
self.current_mouse_button = 0
|
||||
return True
|
||||
@ -115,8 +116,8 @@ class BaseTest(TestCase):
|
||||
if options:
|
||||
final_options.update(options)
|
||||
options = Options(merge_result_dicts(defaults._asdict(), final_options))
|
||||
finalize_keys(options)
|
||||
finalize_mouse_mappings(options)
|
||||
finalize_keys(options, {})
|
||||
finalize_mouse_mappings(options, {})
|
||||
set_options(options)
|
||||
return options
|
||||
|
||||
|
||||
@ -31,7 +31,8 @@ class TestConfParsing(BaseTest):
|
||||
return ans
|
||||
|
||||
def keys_for_func(opts, name):
|
||||
for key, action in opts.keymap.items():
|
||||
for key, actions in opts.keymap.items():
|
||||
for action in actions:
|
||||
if action.func == name:
|
||||
yield key
|
||||
|
||||
@ -51,8 +52,16 @@ class TestConfParsing(BaseTest):
|
||||
self.ae(opts.pointer_shape_when_grabbed, defaults.pointer_shape_when_grabbed)
|
||||
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')
|
||||
self.ae(opts.env, {'A': '1', 'B': 'x1', 'C': '', 'D': DELETE_ENV_VAR})
|
||||
ka = tuple(opts.keymap.values())[0]
|
||||
ka = tuple(opts.keymap.values())[0][0]
|
||||
self.ae(ka.func, 'kitten')
|
||||
self.ae(ka.args, ('b', '--moo'))
|
||||
opts = p('clear_all_shortcuts y', 'action_alias la launch --moo', 'map f1 la')
|
||||
ka = tuple(opts.keymap.values())[0][0]
|
||||
self.ae(ka.func, 'launch')
|
||||
self.ae(ka.args, ('--moo',))
|
||||
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'))
|
||||
opts = p('kitty_mod alt')
|
||||
self.ae(opts.kitty_mod, to_modifiers('alt'))
|
||||
self.ae(next(keys_for_func(opts, 'next_layout')).mods, opts.kitty_mod)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user