Browse Source

modify based on fb

WNomunomu 10 months ago
parent
commit
f052b23262
1 changed files with 17 additions and 120 deletions
  1. 17 120
      packages/editor/src/client/stores/use-editor-shortcuts.ts

+ 17 - 120
packages/editor/src/client/stores/use-editor-shortcuts.ts

@@ -1,16 +1,17 @@
 import { useEffect } from 'react';
 
-import type { SelectionRange, Extension } from '@codemirror/state';
-import { EditorSelection, type ChangeSpec } from '@codemirror/state';
+import type { EditorView } from '@codemirror/view';
 import {
-  keymap, type Command, EditorView, type KeyBinding,
+  keymap, type Command, type KeyBinding,
 } from '@codemirror/view';
 
 import type { UseCodeMirrorEditor } from '../services';
+import { useAddMultiCursorCommand } from '../services/use-codemirror-editor/utils/add-multi-cursor';
 import type { InsertMarkdownElements } from '../services/use-codemirror-editor/utils/insert-markdown-elements';
 import { useInsertMarkdownElements } from '../services/use-codemirror-editor/utils/insert-markdown-elements';
 import { useInsertPrefix } from '../services/use-codemirror-editor/utils/insert-prefix';
 import type { InsertPrefix } from '../services/use-codemirror-editor/utils/insert-prefix';
+import { useMakeCodeBlockExtension } from '../services/use-codemirror-editor/utils/make-text-code-block';
 
 import type { KeyMapMode } from 'src/consts';
 
@@ -41,118 +42,7 @@ const generateAddMarkdownSymbolCommand = (
   return addMarkdownSymbolCommand;
 };
 
-const makeTextCodeBlock: Command = (view: EditorView) => {
-  const state = view.state;
-  const doc = state.doc;
-  const changes: ChangeSpec[] = [];
-  const newSelections: SelectionRange[] = [];
-
-  state.selection.ranges.forEach((range) => {
-    const startLine = doc.lineAt(range.from);
-    const endLine = doc.lineAt(range.to);
-    const selectedText = doc.sliceString(range.from, range.to, '');
-    const isAlreadyWrapped = selectedText.startsWith('```') && selectedText.endsWith('```');
-
-    const codeBlockMarkerLength = 4;
-
-    if (isAlreadyWrapped) {
-      const startMarkerEnd = startLine.from + codeBlockMarkerLength;
-      const endMarkerStart = endLine.to - codeBlockMarkerLength;
-
-      changes.push({
-        from: startLine.from,
-        to: startMarkerEnd,
-        insert: '',
-      });
-
-      changes.push({
-        from: endMarkerStart,
-        to: endLine.to,
-        insert: '',
-      });
-
-      newSelections.push(EditorSelection.range(startLine.from, endMarkerStart - codeBlockMarkerLength));
-    }
-    else {
-      // Add code block markers
-      changes.push({
-        from: startLine.from,
-        insert: '```\n',
-      });
-
-      changes.push({
-        from: endLine.to,
-        insert: '\n```',
-      });
-
-      if (selectedText.length === 0) {
-        newSelections.push(EditorSelection.cursor(startLine.from + codeBlockMarkerLength));
-      }
-      else {
-        newSelections.push(EditorSelection.range(startLine.from, endLine.to + codeBlockMarkerLength * 2));
-      }
-    }
-  });
-
-  view.dispatch({
-    changes,
-    selection: EditorSelection.create(newSelections),
-  });
-
-  return true;
-};
-
-const addMultiCursor = (view: EditorView, direction: 'up' | 'down') => {
-
-  const selection = view.state.selection;
-  const doc = view.state.doc;
-  const ranges = selection.ranges;
-  const newRanges: SelectionRange[] = [];
-
-  ranges.forEach((range) => {
-
-    const head = range.head;
-    const line = doc.lineAt(head);
-    const targetLine = direction === 'up' ? line.number - 1 : line.number + 1;
-
-    if (targetLine < 1 || targetLine > doc.lines) return;
-
-    const targetLineText = doc.line(targetLine);
-
-    const col = Math.min(range.head - line.from, targetLineText.length);
-    const cursorPos = targetLineText.from + col;
-
-    newRanges.push(EditorSelection.cursor(cursorPos));
-
-  });
-
-  if (newRanges.length) {
-    const transaction = {
-      selection: EditorSelection.create([...ranges, ...newRanges]),
-    };
-
-    view.dispatch(transaction);
-  }
-
-  return true;
-};
-
-const makeCodeBlockExtension: Extension = EditorView.domEventHandlers({
-  keydown: (event, view) => {
-
-    const isModKey = event.ctrlKey || event.metaKey;
-
-    if (event.code === 'KeyC' && event.shiftKey && event.altKey && isModKey) {
-      event.preventDefault();
-      makeTextCodeBlock(view);
-      return true;
-    }
-
-    return false;
-  },
-});
-
-export const useCustomKeyBindings = (view?: EditorView, keyMapName?: KeyMapMode): KeyBinding[] => {
+const useCustomKeyBindings = (view?: EditorView, keyMapName?: KeyMapMode): KeyBinding[] => {
 
   const insertMarkdownElements = useInsertMarkdownElements(view);
 
@@ -171,10 +61,12 @@ export const useCustomKeyBindings = (view?: EditorView, keyMapName?: KeyMapMode)
   return customKeyBindings;
 };
 
-export const useKeyBindings = (view?: EditorView, customKeyBindings?: KeyBinding[]): KeyBinding[] => {
+const useKeyBindings = (view?: EditorView, customKeyBindings?: KeyBinding[]): KeyBinding[] => {
 
   const insertMarkdownElements = useInsertMarkdownElements(view);
   const insertPrefix = useInsertPrefix(view);
+  const upMultiCursorCommand = useAddMultiCursorCommand('up');
+  const downMultiCursorCommand = useAddMultiCursorCommand('down');
 
   const keyBindings: KeyBinding[] = [
     { key: 'mod-shift-i', run: generateAddMarkdownSymbolCommand(insertMarkdownElements, '*', '*') },
@@ -184,8 +76,8 @@ export const useKeyBindings = (view?: EditorView, customKeyBindings?: KeyBinding
     { key: 'mod-shift-8', run: generateAddMarkdownSymbolCommand(insertPrefix, '-') },
     { key: 'mod-shift-9', run: generateAddMarkdownSymbolCommand(insertPrefix, '>') },
     { key: 'mod-shift-u', run: generateAddMarkdownSymbolCommand(insertMarkdownElements, '[', ']()') },
-    { key: 'mod-alt-ArrowUp', run: view => addMultiCursor(view, 'up') },
-    { key: 'mod-alt-ArrowDown', run: view => addMultiCursor(view, 'down') },
+    { key: 'mod-alt-ArrowUp', run: upMultiCursorCommand },
+    { key: 'mod-alt-ArrowDown', run: downMultiCursorCommand },
   ];
 
   if (customKeyBindings != null) {
@@ -195,12 +87,17 @@ export const useKeyBindings = (view?: EditorView, customKeyBindings?: KeyBinding
   return keyBindings;
 };
 
-export const useKeyboardShortcuts = (codeMirrorEditor?: UseCodeMirrorEditor, keyBindings?: KeyBinding[]): void => {
+export const useKeyboardShortcuts = (codeMirrorEditor?: UseCodeMirrorEditor, keymapModeName?: KeyMapMode): void => {
+
+  const customKeyBindings = useCustomKeyBindings(codeMirrorEditor?.view, keymapModeName);
+  const keyBindings = useKeyBindings(codeMirrorEditor?.view, customKeyBindings);
+
+  const makeCodeBlockExtension = useMakeCodeBlockExtension();
 
   useEffect(() => {
     const cleanupFunction = codeMirrorEditor?.appendExtensions?.([makeCodeBlockExtension]);
     return cleanupFunction;
-  }, [codeMirrorEditor]);
+  }, [codeMirrorEditor, makeCodeBlockExtension]);
 
   useEffect(() => {