Browse Source

feat: autocomplete cm6

Andrew Bastin 4 years ago
parent
commit
564cce2462

+ 49 - 7
packages/hoppscotch-app/helpers/editor/codemirror.ts

@@ -41,6 +41,7 @@ import { javascriptLanguage } from "@codemirror/lang-javascript"
 import { Language, LanguageSupport } from "@codemirror/language"
 import { linter } from "@codemirror/lint"
 import { jsonLanguage } from "@codemirror/lang-json"
+import { Completion, autocompletion } from "@codemirror/autocomplete"
 import { onBeforeUnmount } from "@vue/runtime-dom"
 import { pipe } from "fp-ts/function"
 import * as O from "fp-ts/Option"
@@ -233,6 +234,34 @@ export function useCodemirror(
   }
 }
 
+const hoppCompleterExt = (completer: Completer): Extension => {
+  return autocompletion({
+    override: [
+      async (context) => {
+        // Expensive operation! Disable on bigger files ?
+        const text = context.state.doc.toJSON().join(context.state.lineBreak)
+
+        const line = context.state.doc.lineAt(context.pos).from
+        const ch = context.pos - line
+
+        const result = await completer(text, { line, ch })
+
+        // Use more completion features ?
+        const completions =
+          result?.completions.map<Completion>((comp) => ({
+            label: comp.text,
+            detail: comp.meta,
+          })) ?? []
+
+        return {
+          from: context.state.wordAt(context.pos)?.from ?? context.pos,
+          options: completions,
+        }
+      },
+    ],
+  })
+}
+
 const hoppLinterExt = (hoppLinter: LinterDefinition): Extension => {
   return linter(async (view) => {
     // Requires full document scan, hence expensive on big files, force disable on big files ?
@@ -257,9 +286,15 @@ const hoppLinterExt = (hoppLinter: LinterDefinition): Extension => {
 
 const hoppLang = (
   language: Language,
-  linter?: LinterDefinition | undefined
+  linter?: LinterDefinition | undefined,
+  completer?: Completer | undefined
 ) => {
-  return new LanguageSupport(language, linter ? [hoppLinterExt(linter)] : [])
+  const exts: Extension[] = []
+
+  if (linter) exts.push(hoppLinterExt(linter))
+  if (completer) exts.push(hoppCompleterExt(completer))
+
+  return new LanguageSupport(language, exts)
 }
 
 const getLanguage = (langMime: string): Language | null => {
@@ -275,11 +310,12 @@ const getLanguage = (langMime: string): Language | null => {
 
 const getEditorLanguage = (
   langMime: string,
-  linter: LinterDefinition | undefined
+  linter: LinterDefinition | undefined,
+  completer: Completer | undefined
 ): Extension =>
   pipe(
     O.fromNullable(getLanguage(langMime)),
-    O.map((lang) => hoppLang(lang, linter)),
+    O.map((lang) => hoppLang(lang, linter, completer)),
     O.getOrElseW(() => [])
   )
 
@@ -338,7 +374,8 @@ export function useNewCodemirror(
       language.of(
         getEditorLanguage(
           (options.extendedEditorConfig.mode as any) ?? "",
-          options.linter ?? undefined
+          options.linter ?? undefined,
+          options.completer ?? undefined
         )
       ),
       lineWrapping.of(
@@ -396,13 +433,18 @@ export function useNewCodemirror(
   )
 
   watch(
-    () => [options.extendedEditorConfig.mode, options.linter],
+    () => [
+      options.extendedEditorConfig.mode,
+      options.linter,
+      options.completer,
+    ],
     () => {
       dispatch({
         effects: language.reconfigure(
           getEditorLanguage(
             (options.extendedEditorConfig.mode as any) ?? "",
-            options.linter ?? undefined
+            options.linter ?? undefined,
+            options.completer ?? undefined
           )
         ),
       })

+ 1 - 0
packages/hoppscotch-app/package.json

@@ -34,6 +34,7 @@
   },
   "dependencies": {
     "@apollo/client": "^3.4.16",
+    "@codemirror/autocomplete": "^0.19.4",
     "@codemirror/basic-setup": "^0.19.0",
     "@codemirror/commands": "^0.19.5",
     "@codemirror/gutter": "^0.19.4",

+ 2 - 0
pnpm-lock.yaml

@@ -20,6 +20,7 @@ importers:
       '@apollo/client': ^3.4.16
       '@babel/core': ^7.16.0
       '@babel/preset-env': ^7.16.0
+      '@codemirror/autocomplete': ^0.19.4
       '@codemirror/basic-setup': ^0.19.0
       '@codemirror/commands': ^0.19.5
       '@codemirror/gutter': ^0.19.4
@@ -135,6 +136,7 @@ importers:
       yargs-parser: ^20.2.9
     dependencies:
       '@apollo/client': 3.4.16_f3f7eb5e21785ef7d5faca94c1a68824
+      '@codemirror/autocomplete': 0.19.4
       '@codemirror/basic-setup': 0.19.0
       '@codemirror/commands': 0.19.5
       '@codemirror/gutter': 0.19.4