Browse Source

improve useInsertPrefix hooks

WNomunomu 1 year ago
parent
commit
be0fb46137

+ 56 - 14
packages/editor/src/client/services/use-codemirror-editor/utils/insert-prefix.ts

@@ -15,6 +15,15 @@ export const useInsertPrefix = (view?: EditorView): InsertPrefix => {
     const startLine = view.state.doc.lineAt(from);
     const startLine = view.state.doc.lineAt(from);
     const endLine = view.state.doc.lineAt(to);
     const endLine = view.state.doc.lineAt(to);
 
 
+    let allLinesEmpty = true;
+    for (let i = startLine.number; i <= endLine.number; i++) {
+      const line = view.state.doc.line(i);
+      if (line.text.trim() !== '') {
+        allLinesEmpty = false;
+        break;
+      }
+    }
+
     let allLinesHavePrefix = true;
     let allLinesHavePrefix = true;
     for (let i = startLine.number; i <= endLine.number; i++) {
     for (let i = startLine.number; i <= endLine.number; i++) {
       const line = view.state.doc.line(i);
       const line = view.state.doc.line(i);
@@ -31,32 +40,65 @@ export const useInsertPrefix = (view?: EditorView): InsertPrefix => {
     for (let i = startLine.number; i <= endLine.number; i++) {
     for (let i = startLine.number; i <= endLine.number; i++) {
       const line = view.state.doc.line(i);
       const line = view.state.doc.line(i);
       const trimmedLine = line.text.trim();
       const trimmedLine = line.text.trim();
+      const leadingSpaces = line.text.match(/^\s*/)?.[0] || '';
+      const contentTrimmed = line.text.trimStart();
 
 
-      if (trimmedLine === '') {
+      if (allLinesEmpty) {
+        // Add prefix to all empty lines
+        const insertText = `${leadingSpaces}${prefix} `;
+        changes.push({
+          from: line.from,
+          to: line.to,
+          insert: insertText,
+        });
+        totalLengthChange += (insertText.length - line.text.length);
         continue;
         continue;
       }
       }
 
 
-      const leadingSpaces = line.text.match(/^\s*/)?.[0] || '';
-      const contentTrimmed = line.text.trimStart();
+      if (trimmedLine === '') {
+        continue;
+      }
 
 
       if (allLinesHavePrefix) {
       if (allLinesHavePrefix) {
-        const contentStartMatch = line.text.match(new RegExp(`^\\s*${prefix}\\s+`));
+        const contentStartMatch = line.text.match(new RegExp(`^\\s*(${prefix}+)\\s*`));
         if (contentStartMatch) {
         if (contentStartMatch) {
-          const prefixWithSpaces = contentStartMatch[0];
-          const indentLevel = Math.floor(leadingSpaces.length / 2) * 2; // Preserve indent level
-          const newIndent = ' '.repeat(indentLevel);
+          if (noSpaceIfPrefixExists) {
+            const existingPrefixes = contentStartMatch[1];
+            const indentLevel = Math.floor(leadingSpaces.length / 2) * 2;
+            const newIndent = ' '.repeat(indentLevel);
+            const newPrefix = `${newIndent}${existingPrefixes}${prefix} `;
+
+            const restOfLine = line.text.slice(contentStartMatch[0].length);
+            const newLine = `${newPrefix}${restOfLine}`;
 
 
-          changes.push({
-            from: line.from,
-            to: line.from + prefixWithSpaces.length,
-            insert: newIndent,
-          });
+            changes.push({
+              from: line.from,
+              to: line.to,
+              insert: newLine,
+            });
 
 
-          totalLengthChange -= (prefixWithSpaces.length - newIndent.length);
+            totalLengthChange += (newLine.length - line.text.length);
+          }
+          else {
+            const prefixWithSpaces = contentStartMatch[0];
+            const indentLevel = Math.floor(leadingSpaces.length / 2) * 2;
+            const newIndent = ' '.repeat(indentLevel);
+
+            changes.push({
+              from: line.from,
+              to: line.from + prefixWithSpaces.length,
+              insert: newIndent,
+            });
+
+            totalLengthChange -= (prefixWithSpaces.length - newIndent.length);
+          }
         }
         }
       }
       }
       else {
       else {
-        const insertText = `${leadingSpaces}${prefix} ${contentTrimmed}`;
+        const insertText = noSpaceIfPrefixExists && line.text.startsWith(prefix)
+          ? `${leadingSpaces}${prefix}${contentTrimmed}`
+          : `${leadingSpaces}${prefix} ${contentTrimmed}`;
+
         changes.push({
         changes.push({
           from: line.from,
           from: line.from,
           to: line.to,
           to: line.to,