Skip to content

Commit 8c223fb

Browse files
authored
[222_65] 数学符号输入后 footer 实时显示对应快捷键 (#3088)
1 parent bbd5d6d commit 8c223fb

File tree

2 files changed

+135
-68
lines changed

2 files changed

+135
-68
lines changed

devel/222_65.md

Lines changed: 117 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -59,74 +59,94 @@
5959
对定界符这类结构,footer 的反查结果可能与菜单 tooltip 不一致
6060
这是由于 footer 只能从结果树逆向推回 source,而菜单直接持有原始 source
6161

62-
## 2026/04/01 修复右侧 footer 快捷键缓存导致的错误显示
62+
测试项八:快捷键直接插入后,右侧 footer 不应被临时消息覆盖
63+
1. 打开任意文档,进入数学模式
64+
2. 使用快捷键直接输入一个会立即合成的 symbol 或 operation
65+
3. 观察右侧 footer 在合成后的显示结果
66+
4. 右侧 footer 应直接稳定显示当前 symbol / operation 对应的快捷键
67+
5. 不应出现“先短暂显示正确结果、随后又被旧的快捷键提示覆盖”的现象
68+
6. 至少验证以下几类:
69+
`a tab -> <alpha>`
70+
根号
71+
分式
72+
73+
## 2026/04/01 快捷键执行后的临时右侧消息会覆盖实时 footer
6374

6475
### What
65-
移除 `src/Edit/Interface/edit_footer.cpp` 中按符号字符串做 key 的全局快捷键缓存,改为每次 footer 更新时按当前上下文实时调用 `kbd-find-inv-binding` 反查快捷键
76+
修复使用快捷键直接敲出 symbol / operation 后,右侧 footer 会先短暂显示正确快捷键、随后又被旧的快捷键提示覆盖掉的问题
6677

6778
### Why
68-
此前右侧 footer 的快捷键显示使用了进程级静态缓存,只以 `<alpha>``<rightarrow>` 这类符号字符串作为缓存 key。
69-
`kbd-find-inv-binding` 实际是上下文相关的反查接口,键盘绑定本身可能带有 mode 和 require 条件。
70-
这样会导致第一次查到的结果被缓存下来,之后即使切换上下文,footer 仍然可能显示旧的快捷键结果,不能满足“实时显示当前快捷键”的需求。
79+
排查发现问题不在 `set_right_footer()` 的计算逻辑,而在快捷键执行路径中的临时消息覆盖:
7180

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`,但结果不再受旧缓存污染
81+
`src/Edit/Interface/edit_keyboard.cpp` :128
7682

77-
## 2026/04/01 补齐 operation footer 的快捷键提示
83+
`try_shortcut()` 在命中快捷键后会先执行
7884

79-
### What
80-
`compute_operation_footer()` 增加快捷键后缀逻辑,使 operation 类型的 footer 也能显示对应快捷键。
85+
`set_message (help, rew)`
8186

82-
### Why
83-
此前实现只在 `compute_text_footer()` 中为 `<symbol>` 追加快捷键提示,而 `compute_operation_footer()` 只返回 `square root``long arrow``hat` 这类文本描述,没有追加快捷键。
84-
这会导致 symbol path 能显示快捷键,但 operation path 不能显示,实际效果与原功能说明不一致。
87+
其中:
88+
- `help` 写入左侧 footer
89+
- `rew` 写入右侧 footer
8590

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 文本后
91+
随后 `src/Edit/Interface/edit_footer.cpp``set_footer()` 的分发逻辑是:
92+
-`message_r == ""` 时,调用无参 `set_right_footer()`,按当前光标位置实时计算 footer
93+
-`message_r != ""` 时,直接调用 `set_right_footer (message_r)`,显示临时右侧消息
9094

91-
## 2026/04/01 结构命令反查需要传 command object,而不是字符串
95+
这就导致:
96+
- 快捷键执行后,基于当前树结构调用 `set_right_footer()` 时,右侧 footer 一度是正确的
97+
- 但紧接着 decoration 刷新又读到了尚未清空的 `message_r`
98+
- 因此右侧 footer 很快又被 `rew` 覆盖
9299

93-
### What
94-
为 footer 的结构类快捷键反查补齐 command object 转换,确认 `kbd-find-inv-binding` 对不同参数形式的行为差异。
100+
表现上就是:
101+
- 乐高符号或结构刚合成的一瞬间,footer 看起来是对的
102+
- 然后马上被刷回快捷键提示本身
95103

96-
### Why
97-
排查发现 `<alpha>` 这类 symbol 可以直接用字符串反查,但 `(make-sqrt)``(make-fraction)``(make-script #f #t)` 这类结构命令如果直接以字符串传给 `kbd-find-inv-binding`,会返回空结果。
98-
原因在于逆向绑定表里存储的是命令对象,而不是命令源码字符串。
104+
### How
105+
src/Edit/Interface/edit_keyboard.cpp :103 `try_shortcut()` 新增 `executed` 标记。
99106

100-
- `"<alpha>"` 作为字符串可以命中
101-
- `"(make-sqrt)"` / `"make-sqrt"` 作为字符串不能命中
102-
- `'(make-sqrt)``(string->object "(make-sqrt)")` 可以命中
103-
- 返回结果是内部 binding 形式,例如 `A-s``A-f`,而不一定是源码里的 `"math s"``"math f"`
107+
src/Edit/Interface/edit_keyboard.cpp :145 修改快捷键执行后的逻辑:
108+
- 只有在快捷键真正执行了 `cmd()``kbd-insert` 时,才认为本次 shortcut 已完成
109+
- 对“只匹配到前缀、尚未完成输入”的情况,不做额外处理
104110

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`
111+
src/Edit/Interface/edit_keyboard.cpp :153 在 shortcut 真正执行完成后:
112+
-`message_r` 清空
113+
- 立即调用无参 `set_right_footer()`
109114

110-
## 2026/04/01 operation footer 在空占位原子节点中提升到父结构节点
115+
这样可以保证:
116+
- 左侧 `help` 提示仍然保留
117+
- 右侧不再被临时 `rew` 覆盖
118+
- footer 最终显示的是当前光标位置对应的实时 symbol / operation shortcut
119+
## 2026/04/01 定界符结构的逆向结果与菜单提示不一致
111120

112121
### What
113-
修复刚插入根号、分式、上下标、上下附标等结构时,右侧 footer 只走 text path、不显示 operation shortcut 的问题
122+
尝试为 `AROUND` / `VAR_AROUND` 结构补齐快捷键显示,并排查为什么 footer 中会出现 `Alt+L [`,而数学工具栏大型定界符菜单悬浮提示显示的是 `[`
114123

115124
### Why
116-
这些结构在插入后会立刻把光标放进内部空原子节点中,例如 `SQRT("")``RSUB("")`
117-
此时 `set_right_footer()` 中的
125+
大型定界符菜单里的每个按钮都带有原始命令 source,例如:
118126

119-
`subtree (et, path_up (tp))`
127+
`(math-bracket-open "[" "]" 'default)`
120128

121-
读到的是空原子子节点,而不是外层结构节点,导致逻辑总是进入 `compute_text_footer()`,根本不会调用 `compute_operation_footer()`
129+
菜单系统在 `TeXmacs/progs/kernel/gui/menu-widget.scm` 中直接对这个 source 调用 `kbd-find-shortcut`,因此能稳定返回按钮自身对应的快捷键
122130

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
131+
footer 则不同:
132+
- footer 拿到的是结果树,如 `around` / `around*`
133+
- 然后再从结果树反推命令 source
134+
- 对括号结构来说,同一个结果树可能对应多条合法绑定:
135+
- 普通绑定:`"[" -> (make-bracket-open "[" "]")`
136+
- 数学默认括号:`(math-bracket-open "[" "]" 'default)`
137+
- large 定界符:`"math:left [" -> (math-bracket-open "[" "]" #t)`
138+
139+
逆向系统在多条候选里可能返回 large 这条,因此 footer 中会看到 `Alt+L [` 这样的前缀式结果。
140+
这并不代表 `Alt+L` 是一个完整快捷键,而是 `math:left` 这个前缀组的显示形式。
129141

142+
### 结论
143+
对于括号这类结构,问题的根源不在 footer 拼接,而在逆向系统本身:
144+
- 菜单是 `source -> shortcut`,一对一,结果稳定
145+
- footer 是 `tree -> source -> shortcut`,一对多,容易命中“合法但不符合直觉”的候选
146+
147+
本轮代码里为复用菜单逻辑,新增了:
148+
- `TeXmacs/progs/kernel/gui/menu-widget.scm` : `kbd-find-shortcut-export`
149+
- `src/Edit/Interface/edit_footer.cpp` : `get_display_shortcut_suffix`
130150
## 2026/04/01 get_operation_shortcut_suffix 补齐结构类命令映射
131151

132152
### What
@@ -156,36 +176,67 @@ src/Edit/Interface/edit_footer.cpp :156 新增 `get_operation_shortcut_suffix`
156176
- 其他结构保留 `(make 'op)` fallback
157177

158178
`compute_operation_footer()` 改为统一调用这个 helper。
179+
## 2026/04/01 operation footer 在空占位原子节点中提升到父结构节点
159180

160-
## 2026/04/01 定界符结构的逆向结果与菜单提示不一致
181+
### What
182+
修复刚插入根号、分式、上下标、上下附标等结构时,右侧 footer 只走 text path、不显示 operation shortcut 的问题。
183+
184+
### Why
185+
这些结构在插入后会立刻把光标放进内部空原子节点中,例如 `SQRT("")``RSUB("")`
186+
此时 `set_right_footer()` 中的
187+
188+
`subtree (et, path_up (tp))`
189+
190+
读到的是空原子子节点,而不是外层结构节点,导致逻辑总是进入 `compute_text_footer()`,根本不会调用 `compute_operation_footer()`
191+
192+
### How
193+
src/Edit/Interface/edit_footer.cpp :512 `set_right_footer()` 修改分发逻辑:
194+
- 当当前节点是原子节点时,先查看 `path_up (tp, 2)` 对应的父节点
195+
- 若父节点标签属于 `LSUB``LSUP``RSUB``RSUP``FRAC``SQRT``ABOVE``BELOW``WIDE``VAR_WIDE`
196+
- 则直接对父节点调用 `compute_operation_footer(parent)`
197+
- 其他情况仍保持原有 text path
198+
## 2026/04/01 结构命令反查需要传 command object,而不是字符串
161199

162200
### What
163-
尝试为 `AROUND` / `VAR_AROUND` 结构补齐快捷键显示,并排查为什么 footer 中会出现 `Alt+L [`,而数学工具栏大型定界符菜单悬浮提示显示的是 `[`
201+
footer 的结构类快捷键反查补齐 command object 转换,确认 `kbd-find-inv-binding` 对不同参数形式的行为差异
164202

165203
### Why
166-
大型定界符菜单里的每个按钮都带有原始命令 source,例如:
204+
排查发现 `<alpha>` 这类 symbol 可以直接用字符串反查,但 `(make-sqrt)``(make-fraction)``(make-script #f #t)` 这类结构命令如果直接以字符串传给 `kbd-find-inv-binding`,会返回空结果。
205+
原因在于逆向绑定表里存储的是命令对象,而不是命令源码字符串。
167206

168-
`(math-bracket-open "[" "]" 'default)`
207+
- `"<alpha>"` 作为字符串可以命中
208+
- `"(make-sqrt)"` / `"make-sqrt"` 作为字符串不能命中
209+
- `'(make-sqrt)``(string->object "(make-sqrt)")` 可以命中
210+
- 返回结果是内部 binding 形式,例如 `A-s``A-f`,而不一定是源码里的 `"math s"``"math f"`
169211

170-
菜单系统在 `TeXmacs/progs/kernel/gui/menu-widget.scm` 中直接对这个 source 调用 `kbd-find-shortcut`,因此能稳定返回按钮自身对应的快捷键。
212+
### How
213+
src/Edit/Interface/edit_footer.cpp :144 `get_shortcut_suffix` 改为:
214+
- 普通 symbol 继续使用 `object (cmd_s)`
215+
-`(` 开头的命令字符串先 `string_to_object (cmd_s)`,再传给 `kbd-find-inv-binding`
216+
## 2026/04/01 补齐 operation footer 的快捷键提示
171217

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)`
218+
### What
219+
`compute_operation_footer()` 增加快捷键后缀逻辑,使 operation 类型的 footer 也能显示对应快捷键。
179220

180-
逆向系统在多条候选里可能返回 large 这条,因此 footer 中会看到 `Alt+L [` 这样的前缀式结果。
181-
这并不代表 `Alt+L` 是一个完整快捷键,而是 `math:left` 这个前缀组的显示形式。
221+
### Why
222+
此前实现只在 `compute_text_footer()` 中为 `<symbol>` 追加快捷键提示,而 `compute_operation_footer()` 只返回 `square root``long arrow``hat` 这类文本描述,没有追加快捷键。
223+
这会导致 symbol path 能显示快捷键,但 operation path 不能显示,实际效果与原功能说明不一致。
182224

183-
### 结论
184-
对于括号这类结构,问题的根源不在 footer 拼接,而在逆向系统本身:
185-
- 菜单是 `source -> shortcut`,一对一,结果稳定
186-
- footer 是 `tree -> source -> shortcut`,一对多,容易命中“合法但不符合直觉”的候选
225+
### How
226+
src/Edit/Interface/edit_footer.cpp :222 `compute_operation_footer` 新增 `suffix`
227+
src/Edit/Interface/edit_footer.cpp :355 使用 `drd->get_name (L (st))` 组装 `"(make '<op>)"`,并通过 `get_shortcut_suffix` 统一反查快捷键
228+
src/Edit/Interface/edit_footer.cpp :356 当存在绑定时,将快捷键后缀追加到 operation footer 文本后
229+
## 2026/04/01 修复右侧 footer 快捷键缓存导致的错误显示
187230

188-
本轮代码里为复用菜单逻辑,新增了:
189-
- `TeXmacs/progs/kernel/gui/menu-widget.scm` : `kbd-find-shortcut-export`
190-
- `src/Edit/Interface/edit_footer.cpp` : `get_display_shortcut_suffix`
231+
### What
232+
移除 `src/Edit/Interface/edit_footer.cpp` 中按符号字符串做 key 的全局快捷键缓存,改为每次 footer 更新时按当前上下文实时调用 `kbd-find-inv-binding` 反查快捷键。
191233

234+
### Why
235+
此前右侧 footer 的快捷键显示使用了进程级静态缓存,只以 `<alpha>``<rightarrow>` 这类符号字符串作为缓存 key。
236+
`kbd-find-inv-binding` 实际是上下文相关的反查接口,键盘绑定本身可能带有 mode 和 require 条件。
237+
这样会导致第一次查到的结果被缓存下来,之后即使切换上下文,footer 仍然可能显示旧的快捷键结果,不能满足“实时显示当前快捷键”的需求。
238+
239+
### How
240+
src/Edit/Interface/edit_footer.cpp 删除 `shortcut_cache`
241+
src/Edit/Interface/edit_footer.cpp :143 `get_shortcut_suffix` 改为直接调用 `kbd-find-inv-binding`
242+
src/Edit/Interface/edit_footer.cpp :161 `compute_text_footer` 继续复用 `get_shortcut_suffix`,但结果不再受旧缓存污染

src/Edit/Interface/edit_keyboard.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "new_window.hpp"
1919
#include "object_l5.hpp"
2020
#include "preferences.hpp"
21+
#include "scheme.hpp"
22+
#include "string.hpp"
2123
#include "tm_buffer.hpp"
2224
#include "tm_window.hpp"
2325

@@ -102,6 +104,7 @@ edit_interface_rep::interrupt_shortcut () {
102104
bool
103105
edit_interface_rep::try_shortcut (string comb) {
104106
int status;
107+
bool executed= false;
105108
command cmd;
106109
string shorth;
107110
string help;
@@ -142,8 +145,21 @@ edit_interface_rep::try_shortcut (string comb) {
142145
call ("set-temporary-message", tree (CONCAT, "keyboard shortcut: ", rew),
143146
verbatim (rhs), shorth == "" ? 1 : 3000);
144147
}
145-
if ((status & 1) == 1) cmd ();
146-
else if (N (shorth) > 0) call ("kbd-insert", shorth);
148+
if ((status & 1) == 1) {
149+
cmd ();
150+
executed= true;
151+
}
152+
else if (N (shorth) > 0) {
153+
call ("kbd-insert", shorth);
154+
executed= true;
155+
}
156+
if (executed) {
157+
string mode= as_string (call ("get-env", "mode"));
158+
if (mode == "math") {
159+
message_r= "";
160+
set_right_footer ();
161+
}
162+
}
147163
// cout << "Mark= " << sh_mark << "\n";
148164
string mode= as_string (call ("get-env", "mode"));
149165
if (mode == "math" && get_preference ("completion style") == "popup") {

0 commit comments

Comments
 (0)