55
66import { DomEditor , IDomEditor } from '@wangeditor-next/core'
77import {
8- Editor , Element as SlateElement , Node as SlateNode , Transforms ,
8+ Editor , Element as SlateElement , Node as SlateNode , Range , Transforms ,
99} from 'slate'
1010
1111function getLastTextLineBeforeSelection ( codeNode : SlateNode , editor : IDomEditor ) : string {
@@ -26,7 +26,7 @@ function getLastTextLineBeforeSelection(codeNode: SlateNode, editor: IDomEditor)
2626
2727function 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