Browse Source

relocate makeCodeBlock

WNomunomu 10 months ago
parent
commit
6e49a23d7b

+ 84 - 0
packages/editor/src/client/services/use-codemirror-editor/utils/make-text-code-block.ts

@@ -0,0 +1,84 @@
+import { EditorSelection } from '@codemirror/state';
+import type { Extension, ChangeSpec, SelectionRange } from '@codemirror/state';
+import type { Command } from '@codemirror/view';
+import { EditorView } from '@codemirror/view';
+
+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 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 useMakeCodeBlockExtension = (): Extension => {
+  return makeCodeBlockExtension;
+};