Browse Source

feat: playground fold (#812)

Shuyoou 6 tháng trước cách đây
mục cha
commit
18e6715f56

+ 8 - 5
client/src/pages/play/hooks/use-codemirror.ts

@@ -5,11 +5,7 @@ import {
   StateEffect,
 } from '@codemirror/state';
 import { EditorView } from '@codemirror/view';
-import { useState, useEffect, KeyboardEventHandler } from 'react';
-import {
-  lineNumbers,
-  highlightActiveLineGutter,
-} from '../language/extensions/gutter';
+import { useState, useEffect } from 'react';
 import {
   highlightSpecialChars,
   drawSelection,
@@ -38,6 +34,12 @@ import {
 } from '@codemirror/autocomplete';
 import { lintKeymap } from '@codemirror/lint';
 
+import {
+  lineNumbers,
+  highlightActiveLineGutter,
+} from '../language/extensions/gutter';
+import { customFoldGutter } from '../language/extensions/fold';
+
 const basicSetup = () => [
   lineNumbers(),
   highlightActiveLineGutter(),
@@ -65,6 +67,7 @@ const basicSetup = () => [
     ...completionKeymap,
     ...lintKeymap,
   ]),
+  customFoldGutter(),
 ];
 
 const External = Annotation.define<boolean>();

+ 25 - 0
client/src/pages/play/language/extensions/fold.ts

@@ -0,0 +1,25 @@
+import { foldService, syntaxTree } from '@codemirror/language';
+import { EditorState } from '@codemirror/state';
+
+export const customFoldGutter = () => {
+  return foldService.of(
+    (state: EditorState, lineStart: number, lineEnd: number) => {
+      try {
+        const text = state.doc.sliceString(lineStart, lineEnd);
+        const node = syntaxTree(state).resolve(lineEnd);
+        if (
+          (node.name === 'Body' && text.endsWith('{')) ||
+          (node.name === 'Array' && text.endsWith('['))
+        ) {
+          return {
+            from: node.from + 1,
+            to: node.to - 1,
+          };
+        }
+      } catch (error) {
+        return null;
+      }
+      return null;
+    }
+  );
+};