diff --git a/TeXmacs/packages/standard/std-fold.ts b/TeXmacs/packages/standard/std-fold.ts index 5e176fcad4..96c510ff79 100644 --- a/TeXmacs/packages/standard/std-fold.ts +++ b/TeXmacs/packages/standard/std-fold.ts @@ -661,13 +661,17 @@ - + - + - |>>> + - |>>> + + + |text-bg-color||>>> + + |text-bg-color||>>> >>> @@ -683,7 +687,7 @@ >|document>|version-both-big|version-both-small>||>>> - >>>> + > <\initial> diff --git a/TeXmacs/progs/generic/diff-text.scm b/TeXmacs/progs/generic/diff-text.scm new file mode 100644 index 0000000000..9272cc23c1 --- /dev/null +++ b/TeXmacs/progs/generic/diff-text.scm @@ -0,0 +1,202 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MODULE : diff-text.scm +;; DESCRIPTION : Diff Text feature for MoganSTEM +;; COPYRIGHT : (C) 2026 AcceleratorX +;; +;; This software falls under the GNU general public license version 3 or later. +;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE +;; in the root directory or . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(texmacs-module (generic diff-text) + (:use (kernel texmacs tm-define) + (utils library cursor) + (version version-compare) + ) ;:use +) ;texmacs-module + +;; ============================================================================= +;; Helper functions +;; ============================================================================= + +(define (remove-random-thes words count) + (cond ((null? words) '()) + ((<= count 0) words) + ((== (car words) "the") + (cond ((<= (random 3) 1) (remove-random-thes (cdr words) (- count 1))) + (else (cons (car words) (remove-random-thes (cdr words) count))) + ) ;cond + ) ; + (else (cons (car words) (remove-random-thes (cdr words) count))) + ) ;cond +) ;define + +(define (insert-random-as words count) + (cond ((null? words) + (if (> count 0) (cons "a" (insert-random-as '() (- count 1))) '()) + ) ; + ((<= count 0) words) + (else (if (== (random 5) 0) + (cons "a" (insert-random-as words (- count 1))) + (cons (car words) (insert-random-as (cdr words) count)) + ) ;if + ) ;else + ) ;cond +) ;define + +(define (upcase-random-words words count) + (cond ((or (null? words) (<= count 0)) words) + ((> (string-length (car words)) 1) + (if (== (random 4) 0) + (cons (upcase-all (car words)) (upcase-random-words (cdr words) (- count 1))) + (cons (car words) (upcase-random-words (cdr words) count)) + ) ;if + ) ; + (else (cons (car words) (upcase-random-words (cdr words) count))) + ) ;cond +) ;define + +(define (demo-suggest t) + (cond ((not t) #f) + ((string? t) + (let* ((words (string-split t #\space)) + (words-no-the (remove-random-thes words 2)) + (words-with-a (insert-random-as words-no-the 2)) + (final-words (upcase-random-words words-with-a 3)) + ) ; + (string-recompose final-words " ") + ) ;let* + ) ; + ((pair? t) (cons (car t) (map demo-suggest (cdr t)))) + (else t) + ) ;cond +) ;define + +(define (diff-check-popup) + ;; 先隐藏弹窗,避免位置错乱 + (set! diff-active? #f) + (hide-diff-popup) + (when (tree-innermost 'version-both) + (set! diff-active? #t) + (show-diff-popup) + ) ;when +) ;define + +(define (diff-scan-next) + (if (not (tree-innermost 'version-both)) + (if (tree-is? (cursor-tree) 'version-both) + ;; 单差异特判:直接送入第一个子段落内部 + (tree-go-to (tree-ref (cursor-tree) 0) :start) + ;; 多差异常规流程:向后搜寻 + (go-to-next-tag 'version-both) + ) ;if + ) ;if + (delayed (:idle 0) (diff-check-popup)) +) ;define + +;; ============================================================================= +;; State variables for Diff Text +;; ============================================================================= + +(define diff-active? #f) + +(tm-define (is-diff-active?) diff-active?) + +(tm-define (diff-enable?) (not (community-stem?))) + +;; ============================================================================= +;; Model evaluation & Feedback functions +;; ============================================================================= + +(tm-define (diff-feedback action) (noop)) + +;; ============================================================================= +;; Diff Text core control flow +;; ============================================================================= + +(tm-define (trigger-diff-text) + (let* ((sel (selection-tree)) + (origin_stree (tree->stree sel)) + (suggested_stree (demo-suggest origin_stree)) + (pre-cur (cursor-path)) + (pre-grain (get-preference "versioning grain")) + ) ; + ;; 设为字符级精度 "detailed";其余选项:"block" (块级)、"rough" (粗粒度) + (set-preference "versioning grain" "detailed") + (let* ((diff-stree (compare-versions origin_stree suggested_stree)) + (diff-tree (stree->tree diff-stree)) + ) ; + (clipboard-cut "primary") + (insert diff-tree) + (go-to pre-cur) + (diff-scan-next) + ) ;let* + ;; 还原精度 + (set-preference "versioning grain" pre-grain) + ) ;let* +) ;tm-define + +(tm-define (accept-diff) + (let ((t (tree-innermost 'version-both))) + (when t + (let* ((new-val (tree-ref t 1)) (p (tree-up t)) (i (tree-index t))) + (tree-remove! p i 1) + (when (not (tree-is? new-val 'version-suppressed)) + (insert new-val) + ) ;when + ) ;let* + ) ;when + ) ;let + (diff-feedback 'accept) + (refresh-window) + (diff-scan-next) +) ;tm-define + +(tm-define (reject-diff) + (let ((t (tree-innermost 'version-both))) + (when t + (let* ((old-val (tree-ref t 0)) (p (tree-up t)) (i (tree-index t))) + (tree-remove! p i 1) + (when (not (tree-is? old-val 'version-suppressed)) + (insert old-val) + ) ;when + ) ;let* + ) ;when + ) ;let + (diff-feedback 'reject) + (refresh-window) + (diff-scan-next) +) ;tm-define + +;; ============================================================================= +;; Keyboard and Mouse Hooks +;; ============================================================================= + +(tm-define (kbd-tab) + (:require (and (diff-enable?) (selection-active?))) + (trigger-diff-text) +) ;tm-define + +(tm-define (keyboard-press key time) + (:require (is-diff-active?)) + (cond ((== key "return") (accept-diff)) + ((== key "backspace") (reject-diff)) + (else (former key time)) + ) ;cond +) ;tm-define + +(tm-define (keyboard-press key time) + (:require (diff-enable?)) + (former key time) + (delayed (:idle 0) (diff-check-popup)) +) ;tm-define + +(tm-define (mouse-event key x y mods time data) + (:require (diff-enable?)) + (former key x y mods time data) + (when (not (== key "move")) + (delayed (:idle 0) (diff-check-popup)) + ) ;when +) ;tm-define diff --git a/TeXmacs/progs/generic/generic-kbd.scm b/TeXmacs/progs/generic/generic-kbd.scm index f0abef03b1..85150399a5 100644 --- a/TeXmacs/progs/generic/generic-kbd.scm +++ b/TeXmacs/progs/generic/generic-kbd.scm @@ -20,6 +20,7 @@ (generic document-edit) (generic generic-edit) (generic ghost-text) + (generic diff-text) (generic format-edit) (generic format-geometry-edit) (source source-edit) diff --git a/TeXmacs/tests/tmu/0840.tmu b/TeXmacs/tests/tmu/0840.tmu new file mode 100644 index 0000000000..564580ee72 --- /dev/null +++ b/TeXmacs/tests/tmu/0840.tmu @@ -0,0 +1,42 @@ +> + +> + +<\body> + + + Southern University of Science and Technology (SUSTech) is an innovation-oriented public university founded by Shenzhen government in the background of China's higher education reform. It aspires to be a model and pioneer for promoting higher education reform. It is committed to serving the mission of promoting Shenzhen as a modern, international, and innovative city and China as a creative country. + + First, SUSTech is widely regarded as a trailblazer and innovator in advancing China's higher education. It was officially approved by the Ministry of Education in April 2012. SUSTech bears the responsibility for exploring and developing a modern university system with Chinese characteristics to serve as a model for cultivating innovative talents. SUSTech aims at a globally renowned university that contributes to the advancement of science and technology. It nurtures promising and creative leaders who excel in interdisciplinary research and creating knowledge for the world. + + Second, SUSTech draws on the experience of world-class science and engineering universities for its disciplinary establishment and governance. It focuses on science, engineering, and medicine in conjunction with distinctive disciplines, including business, humanities, and social sciences. SUSTech offers undergraduate and postgraduate education while conducting research in a series of innovative disciplines. All of those practices shape SUSTech into a think tank for social progress and a generator of new knowledge and new technology. + + Third, SUSTech is building interdisciplinary research centers to generate new scientific and technological wisdom in cross-disciplinary fields such as artificial intelligence, life sciences, Internet of things, robotics, new energy, and intelligent manufacturing. + + In the spirit of "For Truth, Innovation, Reform and Excellence with Diligence and Courage," SUSTech highlights "research, innovation, and entrepreneurship" and dedicates to facilitating innovative projects across China and turning Shenzhen into an innovative, modern, and international metropolis. + + SUSTech also seeks to become an international high-level research university that gathers first-class faculty and nurtures top-notch innovative talents. It aims to produce internationally recognized academic achievements and advance scientific and technological applications. + + +<\initial> + <\collection> + + + + + + + +<\references> + <\collection> + > + + + +<\auxiliary> + <\collection> + <\associate|toc> + |math-font-series||GENERAL INFORMATION>|.>>>>|> + + + diff --git a/devel/0840.md b/devel/0840.md new file mode 100644 index 0000000000..4fdfc93f83 --- /dev/null +++ b/devel/0840.md @@ -0,0 +1,55 @@ +# [0840] AI Suggestion 功能初步实现 + +## 1 相关文档 +- [0834](0834.md) - 自动补全初步实现 + +## 2 任务相关的代码文件 +- `TeXmacs/progs/generic/generic-kbd.scm` — 注册 `kbd-tab` 键盘钩子以引入 `diff-text` 模块 +- `TeXmacs/progs/generic/diff-text.scm` — 新增 `diff-text` 模块,实现富文本 AST 树级递归修改生成、自愈式双重重载按键拦截及鼠标环境自适应检测逻辑 +- `TeXmacs/packages/standard/std-fold.ts` — 将 `version-both` 差异配色及背景色升级为对齐弹窗的现代淡色调,并将 `version-suppressed` 空白占位符设置为空白隐藏 +- `src/Edit/editor.hpp` / `src/Edit/Interface/edit_interface.hpp` — 添加 `show_diff_popup`/`hide_diff_popup` 的编辑器接口声明 +- `src/Edit/Interface/edit_mouse.cpp` — 实现编辑器接口转调至 Qt 侧简易部件弹窗接口 +- `src/Scheme/Glue/glue_editor.lua` — 为 `show_diff_popup`/`hide_diff_popup` 注册 Scheme 与 C++ 黏合绑定 +- `src/Plugins/Qt/QTMUserPromptPopup.hpp` / `QTMUserPromptPopup.cpp` — 重构基类 `QTMUserPromptPopup` 支持子类自定义按钮文本(“接受 Enter”/“拒绝 Backspace”),并实现派生子类 `QTMDiffTextPopup` +- `src/Plugins/Qt/qt_simple_widget.hpp` / `qt_simple_widget.cpp` — 管理 `diffTextPopup` 弹窗实例的生命周期、显示隐藏与滚动 +- `src/Plugins/Qt/QTMWidget.cpp` — 增加滚动事件监听,确保页面滚动时差异对比弹窗同步跟随滚动 + +## 3 如何测试 + +### 3.1 确定性测试(单元测试) +```bash +xmake b stem +xmake r stem +``` + +### 3.2 非确定性测试(交互验证) +1. 使用商业版(`xmake f --is_community=false && xmake b stem`)构建 MoganSTEM +2. 打开 `TeXmacs\tests\tmu\0840.tmu` +3. 选中**一个**段落,按下 `tab` 触发一个 AI Suggestion 的 demo(随机删除一些 `the`,插入一些 `a`,大写一些单词) +4. 选中**多个**段落,按下 `tab` 也会触发 AI Suggestion,逻辑相同 +5. 鼠标可以在不同的 `version-both` 节点间跳转,弹窗会自动贴合光标位置 +6. 也可以通过键盘移动光标到不同的 `version-both` 节点,弹窗会自动贴合光标位置 +7. 光标进入 `version-both` 节点后,可以通过快捷键 `Enter`/`Backspace` 来同意或拒绝当前的差异对比,会立刻生效 +8. 也可以通过鼠标点击弹窗上的按钮来同意或拒绝当前的差异对比,会立刻生效 +9. 使用社区版(`xmake f --is_community=true && xmake b stem`)构建 MoganSTEM,上述功能不被触发 + +## 4 What +在自动补全框架下进一步设计并实现了基于富文本 AST 对照的差异对比预览(Diff Text)交互系统: +- 支持对多段落、富文本及数学公式等复杂节点在保留原有排版骨架的前提下进行细粒度字符比对。 +- 实现一处一处跳转确认的冲突决策(Conflict-by-conflict)流转。 +- 引入无状态自愈式全局监听器,支持弹窗位置随光标的移动而自动贴合、隐藏和显示。 +- 在 C++ 侧重构了气泡弹窗,支持在子类中自定义采纳和拒绝的快捷键文案。 +- 重构了 `version-both` 样式与配色高亮,使其底色更为淡雅柔和。 +- 隐藏了 `version-suppressed` 占位节点原本的乘号(`×`)图标,使其在对比时完全隐形以改善观感。 + +## 5 How +1. **树级递归建议生成**: + 在 `diff-text.scm` 中,设计 `demo-suggest` 函数递归扫描选区树,保持原有树节点拓扑外壳,仅在叶子文本节点上应用随机的删除、增加与大写变换逻辑。 +2. **编辑器级删除与插入**: + 在同意(`accept-diff`)或拒绝(`reject-diff`)时,通过 `tree-remove!` 在位移除当前的 `version-both` 节点,并在光标前执行 `(insert ...)` 原地写入纯文本内容。对于纯删除或增加所产生的 `version-suppressed` 占位符节点做空插入特判。 +3. **逐处跳转与弹窗自适应**: + 通过在 `keyboard-press` 增加双重函数重载分发,区分高优先级决策按键拦截(回车/退格)与低优先级常驻事件监听。当光标被流转至下一处或通过鼠标、方向键位移至 `version-both` 节点内部时,延迟调用 `diff-check-popup`。在其中先隐后显,确保弹窗位置始终自适应贴合最新光标。 +4. **自定义按钮文案**: + 重构基类 `QTMUserPromptPopup` 构造函数接收 `acceptText` 与 `rejectText` 参数,并在子类 `QTMGhostTextPopup` 与 `QTMDiffTextPopup` 中调用基构造函数定义特定的提示文案。 +5. **样式高亮与占位隐藏**: + 在 `std-fold.ts` 中,将新旧版本差异配色对齐到弹窗按键的 `#10b981` (绿) 与 `#ef4444` (红),并使用 `text-bg-color` 附带现代极淡底色高亮(`#ecfdf5` 和 `#fef2f2`)。同时重构 `version-suppressed` 宏为空宏使其完全隐形。 diff --git a/src/Edit/Interface/edit_interface.hpp b/src/Edit/Interface/edit_interface.hpp index 20a050479c..9811d0ee59 100644 --- a/src/Edit/Interface/edit_interface.hpp +++ b/src/Edit/Interface/edit_interface.hpp @@ -275,6 +275,8 @@ class edit_interface_rep : virtual public editor_rep { void show_ghost_popup (); void hide_ghost_popup (); + void show_diff_popup (); + void hide_diff_popup (); /* the footer */ tree get_shortcut_suffix (string cmd_s); diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index c0e5d6b5c5..5800ee0e65 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -1332,6 +1332,24 @@ edit_interface_rep::hide_ghost_popup () { #endif } +void +edit_interface_rep::show_diff_popup () { +#ifdef QTTEXMACS + if (qt_simple_widget_rep* qsw= dynamic_cast (this)) { + qsw->show_diff_popup (); + } +#endif +} + +void +edit_interface_rep::hide_diff_popup () { +#ifdef QTTEXMACS + if (qt_simple_widget_rep* qsw= dynamic_cast (this)) { + qsw->hide_diff_popup (); + } +#endif +} + bool edit_interface_rep::is_point_in_text_popup (SI x, SI y) { #ifdef QTTEXMACS diff --git a/src/Edit/editor.hpp b/src/Edit/editor.hpp index 36ea9c4da1..a1dc694c4d 100644 --- a/src/Edit/editor.hpp +++ b/src/Edit/editor.hpp @@ -189,6 +189,8 @@ class editor_rep : public simple_widget_rep { virtual void source_complete_try () = 0; virtual void show_ghost_popup () = 0; virtual void hide_ghost_popup () = 0; + virtual void show_diff_popup () = 0; + virtual void hide_diff_popup () = 0; virtual void complete_start (string prefix, array compls) = 0; virtual bool complete_keypress (string key) = 0; virtual bool source_complete_keypress (string key) = 0; diff --git a/src/Plugins/Qt/QTMUserPromptPopup.cpp b/src/Plugins/Qt/QTMUserPromptPopup.cpp index 2e510658cf..ab9f4bae75 100644 --- a/src/Plugins/Qt/QTMUserPromptPopup.cpp +++ b/src/Plugins/Qt/QTMUserPromptPopup.cpp @@ -18,7 +18,9 @@ // QTMUserPromptPopup: 用于处理用户与 AI 生成方案的交互,父类是 QTMBasePopup // ============================================================================= QTMUserPromptPopup::QTMUserPromptPopup (QWidget* parent, - qt_simple_widget_rep* owner) + qt_simple_widget_rep* owner, + const QString& acceptText, + const QString& rejectText) : QWidget (parent), owner (owner), layout (nullptr) { setObjectName ("user_prompt_popup"); @@ -70,7 +72,7 @@ QTMUserPromptPopup::QTMUserPromptPopup (QWidget* parent, container->setLayout (innerLayout); // 1. 接受按钮 (现代祖母绿配色) - acceptBtn= new QPushButton ("接受 →", container); + acceptBtn= new QPushButton (acceptText, container); acceptBtn->setObjectName ("accept_btn"); acceptBtn->setStyleSheet ("QPushButton#accept_btn { " "background-color: #10b981; " @@ -92,7 +94,7 @@ QTMUserPromptPopup::QTMUserPromptPopup (QWidget* parent, innerLayout->addWidget (acceptBtn); // 2. 拒绝按钮 (轻柔番茄红配色) - rejectBtn= new QPushButton ("拒绝 Esc", container); + rejectBtn= new QPushButton (rejectText, container); rejectBtn->setObjectName ("reject_btn"); rejectBtn->setStyleSheet ("QPushButton#reject_btn { " "background-color: #ef4444; " @@ -255,7 +257,7 @@ QTMUserPromptPopup::eventFilter (QObject* obj, QEvent* event) { // ============================================================================= QTMGhostTextPopup::QTMGhostTextPopup (QWidget* parent, qt_simple_widget_rep* owner) - : QTMUserPromptPopup (parent, owner) { + : QTMUserPromptPopup (parent, owner, "接受 →", "拒绝 Esc") { setObjectName ("ghost_text_popup"); } @@ -282,3 +284,36 @@ void QTMGhostTextPopup::onBadClicked () { call ("ghost-feedback", "bad"); } + +// ============================================================================= +// QTMDiffTextPopup: Diff Text AI建议的悬浮操作框,父类是 QTMUserPromptPopup +// ============================================================================= +QTMDiffTextPopup::QTMDiffTextPopup (QWidget* parent, + qt_simple_widget_rep* owner) + : QTMUserPromptPopup (parent, owner, "接受 Enter", "拒绝 Backspace") { + setObjectName ("diff_text_popup"); +} + +QTMDiffTextPopup::~QTMDiffTextPopup () {} + +void +QTMDiffTextPopup::onAcceptClicked () { + hide (); + call ("accept-diff"); +} + +void +QTMDiffTextPopup::onRejectClicked () { + hide (); + call ("reject-diff"); +} + +void +QTMDiffTextPopup::onGoodClicked () { + call ("diff-feedback", "good"); +} + +void +QTMDiffTextPopup::onBadClicked () { + call ("diff-feedback", "bad"); +} diff --git a/src/Plugins/Qt/QTMUserPromptPopup.hpp b/src/Plugins/Qt/QTMUserPromptPopup.hpp index 9fe81a7220..90fbe64eb7 100644 --- a/src/Plugins/Qt/QTMUserPromptPopup.hpp +++ b/src/Plugins/Qt/QTMUserPromptPopup.hpp @@ -31,7 +31,8 @@ class QTMUserPromptPopup : public QWidget { QPushButton* badBtn; public: - QTMUserPromptPopup (QWidget* parent, qt_simple_widget_rep* owner); + QTMUserPromptPopup (QWidget* parent, qt_simple_widget_rep* owner, + const QString& acceptText, const QString& rejectText); virtual ~QTMUserPromptPopup (); // 显示悬浮框并定位 @@ -77,4 +78,21 @@ class QTMGhostTextPopup : public QTMUserPromptPopup { void onBadClicked () override; }; +// ============================================================================= +// QTMDiffTextPopup: Diff Text AI建议的悬浮操作框,父类是 QTMUserPromptPopup +// ============================================================================= +class QTMDiffTextPopup : public QTMUserPromptPopup { + Q_OBJECT + +public: + QTMDiffTextPopup (QWidget* parent, qt_simple_widget_rep* owner); + ~QTMDiffTextPopup () override; + +protected: + void onAcceptClicked () override; + void onRejectClicked () override; + void onGoodClicked () override; + void onBadClicked () override; +}; + #endif // QT_USER_PROMPT_POPUP_HPP diff --git a/src/Plugins/Qt/QTMWidget.cpp b/src/Plugins/Qt/QTMWidget.cpp index a29dabe9c2..14eb04441b 100644 --- a/src/Plugins/Qt/QTMWidget.cpp +++ b/src/Plugins/Qt/QTMWidget.cpp @@ -163,6 +163,7 @@ QTMWidget::scrollContentsBy (int dx, int dy) { tm_widget ()->scroll_image_popup_by (dx, dy); tm_widget ()->scroll_text_popup_by (dx, dy); tm_widget ()->scroll_ghost_popup_by (dx, dy); + tm_widget ()->scroll_diff_popup_by (dx, dy); if (edit_interface_rep* ed= dynamic_cast (tm_widget ())) { ed->update_text_popup (); diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index 2a84a892cb..a53b393889 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -909,3 +909,40 @@ qt_simple_widget_rep::scroll_ghost_popup_by (SI x, SI y) { ghostTextPopup->updatePosition (); } } + +void +qt_simple_widget_rep::ensure_diff_popup () { + if (diffTextPopup) { + if (diffTextPopup->parent () != canvas ()) { + diffTextPopup->setParent (canvas ()); + } + return; + } + diffTextPopup= new QTMDiffTextPopup (canvas (), this); + if (is_empty (tm_style_sheet)) { + diffTextPopup->setStyle (qtmstyle ()); + } +} + +void +qt_simple_widget_rep::show_diff_popup () { + ensure_diff_popup (); + diffTextPopup->showPopup (); +} + +void +qt_simple_widget_rep::hide_diff_popup () { + if (diffTextPopup) { + diffTextPopup->hide (); + } +} + +void +qt_simple_widget_rep::scroll_diff_popup_by (SI x, SI y) { + if (diffTextPopup) { + QPoint qp (x, y); + coord2 p= from_qpoint (qp); + diffTextPopup->scrollBy (p.x1, p.x2); + diffTextPopup->updatePosition (); + } +} diff --git a/src/Plugins/Qt/qt_simple_widget.hpp b/src/Plugins/Qt/qt_simple_widget.hpp index 2b03d7cfdc..0ddaf30309 100644 --- a/src/Plugins/Qt/qt_simple_widget.hpp +++ b/src/Plugins/Qt/qt_simple_widget.hpp @@ -26,6 +26,7 @@ class QTMMathCompletionPopup; class QTMImagePopup; class QTMTextPopup; class QTMGhostTextPopup; +class QTMDiffTextPopup; /*! A widget containing a TeXmacs canvas. @@ -138,6 +139,12 @@ class qt_simple_widget_rep : public qt_widget_rep { void hide_ghost_popup (); void scroll_ghost_popup_by (SI x, SI y); + ////////////////////// Diff text popup support + void ensure_diff_popup (); + void show_diff_popup (); + void hide_diff_popup (); + void scroll_diff_popup_by (SI x, SI y); + ////////////////////// backing store management static void repaint_all (); // called by qt_gui_rep::update() @@ -150,6 +157,7 @@ class qt_simple_widget_rep : public qt_widget_rep { QPointer imagePopUp; QPointer textPopup; QPointer ghostTextPopup; + QPointer diffTextPopup; #ifdef USE_MUPDF_RENDERER double bs_zoomf; picture backing_store; diff --git a/src/Scheme/Glue/glue_editor.lua b/src/Scheme/Glue/glue_editor.lua index 05f276eff6..6da3294237 100644 --- a/src/Scheme/Glue/glue_editor.lua +++ b/src/Scheme/Glue/glue_editor.lua @@ -1114,6 +1114,16 @@ function main() cpp_name = "hide_ghost_popup", ret_type = "void" }, + { + scm_name = "show-diff-popup", + cpp_name = "show_diff_popup", + ret_type = "void" + }, + { + scm_name = "hide-diff-popup", + cpp_name = "hide_diff_popup", + ret_type = "void" + }, { scm_name = "get-input-mode", cpp_name = "get_input_mode",