Add some tests for mappings

This commit is contained in:
Kovid Goyal 2024-01-25 13:56:42 +05:30
parent 30e3ad83bc
commit cec427777c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 107 additions and 8 deletions

View File

@ -20,6 +20,7 @@
ring_bell,
set_ignore_os_keyboard_processing,
)
from .options.types import Options
from .options.utils import KeyboardMode, KeyDefinition, KeyMap
from .typing import ScreenType
@ -70,12 +71,12 @@ def update_keymap(self, global_shortcuts:Optional[Dict[str, SingleKey]] = None)
if global_shortcuts is None:
if is_macos:
from .main import set_cocoa_global_shortcuts
global_shortcuts = set_cocoa_global_shortcuts(get_options())
global_shortcuts = set_cocoa_global_shortcuts(self.get_options())
else:
global_shortcuts = {}
self.global_shortcuts_map: KeyMap = {v: [KeyDefinition(definition=k)] for k, v in global_shortcuts.items()}
self.global_shortcuts = global_shortcuts
self.keyboard_modes = get_options().keyboard_modes.copy()
self.keyboard_modes = self.get_options().keyboard_modes.copy()
km = self.keyboard_modes[''].keymap
self.keyboard_modes[''].keymap = km = km.copy()
for sc in self.global_shortcuts.values():
@ -101,11 +102,6 @@ def push_keyboard_mode(self, new_mode: str) -> None:
mode = self.keyboard_modes[new_mode]
self._push_keyboard_mode(mode)
def debug_print(self, *args: Any, end: str = '\n') -> None:
b = get_boss()
if b.args.debug_keyboard:
print(*args, end=end, flush=True)
def matching_key_actions(self, candidates: Iterable[KeyDefinition]) -> List[KeyDefinition]:
w = self.get_active_window()
matches = []
@ -207,7 +203,7 @@ def show_error(self, title: str, msg: str) -> None:
return get_boss().show_error(title, msg)
def ring_bell(self) -> None:
if get_options().enable_audio_bell:
if self.get_options().enable_audio_bell:
ring_bell()
def combine(self, action_definition: str) -> bool:
@ -215,4 +211,12 @@ def combine(self, action_definition: str) -> bool:
def set_ignore_os_keyboard_processing(self, on: bool) -> None:
set_ignore_os_keyboard_processing(on)
def get_options(self) -> Options:
return get_options()
def debug_print(self, *args: Any, end: str = '\n') -> None:
b = get_boss()
if b.args.debug_keyboard:
print(*args, end=end, flush=True)
# }}}

View File

@ -5,6 +5,7 @@
import kitty.fast_data_types as defines
from kitty.key_encoding import EventType, KeyEvent, decode_key_event, encode_key_event
from kitty.keys import Mappings
from . import BaseTest
@ -504,3 +505,97 @@ def enc(button=L, action=defines.PRESS, mods=0, x=1, y=1):
self.ae(enc(mods=defines.GLFW_MOD_SHIFT), '<4;1;1M')
self.ae(enc(mods=defines.GLFW_MOD_ALT), '<8;1;1M')
self.ae(enc(mods=defines.GLFW_MOD_CONTROL), '<16;1;1M')
def test_mapping(self):
from kitty.config import load_config
from kitty.options.utils import parse_shortcut
af = self.assertFalse
class Window:
def __init__(self, id=1):
self.key_seqs = []
self.id = id
def send_key_sequence(self, *s):
self.key_seqs.extend(s)
class TM(Mappings):
def __init__(self, *lines, active_window = Window()):
self.active_window = active_window
self.windows = [active_window]
bad_lines = []
self.options = load_config(overrides=lines, accumulate_bad_lines=bad_lines)
af(bad_lines)
super().__init__()
def get_active_window(self):
return self.active_window
def match_windows(self, expr: str):
for w in self.windows:
if str(w.id) == expr:
yield w
def show_error(self, title: str, msg: str) -> None:
pass
def ring_bell(self) -> None:
pass
def debug_print(self, *args, end: str = '\n') -> None:
pass
def combine(self, action_definition: str) -> bool:
self.actions.append(action_definition)
return bool(action_definition)
def set_ignore_os_keyboard_processing(self, on: bool) -> None:
pass
def get_options(self):
return self.options
def __call__(self, *keys: str):
self.actions = []
self.active_window.key_seqs = []
consumed = []
for key in keys:
sk = parse_shortcut(key)
ev = defines.KeyEvent(sk.key, 0, 0, sk.mods)
consumed.append(self.dispatch_possible_special_key(ev))
return consumed
tm = TM('map ctrl+a new_window_with_cwd')
self.ae(tm('ctrl+a'), [True])
self.ae(tm.actions, ['new_window_with_cwd'])
tm = TM('map ctrl+f>2 set_font_size 20')
self.ae(tm('ctrl+f', '2'), [True, True])
self.ae(tm.actions, ['set_font_size 20'])
af(tm.active_window.key_seqs)
# unmatched multi key mapping should send all keys to child
self.ae(tm('ctrl+f', '1'), [True, False])
af(tm.actions)
self.ae(len(tm.active_window.key_seqs), 1) # ctrl+f should have been sent to the window
# unmap
tm = TM('map kitty_mod+enter')
self.ae(tm('ctrl+shift+enter'), [False])
# single key mapping overrides all multi-key mappings with same prefix
tm = TM('map kitty_mod+p new_window')
self.ae(tm('ctrl+shift+p', 'f'), [True, False])
self.ae(tm.actions, ['new_window'])
# changing a multi key mapping
tm = TM('map kitty_mod+p>f new_window')
self.ae(tm('ctrl+shift+p', 'f'), [True, True])
self.ae(tm.actions, ['new_window'])
# different behavior with focus selection
tm = TM('map --when-focus-on 2 kitty_mod+t')
tm.windows.append(Window(2))
self.ae(tm('ctrl+shift+t'), [True])
tm.active_window = tm.windows[1]
self.ae(tm('ctrl+shift+t'), [False])