Skip to content

Commit b7c7ad5

Browse files
authored
Merge pull request #5726 from Textualize/keymap-key
normalize keys
2 parents 748fc07 + 852e503 commit b7c7ad5

File tree

4 files changed

+35
-2
lines changed

4 files changed

+35
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- Fixed markup escaping edge cases https://github.com/Textualize/textual/pull/5697
1313
- Fixed incorrect auto height in Collapsible https://github.com/Textualize/textual/pull/5703
14+
- Fixed issue with keymaps and single-letter keys https://github.com/Textualize/textual/pull/5726
1415

1516
### Changed
1617

src/textual/app.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
REPLACED_KEYS,
108108
_character_to_key,
109109
_get_unicode_name_from_key,
110+
_normalize_key_list,
110111
format_key,
111112
)
112113
from textual.messages import CallbackType, Prune
@@ -3697,6 +3698,13 @@ def action_help_quit(self) -> None:
36973698
)
36983699
return
36993700

3701+
@classmethod
3702+
def _normalize_keymap(cls, keymap: Keymap) -> Keymap:
3703+
"""Normalizes the keys in a keymap, so they use long form, i.e. "question_mark" rather than "?"."""
3704+
return {
3705+
binding_id: _normalize_key_list(keys) for binding_id, keys in keymap.items()
3706+
}
3707+
37003708
def set_keymap(self, keymap: Keymap) -> None:
37013709
"""Set the keymap, a mapping of binding IDs to key strings.
37023710
@@ -3709,7 +3717,8 @@ def set_keymap(self, keymap: Keymap) -> None:
37093717
Args:
37103718
keymap: A mapping of binding IDs to key strings.
37113719
"""
3712-
self._keymap = keymap
3720+
3721+
self._keymap = self._normalize_keymap(keymap)
37133722
self.refresh_bindings()
37143723

37153724
def update_keymap(self, keymap: Keymap) -> None:
@@ -3721,7 +3730,8 @@ def update_keymap(self, keymap: Keymap) -> None:
37213730
Args:
37223731
keymap: A mapping of binding IDs to key strings.
37233732
"""
3724-
self._keymap = {**self._keymap, **keymap}
3733+
3734+
self._keymap = {**self._keymap, **self._normalize_keymap(keymap)}
37253735
self.refresh_bindings()
37263736

37273737
def handle_bindings_clash(

src/textual/keys.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,15 @@ def _character_to_key(character: str) -> str:
354354
key = character
355355
key = KEY_NAME_REPLACEMENTS.get(key, key)
356356
return key
357+
358+
359+
def _normalize_key_list(keys: str) -> str:
360+
"""Normalizes a comma separated list of keys.
361+
362+
Replaces single letter keys with full name.
363+
"""
364+
365+
keys_list = [key.strip() for key in keys.split(",")]
366+
return ",".join(
367+
_character_to_key(key) if len(key) == 1 else key for key in keys_list
368+
)

tests/test_binding.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,13 @@ def signal_bindings_updated(screen: Screen) -> None:
127127
app.set_keymap({"quit": "f1"})
128128
await pilot.pause()
129129
assert bindings_updated == [app.screen, app.screen]
130+
131+
132+
async def test_keymap_key() -> None:
133+
app: App[None] = App()
134+
135+
async with app.run_test():
136+
app.set_keymap({"foo": "?,space"})
137+
assert app._keymap == {"foo": "question_mark,space"}
138+
app.update_keymap({"bar": "$"})
139+
assert app._keymap == {"bar": "dollar_sign", "foo": "question_mark,space"}

0 commit comments

Comments
 (0)