Fix sequence mapping

This commit is contained in:
Kovid Goyal 2023-11-30 21:17:02 +05:30
parent d7633b95d0
commit 8d1fde18f8
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
3 changed files with 38 additions and 20 deletions

View file

@ -1370,24 +1370,26 @@ class Boss:
ring_bell()
return True
else:
final_action = self.matching_key_action(key_action)
if final_action is not None:
final_actions = self.matching_key_actions(key_action)
if final_actions:
mode_pos = len(self.keyboard_mode_stack) - 1
if final_action.is_sequence:
if mode.sequence_left is None:
if final_actions[0].is_sequence:
if not mode.is_sequence:
sm = KeyboardMode('__sequence__')
sm.end_on_action = True
sm.sequence_left = final_action.rest[1:]
sm.keymap[final_action.rest[0]].append(final_action)
sm.is_sequence = True
for fa in final_actions:
sm.keymap[fa.rest[0]].append(fa.shift_sequence_and_copy())
self._push_keyboard_mode(sm)
elif mode.sequence_left:
mode.keymap.clear()
mode.keymap[mode.sequence_left[0]].append(final_action)
mode.sequence_left = mode.sequence_left[1:]
else:
self.pop_keyboard_mode()
return self.combine(final_action.definition)
if len(final_actions) == 1:
self.pop_keyboard_mode()
return self.combine(final_actions[0].definition)
mode.keymap.clear()
for fa in final_actions:
mode.keymap[fa.rest[0]].append(fa.shift_sequence_and_copy())
return True
final_action = final_actions[0]
consumed = self.combine(final_action.definition)
if consumed and not is_root_mode and mode.end_on_action:
if mode_pos < len(self.keyboard_mode_stack) and self.keyboard_mode_stack[mode_pos] is mode:
@ -1397,20 +1399,32 @@ class Boss:
return consumed
return False
def matching_key_action(self, candidates: Iterable[KeyDefinition]) -> Optional[KeyDefinition]:
def matching_key_actions(self, candidates: Iterable[KeyDefinition]) -> List[KeyDefinition]:
w = self.active_window
ans = None
matches = []
has_sequence_match = False
for x in candidates:
if x.options.when_focus_on:
try:
if w and w in self.match_windows(x.options.when_focus_on):
ans = x
matches.append(x)
if x.is_sequence:
has_sequence_match = True
except Exception:
self.show_error(_('Invalid key mapping'), _(
'The match expression {0} is not valid for {1}').format(x.options.when_focus_on, '--when-focus-on'))
return []
else:
ans = x
return ans
if x.is_sequence:
has_sequence_match = True
matches.append(x)
if has_sequence_match:
matches = [x for x in matches if x.is_sequence]
q = matches[-1].options.when_focus_on
matches = [x for x in matches if x.options.when_focus_on == q]
else:
matches = [matches[-1]]
return matches
def cancel_current_visual_select(self) -> None:
if self.current_visual_select:
@ -1975,6 +1989,7 @@ class Boss:
overlay_for=overlay_for,
)
@ac('misc', 'Show an error message with the specified title and text')
def show_error(self, title: str, msg: str) -> None:
tab = self.active_tab
w = self.active_window

View file

@ -65,7 +65,7 @@ class InvalidMods(ValueError):
@func_with_args(
'pass_selection_to_program', 'new_window', 'new_tab', 'new_os_window',
'new_window_with_cwd', 'new_tab_with_cwd', 'new_os_window_with_cwd',
'launch', 'mouse_handle_click'
'launch', 'mouse_handle_click', 'show_error',
)
def shlex_parse(func: str, rest: str) -> FuncArgsType:
return func, to_cmdline(rest)
@ -1184,6 +1184,9 @@ class KeyDefinition(BaseDefinition):
ans = f'[--when-focus-on={self.options.when_focus_on}]{ans}'
return ans
def shift_sequence_and_copy(self) -> 'KeyDefinition':
return KeyDefinition(self.is_sequence, self.trigger, self.rest[1:], self.definition, self.options)
def resolve_and_copy(self, kitty_mod: int) -> 'KeyDefinition':
def r(k: SingleKey) -> SingleKey:
return k.resolve_kitty_mod(kitty_mod)
@ -1199,7 +1202,7 @@ class KeyboardMode:
passthrough_unknown: bool = False
end_on_action: bool = False
sequence_left: Optional[Sequence[SingleKey]] = None
is_sequence: bool = False
def __init__(self, name: str = '') -> None:
self.name = name

View file

@ -62,7 +62,7 @@ __all__ = (
'GraphicsCommandType', 'HandlerType', 'AbstractEventLoop', 'AddressFamily', 'Socket', 'CompletedProcess',
'PopenType', 'Protocol', 'TypedDict', 'MarkType', 'ImageManagerType', 'Debug', 'LoopType', 'MouseEvent',
'TermManagerType', 'BossType', 'ChildType', 'BadLineType', 'MouseButton',
'KeyActionType', 'KeyMap', 'KittyCommonOpts', 'AliasMap', 'SequenceMap', 'CoreTextFont', 'WindowSystemMouseEvent',
'KeyActionType', 'KeyMap', 'KittyCommonOpts', 'AliasMap', 'CoreTextFont', 'WindowSystemMouseEvent',
'FontConfigPattern', 'ScreenType', 'StartupCtx', 'KeyEventType', 'LayoutType', 'PowerlineStyle',
'RemoteCommandType', 'SessionType', 'SessionTab', 'SpecialWindowInstance', 'TabType', 'ScreenSize', 'WindowType'
)