@@ -1136,6 +1136,38 @@ const copyAsMarkdown = async () => {
11361136 }
11371137}
11381138
1139+ // 转换整篇的缩进:空格 ↔ 制表符(按 tab 宽度换算)
1140+ const convertIndentation = (toTabs : boolean ) => {
1141+ const view = editorView .value
1142+ if (! view ) {
1143+ return
1144+ }
1145+ const size = editorConfig .value ?.tab_size ?? 2
1146+ const original = view .state .doc .toString ()
1147+ const out = original .split (' \n ' ).map ((line : string ) => {
1148+ const m = line .match (/ ^ [ \t ] + / )
1149+ if (! m ) {
1150+ return line
1151+ }
1152+ // 把行首空白展开为列数(tab 计为 size 列)
1153+ let cols = 0
1154+ for (const ch of m [0 ]) {
1155+ cols += ch === ' \t ' ? size : 1
1156+ }
1157+ const rest = line .slice (m [0 ].length )
1158+ return toTabs
1159+ ? ' \t ' .repeat (Math .floor (cols / size )) + ' ' .repeat (cols % size ) + rest
1160+ : ' ' .repeat (cols ) + rest
1161+ }).join (' \n ' )
1162+ if (out === original ) {
1163+ return
1164+ }
1165+ const head = Math .min (view .state .selection .main .head , out .length )
1166+ view .dispatch ({changes: {from: 0 , to: view .state .doc .length , insert: out }, selection: {anchor: head }})
1167+ view .focus ()
1168+ toast .success (t (' app.indentConverted' ))
1169+ }
1170+
11391171// AI 自然语言生成 / 选区改写
11401172const showGenerate = ref (false )
11411173const generateSelection = ref (' ' )
@@ -2193,6 +2225,8 @@ const paletteCommands = computed<PaletteCommand[]>(() => [
21932225 {id: ' removeDuplicateLines' , label: t (' command.removeDuplicateLines' ), group: t (' command.groupText' ), icon: ListChecks , run : () => removeDuplicateLines ()},
21942226 {id: ' trimTrailingWhitespace' , label: t (' command.trimTrailingWhitespace' ), group: t (' command.groupText' ), icon: Eraser , run : () => trimTrailingWhitespace ()},
21952227 {id: ' copyAsMarkdown' , label: t (' command.copyAsMarkdown' ), group: t (' command.groupText' ), icon: Code2 , run : () => copyAsMarkdown ()},
2228+ {id: ' indentToSpaces' , label: t (' command.indentToSpaces' ), group: t (' command.groupText' ), icon: Eraser , run : () => convertIndentation (false )},
2229+ {id: ' indentToTabs' , label: t (' command.indentToTabs' ), group: t (' command.groupText' ), icon: Eraser , run : () => convertIndentation (true )},
21962230 {id: ' toggleAutoReveal' , label: t (' command.toggleAutoReveal' ), icon: FolderOpen , run : () => toggleAutoReveal ()},
21972231 {id: ' toggleSidebar' , label: t (' command.toggleSidebar' ), icon: PanelLeft , hint: hintOf (' toggleSidebar' ), run : () => toggleSidebar ()},
21982232 {id: ' toggleZen' , label: t (' command.toggleZen' ), icon: Minimize2 , run : () => toggleZen ()},
0 commit comments