Skip to content

Commit 8c762a9

Browse files
authored
feat(code block): add code block handletab (#463)
* feat(code block): add code block handletab * Create thin-windows-roll.md
1 parent df777d3 commit 8c762a9

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

.changeset/thin-windows-roll.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@wangeditor-next/editor": patch
3+
"@wangeditor-next/basic-modules": patch
4+
---
5+
6+
feat(code block): add code block handletab

packages/basic-modules/src/modules/code-block/plugin.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { DomEditor, IDomEditor } from '@wangeditor-next/core'
77
import {
8-
Editor, Element as SlateElement, Node as SlateNode, Transforms,
8+
Editor, Element as SlateElement, Node as SlateNode, Range, Transforms,
99
} from 'slate'
1010

1111
function getLastTextLineBeforeSelection(codeNode: SlateNode, editor: IDomEditor): string {
@@ -26,7 +26,7 @@ function getLastTextLineBeforeSelection(codeNode: SlateNode, editor: IDomEditor)
2626

2727
function withCodeBlock<T extends IDomEditor>(editor: T): T {
2828
const {
29-
insertBreak, normalizeNode, insertData,
29+
insertBreak, normalizeNode, insertData, handleTab,
3030
} = editor
3131
const newEditor = editor
3232

@@ -57,6 +57,60 @@ function withCodeBlock<T extends IDomEditor>(editor: T): T {
5757
newEditor.insertText('\n')
5858
}
5959

60+
// 重写 handleTab 方法
61+
editor.handleTab = () => {
62+
const { selection } = editor
63+
64+
if (!selection) { return }
65+
66+
// 检查是否在代码块内
67+
const codeNode = DomEditor.getSelectedNodeByType(editor, 'code')
68+
69+
if (!codeNode || Range.isCollapsed(selection)) {
70+
// 不在代码块内或折叠的选区 ,使用原始的 tab 处理
71+
handleTab()
72+
return
73+
}
74+
75+
// 获取选中的文本
76+
const [start, end] = [selection.anchor, selection.focus].sort((a, b) => a.offset - b.offset)
77+
// @ts-ignore
78+
const codeText = (codeNode.children[0] as any).text
79+
const lines = codeText.split('\n')
80+
81+
// 计算受影响的行
82+
const startLine = codeText.slice(0, start.offset).split('\n').length - 1
83+
const endLine = codeText.slice(0, end.offset).split('\n').length - 1
84+
85+
// 处理每一行的缩进
86+
const newLines = lines.map((line, index) => {
87+
if (index >= startLine && index <= endLine) {
88+
// 增加缩进(添加 2 个空格)
89+
return ` ${line}`
90+
}
91+
return line
92+
})
93+
94+
// 更新代码块内容
95+
const newText = newLines.join('\n')
96+
97+
// 计算新的光标位置
98+
const newSelection = {
99+
anchor: { path: start.path, offset: start.offset + 2 },
100+
focus: { path: end.path, offset: end.offset + 2 },
101+
}
102+
103+
Transforms.insertText(editor, newText, {
104+
at: {
105+
anchor: { path: start.path, offset: 0 },
106+
focus: { path: end.path, offset: codeText.length },
107+
},
108+
})
109+
110+
// 恢复选区
111+
Transforms.select(editor, newSelection)
112+
}
113+
60114
// 重写 normalizeNode
61115
newEditor.normalizeNode = ([node, path]) => {
62116
const type = DomEditor.getNodeType(node)

0 commit comments

Comments
 (0)