Explorar o código

create extensions for emoji autocompletion

WNomunomu %!s(int64=2) %!d(string=hai) anos
pai
achega
e27433ca6d

+ 1 - 3
packages/editor/src/components/CodeMirrorEditorMain.tsx

@@ -49,7 +49,7 @@ const getEmojiDataArray = (): string[] => {
 const emojiDataArray = getEmojiDataArray();
 
 const emojiOptions = emojiDataArray.map(
-  tag => ({ label: `:${tag}`, type: 'keyword' }),
+  tag => ({ label: `:${tag}:`, type: 'keyword' }),
 );
 
 const completeEmojiInput = (context: CompletionContext) => {
@@ -59,8 +59,6 @@ const completeEmojiInput = (context: CompletionContext) => {
 
   if (!emojiBefore && !context.explicit) return null;
 
-  console.log('kohsei');
-
   return {
     from: emojiBefore ? nodeBefore.from + emojiBefore.index : context.pos,
     options: emojiOptions,

+ 63 - 2
packages/editor/src/services/codemirror-editor/use-codemirror-editor/use-codemirror-editor.ts

@@ -1,11 +1,14 @@
 import { useMemo } from 'react';
 
+import type { CompletionContext } from '@codemirror/autocomplete';
 import { indentWithTab, defaultKeymap } from '@codemirror/commands';
 import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
+import { syntaxTree } from '@codemirror/language';
 import { languages } from '@codemirror/language-data';
 import { EditorState, Prec, type Extension } from '@codemirror/state';
 import { keymap, EditorView } from '@codemirror/view';
 import { useCodeMirror, type UseCodeMirror } from '@uiw/react-codemirror';
+import emojiData from 'emoji-mart/data/all.json';
 import deepmerge from 'ts-deepmerge';
 
 import { useAppendExtensions, type AppendExtensions } from './utils/append-extensions';
@@ -33,13 +36,71 @@ const defaultExtensions: Extension[] = [
   Prec.lowest(keymap.of(defaultKeymap)),
 ];
 
+const getEmojiDataArray = (): string[] => {
+  const rawEmojiDataArray = emojiData.categories;
+
+  const emojiCategoriesData = [
+    'people',
+    'nature',
+    'foods',
+    'activity',
+    'places',
+    'objects',
+    'symbols',
+    'flags',
+  ];
+
+  const fixedEmojiDataArray: string[] = [];
+
+  emojiCategoriesData.forEach((value) => {
+    const tempArray = rawEmojiDataArray.find(obj => obj.id === value)?.emojis;
+
+    if (tempArray == null) {
+      return;
+    }
+
+    fixedEmojiDataArray.push(...tempArray);
+  });
+
+  return fixedEmojiDataArray;
+};
+
+const emojiDataArray = getEmojiDataArray();
+
+const emojiOptions = emojiDataArray.map(
+  tag => ({ label: `:${tag}:`, type: 'keyword' }),
+);
+
+const completeEmojiInput = (context: CompletionContext) => {
+  const nodeBefore = syntaxTree(context.state).resolveInner(context.pos, -1);
+  const textBefore = context.state.sliceDoc(nodeBefore.from, context.pos);
+  const emojiBefore = /:\w*$/.exec(textBefore);
+
+  if (!emojiBefore && !context.explicit) return null;
+
+  console.log('kohsei');
+
+  return {
+    from: emojiBefore ? nodeBefore.from + emojiBefore.index : context.pos,
+    options: emojiOptions,
+    validFor: /^(:\w*)?$/,
+  };
+};
+
+const emojiCompletion = markdownLanguage.data.of({
+  autocomplete: completeEmojiInput,
+});
+
 export const useCodeMirrorEditor = (props?: UseCodeMirror): UseCodeMirrorEditor => {
 
-  const mergedProps = useMemo<UseCodeMirror>(() => {
+  const mergedProps = useMemo(() => {
     return deepmerge(
       props ?? {},
       {
-        extensions: defaultExtensions,
+        extensions: [
+          defaultExtensions,
+          emojiCompletion,
+        ],
         // Reset settings of react-codemirror.
         // The extension defined first will be used, so it must be disabled here.
         indentWithTab: false,