mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 08:26:56 +00:00
Cleanup previous PR
Actually respect the fallback order when finding matching shortcuts
This commit is contained in:
parent
3e5b3eb55d
commit
88ee80b327
8 changed files with 130 additions and 90 deletions
|
|
@ -168,6 +168,8 @@ Detailed list of changes
|
|||
0.47.0 [future]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- For builtin key mappings automatically fallback to matching ASCII key when the pressed key has no matches and is a non-English character (:pull:`9671`)
|
||||
|
||||
- :doc:`Remote control <remote-control>`: Expose :code:`session_name` in the output of ``kitten @ ls`` for each window (:iss:`9732`)
|
||||
|
||||
- Fix thickness of diagonal lines in box drawing characters not the same as horizontal/vertical lines (:iss:`9719`)
|
||||
|
|
@ -184,6 +186,7 @@ Detailed list of changes
|
|||
|
||||
- The :opt:`show_hyperlink_targets` option now allows specifying a keyboard modifier so that target URLs are only shown on hover when the modifier is pressed (:pull:`9741`)
|
||||
|
||||
|
||||
0.46.2 [2026-03-21]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -173,6 +173,8 @@ def generate_class(defn: Definition, loc: str) -> tuple[str, str]:
|
|||
fmod = f'{loc}.options.utils'
|
||||
imports.add((fmod, ftype))
|
||||
return ftype
|
||||
if loc == 'kitty':
|
||||
imports.add(('kitty.options.utils', 'KeyFallbackType'))
|
||||
|
||||
for aname, action in defn.actions.items():
|
||||
option_names.add(aname)
|
||||
|
|
@ -620,7 +622,7 @@ def gen_go_code(defn: Definition) -> str:
|
|||
a('KeyboardShortcuts: []*config.KeyAction{')
|
||||
for sc in keyboard_shortcuts:
|
||||
options, leftover = parse_options_for_map(sc.parseable_text)
|
||||
allow_fallback = options.allow_fallback
|
||||
allow_fallback = ','.join(x.value for x in options.allow_fallback)
|
||||
key_spec, action = leftover.split(None, 1)
|
||||
aname, _, aargs = action.partition(' ')
|
||||
aname = serialize_as_go_string(aname)
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ class ShortcutMapping(Mapping):
|
|||
from kitty.options.utils import parse_options_for_map
|
||||
_, remainder = parse_options_for_map(raw_definition)
|
||||
parts = remainder.split(maxsplit=1)
|
||||
self.key = parts[0] if parts else ''
|
||||
self.key = parts[0]
|
||||
self.action_def = parts[1] if len(parts) > 1 else ''
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ from .fast_data_types import (
|
|||
set_ignore_os_keyboard_processing,
|
||||
)
|
||||
from .options.types import Options
|
||||
from .options.utils import KeyboardMode, KeyDefinition, KeyMap, KeyMapOptions
|
||||
from .options.utils import KeyboardMode, KeyDefinition, KeyFallbackType, KeyMap, KeyMapOptions
|
||||
from .typing_compat import ScreenType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .window import Window
|
||||
|
||||
mod_mask = GLFW_MOD_ALT | GLFW_MOD_CONTROL | GLFW_MOD_SHIFT | GLFW_MOD_SUPER | GLFW_MOD_META | GLFW_MOD_HYPER
|
||||
_global_shortcut_options = KeyMapOptions(allow_fallback='shifted,ascii')
|
||||
_global_shortcut_options = KeyMapOptions(allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate))
|
||||
|
||||
|
||||
def keyboard_mode_name(screen: ScreenType) -> str:
|
||||
|
|
@ -43,24 +43,37 @@ def keyboard_mode_name(screen: ScreenType) -> str:
|
|||
def get_shortcut(keymap: KeyMap, ev: KeyEvent) -> list[KeyDefinition] | 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:
|
||||
candidate = keymap.get(SingleKey(mods & (~GLFW_MOD_SHIFT), False, ev.shifted_key))
|
||||
if candidate:
|
||||
filtered = [d for d in candidate if 'shifted' in d.options.allow_fallback]
|
||||
if filtered:
|
||||
ans = filtered
|
||||
if ans is None and ev.alternate_key and 127 < ev.key < 0xE000:
|
||||
candidate = keymap.get(SingleKey(mods, False, ev.alternate_key))
|
||||
if candidate:
|
||||
filtered = [d for d in candidate if 'ascii' in d.options.allow_fallback]
|
||||
if filtered:
|
||||
ans = filtered
|
||||
if ans is None:
|
||||
priority_map: dict[int, int] = {}
|
||||
items: list[KeyDefinition] = []
|
||||
|
||||
def add(q: list[KeyDefinition] | None, ft: KeyFallbackType) -> None:
|
||||
if q:
|
||||
for d in q:
|
||||
prio = -1
|
||||
for i, x in enumerate(d.options.allow_fallback):
|
||||
if x is ft:
|
||||
prio = i
|
||||
break
|
||||
key = id(d)
|
||||
if -1 < prio < priority_map.get(key, 100000):
|
||||
if key not in priority_map:
|
||||
items.append(d)
|
||||
priority_map[key] = prio
|
||||
if ev.shifted_key and mods & GLFW_MOD_SHIFT:
|
||||
add(keymap.get(SingleKey(mods & (~GLFW_MOD_SHIFT), False, ev.shifted_key)), KeyFallbackType.shifted)
|
||||
if ev.alternate_key and 127 < ev.key < 0xE000:
|
||||
add(keymap.get(SingleKey(mods, False, ev.alternate_key)), KeyFallbackType.alternate)
|
||||
if items:
|
||||
ans = sorted(items, key=lambda x: priority_map[id(x)])
|
||||
|
||||
if ans is None:
|
||||
ans = keymap.get(SingleKey(mods, True, ev.native_key))
|
||||
return ans
|
||||
|
||||
|
||||
def shortcut_matches(s: SingleKey, ev: KeyEvent) -> bool:
|
||||
' used only for testing '
|
||||
mods = ev.mods & mod_mask
|
||||
smods = s.mods & mod_mask
|
||||
if s.is_native:
|
||||
|
|
|
|||
96
kitty/options/types.py
generated
96
kitty/options/types.py
generated
|
|
@ -11,8 +11,8 @@ import kitty.fast_data_types
|
|||
from kitty.fonts import FontSpec
|
||||
import kitty.fonts
|
||||
from kitty.options.utils import (
|
||||
AliasMap, KeyDefinition, KeyMapOptions, KeyboardModeMap, MouseHideWait, MouseMap, MouseMapping,
|
||||
NotifyOnCmdFinish, TabBarMarginHeight
|
||||
AliasMap, KeyDefinition, KeyFallbackType, KeyMapOptions, KeyboardModeMap, MouseHideWait, MouseMap,
|
||||
MouseMapping, NotifyOnCmdFinish, TabBarMarginHeight
|
||||
)
|
||||
import kitty.options.utils
|
||||
from kitty.types import FloatEdges
|
||||
|
|
@ -848,23 +848,23 @@ defaults.watcher = {}
|
|||
|
||||
defaults.map = [
|
||||
# copy_to_clipboard
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=99), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='copy_to_clipboard'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=99), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='copy_to_clipboard'),
|
||||
# paste_from_clipboard
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=118), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='paste_from_clipboard'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=118), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='paste_from_clipboard'),
|
||||
# paste_from_selection
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=115), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='paste_from_selection'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=115), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='paste_from_selection'),
|
||||
# paste_from_selection
|
||||
KeyDefinition(trigger=SingleKey(mods=1, key=57348), definition='paste_from_selection'),
|
||||
# pass_selection_to_program
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=111), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='pass_selection_to_program'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=111), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='pass_selection_to_program'),
|
||||
# scroll_line_up
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57352), definition='scroll_line_up'),
|
||||
# scroll_line_up
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=107), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='scroll_line_up'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=107), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='scroll_line_up'),
|
||||
# scroll_line_down
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57353), definition='scroll_line_down'),
|
||||
# scroll_line_down
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=106), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='scroll_line_down'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=106), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='scroll_line_down'),
|
||||
# scroll_page_up
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57354), definition='scroll_page_up'),
|
||||
# scroll_page_down
|
||||
|
|
@ -874,33 +874,33 @@ defaults.map = [
|
|||
# scroll_end
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57357), definition='scroll_end'),
|
||||
# scroll_to_previous_prompt
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=122), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='scroll_to_prompt -1'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=122), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='scroll_to_prompt -1'),
|
||||
# scroll_to_next_prompt
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=120), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='scroll_to_prompt 1'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=120), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='scroll_to_prompt 1'),
|
||||
# show_scrollback
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=104), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='show_scrollback'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=104), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='show_scrollback'),
|
||||
# show_last_command_output
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=103), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='show_last_command_output'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=103), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='show_last_command_output'),
|
||||
# search_scrollback
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=47), definition='search_scrollback'),
|
||||
# new_window
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57345), definition='new_window'),
|
||||
# new_os_window
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=110), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='new_os_window'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=110), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='new_os_window'),
|
||||
# close_window
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=119), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='close_window'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=119), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='close_window'),
|
||||
# next_window
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=93), definition='next_window'),
|
||||
# previous_window
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=91), definition='previous_window'),
|
||||
# move_window_forward
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=102), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='move_window_forward'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=102), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='move_window_forward'),
|
||||
# move_window_backward
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=98), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='move_window_backward'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=98), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='move_window_backward'),
|
||||
# move_window_to_top
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=96), definition='move_window_to_top'),
|
||||
# start_resizing_window
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=114), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='start_resizing_window'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=114), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='start_resizing_window'),
|
||||
# first_window
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=49), definition='first_window'),
|
||||
# second_window
|
||||
|
|
@ -934,17 +934,17 @@ defaults.map = [
|
|||
# previous_tab
|
||||
KeyDefinition(trigger=SingleKey(mods=5, key=57346), definition='previous_tab'),
|
||||
# new_tab
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=116), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='new_tab'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=116), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='new_tab'),
|
||||
# close_tab
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=113), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='close_tab'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=113), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='close_tab'),
|
||||
# move_tab_forward
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=46), definition='move_tab_forward'),
|
||||
# move_tab_backward
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=44), definition='move_tab_backward'),
|
||||
# set_tab_title
|
||||
KeyDefinition(trigger=SingleKey(mods=258, key=116), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='set_tab_title'),
|
||||
KeyDefinition(trigger=SingleKey(mods=258, key=116), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='set_tab_title'),
|
||||
# next_layout
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=108), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='next_layout'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=108), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='next_layout'),
|
||||
# increase_font_size
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=61), definition='change_font_size all +2.0'),
|
||||
# increase_font_size
|
||||
|
|
@ -958,25 +958,25 @@ defaults.map = [
|
|||
# reset_font_size
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57347), definition='change_font_size all 0'),
|
||||
# open_url
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=101), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='open_url_with_hints'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=101), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='open_url_with_hints'),
|
||||
# insert_selected_path
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=102),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten hints --type path --program -'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=102),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten hints --type path --program -'),
|
||||
# open_selected_path
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(mods=1, key=102),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten hints --type path'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(mods=1, key=102),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten hints --type path'),
|
||||
# insert_chosen_file
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=99),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten choose-files'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=99),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten choose-files'),
|
||||
# insert_chosen_directory
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=100),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten choose-files --mode=dir'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=100),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten choose-files --mode=dir'),
|
||||
# insert_selected_line
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=108),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten hints --type line --program -'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=108),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten hints --type line --program -'),
|
||||
# insert_selected_word
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=119),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten hints --type word --program -'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=119),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten hints --type word --program -'),
|
||||
# insert_selected_hash
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=104),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten hints --type hash --program -'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=104),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten hints --type hash --program -'),
|
||||
# goto_file_line
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=110),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten hints --type linenum'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=110),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten hints --type linenum'),
|
||||
# open_selected_hyperlink
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=121),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten hints --type hyperlink'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=121),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten hints --type hyperlink'),
|
||||
# show_kitty_doc
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57364), definition='show_kitty_doc overview'),
|
||||
# command_palette
|
||||
|
|
@ -986,19 +986,19 @@ defaults.map = [
|
|||
# toggle_maximized
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57373), definition='toggle_maximized'),
|
||||
# input_unicode_character
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=117), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='kitten unicode_input'),
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=117), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='kitten unicode_input'),
|
||||
# edit_config_file
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57365), definition='edit_config_file'),
|
||||
# kitty_shell
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57344), definition='kitty_shell window'),
|
||||
# increase_background_opacity
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=109),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='set_background_opacity +0.1'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=109),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='set_background_opacity +0.1'),
|
||||
# decrease_background_opacity
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=108),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='set_background_opacity -0.1'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=108),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='set_background_opacity -0.1'),
|
||||
# full_background_opacity
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=49),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='set_background_opacity 1'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=49),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='set_background_opacity 1'),
|
||||
# reset_background_opacity
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=100),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='set_background_opacity default'),
|
||||
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=97), rest=(SingleKey(key=100),), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='set_background_opacity default'),
|
||||
# reset_terminal
|
||||
KeyDefinition(trigger=SingleKey(mods=256, key=57349), definition='clear_terminal reset active'),
|
||||
# reload_config_file
|
||||
|
|
@ -1008,8 +1008,8 @@ defaults.map = [
|
|||
]
|
||||
|
||||
if is_macos:
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=99), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='copy_or_noop'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=118), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='paste_from_clipboard'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=99), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='copy_or_noop'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=118), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='paste_from_clipboard'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=57354), definition='scroll_line_up'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57352), definition='scroll_line_up'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=57355), definition='scroll_line_down'))
|
||||
|
|
@ -1018,11 +1018,11 @@ if is_macos:
|
|||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57355), definition='scroll_page_down'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57356), definition='scroll_home'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57357), definition='scroll_end'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=102), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='search_scrollback'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=102), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='search_scrollback'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57345), definition='new_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=110), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='new_os_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=100), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='close_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=114), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='start_resizing_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=110), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='new_os_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=100), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='close_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=114), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='start_resizing_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=49), definition='first_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=50), definition='second_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=51), definition='third_window'))
|
||||
|
|
@ -1034,18 +1034,18 @@ if is_macos:
|
|||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=57), definition='ninth_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=93), definition='next_tab'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=91), definition='previous_tab'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=116), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='new_tab'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=119), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='close_tab'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=119), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='close_os_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=105), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='set_tab_title'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=116), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='new_tab'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=119), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='close_tab'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=119), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='close_os_window'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=105), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='set_tab_title'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=43), definition='change_font_size all +2.0'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=61), definition='change_font_size all +2.0'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=61), definition='change_font_size all +2.0'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=45), definition='change_font_size all -2.0'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=45), definition='change_font_size all -2.0'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=48), definition='change_font_size all 0'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=12, key=102), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='toggle_fullscreen'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=115), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback='ascii,shifted'), definition='toggle_macos_secure_keyboard_entry'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=12, key=102), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='toggle_fullscreen'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=115), options=KeyMapOptions(when_focus_on='', new_mode='', mode='', on_unknown='beep', on_action='keep', timeout=None, allow_fallback=(KeyFallbackType.shifted, KeyFallbackType.alternate)), definition='toggle_macos_secure_keyboard_entry'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=96), definition='macos_cycle_through_os_windows'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=96), definition='macos_cycle_through_os_windows_backwards'))
|
||||
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=12, key=32), definition='kitten unicode_input'))
|
||||
|
|
|
|||
|
|
@ -1292,7 +1292,7 @@ class LiteralField(Generic[T]):
|
|||
val = obj.__dict__.get(self._name)
|
||||
if val is None or isinstance(val, LiteralField):
|
||||
return self._vals[0]
|
||||
return val
|
||||
return cast(T, val)
|
||||
|
||||
def __set__(self, obj: object, value: str) -> None:
|
||||
if value not in self._vals:
|
||||
|
|
@ -1304,6 +1304,14 @@ OnUnknown = Literal['beep', 'end', 'ignore', 'passthrough']
|
|||
OnAction = Literal['keep', 'end']
|
||||
|
||||
|
||||
class KeyFallbackType(enum.Enum):
|
||||
shifted = 'shifted'
|
||||
alternate = 'alternate'
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'KeyFallbackType.{self.value}'
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class KeyMapOptions:
|
||||
when_focus_on: str = ''
|
||||
|
|
@ -1312,7 +1320,7 @@ class KeyMapOptions:
|
|||
on_unknown: LiteralField[OnUnknown] = LiteralField[OnUnknown](get_args(OnUnknown))
|
||||
on_action: LiteralField[OnAction] = LiteralField[OnAction](get_args(OnAction))
|
||||
timeout: float | None = None
|
||||
allow_fallback: str = 'shifted'
|
||||
allow_fallback: tuple[KeyFallbackType, ...] = (KeyFallbackType.shifted,)
|
||||
|
||||
|
||||
default_key_map_options = KeyMapOptions()
|
||||
|
|
@ -1385,17 +1393,19 @@ key_map_option_converters: defaultdict[str, Callable[[str], Any]] = defaultdict(
|
|||
key_map_option_converters['timeout'] = float
|
||||
|
||||
|
||||
_allowed_fallback_values = frozenset(('shifted', 'ascii'))
|
||||
|
||||
|
||||
def _convert_allow_fallback(val: str) -> str:
|
||||
if not val or val == 'none':
|
||||
return ''
|
||||
parts = tuple(x.strip() for x in val.split(','))
|
||||
invalid = set(parts) - _allowed_fallback_values
|
||||
if invalid:
|
||||
raise ValueError(f'allow_fallback values must be a subset of {_allowed_fallback_values}, got: {invalid}')
|
||||
return ','.join(parts)
|
||||
def _convert_allow_fallback(val: str) -> tuple[KeyFallbackType, ...]:
|
||||
match val:
|
||||
case '' | 'none':
|
||||
return ()
|
||||
case 'shifted,ascii':
|
||||
return (KeyFallbackType.shifted, KeyFallbackType.alternate)
|
||||
case 'ascii,shifted':
|
||||
return (KeyFallbackType.alternate, KeyFallbackType.shifted)
|
||||
case 'shifted':
|
||||
return (KeyFallbackType.shifted,)
|
||||
case 'ascii':
|
||||
return (KeyFallbackType.alternate,)
|
||||
raise ValueError(f'allow_fallback values must be a subset of shifted, ascii, got: {val}')
|
||||
|
||||
|
||||
key_map_option_converters['allow_fallback'] = _convert_allow_fallback
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from functools import partial
|
|||
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 kitty.options.utils import KeyFallbackType
|
||||
|
||||
from . import BaseTest
|
||||
|
||||
|
|
@ -680,7 +681,7 @@ class TestKeys(BaseTest):
|
|||
|
||||
def test_get_shortcut_per_mapping_fallback(self):
|
||||
from kitty.keys import get_shortcut
|
||||
from kitty.options.utils import KeyDefinition, KeyMapOptions
|
||||
from kitty.options.utils import KeyDefinition, KeyMapOptions, _convert_allow_fallback
|
||||
|
||||
ctrl = defines.GLFW_MOD_CONTROL
|
||||
shift = defines.GLFW_MOD_SHIFT
|
||||
|
|
@ -688,8 +689,7 @@ class TestKeys(BaseTest):
|
|||
latin_c = ord('c')
|
||||
|
||||
def make_kd(definition='test_action', allow_fallback='shifted'):
|
||||
opts = KeyMapOptions()
|
||||
object.__setattr__(opts, 'allow_fallback', allow_fallback)
|
||||
opts = KeyMapOptions(allow_fallback=_convert_allow_fallback(allow_fallback))
|
||||
return KeyDefinition(definition=definition, options=opts)
|
||||
|
||||
# non-ASCII key + alternate_key + allow_fallback includes ascii → match
|
||||
|
|
@ -700,6 +700,18 @@ class TestKeys(BaseTest):
|
|||
self.assertIsNotNone(result)
|
||||
self.assertIs(result[0], kd_ascii)
|
||||
|
||||
# sorting by fallback order
|
||||
kd1 = make_kd('ascii', allow_fallback='ascii,shifted')
|
||||
kd2 = make_kd('shifted', allow_fallback='shifted,ascii')
|
||||
keymap = {defines.SingleKey(ctrl, False, latin_c): [kd1, kd2]}
|
||||
ev = defines.KeyEvent(cyrillic_s, 0, latin_c, ctrl)
|
||||
result = get_shortcut(keymap, ev)
|
||||
self.assertEqual(result, [kd1, kd2])
|
||||
keymap = {defines.SingleKey(0, False, latin_c): [kd1, kd2]}
|
||||
ev = defines.KeyEvent(ord('C'), latin_c, 0, shift)
|
||||
result = get_shortcut(keymap, ev)
|
||||
self.assertEqual(result, [kd2, kd1])
|
||||
|
||||
# non-ASCII key + alternate_key + allow_fallback='shifted' (no ascii) → no ascii match
|
||||
kd_shifted_only = make_kd('copy', allow_fallback='shifted')
|
||||
keymap = {defines.SingleKey(ctrl, False, latin_c): [kd_shifted_only]}
|
||||
|
|
@ -842,34 +854,34 @@ class TestKeys(BaseTest):
|
|||
|
||||
# default: no --allow-fallback → allow_fallback='shifted'
|
||||
kd = first_kd('ctrl+c copy_to_clipboard')
|
||||
self.ae(kd.options.allow_fallback, 'shifted')
|
||||
self.ae(kd.options.allow_fallback, (KeyFallbackType.shifted,))
|
||||
|
||||
# --allow-fallback=shifted,ascii
|
||||
kd = first_kd('--allow-fallback=shifted,ascii ctrl+c copy_to_clipboard')
|
||||
self.assertIn('shifted', kd.options.allow_fallback)
|
||||
self.assertIn('ascii', kd.options.allow_fallback)
|
||||
self.assertIn(KeyFallbackType.shifted, kd.options.allow_fallback)
|
||||
self.assertIn(KeyFallbackType.alternate, kd.options.allow_fallback)
|
||||
|
||||
# --allow-fallback=ascii (only ascii, no shifted)
|
||||
kd = first_kd('--allow-fallback=ascii ctrl+c copy_to_clipboard')
|
||||
self.ae(kd.options.allow_fallback, 'ascii')
|
||||
self.assertNotIn('shifted', kd.options.allow_fallback)
|
||||
self.ae(kd.options.allow_fallback, (KeyFallbackType.alternate,))
|
||||
self.assertNotIn(KeyFallbackType.shifted, kd.options.allow_fallback)
|
||||
|
||||
# --allow-fallback=shifted (explicit, same as default)
|
||||
kd = first_kd('--allow-fallback=shifted ctrl+c copy_to_clipboard')
|
||||
self.ae(kd.options.allow_fallback, 'shifted')
|
||||
self.ae(kd.options.allow_fallback, (KeyFallbackType.shifted,))
|
||||
|
||||
# invalid value raises
|
||||
self.assertRaises(ValueError, first_kd, '--allow-fallback=bogus ctrl+c copy_to_clipboard')
|
||||
|
||||
# order normalization: ascii,shifted → sorted as ascii,shifted
|
||||
kd = first_kd('--allow-fallback=ascii,shifted ctrl+c copy_to_clipboard')
|
||||
self.ae(kd.options.allow_fallback, 'ascii,shifted')
|
||||
self.ae(kd.options.allow_fallback, (KeyFallbackType.alternate, KeyFallbackType.shifted))
|
||||
|
||||
# --allow-fallback=none → empty string (no fallback)
|
||||
kd = first_kd('--allow-fallback=none ctrl+c copy_to_clipboard')
|
||||
self.ae(kd.options.allow_fallback, '')
|
||||
self.ae(kd.options.allow_fallback, ())
|
||||
|
||||
# combined with other options
|
||||
kd = first_kd('--when-focus-on 1 --allow-fallback=ascii ctrl+c copy_to_clipboard')
|
||||
self.ae(kd.options.allow_fallback, 'ascii')
|
||||
self.ae(kd.options.allow_fallback, (KeyFallbackType.alternate,))
|
||||
self.ae(kd.options.when_focus_on, '1')
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ func validateAllowFallback(value string) error {
|
|||
if value == "" || value == "none" {
|
||||
return nil
|
||||
}
|
||||
for _, part := range strings.Split(value, ",") {
|
||||
for part := range strings.SplitSeq(value, ",") {
|
||||
part = strings.TrimSpace(part)
|
||||
if part != "shifted" && part != "ascii" {
|
||||
return fmt.Errorf("Invalid allow-fallback value %#v, allowed values: shifted, ascii, none", part)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue