Просмотр исходного кода

137432 insert 1 when push enter on number list

soumaeda 2 лет назад
Родитель
Сommit
e3c97b8bbb

+ 2 - 45
packages/editor/src/components/CodeMirrorEditor/CodeMirrorEditor.tsx

@@ -8,6 +8,7 @@ import type { ReactCodeMirrorProps } from '@uiw/react-codemirror';
 
 import { GlobalCodeMirrorEditorKey, AcceptedUploadFileType } from '../../consts';
 import { useFileDropzone, FileDropzoneOverlay } from '../../services';
+import { newlineAndIndentContinueMarkdownList } from '../../services/list-util/markdown-list-util';
 import { useCodeMirrorEditorIsolated } from '../../stores';
 
 import { Toolbar } from './Toolbar';
@@ -46,50 +47,6 @@ export const CodeMirrorEditor = (props: Props): JSX.Element => {
   }, [onChange]);
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey, containerRef.current, cmProps);
 
-  /**
-   * return the postion of the BOL(beginning of line)
-   */
-  const getBol = (editor: EditorView) => {
-    const curPos = editor.state.selection.main.head;
-    return editor.state.doc.lineAt(curPos).from;
-  };
-
-  const getStrFromBol = (editor: EditorView) => {
-    const curPos = editor.state.selection.main.head;
-    return editor.state.sliceDoc(getBol(editor), curPos);
-  };
-
-  const selectLowerPos = (editor: EditorView, pos1: number, pos2: number) => {
-    // if both is in same line
-    if (editor.state.doc.lineAt(pos1).number === editor.state.doc.lineAt(pos2).number) {
-      return (editor.state.doc.lineAt(pos1).from < editor.state.doc.lineAt(pos1).to) ? pos2 : pos1;
-    }
-    return (editor.state.doc.lineAt(pos1) < editor.state.doc.lineAt(pos2)) ? pos2 : pos1;
-  };
-
-  const replaceBolToCurrentPos = (editor: EditorView, text: string) => {
-    const curPos = editor.state.selection.main.head;
-    const pos = selectLowerPos(editor, editor.state.doc.lineAt(curPos).from, editor.state.doc.lineAt(curPos).to);
-    editor.dispatch({
-      changes: {
-        from: getBol(editor),
-        to: pos,
-        insert: text,
-      },
-    });
-  };
-
-  const indentAndMarkOnlyRE = /^(\d+)[.)](\s*)$/;
-
-  // eslint-disable-next-line react-hooks/exhaustive-deps
-  const newlineAndIndentContinueMarkdownList = (editor: EditorView) => {
-    const strFromBol = getStrFromBol(editor);
-
-    if (indentAndMarkOnlyRE.test(strFromBol)) {
-      replaceBolToCurrentPos(editor, '1. ');
-    }
-  };
-
   useEffect(() => {
     const handleEnterKey = (event: KeyboardEvent) => {
       if (event.key === 'Enter') {
@@ -104,7 +61,7 @@ export const CodeMirrorEditor = (props: Props): JSX.Element => {
     return () => {
       codeMirrorEditor?.view?.dom.removeEventListener('keydown', handleEnterKey);
     };
-  }, [codeMirrorEditor, newlineAndIndentContinueMarkdownList]);
+  }, [codeMirrorEditor]);
 
   useEffect(() => {
     if (indentSize == null) {

+ 32 - 0
packages/editor/src/services/list-util/markdown-list-util.ts

@@ -0,0 +1,32 @@
+import { EditorView } from '@codemirror/view';
+
+const getBol = (editor: EditorView) => {
+  const curPos = editor.state.selection.main.head;
+  const aboveLine = editor.state.doc.lineAt(curPos).number - 1;
+  return editor.state.doc.line(aboveLine).from;
+};
+
+const getStrFromBol = (editor: EditorView) => {
+  const curPos = editor.state.selection.main.head;
+  return editor.state.sliceDoc(getBol(editor), curPos);
+};
+
+const indentAndMarkRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/;
+
+export const newlineAndIndentContinueMarkdownList = (editor: EditorView): void => {
+  const strFromBol = getStrFromBol(editor);
+
+  if (indentAndMarkRE.test(strFromBol)) {
+    // continue list
+    const indentAndMark = strFromBol.match(indentAndMarkRE)[0];
+    const curPos = editor.state.selection.main.head;
+    const line = editor.state.doc.lineAt(curPos).from;
+    editor.dispatch({
+      changes: {
+        from: line,
+        to: curPos,
+        insert: indentAndMark,
+      },
+    });
+  }
+};