mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-06-25 10:27:24 +00:00
Allow more options for what to do in a custom keyboard mode on unknown and action events
This commit is contained in:
parent
ca6c607148
commit
d191896528
3 changed files with 51 additions and 17 deletions
|
|
@ -1369,6 +1369,13 @@ class Boss:
|
|||
return False
|
||||
if self.global_shortcuts_map and get_shortcut(self.global_shortcuts_map, ev):
|
||||
return True
|
||||
if not is_root_mode:
|
||||
if mode.on_unknown in ('beep', 'ignore'):
|
||||
if mode.on_unknown == 'beep' and get_options().enable_audio_bell:
|
||||
ring_bell()
|
||||
return True
|
||||
if mode.on_unknown == 'passthrough':
|
||||
return False
|
||||
if not self.pop_keyboard_mode():
|
||||
if get_options().enable_audio_bell:
|
||||
ring_bell()
|
||||
|
|
@ -1380,7 +1387,7 @@ class Boss:
|
|||
if final_actions[0].is_sequence:
|
||||
if not mode.is_sequence:
|
||||
sm = KeyboardMode('__sequence__')
|
||||
sm.end_on_action = True
|
||||
sm.on_action = 'end'
|
||||
sm.is_sequence = True
|
||||
for fa in final_actions:
|
||||
sm.keymap[fa.rest[0]].append(fa.shift_sequence_and_copy())
|
||||
|
|
@ -1399,7 +1406,7 @@ class Boss:
|
|||
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 consumed and not is_root_mode and mode.on_action == 'end':
|
||||
if mode_pos < len(self.keyboard_mode_stack) and self.keyboard_mode_stack[mode_pos] is mode:
|
||||
del self.keyboard_mode_stack[mode_pos]
|
||||
if not self.keyboard_mode_stack:
|
||||
|
|
@ -1463,7 +1470,7 @@ class Boss:
|
|||
self.current_visual_select.window_used_for_selection_id = 0 if w is None else w.id
|
||||
return
|
||||
km = KeyboardMode('__visual_select__')
|
||||
km.end_on_action = True
|
||||
km.on_action = 'end'
|
||||
fmap = get_name_to_functional_number_map()
|
||||
alphanumerics = get_options().visual_window_select_characters
|
||||
for idx, window in tab.windows.iter_windows_with_number(only_visible=True):
|
||||
|
|
|
|||
|
|
@ -105,8 +105,8 @@ def finalize_keys(opts: Options, accumulate_bad_lines: Optional[List[BadLine]] =
|
|||
for defn in defns:
|
||||
if defn.options.new_mode:
|
||||
modes[defn.options.new_mode] = nm = KeyboardMode(defn.options.new_mode)
|
||||
nm.passthrough_unknown = defn.options.passthrough_unknown
|
||||
nm.end_on_action = defn.options.end_on_action
|
||||
nm.on_unknown = defn.options.on_unknown
|
||||
nm.on_action = defn.options.on_action
|
||||
defn.definition = f'push_keyboard_mode {defn.options.new_mode}'
|
||||
try:
|
||||
m = modes[defn.options.mode]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,25 @@ import sys
|
|||
from collections import defaultdict
|
||||
from dataclasses import dataclass, fields
|
||||
from functools import lru_cache
|
||||
from typing import Any, Callable, Container, Dict, FrozenSet, Iterable, Iterator, List, NamedTuple, Optional, Sequence, Tuple, Union
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
Container,
|
||||
Dict,
|
||||
FrozenSet,
|
||||
Generic,
|
||||
Iterable,
|
||||
Iterator,
|
||||
List,
|
||||
Literal,
|
||||
NamedTuple,
|
||||
Optional,
|
||||
Sequence,
|
||||
Tuple,
|
||||
TypeVar,
|
||||
Union,
|
||||
get_args,
|
||||
)
|
||||
|
||||
import kitty.fast_data_types as defines
|
||||
from kitty.conf.utils import (
|
||||
|
|
@ -1134,20 +1152,29 @@ class MouseMapping(BaseDefinition):
|
|||
return MouseEvent(self.button, self.mods, self.repeat_count, self.grabbed)
|
||||
|
||||
|
||||
class BoolField:
|
||||
def __init__(self, default: bool = False):
|
||||
self._default = default
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
class LiteralField(Generic[T]):
|
||||
def __init__(self, vals: Tuple[T, ...]):
|
||||
self._vals = vals
|
||||
|
||||
def __set_name__(self, owner: object, name: str) -> None:
|
||||
self._name = "_" + name
|
||||
|
||||
def __get__(self, obj: object, type: Optional[type] = None) -> bool:
|
||||
def __get__(self, obj: object, type: Optional[type] = None) -> T:
|
||||
if obj is None:
|
||||
return self._default
|
||||
return getattr(obj, self._name, self._default)
|
||||
return self._vals[0]
|
||||
return getattr(obj, self._name, self._vals[0])
|
||||
|
||||
def __set__(self, obj: object, value: str) -> None:
|
||||
setattr(obj, self._name, to_bool(value))
|
||||
if value not in self._vals:
|
||||
raise KeyError(f'Invalid value for {self._name[1:]}: {value!r}')
|
||||
setattr(obj, self._name, value)
|
||||
|
||||
|
||||
OnUnknown = Literal['beep', 'end', 'ignore', 'passthrough']
|
||||
OnAction = Literal['keep', 'end']
|
||||
|
||||
|
||||
@dataclass(init=False, frozen=True)
|
||||
|
|
@ -1155,8 +1182,8 @@ class KeyMapOptions:
|
|||
when_focus_on: str = ''
|
||||
new_mode: str = ''
|
||||
mode: str = ''
|
||||
passthrough_unknown: BoolField = BoolField(False)
|
||||
end_on_action: BoolField = BoolField(False)
|
||||
on_unknown = LiteralField[OnUnknown](get_args(OnUnknown))
|
||||
on_action = LiteralField[OnAction](get_args(OnAction))
|
||||
|
||||
|
||||
default_key_map_options = KeyMapOptions()
|
||||
|
|
@ -1205,8 +1232,8 @@ class KeyDefinition(BaseDefinition):
|
|||
|
||||
class KeyboardMode:
|
||||
|
||||
passthrough_unknown: bool = False
|
||||
end_on_action: bool = False
|
||||
on_unknown: OnUnknown = get_args(OnUnknown)[0]
|
||||
on_action : OnAction = get_args(OnAction)[0]
|
||||
is_sequence: bool = False
|
||||
|
||||
def __init__(self, name: str = '') -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue