diff --git a/devel/202_106.md b/devel/202_106.md new file mode 100644 index 0000000000..57a891c5f4 --- /dev/null +++ b/devel/202_106.md @@ -0,0 +1,40 @@ +# 2886 Display Symbol Shortcuts in Right Footer + +## How to Test +1. Open a document in the editor. +2. Move the cursor to a position where a symbol is present. +3. Verify that the right footer displays the corresponding keyboard shortcut. +4. Move the cursor away from the symbol and confirm that the footer clears. + +--- + +## 2026/02/28 Display corresponding symbol shortcut keys in the right + +### What +Display the keyboard shortcut of a symbol in the right footer when the editor cursor is positioned at or near that symbol. + + +### How + +**Shortcut lookup (Scheme)** +`kbd-find-inv-binding` – resolves a command string (e.g., ``) to its inverse keyboard shortcut. + +**C++ integration** +`src/Edit/Interface/edit_footer.cpp` – two shortcut display paths: + +- **Symbol path:** + `get_shortcut_suffix(cmd_s)` calls `kbd-find-inv-binding`, rewrites the keybinding via `kbd_system_rewrite`, formats it as `" [Shortcut]"`, and caches the result using a static `hashmap`. + +- **Operation path:** + `compute_operation_footer()` retrieves the operation name via `drd->get_name(...)`, resolves its shortcut using `kbd_shortcut("(make ')")`, and appends it as `" [Shortcut]"`. + +**Footer rendering logic** +In `compute_text_footer()`: +- Detects symbol commands using `starts(r, "<")` (excluding `<#...>` internal commands). +- Retrieves the shortcut suffix via `get_shortcut_suffix()`. +- Appends the formatted shortcut to the displayed symbol in the footer. + +**Performance optimization** +A static `shortcut_cache` avoids repeated Scheme lookups during frequent cursor updates. Only the symbol resolution path uses caching. + +--- \ No newline at end of file diff --git a/src/Edit/Interface/edit_footer.cpp b/src/Edit/Interface/edit_footer.cpp index 8629d1183a..017fdbe5b7 100644 --- a/src/Edit/Interface/edit_footer.cpp +++ b/src/Edit/Interface/edit_footer.cpp @@ -130,6 +130,24 @@ edit_interface_rep::set_middle_footer () { * Set right footer with information about cursor position ******************************************************************************/ +// Cache for keyboard shortcuts +static hashmap shortcut_cache (""); + +tree +edit_interface_rep::get_shortcut_suffix (string cmd_s) { + if (shortcut_cache->contains (cmd_s)) return shortcut_cache[cmd_s]; + + object result_obj= call ("kbd-find-inv-binding", object (cmd_s)); + string binding = as_string (result_obj); + tree result = ""; + if (binding != "" && binding != "#f") { + tree shortcut_tree= sv->kbd_system_rewrite (binding); + result = concat (" [", shortcut_tree, "]"); + } + shortcut_cache (cmd_s)= result; + return result; +} + void edit_interface_rep::set_right_footer (tree r) { SERVER ( @@ -147,9 +165,12 @@ edit_interface_rep::compute_text_footer (tree st) { if (r == "") r= "start"; if (r == " ") r= "space"; if (r == "space" && get_env_string (MODE) == "math") r= "apply"; - if (starts (r, "<") && !starts (r, "<#")) + if (starts (r, "<") && !starts (r, "<#")) { + tree suffix= get_shortcut_suffix (r); if (cork_to_utf8 (r) != r) r= r * " (" * r (1, N (r) - 1) * ")"; - if (starts (r, "<")) return verbatim (r); + if (suffix != "") return concat (verbatim (r), suffix); + return verbatim (r); + } return r; } @@ -327,6 +348,10 @@ edit_interface_rep::compute_operation_footer (tree st) { } } if (last_item (tp) == 0) r= concat ("before ", r); + string op_name = drd->get_name (L (st)); + tree shortcut = kbd_shortcut ("(make '" * op_name * ")"); + string shortcut_s= as_string (shortcut); + if (shortcut_s != "") r= concat (r, " [", shortcut, "]"); return r; } diff --git a/src/Edit/Interface/edit_interface.hpp b/src/Edit/Interface/edit_interface.hpp index db5e7cfb45..86ae7a6537 100644 --- a/src/Edit/Interface/edit_interface.hpp +++ b/src/Edit/Interface/edit_interface.hpp @@ -259,6 +259,7 @@ class edit_interface_rep : virtual public editor_rep { bool should_show_image_popup (tree t); /* the footer */ + tree get_shortcut_suffix (string cmd_s); tree compute_text_footer (tree st); tree compute_operation_footer (tree st); tree compute_compound_footer (tree t, path p);