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

create insertNewlineContinueKeymap

kosei-n 2 лет назад
Родитель
Сommit
4660db1eff

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

@@ -9,7 +9,7 @@ import type { ReactCodeMirrorProps } from '@uiw/react-codemirror';
 import { GlobalCodeMirrorEditorKey, AcceptedUploadFileType } from '../../consts';
 import { useFileDropzone, FileDropzoneOverlay } from '../../services';
 import {
-  getLineToCursor, adjustPasteData,
+  adjustPasteData,
   // useNewlineAndIndentContinueMarkdownList,
 } from '../../services/list-util/markdown-list-util';
 import { useCodeMirrorEditorIsolated } from '../../stores';
@@ -108,7 +108,7 @@ export const CodeMirrorEditor = (props: Props): JSX.Element => {
 
         const textData = event.clipboardData.getData('text/plain');
 
-        const strFromBol = getLineToCursor(editor);
+        // const strFromBol = getLineToCursor(editor);
 
         const adjusted = adjustPasteData(strFromBol, textData);
 

+ 5 - 3
packages/editor/src/services/codemirror-editor/use-codemirror-editor/use-codemirror-editor.ts

@@ -22,14 +22,16 @@ import { FoldDrawio, useFoldDrawio } from './utils/fold-drawio';
 import { useGetDoc, type GetDoc } from './utils/get-doc';
 import { useInitDoc, type InitDoc } from './utils/init-doc';
 import { useInsertMarkdownElements, type InsertMarkdowElements } from './utils/insert-markdown-elements';
+import { insertNewlineContinueMarkup } from './utils/insert-newline-continue-markup';
 import { useInsertPrefix, type InsertPrefix } from './utils/insert-prefix';
 import { useInsertText, type InsertText } from './utils/insert-text';
 import { useReplaceText, type ReplaceText } from './utils/replace-text';
 import { useSetCaretLine, type SetCaretLine } from './utils/set-caret-line';
 
+
 const markdownKeymap = [
   { key: 'Backspace', run: deleteMarkupBackward },
-  { key: 'Enter', run:  }
+  { key: 'Enter', run: insertNewlineContinueMarkup },
 ];
 
 const markdownHighlighting = HighlightStyle.define([
@@ -61,8 +63,8 @@ export type UseCodeMirrorEditor = {
 
 const defaultExtensions: Extension[] = [
   EditorView.lineWrapping,
-  markdown({ base: markdownLanguage, codeLanguages: languages }),
-  // keymap.of(markdownKeymap),
+  markdown({ base: markdownLanguage, codeLanguages: languages, addKeymap: false }),
+  keymap.of(markdownKeymap),
   keymap.of([indentWithTab]),
   Prec.lowest(keymap.of(defaultKeymap)),
   syntaxHighlighting(markdownHighlighting),

+ 65 - 0
packages/editor/src/services/codemirror-editor/use-codemirror-editor/utils/insert-newline-continue-markup.ts

@@ -0,0 +1,65 @@
+import type { ChangeSpec, StateCommand } from '@codemirror/state';
+
+// https://regex101.com/r/7BN2fR/5
+const indentAndMarkRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/;
+const indentAndMarkOnlyRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/;
+
+export const insertNewlineContinueMarkup: StateCommand = ({ state, dispatch }) => {
+
+  const changes: ChangeSpec[] = [];
+  let insert: string;
+  let nextCurPos: number;
+
+  const curPos = state.selection.main.head;
+
+  const aboveLine = state.doc.lineAt(curPos).number;
+  const bolPos = state.doc.line(aboveLine).from;
+
+  const strFromBol = state.sliceDoc(bolPos, curPos);
+
+  if (indentAndMarkOnlyRE.test(strFromBol)) {
+    insert = state.lineBreak;
+    nextCurPos = curPos + insert.length;
+
+    changes.push({
+      from: bolPos,
+      to: nextCurPos,
+      insert,
+    });
+  }
+
+  else if (indentAndMarkRE.test(strFromBol)) {
+    const indentAndMark = strFromBol.match(indentAndMarkRE)?.[0];
+
+    if (indentAndMark == null) {
+      return false;
+    }
+
+    insert = indentAndMark;
+    nextCurPos = curPos + insert.length + 1;
+
+    changes.push({
+      from: curPos,
+      insert,
+    });
+  }
+
+  else {
+    insert = state.lineBreak;
+    nextCurPos = curPos + insert.length;
+
+    changes.push({
+      from: curPos,
+      insert,
+    });
+  }
+
+  dispatch(state.update({
+    changes,
+    selection: { anchor: nextCurPos },
+    scrollIntoView: true,
+    userEvent: 'input',
+  }));
+
+  return true;
+};

+ 18 - 28
packages/editor/src/services/list-util/markdown-list-util.ts

@@ -2,6 +2,7 @@ import { useCallback } from 'react';
 
 import { EditorView } from '@codemirror/view';
 
+
 import { useInsertText } from '../codemirror-editor/use-codemirror-editor/utils/insert-text';
 
 
@@ -10,41 +11,30 @@ export type NewlineAndIndentContinueMarkdownList = ((editor: EditorView) => void
 // https://regex101.com/r/7BN2fR/5
 const indentAndMarkRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/;
 
-export const getLineToCursor = (editor: EditorView, lineNumBeforeCursor = 0): string => {
-  const curPos = editor.state.selection.main.head;
-  const firstLineNumToGet = editor.state.doc.lineAt(curPos).number - lineNumBeforeCursor;
-
-  const fixedFirstLineNumToGet = Math.max(firstLineNumToGet, 1);
-
-  const firstLineToGet = editor.state.doc.line(fixedFirstLineNumToGet).from;
-
-  return editor.state.sliceDoc(firstLineToGet, curPos);
-};
-
-export const useNewlineAndIndentContinueMarkdownList = (editor?: EditorView): NewlineAndIndentContinueMarkdownList => {
-  const insertText = useInsertText(editor);
+// export const useNewlineAndIndentContinueMarkdownList = (editor?: EditorView): NewlineAndIndentContinueMarkdownList => {
+//   const insertText = useInsertText(editor);
 
-  const newlineAndIndentContinueMarkdownList = useCallback((view: EditorView) => {
+//   const newlineAndIndentContinueMarkdownList = useCallback((view: EditorView) => {
 
-    const curPos = view?.state.selection.main.head;
-    const lineStartPos = view?.state.doc.lineAt(curPos).from;
+//     const curPos = view?.state.selection.main.head;
+//     const lineStartPos = view?.state.doc.lineAt(curPos).from;
 
-    const getStrFromAboveLine = getLineToCursor(view, 1);
+//     const getStrFromAboveLine = getLineToCursor(view, 1);
 
-    const matchResult = getStrFromAboveLine.match(indentAndMarkRE);
+//     const matchResult = getStrFromAboveLine.match(indentAndMarkRE);
 
-    if (matchResult != null) {
-      const indentAndMark = matchResult[0];
-      insertText(indentAndMark, lineStartPos, curPos);
-    }
-  }, [insertText]);
+//     if (matchResult != null) {
+//       const indentAndMark = matchResult[0];
+//       insertText(indentAndMark, lineStartPos, curPos);
+//     }
+//   }, [insertText]);
 
-  if (editor == null) {
-    return;
-  }
+//   if (editor == null) {
+//     return;
+//   }
 
-  return () => { newlineAndIndentContinueMarkdownList(editor) };
-};
+//   return () => { newlineAndIndentContinueMarkdownList(editor) };
+// };
 
 export const adjustPasteData = (indentAndMark: string, text: string): string => {