Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions TeXmacs/misc/themes/liii-night.css
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,31 @@ QToolButton#image-align-button:checked:hover {
background: rgb(133, 133, 133);
}

/****************************************************************************
* 代码悬浮菜单样式
****************************************************************************/

QWidget#code_popup {
background: #2c2c2c;
border: none;
border-radius: 8px;
}

QToolButton#code-popup-button {
background-color: transparent;
border: none;
padding: 4px 10px;
color: #ffffff;
}

QToolButton#code-popup-button:hover {
background-color: rgba(128, 128, 128, 0.3);
}

QToolButton#code-popup-button:pressed {
background-color: rgba(128, 128, 128, 0.5);
}

/****************************************************************************
* 分组框样式
****************************************************************************/
Expand Down
25 changes: 25 additions & 0 deletions TeXmacs/misc/themes/liii.css
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,31 @@ QToolButton#image-align-button:checked:hover {
background: rgb(180, 212, 255);
}

/****************************************************************************
* 代码悬浮菜单样式
****************************************************************************/

QWidget#code_popup {
background: #ffffff;
border: none;
border-radius: 8px;
}

QToolButton#code-popup-button {
background-color: transparent;
border: none;
padding: 4px 10px;
color: #1d1d1f;
}

QToolButton#code-popup-button:hover {
background-color: rgba(128, 128, 128, 0.3);
}

QToolButton#code-popup-button:pressed {
background-color: rgba(128, 128, 128, 0.5);
}

/****************************************************************************
* 分组框样式
****************************************************************************/
Expand Down
9 changes: 7 additions & 2 deletions TeXmacs/plugins/code/progs/prog/prog-drd.scm
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@

(define-group inline-code-tag
verbatim scm cpp mmx r fortran
python scilab shell)
python scilab shell
bash csv gnuplot goldfish java javascript json julia lua matlab moonbit
r7rs scala sql)

(define-group block-code-tag
verbatim-code scm-code cpp-code mmx-code r-code fortran-code
python-code scilab-code shell-code)
python-code scilab-code shell-code
bash-code csv-code gnuplot-code goldfish-code java-code javascript-code
json-code julia-code lua-code matlab-code moonbit-code r7rs-code
scala-code sql-code)

;; Listings
(define-group listing-tag
Expand Down
116 changes: 115 additions & 1 deletion TeXmacs/progs/prog/prog-edit.scm
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

(texmacs-module (prog prog-edit)
(:use (utils library tree)
(utils library cursor)))
(utils library cursor)
(utils edit selections)
(generic document-style)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Basic routines for textual programs
Expand All @@ -26,6 +28,118 @@
(dt (tree-ref ct :up)))
(and (tree-atomic? ct) (tree-is? dt 'document))))

(tm-define (code-popup-copy t)
(:synopsis "Copy code tree to clipboard")
(when (tree-select t)
(clipboard-copy-export "verbatim" "primary")
(selection-cancel)))

(define code-popup-inline-options
'(("verbatim" "verbatim")
("scheme" "scm")
("c++" "cpp")
("r" "r")
("python" "python")
("shell" "shell")
("bash" "bash")
("csv" "csv")
("gnuplot" "gnuplot")
("goldfish" "goldfish-lang")
("java" "java")
("javascript" "javascript")
("json" "json")
("julia" "julia")
("lua" "lua")
("matlab" "matlab")
("moonbit" "moonbit")
("r7rs" "r7rs")
("scala" "scala")
("sql" "sql")))

(define code-popup-block-options
'(("verbatim" "verbatim-code")
("scheme" "scm-code")
("c++" "cpp-code")
("r" "r-code")
("python" "python-code")
("shell" "shell-code")
("bash" "bash-code")
("csv" "csv-code")
("gnuplot" "gnuplot-code")
("goldfish" "goldfish-code")
("java" "java-code")
("javascript" "javascript-code")
("json" "json-code")
("julia" "julia-code")
("lua" "lua-code")
("matlab" "matlab-code")
("moonbit" "moonbit-code")
("r7rs" "r7rs-code")
("scala" "scala-code")
("sql" "sql-code")))

(define code-popup-listing-options
'(("verbatim" "listing")
("c++" "cpp-listing")
("scheme" "scm-listing")
("shell" "shell-listing")))

(define (code-popup-tag-in? tag opts)
(cond ((null? opts) #f)
((string=? tag (cadr (car opts))) #t)
(else (code-popup-tag-in? tag (cdr opts)))))

(define (code-popup-tag-kind tag)
(cond ((string=? tag "code") 'block)
((code-popup-tag-in? tag code-popup-listing-options) 'listing)
((code-popup-tag-in? tag code-popup-block-options) 'block)
((code-popup-tag-in? tag code-popup-inline-options) 'inline)
(else #f)))

(tm-define (code-popup-language-current t)
(:synopsis "Return current code tag name")
(symbol->string (tree-label t)))

(define code-popup-packages
'("bash" "csv" "gnuplot" "goldfish" "java" "javascript" "json" "julia" "lua"
"matlab" "moonbit" "octave" "python" "r" "r7rs" "scala" "sql"))

(define (code-popup-base-tag tag)
(cond ((string-ends? tag "-code") (string-drop-right tag 5))
((string-ends? tag "-listing") (string-drop-right tag 8))
((string-ends? tag "-lang") (string-drop-right tag 5))
(else tag)))

(define (code-popup-ensure-package tag)
(let* ((base (code-popup-base-tag tag))
(pack (and (in? base code-popup-packages) base)))
(when (and pack (not (has-style-package? pack)))
(add-style-package pack))))

(tm-define (code-popup-make tag)
(:synopsis "Make code tag with auto package")
(code-popup-ensure-package (symbol->string tag))
(make tag))

(tm-define (code-popup-language-options t)
(:synopsis "Return menu options for code popup")
(let* ((tag (symbol->string (tree-label t)))
(kind (code-popup-tag-kind tag))
(opts (cond ((eq? kind 'listing) code-popup-listing-options)
((eq? kind 'block) code-popup-block-options)
(else code-popup-inline-options))))
(map (lambda (it) (string-append (car it) "\t" (cadr it))) opts)))

(tm-define (code-popup-set-language t target)
(:synopsis "Change code tag for current code tree")
(let* ((kind (code-popup-tag-kind (symbol->string (tree-label t))))
(opts (cond ((eq? kind 'listing) code-popup-listing-options)
((eq? kind 'block) code-popup-block-options)
(else code-popup-inline-options))))
(when (code-popup-tag-in? target opts)
(code-popup-ensure-package target)
(tree-assign-node! t (string->symbol target)))))

(tm-define (program-tree)
(:synopsis "get the entire program tree")
(let* ((ct (cursor-tree))
Expand Down
92 changes: 92 additions & 0 deletions TeXmacs/tests/tmu/209_13.tmu
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<TMU|<tuple|1.1.0|2026.1.2>>

<style|<tuple|generic|chinese|table-captions-above|number-europe|preview-ref|python|java>>

<\body>
C++代码块:

<\cpp-code>
#include \<less\>stdio.h\<gtr\>

cout\<less\>\<less\>"Hello World!"
</cpp-code>

C++行内代码:

<cpp|cout\<less\>\<less\>"Hello World!";>

C++代码清单:

<\cpp-listing>
#include \<less\>stdio.h\<gtr\>

cout\<less\>\<less\>"Hello World!";
</cpp-listing>

<with|par-mode|center|>

\;

Python代码块:

<\python>
nums = [1, 2, 3, 4]

for x in nums:

\ \ \ \ print(x)
</python>

Python行内代码

\;

<\python>
print("Hello, World!")

\;
</python>

\;

Scheme代码清单:

<\scm-listing>
(display "Hello, World!")

(newline)
</scm-listing>

\;

Java代码块:

<\java-code>
public class Main {

\ \ \ \ public static void main(String[] args) {

\ \ \ \ \ \ \ \ System.out.println("Hello, World!");

\ \ \ \ }

}
</java-code>

\;

Java行内代码:

<java|System.out.println("Hello, World!");>

\;

\;
</body>

<\initial>
<\collection>
<associate|page-medium|paper>
<associate|page-screen-margin|false>
</collection>
</initial>
66 changes: 66 additions & 0 deletions devel/209_13.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# 209_13 添加代码悬浮菜单

## 如何测试

1. 在 Mogan 中插入:
- 块级代码(Python / C++ / Scheme / Shell 等)
- 行内代码
- 代码清单

2. 将鼠标悬浮到代码区域,右上角:
- 应显示「复制」与「语言切换」按钮。

3. 点击「复制」:
- 粘贴到外部编辑器,应为纯文本代码。

4. 使用语言菜单切换标签:
- 如 `cpp-code` → `python-code`
- 应自动添加所需宏包。

5. 移开鼠标:
- 菜单应延迟约 0.5s 消失。

### 测试文档

- `TeXmacs/tests/tmu/209_13.tmu`

## 2026/01/29 代码悬浮菜单-语言切换

### What

- 新增代码悬浮菜单(复制 + 语言切换),支持块级 / 行内 / 代码清单。
- 菜单固定在代码块右上角,提升可点击性。
- 悬浮离开后延迟约 0.5s 隐藏,避免移动过快无法点击。
- 切换语言标签(如 `cpp-code` → `python-code`)自动补齐所需宏包。

### How

- 鼠标悬浮检测与显示逻辑:
`src/Edit/Interface/edit_mouse.cpp`
- Qt 菜单组件:
`src/Plugins/Qt/QTMCodePopup.cpp`
`src/Plugins/Qt/QTMCodePopup.hpp`
- Scheme 复制与语言切换:
`TeXmacs/progs/prog/prog-edit.scm`


## 2026/01/28 代码悬浮菜单-复制

### What

- 新增代码悬浮菜单(Qt 端)及显示 / 隐藏 / 滚动同步逻辑。
- 鼠标悬浮检测支持块级与行内代码。
- 复制操作通过 Scheme 导出为 `verbatim`。
- C++ 侧补齐 Scheme 端支持的代码环境标签。
- 主题中增加 code popup 样式(浅色 / 深色)。

### How

- C++:新增 `QTMCodePopup`,并在 `qt_simple_widget` / `QTMWidget` 接入显示与滚动同步。
- C++:在 `edit_mouse.cpp` 中沿祖先路径查找代码节点,使用 `is_verbatim()` 判断。
- Scheme:新增 `code-popup-copy`,使用
`clipboard-copy-export "verbatim"` 实现纯文本复制。
- 主题:添加 `#code_popup` 与 `#code-popup-button` 样式。
- `is_verbatim()` 补齐 `python-code` 等标签,与 Scheme 侧定义对齐。


Loading