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
116 changes: 116 additions & 0 deletions TeXmacs/progs/generic/generic-edit.scm
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,122 @@
(set-message `(concat "Use " ,sh " in order to insert a tab")
"tab"))))

;; 辅助函数:定义 enumerate-tag-list
(define (enumerate-tag-list)
'(enumerate enumerate-1 enumerate-2 enumerate-3 enumerate-4))

;; 辅助函数:检查是否在有序列表环境中
(define (in-enumerate-context?)
(not (not (tree-search-upwards (focus-tree) (lambda (node) (tree-in? node (enumerate-tag-list)))))))

;; 辅助函数:查找包含 item 的 concat 包装和真正的 item list
(define (find-item-wrapper-and-list item)
(let ((wrapper #f)
(item-list #f))
(let loop ((current (tree-outer item)))
(if (tree-is? current 'concat)
(begin
(set! wrapper current)
(loop (tree-outer current))
)
(set! item-list current)
)
)
(values wrapper item-list)
)
)

;; 辅助函数:提取 item 内容(处理 concat 包装)
(define (extract-item-content item wrapper)
(if (and item (> (tree-arity item) 0))
(tree-copy (tree-ref item 0))
(if (and wrapper (> (tree-arity wrapper) 1))
(let ((content #f))
(do ((i 1 (+ i 1)))
((or content (>= i (tree-arity wrapper))))
(let ((child (tree-ref wrapper i)))
(if (not (tree-is? child 'item))
(set! content (tree-copy child))
#f
)
)
)
content
)
#f
)
)
)

;; 辅助函数:在列表中移除 item(处理 concat 包装)
(define (remove-item-from-list item wrapper item-list)
(if wrapper
;; 如果有 wrapper,移除整个 wrapper
(let ((wrapper-index (tree-index wrapper)))
(tree-remove! item-list wrapper-index 1)
)
;; 否则移除单个 item
(let ((item-index (tree-index item)))
(tree-remove! item-list item-index 1)
)
)
)

;; 在有序列表中实现缩进功能
(tm-define (kbd-variant t forwards?)
(:require (and in-enumerate-context? (tree-is? (focus-tree) 'item)))
"在有序列表中按Tab键创建子列表"

(let ((item (focus-tree)))

;; 步骤 1: 查找包装和列表
(call-with-values (lambda () (find-item-wrapper-and-list item))
(lambda (wrapper item-list)

(if (and item item-list)
(let ((item-index (if wrapper (tree-index wrapper) (tree-index item))))

(if (> item-index 0)
(let ((prev-item (tree-ref item-list (- item-index 1))))

;; 步骤 2: 提取内容
(let ((item-content (extract-item-content item wrapper)))

;; 步骤 3: 创建子列表并移动内容
(tree-go-to prev-item :end)
(insert-return)
(make-tmlist 'enumerate)

(if item-content
(let ((new-item (focus-tree)))
(let ((content-stree (tree->stree item-content)))
(tree-set! new-item `(concat (item), content-stree))
(tree-go-to new-item)
)
)
#f
)

;; 步骤 4: 从原列表中移除
(remove-item-from-list item wrapper item-list)
)
)
(begin
(noop)
)
)
)
(begin
(and-with p (tree-outer t)
(kbd-variant p forwards?)
)
)
)
)
)
)
)

(tm-define (kbd-variant t forwards?)
(:require (and (tree-in? t '(label reference pageref eqref smart-ref))
(cursor-inside? t)))
Expand Down
49 changes: 49 additions & 0 deletions devel/201_84.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 201_84 有序列表中实现Tab键缩进功能

## 如何测试
- 创建一个有序列表(enumerate环境)
- 在列表中添加多个item
- 将光标放在第二个或后续item上
- 按Tab键,观察当前item是否缩进成为前一个item的子列表项
- 测试带concat包装的item是否也能正常缩进
- 测试第一个item按Tab键是否无反应(因为没有前一个item可以缩进)

## 2026/02/13 新增有序列表Tab键缩进功能

### What
在TeXmacs/progs/generic/generic-edit.scm中新增了有序列表的Tab键缩进功能。当用户在有序列表的item上按Tab键时,该item会缩进成为前一个item的子列表项。

### Why
在LaTeX等文档编辑器中,有序列表支持通过Tab键将列表项缩进为子列表,这是常见的编辑功能。TeXmacs此前缺少这一功能,用户体验不够友好。通过添加此功能,用户可以更方便地创建嵌套的有序列表结构。

### How
在generic-edit.scm中新增了以下内容:

1. **辅助函数**:
- `enumerate-tag-list`: 定义有序列表的标签列表(enumerate, enumerate-1, enumerate-2, enumerate-3, enumerate-4)
- `in-enumerate-context?`: 检查当前是否在有序列表环境中
- `find-item-wrapper-and-list`: 查找包含item的concat包装和真正的item list
- `extract-item-content`: 提取item内容,处理concat包装的情况
- `remove-item-from-list`: 从列表中移除item,处理concat包装的情况

2. **kbd-variant函数重载**:
- 新增了kbd-variant函数的特定版本,专门处理在有序列表中按Tab键的场景
- 该函数会检查当前是否在有序列表环境中,并且光标是否在item上
- 当条件满足时,执行以下操作:
a. 查找item的包装和所属列表
b. 检查是否有前一个item
c. 提取当前item的内容
d. 在前一个item末尾创建子列表
e. 将提取的内容移动到新创建的子列表item中
f. 从原列表中移除当前item

### 涉及的功能模块
- 文档编辑功能(generic-edit.scm)
- 列表环境处理(enumerate环境)
- 键盘快捷键处理(kbd-variant)
- 树结构操作(tree操作相关函数)

### 解决的问题
- 解决了有序列表中无法通过Tab键创建子列表的问题
- 提升了用户在编辑有序列表时的效率
- 使TeXmacs的列表编辑功能更符合主流文档编辑器的使用习惯