feat: autocomplete cm6

This commit is contained in:
Andrew Bastin
2021-11-08 16:33:36 +05:30
parent 8f166b8b3f
commit 564cce2462
3 changed files with 52 additions and 7 deletions

View File

@@ -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
)
),
})

View File

@@ -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
pnpm-lock.yaml generated
View File

@@ -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