zulip-terminal
zulip-terminal copied to clipboard
Hotkeys/display
What does this PR do, and why?
Adds support to control and format the display of hotkey combinations to the user.
To render keys as seen on the keyboard, and/or using symbols for special keys.
To allow using different types of hotkey displays in different parts of the UI.
- Help Menu (Before)
- Help Menu (Using keyboard representation)
- Help Menu (Using symbols)
External discussion & connections
- [x] Partially fixes issue #1327
- [x] Partially fixes issue #945
- [x] Builds upon previous unmerged work in PR #1354
How did you test this?
- [x] Manually - Visual changes
- [x] Adapting existing automated tests
- [x] Adding automated tests for new behavior (or missing tests)
Table of Contents
- Changes Made
-
Decisions (feedback needed)
- Dev Decisions
- Symbol Decisions
-
Visual Changes
- Help Menu Comparison
-
Reference Data
- Key Mapping
- Hotkey Functions
- Commit Flow (in short)
Changes Made
View Changes Made
Places where hotkeys are displayed to the user:
- Zulip Terminal (updated)
- Buttons, Popups
- Help Menu
- Footer
- Menu View headers
- Docs (not updated)
- hotkeys.md
The next step: fully fixing issue #945
Introduced 2 ways of controlling display of hotkeys:
- The mapping function: Programmatically generate a uniform user-friendly version of all keys
- The mapping dict: Control the display of specific keys through a mapping dictionary (allows customization)
Added support for:
- [x] Keyboard representation
- [x] capitalization of special keys
- [x] capitalization of alphabet keys + use of Shift
- [x] custom renaming like PgUp, PgDown
- [x] Symbols
- [ ] Support keys of different platforms
Urwid maps Alt to meta.
As of now, there are no shortcuts using the Super/Command/Windows key.
So, support for this has not been added in this PR. - [ ] Adding a '+' between keys
Decisions (feedback needed)
Dev Decisions
View Dev Decisions
- New Hotkey Functions
Options available:
- [x] Write the code for each occurrence (redundancy)
In
ui.py
andviews.py
, (just 2 occurrences)
", ".join( [keyboard_key_for_urwid_key(urwid_key) for urwid_key in random_command["keys"]] )
- [ ] Write a function and call it (bulky)
def keyboard_keys_for_urwid_keys(urwid_keys: List[str]) -> List[str]:
""" Returns the user-friendly keyboard keys for a list of urwid keys """
return [keyboard_key_for_urwid_key(urwid_key) for urwid_key in urwid_keys]
- Handling "Line too Long" linting errors, due to long function names
Options available:
- [ ] Rename functions
- Existing functions with extremely similar names
- Rename them as well
- Existing functions with extremely similar names
- [x] Fix each occurrence (calling code) by breaking it down into multiple lines (black formatting) Con: Increases LOC by a lot.
- [ ] Adding aliases to the function
-
Location of URWID_KEY_TO_KEYBOARD_KEY_MAPPING
Ideally, the map should be located in zulipterminal/config/ui_mappings.py.
But, there's a circular import issue.
keys.py
imports fromui_mappings.py
imports fromhelper.py
imports fromkeys.py
helper.py
- defines types (
StreamAccessType
andUserStatus
) that are used byui_mappings.py
, - uses a key for the command
NARROW_MESSAGE_RECIPIENT
.
Options available:
-
[ ] Put the map in ui_mappings.py
- [ ] Move the custom types outside helper.py, and import
- [ ] To ui_mappings.py (uses those types)
- [ ] To api_types.py (loads early, types are not actually API types)
- [ ] To model.py (uses it, but loads much later)
- [ ] somewhere else?
- [ ] Move the custom types outside helper.py, and import
-
[x] Put the map in keys.py
- Organization of the commits Commit Flow (in short)
Symbol Decisions
View Symbol Decisions
- Symbols vs Keys
Options available:
- [ ] in addition to text name of keys
- [x] as replacement of key names
Assumption: Terminal users would be able to recognize or figure out keys' symbols
- Symbol Options
Symbol Options
Key | Option 1 | Option 2 |
---|---|---|
Ctrl | ||
Meta | ||
Enter | ||
Shift | ||
Arrow keys | ||
- Meta key:
Alt key
(option 2) takes up more width, so went withOption key
(option 1)
Visual Changes:
View Visual Changes
Footer Comparison
Applied | Footer |
---|---|
Keyboard Keys | |
Keyboard Keys | |
Symbols |
Right Edge (just meta key symbols)
Applied | Right Edge |
---|---|
Keyboard keys | |
Keyboard keys | |
Symbols | |
Symbols |
Header - arrow keys
Header | Change |
---|---|
1 space | |
2 spaces |
Left Column View
Left Column View Sizing |
---|
View visual comparison of the symbol options
Observations:
-
Alt
+Enter
- cuts too close to the right edge of the Help Menu- But only when using symbols (The text version wraps around fine)
- When using "Shift", the size of the left side panel is extended and fixed (cannot be shrunken/wrapped)
- Minimum length of terminal for the Help Menu symbols to render: 66 columns
Help Menu Comparison
View images: Help Menu Comparison
Help Menu (Before)
View images: Help Menu (Before)
Help Menu (Keyboard representation)
View images: Help Menu (Keyboard representation)
Help Menu (Symbols)
View images: Help Menu (Symbols)
Reference Data
View Reference Data
Target Reference for Keys: this (from Zulip docs) Flow: hotkeys in the UI -> Urwid keys -> Zulip Terminal cmd -> Urwid cmd -> command string in Urwid
Key Mapping
Old keys | New keys | Symbols version |
---|---|---|
ctrl, shift, meta, enter, esc | Ctrl, Shift, Alt, Enter, Esc | ✲, ⇧, ⌥, ⏎, NA |
up, down, left, right | Up, Down, Left, Right | ↑, ↓, ←, → |
lowercase alphabets | uppercase alphabets | NA |
uppercase alphabets | Shift + uppercase alphabets | NA |
symbols | NA | NA |
page up, page down | PgUp, PgDown | NA |
These are the keys in use in hotkey combinations.
Hotkey Functions
(keys.py
)
Function | Purpose | Existing/New |
---|---|---|
keys_for_command(cmd) | Get urwid keys - used in keypresses | Existing |
primary_key_for_command(cmd) | used in keypresses | Existing |
keyboard_keys_for_command(cmd) | used in the UI | New |
primary_keyboard_key_for_command(cmd) | used in the UI | New |
Aux Function | Purpose | Existing/New |
---|---|---|
is_command_key() | check if valid command | Existing |
commands_for_random_tips() | gets KeyBindings, used in footer | Existing |
substitute_selected_keyboard_keys(key) | apply mapping dict | New |
keyboard_key_for_urwid_key(key) | mapping function | New |
Commit Flow (in short)
- Add mapping function: urwid key -> formatted key (keyboard representation)
- Add mapping dict: urwid key -> custom display
- Support combined use of mapping function + dict
- Add functions: commands -> keyboard keys
- Update the UI to use the keyboard keys
- Add symbols map
- Update the mapping dict and function to use symbols (replacing text representation) in the UI
- Update View headers to use arrow keys
@zulipbot add "area: hotkeys" "PR needs review" "feedback wanted" "enhancement"
Hello @zulip/server-hotkeys members, this pull request was labeled with the "area: hotkeys" label, so you may want to check it out!
@zulipbot remove "PR awaiting update" @zulipbot add "PR needs review"
@zulipbot remove "PR awaiting update" @zulipbot add "PR needs review"
@Niloth-p Thanks for the update - I just pushed back with minor commit text updates, and will merge shortly :tada:
The test ids you've added are fine as they are, though if the parametrize data and the ids run too long then it's generally good to include them inline instead so it's clear how they connect and that they don't get out of sync.
Other than the elements that we've already discussed for following up on this:
- Your new test array is coupled to the current keymap, so changes of that will impact tests and vice versa. This occurs for other tests in this file, so a commit with refactor(s) to tidy that up using a common approach similar to the random tips would be useful.
This sufficiently fixes #1327 as a first pass.
Generally see #zulip-terminal > Keyboard rendering followups for related discussion of next steps.