2
0
Shuyoou 4 сар өмнө
parent
commit
d5c1edc1b6

+ 1 - 2
client/package.json

@@ -10,8 +10,7 @@
     "@codemirror/commands": "^6.6.0",
     "@codemirror/commands": "^6.6.0",
     "@codemirror/lang-javascript": "^6.2.2",
     "@codemirror/lang-javascript": "^6.2.2",
     "@codemirror/lang-json": "^6.0.1",
     "@codemirror/lang-json": "^6.0.1",
-    "@codemirror/language": "^6.10.1",
-    "@codemirror/legacy-modes": "^6.5.0",
+    "@codemirror/language": "6.10.2",
     "@codemirror/lint": "^6.8.0",
     "@codemirror/lint": "^6.8.0",
     "@codemirror/state": "^6.4.1",
     "@codemirror/state": "^6.4.1",
     "@codemirror/view": "^6.28.6",
     "@codemirror/view": "^6.28.6",

+ 6 - 23
client/src/pages/play/JSONEditor.tsx

@@ -1,30 +1,14 @@
-import { EditorView, ViewUpdate } from '@codemirror/view';
+import { EditorView } from '@codemirror/view';
 import { FC, useRef, useMemo } from 'react';
 import { FC, useRef, useMemo } from 'react';
 import { useTheme } from '@mui/material';
 import { useTheme } from '@mui/material';
 import { json, jsonParseLinter } from '@codemirror/lang-json';
 import { json, jsonParseLinter } from '@codemirror/lang-json';
 import { linter } from '@codemirror/lint';
 import { linter } from '@codemirror/lint';
+import { githubLight } from '@ddietr/codemirror-themes/github-light';
+import { githubDark } from '@ddietr/codemirror-themes/github-dark';
+import { Compartment } from '@codemirror/state';
 
 
 import { useCodeMirror } from './hooks/use-codemirror';
 import { useCodeMirror } from './hooks/use-codemirror';
-import { jsonFoldGutter } from './language/extensions/fold';
-
 import { getCMStyle, getStyles } from './style';
 import { getCMStyle, getStyles } from './style';
-import {
-  HighlightStyle,
-  StreamLanguage,
-  syntaxHighlighting,
-} from '@codemirror/language';
-import { json as jsonMode } from '@codemirror/legacy-modes/mode/javascript';
-import { tags } from '@lezer/highlight';
-
-const getJsonHighlightStyle = (isDarkMode: boolean) =>
-  HighlightStyle.define([
-    { tag: tags.string, color: isDarkMode ? '#9CDCFE' : '#085bd7' },
-    { tag: tags.number, color: isDarkMode ? '#50fa7b' : '#0c7e5e' },
-    { tag: tags.bool, color: '#a00' },
-    { tag: tags.null, color: '#a00' },
-    { tag: tags.propertyName, color: '#a0a' },
-    { tag: tags.punctuation, color: '#555' },
-  ]);
 
 
 type Props = {
 type Props = {
   value: string;
   value: string;
@@ -35,6 +19,7 @@ type Props = {
 export const JSONEditor: FC<Props> = props => {
 export const JSONEditor: FC<Props> = props => {
   const { value, editable = true, onChange } = props;
   const { value, editable = true, onChange } = props;
   const theme = useTheme();
   const theme = useTheme();
+  const themeCompartment = new Compartment();
   const container = useRef<HTMLDivElement>(null);
   const container = useRef<HTMLDivElement>(null);
   const classes = getStyles();
   const classes = getStyles();
 
 
@@ -45,10 +30,8 @@ export const JSONEditor: FC<Props> = props => {
       EditorView.lineWrapping,
       EditorView.lineWrapping,
       EditorView.editable.of(editable),
       EditorView.editable.of(editable),
       EditorView.theme(getCMStyle(theme)),
       EditorView.theme(getCMStyle(theme)),
-      StreamLanguage.define(jsonMode as any),
-      syntaxHighlighting(getJsonHighlightStyle(isDarkMode)),
+      themeCompartment.of(isDarkMode ? githubDark : githubLight),
       json(),
       json(),
-      jsonFoldGutter(),
       linter(jsonParseLinter()),
       linter(jsonParseLinter()),
     ];
     ];
   }, [theme.palette.mode, isDarkMode, editable]);
   }, [theme.palette.mode, isDarkMode, editable]);

+ 24 - 3
client/src/pages/play/Play.tsx

@@ -14,9 +14,13 @@ import { ATTU_PLAY_CODE } from '@/consts';
 import { authContext, dataContext } from '@/context';
 import { authContext, dataContext } from '@/context';
 import { useNavigationHook } from '@/hooks';
 import { useNavigationHook } from '@/hooks';
 import { ALL_ROUTER_TYPES } from '@/router/consts';
 import { ALL_ROUTER_TYPES } from '@/router/consts';
-import { DEFAULT_CODE_VALUE } from '@/pages/play/Constants';
+import {
+  DEFAULT_CODE_VALUE,
+  DEFAULT_FOLD_LINE_RANGES,
+} from '@/pages/play/Constants';
 
 
 import { useCodeMirror } from './hooks/use-codemirror';
 import { useCodeMirror } from './hooks/use-codemirror';
+import { useCodelensShortcuts } from './hooks/use-codelens-shortcuts';
 import { Autocomplete } from './language/extensions/autocomplete';
 import { Autocomplete } from './language/extensions/autocomplete';
 import { KeyMap } from './language/extensions/keymap';
 import { KeyMap } from './language/extensions/keymap';
 import { MilvusHTTP } from './language/milvus.http';
 import { MilvusHTTP } from './language/milvus.http';
@@ -24,7 +28,13 @@ import { getCMStyle, getStyles } from './style';
 import { CustomEventNameEnum, PlaygroundCustomEventDetail } from './Types';
 import { CustomEventNameEnum, PlaygroundCustomEventDetail } from './Types';
 import { DocumentEventManager } from './utils/event';
 import { DocumentEventManager } from './utils/event';
 import { JSONEditor } from './JSONEditor';
 import { JSONEditor } from './JSONEditor';
-import { customFoldGutter, persistFoldState } from './language/extensions/fold';
+import {
+  customFoldGutter,
+  foldByLineRanges,
+  loadFoldState,
+  persistFoldState,
+  recoveryFoldState,
+} from './language/extensions/fold';
 
 
 const Play: FC = () => {
 const Play: FC = () => {
   // hooks
   // hooks
@@ -67,7 +77,6 @@ const Play: FC = () => {
       placeholder('Write your code here'),
       placeholder('Write your code here'),
       EditorView.lineWrapping,
       EditorView.lineWrapping,
       EditorView.theme(getCMStyle(theme)),
       EditorView.theme(getCMStyle(theme)),
-      KeyMap(),
       MilvusHTTP({
       MilvusHTTP({
         baseUrl: getBaseUrl(),
         baseUrl: getBaseUrl(),
         token,
         token,
@@ -76,6 +85,7 @@ const Play: FC = () => {
         isManaged,
         isManaged,
         isDarkMode: theme.palette.mode === 'dark',
         isDarkMode: theme.palette.mode === 'dark',
       }),
       }),
+      KeyMap(),
       Autocomplete({ databases, collections }),
       Autocomplete({ databases, collections }),
       customFoldGutter(),
       customFoldGutter(),
       persistFoldState(),
       persistFoldState(),
@@ -86,12 +96,23 @@ const Play: FC = () => {
     setCode(code);
     setCode(code);
   }, []);
   }, []);
 
 
+  const onEditorViewLoaded = (editorView: EditorView) => {
+    const foldState = loadFoldState();
+    if (foldState) {
+      recoveryFoldState(editorView);
+    } else if (code === DEFAULT_CODE_VALUE) {
+      foldByLineRanges(editorView, DEFAULT_FOLD_LINE_RANGES);
+    }
+  };
+
   useCodeMirror({
   useCodeMirror({
     container: container.current,
     container: container.current,
     value: code,
     value: code,
     extensions,
     extensions,
     onChange: handleCodeChange,
     onChange: handleCodeChange,
+    onLoaded: onEditorViewLoaded,
   });
   });
+  useCodelensShortcuts(container.current);
 
 
   // save code to local storage
   // save code to local storage
   useEffect(() => {
   useEffect(() => {

+ 29 - 0
client/src/pages/play/hooks/use-codelens-shortcuts.ts

@@ -0,0 +1,29 @@
+import { useEffect } from 'react';
+
+export const useCodelensShortcuts = (container: HTMLDivElement | null) => {
+  useEffect(() => {
+    const handler = (event: Event) => {
+      if (event instanceof KeyboardEvent) {
+        if (event.metaKey && event.shiftKey && event.key === 'Enter') {
+          const currentRunButton = document.querySelector(
+            '.milvus-http-request-highlight .playground-codelens .run-button'
+          );
+          currentRunButton?.dispatchEvent(new MouseEvent('click'));
+          event.preventDefault();
+        } else if (event.metaKey && event.key === 'h') {
+          const currentDocsButton = document.querySelector(
+            '.milvus-http-request-highlight .playground-codelens .docs-button'
+          );
+          currentDocsButton?.dispatchEvent(new MouseEvent('click'));
+          event.preventDefault();
+        }
+      }
+    };
+
+    container?.addEventListener('keydown', handler);
+
+    return () => {
+      container?.removeEventListener('keydown', handler);
+    };
+  }, [container]);
+};

+ 3 - 43
client/src/pages/play/hooks/use-codemirror.ts

@@ -33,20 +33,11 @@ import {
   completionKeymap,
   completionKeymap,
 } from '@codemirror/autocomplete';
 } from '@codemirror/autocomplete';
 import { lintKeymap } from '@codemirror/lint';
 import { lintKeymap } from '@codemirror/lint';
-import {
-  DEFAULT_CODE_VALUE,
-  DEFAULT_FOLD_LINE_RANGES,
-} from '@/pages/play/Constants';
 
 
 import {
 import {
   lineNumbers,
   lineNumbers,
   highlightActiveLineGutter,
   highlightActiveLineGutter,
 } from '../language/extensions/gutter';
 } from '../language/extensions/gutter';
-import {
-  foldByLineRanges,
-  loadFoldState,
-  recoveryFoldState,
-} from '../language/extensions/fold';
 
 
 const basicSetup = () => [
 const basicSetup = () => [
   lineNumbers(),
   lineNumbers(),
@@ -84,10 +75,11 @@ export interface UseCodeMirrorProps {
   value?: string;
   value?: string;
   extensions?: Extension[];
   extensions?: Extension[];
   onChange?: (value: string) => void;
   onChange?: (value: string) => void;
+  onLoaded?: (view: EditorView) => void;
 }
 }
 
 
 export const useCodeMirror = (props: UseCodeMirrorProps) => {
 export const useCodeMirror = (props: UseCodeMirrorProps) => {
-  const { value, extensions, onChange } = props;
+  const { value, extensions, onChange, onLoaded } = props;
 
 
   const [container, setContainer] = useState<HTMLDivElement | null>();
   const [container, setContainer] = useState<HTMLDivElement | null>();
   const viewRef = useRef<EditorView>();
   const viewRef = useRef<EditorView>();
@@ -115,13 +107,8 @@ export const useCodeMirror = (props: UseCodeMirrorProps) => {
         parent: container,
         parent: container,
       });
       });
 
 
-      const foldState = loadFoldState();
-      if (foldState) {
-        recoveryFoldState(editorView);
-      } else if (value === DEFAULT_CODE_VALUE) {
-        foldByLineRanges(editorView, DEFAULT_FOLD_LINE_RANGES);
-      }
       viewRef.current = editorView;
       viewRef.current = editorView;
+      onLoaded?.(editorView);
     }
     }
 
 
     return () => {
     return () => {
@@ -162,32 +149,5 @@ export const useCodeMirror = (props: UseCodeMirrorProps) => {
 
 
   useEffect(() => setContainer(props.container), [props.container]);
   useEffect(() => setContainer(props.container), [props.container]);
 
 
-  // Handle codelens shortcuts
-  useEffect(() => {
-    const handler = (event: Event) => {
-      if (event instanceof KeyboardEvent) {
-        if (event.metaKey && event.shiftKey && event.key === 'Enter') {
-          const currentRunButton = document.querySelector(
-            '.milvus-http-request-highlight .playground-codelens .run-button'
-          );
-          currentRunButton?.dispatchEvent(new MouseEvent('click'));
-          event.preventDefault();
-        } else if (event.metaKey && event.key === 'h') {
-          const currentDocsButton = document.querySelector(
-            '.milvus-http-request-highlight .playground-codelens .docs-button'
-          );
-          currentDocsButton?.dispatchEvent(new MouseEvent('click'));
-          event.preventDefault();
-        }
-      }
-    };
-
-    container?.addEventListener('keydown', handler);
-
-    return () => {
-      container?.removeEventListener('keydown', handler);
-    };
-  }, [container]);
-
   return { view: viewRef.current };
   return { view: viewRef.current };
 };
 };

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

@@ -105,52 +105,3 @@ export const recoveryFoldState = (view: EditorView) => {
     }
     }
   }
   }
 };
 };
-
-export const jsonFoldGutter = () => {
-  return foldService.of(
-    (state: EditorState, lineStart: number, lineEnd: number) => {
-      try {
-        const text = state.doc.sliceString(lineStart, lineEnd);
-        const lines = state.doc.lines;
-        if (text.endsWith('{') || text.endsWith('[')) {
-          const letter = text.endsWith('{') ? '{' : '[';
-          const line = state.doc.lineAt(lineStart);
-          let to = line.to;
-          const matches = [letter];
-          for (let i = line.number + 1; i <= lines; i++) {
-            const nextLine = state.doc.line(i);
-            const nextText = nextLine.text.trim();
-            for (const char of nextText) {
-              if (char === '{' || char === '[') {
-                matches.push(char);
-              } else if (char === '}') {
-                if (matches[matches.length - 1] === '{') {
-                  matches.pop();
-                }
-              } else if (char === ']') {
-                if (matches[matches.length - 1] === '[') {
-                  matches.pop();
-                }
-              }
-            }
-            if (matches.length === 0) {
-              if (nextText.endsWith('}') || nextText.endsWith(']')) {
-                to = nextLine.to - 1;
-              } else {
-                to = nextLine.to - 2;
-              }
-              break;
-            }
-          }
-          return {
-            from: lineEnd,
-            to: to,
-          };
-        }
-      } catch (error) {
-        return null;
-      }
-      return null;
-    }
-  );
-};

+ 7 - 0
client/src/pages/play/style.tsx

@@ -44,6 +44,9 @@ export const getCMStyle = (theme: Theme) => {
       height: '100%',
       height: '100%',
       borderRadius: '4px',
       borderRadius: '4px',
     },
     },
+    '&.cm-editor.cm-focused': {
+      outline: 'none',
+    },
     '&.cm-editor .cm-cursor': {
     '&.cm-editor .cm-cursor': {
       borderColor: theme.palette.text.primary,
       borderColor: theme.palette.text.primary,
     },
     },
@@ -53,6 +56,10 @@ export const getCMStyle = (theme: Theme) => {
       overflow: 'auto',
       overflow: 'auto',
     },
     },
     '.cm-line': { padding: ' 0 4px 0 2px' },
     '.cm-line': { padding: ' 0 4px 0 2px' },
+    '.cm-line .cm-foldPlaceholder': {
+      backgroundColor: 'transparent',
+      border: 'none',
+    },
     '.cm-content': {
     '.cm-content': {
       fontSize: '13px',
       fontSize: '13px',
       fontFamily: 'IBM Plex Mono, monospace',
       fontFamily: 'IBM Plex Mono, monospace',

+ 1 - 20
client/yarn.lock

@@ -418,7 +418,7 @@
     "@codemirror/language" "^6.0.0"
     "@codemirror/language" "^6.0.0"
     "@lezer/json" "^1.0.0"
     "@lezer/json" "^1.0.0"
 
 
-"@codemirror/language@^6.0.0", "@codemirror/language@^6.6.0":
+"@codemirror/language@6.10.2", "@codemirror/language@^6.0.0", "@codemirror/language@^6.6.0":
   version "6.10.2"
   version "6.10.2"
   resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.10.2.tgz#4056dc219619627ffe995832eeb09cea6060be61"
   resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.10.2.tgz#4056dc219619627ffe995832eeb09cea6060be61"
   integrity sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==
   integrity sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==
@@ -430,25 +430,6 @@
     "@lezer/lr" "^1.0.0"
     "@lezer/lr" "^1.0.0"
     style-mod "^4.0.0"
     style-mod "^4.0.0"
 
 
-"@codemirror/language@^6.10.1":
-  version "6.11.0"
-  resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.11.0.tgz#5ae90972601497f4575f30811519d720bf7232c9"
-  integrity sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==
-  dependencies:
-    "@codemirror/state" "^6.0.0"
-    "@codemirror/view" "^6.23.0"
-    "@lezer/common" "^1.1.0"
-    "@lezer/highlight" "^1.0.0"
-    "@lezer/lr" "^1.0.0"
-    style-mod "^4.0.0"
-
-"@codemirror/legacy-modes@^6.5.0":
-  version "6.5.0"
-  resolved "https://registry.yarnpkg.com/@codemirror/legacy-modes/-/legacy-modes-6.5.0.tgz#21c8cf818f9ea4d6eba9f22afdfef010d1d9f754"
-  integrity sha512-dNw5pwTqtR1giYjaJyEajunLqxGavZqV0XRtVZyMJnNOD2HmK9DMUmuCAr6RMFGRJ4l8OeQDjpI/us+R09mQsw==
-  dependencies:
-    "@codemirror/language" "^6.0.0"
-
 "@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.0":
 "@codemirror/lint@^6.0.0", "@codemirror/lint@^6.8.0":
   version "6.8.1"
   version "6.8.1"
   resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.1.tgz#6427848815baaf68c08e98c7673b804d3d8c0e7f"
   resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.1.tgz#6427848815baaf68c08e98c7673b804d3d8c0e7f"