|
| 1 | +[222_65] 修复右侧 footer 快捷键显示错误,并补齐 operation footer 的快捷键提示 |
| 2 | + |
| 3 | +## 如何测试 |
| 4 | + |
| 5 | +测试项一:数学符号在右侧 footer 中显示对应快捷键 |
| 6 | +1. 打开任意文档,进入数学模式 |
| 7 | +2. 输入 `a tab`,得到 `<alpha>` |
| 8 | +3. 将光标移动到 `<alpha>` 附近 |
| 9 | +4. 右侧 footer 应显示 `<alpha>` 以及对应的快捷键提示,不应只显示符号本身 |
| 10 | + |
| 11 | +测试项二:不同数学符号都能实时显示对应快捷键 |
| 12 | +1. 打开任意文档,进入数学模式 |
| 13 | +2. 输入 `- >`,得到 `<rightarrow>` |
| 14 | +3. 将光标移走,再移动到 `<rightarrow>` 附近 |
| 15 | +4. 右侧 footer 应显示 `<rightarrow>` 以及对应的快捷键提示 |
| 16 | +5. 再输入 `@ @`,得到 `<infty>` |
| 17 | +6. 将光标移走,再移动到 `<infty>` 附近 |
| 18 | +7. 右侧 footer 应更新为 `<infty>` 的快捷键提示,不应继续停留在 `<rightarrow>` 的结果 |
| 19 | + |
| 20 | +测试项三:同一个符号在不同上下文中切换时,footer 应按当前上下文实时更新 |
| 21 | +1. 打开任意文档,先进入一个可以显示符号快捷键的上下文 |
| 22 | +2. 将光标移动到某个带快捷键提示的符号附近,记录右侧 footer 内容 |
| 23 | +3. 切换到另一个编辑上下文,再将光标移动到相同符号附近 |
| 24 | +4. 右侧 footer 应按当前上下文重新计算结果,不应复用上一次上下文中的旧显示结果 |
| 25 | + |
| 26 | +测试项四:光标连续移动时,footer 快捷键提示应持续更新 |
| 27 | +1. 打开任意包含多个符号和 operation 的文档 |
| 28 | +2. 使用方向键连续移动光标,依次经过普通字符、数学符号、结构性节点 |
| 29 | +3. 右侧 footer 应随着光标位置实时切换显示内容 |
| 30 | +4. 不应出现已经离开的符号快捷键残留在 footer 中的情况 |
| 31 | + |
| 32 | +测试项五:根号、分式、上下标等结构在插入后应显示 operation 快捷键 |
| 33 | +1. 打开任意文档,进入数学模式 |
| 34 | +2. 依次执行以下操作: |
| 35 | + 输入根号 |
| 36 | + 输入分式 |
| 37 | + 输入右下标 / 右上标 |
| 38 | +3. 每次插入后,光标都会落在结构内部空槽中 |
| 39 | +4. 右侧 footer 应显示对应的 operation 文案和快捷键,不应退化为普通 text footer |
| 40 | +5. 至少验证以下几类: |
| 41 | + `square root` |
| 42 | + `fraction` |
| 43 | + `subscript` / `superscript` |
| 44 | + |
| 45 | +测试项六:大运算符应显示对应快捷键 |
| 46 | +1. 打开任意文档,进入数学模式 |
| 47 | +2. 插入 `sum`、`prod`、`int` 等大运算符 |
| 48 | +3. 将光标移动到这些结构附近 |
| 49 | +4. 右侧 footer 应显示对应 operation 文案和快捷键 |
| 50 | +5. 不应继续走默认 `(make 'op)` fallback 而丢失快捷键 |
| 51 | + |
| 52 | +测试项七:定界符结构的快捷键显示行为 |
| 53 | +1. 打开任意文档,进入数学模式 |
| 54 | +2. 分别插入 `()`, `[]`, `{}` 等定界符结构 |
| 55 | +3. 将光标移动到对应结构附近,观察右侧 footer 中的快捷键提示 |
| 56 | +4. 再打开数学工具栏中的大型定界符菜单,将鼠标悬浮到对应符号上,观察工具栏菜单的快捷键提示 |
| 57 | +5. 对比两者是否一致 |
| 58 | +6. 当前已知结论: |
| 59 | + 对定界符这类结构,footer 的反查结果可能与菜单 tooltip 不一致 |
| 60 | + 这是由于 footer 只能从结果树逆向推回 source,而菜单直接持有原始 source |
| 61 | + |
| 62 | +## 2026/04/01 修复右侧 footer 快捷键缓存导致的错误显示 |
| 63 | + |
| 64 | +### What |
| 65 | +移除 `src/Edit/Interface/edit_footer.cpp` 中按符号字符串做 key 的全局快捷键缓存,改为每次 footer 更新时按当前上下文实时调用 `kbd-find-inv-binding` 反查快捷键。 |
| 66 | + |
| 67 | +### Why |
| 68 | +此前右侧 footer 的快捷键显示使用了进程级静态缓存,只以 `<alpha>`、`<rightarrow>` 这类符号字符串作为缓存 key。 |
| 69 | +但 `kbd-find-inv-binding` 实际是上下文相关的反查接口,键盘绑定本身可能带有 mode 和 require 条件。 |
| 70 | +这样会导致第一次查到的结果被缓存下来,之后即使切换上下文,footer 仍然可能显示旧的快捷键结果,不能满足“实时显示当前快捷键”的需求。 |
| 71 | + |
| 72 | +### How |
| 73 | +src/Edit/Interface/edit_footer.cpp 删除 `shortcut_cache` |
| 74 | +src/Edit/Interface/edit_footer.cpp :143 `get_shortcut_suffix` 改为直接调用 `kbd-find-inv-binding` |
| 75 | +src/Edit/Interface/edit_footer.cpp :161 `compute_text_footer` 继续复用 `get_shortcut_suffix`,但结果不再受旧缓存污染 |
| 76 | + |
| 77 | +## 2026/04/01 补齐 operation footer 的快捷键提示 |
| 78 | + |
| 79 | +### What |
| 80 | +为 `compute_operation_footer()` 增加快捷键后缀逻辑,使 operation 类型的 footer 也能显示对应快捷键。 |
| 81 | + |
| 82 | +### Why |
| 83 | +此前实现只在 `compute_text_footer()` 中为 `<symbol>` 追加快捷键提示,而 `compute_operation_footer()` 只返回 `square root`、`long arrow`、`hat` 这类文本描述,没有追加快捷键。 |
| 84 | +这会导致 symbol path 能显示快捷键,但 operation path 不能显示,实际效果与原功能说明不一致。 |
| 85 | + |
| 86 | +### How |
| 87 | +src/Edit/Interface/edit_footer.cpp :222 `compute_operation_footer` 新增 `suffix` |
| 88 | +src/Edit/Interface/edit_footer.cpp :355 使用 `drd->get_name (L (st))` 组装 `"(make '<op>)"`,并通过 `get_shortcut_suffix` 统一反查快捷键 |
| 89 | +src/Edit/Interface/edit_footer.cpp :356 当存在绑定时,将快捷键后缀追加到 operation footer 文本后 |
| 90 | + |
| 91 | +## 2026/04/01 结构命令反查需要传 command object,而不是字符串 |
| 92 | + |
| 93 | +### What |
| 94 | +为 footer 的结构类快捷键反查补齐 command object 转换,确认 `kbd-find-inv-binding` 对不同参数形式的行为差异。 |
| 95 | + |
| 96 | +### Why |
| 97 | +排查发现 `<alpha>` 这类 symbol 可以直接用字符串反查,但 `(make-sqrt)`、`(make-fraction)`、`(make-script #f #t)` 这类结构命令如果直接以字符串传给 `kbd-find-inv-binding`,会返回空结果。 |
| 98 | +原因在于逆向绑定表里存储的是命令对象,而不是命令源码字符串。 |
| 99 | + |
| 100 | +- `"<alpha>"` 作为字符串可以命中 |
| 101 | +- `"(make-sqrt)"` / `"make-sqrt"` 作为字符串不能命中 |
| 102 | +- `'(make-sqrt)` 和 `(string->object "(make-sqrt)")` 可以命中 |
| 103 | +- 返回结果是内部 binding 形式,例如 `A-s`、`A-f`,而不一定是源码里的 `"math s"`、`"math f"` |
| 104 | + |
| 105 | +### How |
| 106 | +src/Edit/Interface/edit_footer.cpp :144 `get_shortcut_suffix` 改为: |
| 107 | +- 普通 symbol 继续使用 `object (cmd_s)` |
| 108 | +- 以 `(` 开头的命令字符串先 `string_to_object (cmd_s)`,再传给 `kbd-find-inv-binding` |
| 109 | + |
| 110 | +## 2026/04/01 operation footer 在空占位原子节点中提升到父结构节点 |
| 111 | + |
| 112 | +### What |
| 113 | +修复刚插入根号、分式、上下标、上下附标等结构时,右侧 footer 只走 text path、不显示 operation shortcut 的问题。 |
| 114 | + |
| 115 | +### Why |
| 116 | +这些结构在插入后会立刻把光标放进内部空原子节点中,例如 `SQRT("")`、`RSUB("")`。 |
| 117 | +此时 `set_right_footer()` 中的 |
| 118 | + |
| 119 | +`subtree (et, path_up (tp))` |
| 120 | + |
| 121 | +读到的是空原子子节点,而不是外层结构节点,导致逻辑总是进入 `compute_text_footer()`,根本不会调用 `compute_operation_footer()`。 |
| 122 | + |
| 123 | +### How |
| 124 | +src/Edit/Interface/edit_footer.cpp :512 `set_right_footer()` 修改分发逻辑: |
| 125 | +- 当当前节点是原子节点时,先查看 `path_up (tp, 2)` 对应的父节点 |
| 126 | +- 若父节点标签属于 `LSUB`、`LSUP`、`RSUB`、`RSUP`、`FRAC`、`SQRT`、`ABOVE`、`BELOW`、`WIDE`、`VAR_WIDE` |
| 127 | +- 则直接对父节点调用 `compute_operation_footer(parent)` |
| 128 | +- 其他情况仍保持原有 text path |
| 129 | + |
| 130 | +## 2026/04/01 get_operation_shortcut_suffix 补齐结构类命令映射 |
| 131 | + |
| 132 | +### What |
| 133 | +新增 `get_operation_shortcut_suffix(tree st)`,把 operation footer 的快捷键反查从统一的 `(make 'op)` fallback 提升为“按结构类别选择命令对象”。 |
| 134 | + |
| 135 | +### Why |
| 136 | +结构类节点的实际插入命令并不统一: |
| 137 | +- `FRAC` 对应 `(make-fraction)` |
| 138 | +- `SQRT` 对应 `(make-sqrt)` / `(make-var-sqrt)` |
| 139 | +- `RSUB/RSUP/LSUB/LSUP` 对应 `(make-script ...)` |
| 140 | +- `ABOVE/BELOW` 对应 `(make-above)` / `(make-below)` |
| 141 | +- `BIG(sum)`、`BIG(prod)`、`BIG(int)` 对应 `(math-big-operator "...")` |
| 142 | +- `WIDE/VAR_WIDE` 对应 `(make-wide "...")` / `(make-wide-under "...")` |
| 143 | + |
| 144 | +如果继续统一走 `(make 'op)`,这些结构大都无法正确反查。 |
| 145 | + |
| 146 | +### How |
| 147 | +src/Edit/Interface/edit_interface.hpp 新增 `get_operation_shortcut_suffix (tree st)` 声明。 |
| 148 | + |
| 149 | +src/Edit/Interface/edit_footer.cpp :156 新增 `get_operation_shortcut_suffix`: |
| 150 | +- `FRAC` -> `(make-fraction)` |
| 151 | +- `SQRT` -> `(make-sqrt)` / `(make-var-sqrt)` |
| 152 | +- `LSUB/LSUP/RSUB/RSUP` -> `(make-script ...)` |
| 153 | +- `ABOVE/BELOW` -> `(make-above)` / `(make-below)` |
| 154 | +- `BIG` -> 根据 `st[0]` 中的 `<sum>` / `<prod>` / `<int>` 等内容,组装 `(math-big-operator "...")` |
| 155 | +- `WIDE/VAR_WIDE` -> `(make-wide "...")` / `(make-wide-under "...")` |
| 156 | +- 其他结构保留 `(make 'op)` fallback |
| 157 | + |
| 158 | +`compute_operation_footer()` 改为统一调用这个 helper。 |
| 159 | + |
| 160 | +## 2026/04/01 定界符结构的逆向结果与菜单提示不一致 |
| 161 | + |
| 162 | +### What |
| 163 | +尝试为 `AROUND` / `VAR_AROUND` 结构补齐快捷键显示,并排查为什么 footer 中会出现 `Alt+L [`,而数学工具栏大型定界符菜单悬浮提示显示的是 `[`。 |
| 164 | + |
| 165 | +### Why |
| 166 | +大型定界符菜单里的每个按钮都带有原始命令 source,例如: |
| 167 | + |
| 168 | +`(math-bracket-open "[" "]" 'default)` |
| 169 | + |
| 170 | +菜单系统在 `TeXmacs/progs/kernel/gui/menu-widget.scm` 中直接对这个 source 调用 `kbd-find-shortcut`,因此能稳定返回按钮自身对应的快捷键。 |
| 171 | + |
| 172 | +footer 则不同: |
| 173 | +- footer 拿到的是结果树,如 `around` / `around*` |
| 174 | +- 然后再从结果树反推命令 source |
| 175 | +- 对括号结构来说,同一个结果树可能对应多条合法绑定: |
| 176 | + - 普通绑定:`"[" -> (make-bracket-open "[" "]")` |
| 177 | + - 数学默认括号:`(math-bracket-open "[" "]" 'default)` |
| 178 | + - large 定界符:`"math:left [" -> (math-bracket-open "[" "]" #t)` |
| 179 | + |
| 180 | +逆向系统在多条候选里可能返回 large 这条,因此 footer 中会看到 `Alt+L [` 这样的前缀式结果。 |
| 181 | +这并不代表 `Alt+L` 是一个完整快捷键,而是 `math:left` 这个前缀组的显示形式。 |
| 182 | + |
| 183 | +### 结论 |
| 184 | +对于括号这类结构,问题的根源不在 footer 拼接,而在逆向系统本身: |
| 185 | +- 菜单是 `source -> shortcut`,一对一,结果稳定 |
| 186 | +- footer 是 `tree -> source -> shortcut`,一对多,容易命中“合法但不符合直觉”的候选 |
| 187 | + |
| 188 | +本轮代码里为复用菜单逻辑,新增了: |
| 189 | +- `TeXmacs/progs/kernel/gui/menu-widget.scm` : `kbd-find-shortcut-export` |
| 190 | +- `src/Edit/Interface/edit_footer.cpp` : `get_display_shortcut_suffix` |
| 191 | + |
0 commit comments