feat: add linting cm6

This commit is contained in:
Andrew Bastin
2021-11-08 15:21:09 +05:30
parent fe7192ae61
commit 8f166b8b3f
3 changed files with 73 additions and 25 deletions

View File

@@ -30,16 +30,20 @@ import { watch, onMounted, ref, Ref, useContext } from "@nuxtjs/composition-api"
import { import {
EditorState, EditorState,
Compartment, Compartment,
StateField,
EditorSelection, EditorSelection,
TransactionSpec, TransactionSpec,
Extension,
} from "@codemirror/state" } from "@codemirror/state"
import { EditorView, keymap, ViewPlugin, ViewUpdate } from "@codemirror/view" import { EditorView, keymap, ViewPlugin, ViewUpdate } from "@codemirror/view"
import { defaultKeymap } from "@codemirror/commands" import { defaultKeymap } from "@codemirror/commands"
import { basicSetup } from "@codemirror/basic-setup" import { basicSetup } from "@codemirror/basic-setup"
import { javascript } from "@codemirror/lang-javascript" import { javascriptLanguage } from "@codemirror/lang-javascript"
import { json } from "@codemirror/lang-json" import { Language, LanguageSupport } from "@codemirror/language"
import { linter } from "@codemirror/lint"
import { jsonLanguage } from "@codemirror/lang-json"
import { onBeforeUnmount } from "@vue/runtime-dom" import { onBeforeUnmount } from "@vue/runtime-dom"
import { pipe } from "fp-ts/function"
import * as O from "fp-ts/Option"
import { isJSONContentType } from "../utils/contenttypes" import { isJSONContentType } from "../utils/contenttypes"
import { Completer } from "./completion" import { Completer } from "./completion"
import { LinterDefinition } from "./linting/linter" import { LinterDefinition } from "./linting/linter"
@@ -229,21 +233,56 @@ export function useCodemirror(
} }
} }
const getEditorLanguage = (mode: string) => { const hoppLinterExt = (hoppLinter: LinterDefinition): Extension => {
if (isJSONContentType(mode)) { return linter(async (view) => {
return json() // Requires full document scan, hence expensive on big files, force disable on big files ?
} else if (mode === "application/javascript") { const linterResult = await hoppLinter(
return javascript() view.state.doc.toJSON().join(view.state.lineBreak)
} else { )
return StateField.define({
create() { return linterResult.map((result) => {
return null const startPos =
}, view.state.doc.line(result.from.line + 1).from + result.from.ch
update() {}, const endPos = view.state.doc.line(result.to.line + 1).from + result.to.ch
return {
from: startPos,
to: endPos,
message: result.message,
severity: result.severity,
}
}) })
} })
} }
const hoppLang = (
language: Language,
linter?: LinterDefinition | undefined
) => {
return new LanguageSupport(language, linter ? [hoppLinterExt(linter)] : [])
}
const getLanguage = (langMime: string): Language | null => {
if (isJSONContentType(langMime)) {
return jsonLanguage
} else if (langMime === "application/javascript") {
return javascriptLanguage
}
// None matched, so return null
return null
}
const getEditorLanguage = (
langMime: string,
linter: LinterDefinition | undefined
): Extension =>
pipe(
O.fromNullable(getLanguage(langMime)),
O.map((lang) => hoppLang(lang, linter)),
O.getOrElseW(() => [])
)
export function useNewCodemirror( export function useNewCodemirror(
el: Ref<any | null>, el: Ref<any | null>,
value: Ref<string>, value: Ref<string>,
@@ -297,7 +336,10 @@ export function useNewCodemirror(
), ),
EditorState.changeFilter.of(() => !options.extendedEditorConfig.readOnly), EditorState.changeFilter.of(() => !options.extendedEditorConfig.readOnly),
language.of( language.of(
getEditorLanguage((options.extendedEditorConfig.mode as any) ?? "") getEditorLanguage(
(options.extendedEditorConfig.mode as any) ?? "",
options.linter ?? undefined
)
), ),
lineWrapping.of( lineWrapping.of(
options.extendedEditorConfig.lineWrapping options.extendedEditorConfig.lineWrapping
@@ -354,11 +396,14 @@ export function useNewCodemirror(
) )
watch( watch(
() => options.extendedEditorConfig.mode, () => [options.extendedEditorConfig.mode, options.linter],
(newMode) => { () => {
dispatch({ dispatch({
effects: language.reconfigure( effects: language.reconfigure(
getEditorLanguage((newMode as any) ?? "") getEditorLanguage(
(options.extendedEditorConfig.mode as any) ?? "",
options.linter ?? undefined
)
), ),
}) })
} }

View File

@@ -40,6 +40,7 @@
"@codemirror/lang-javascript": "^0.19.2", "@codemirror/lang-javascript": "^0.19.2",
"@codemirror/lang-json": "^0.19.1", "@codemirror/lang-json": "^0.19.1",
"@codemirror/language": "^0.19.3", "@codemirror/language": "^0.19.3",
"@codemirror/lint": "^0.19.2",
"@codemirror/state": "^0.19.3", "@codemirror/state": "^0.19.3",
"@codemirror/text": "^0.19.5", "@codemirror/text": "^0.19.5",
"@codemirror/view": "^0.19.12", "@codemirror/view": "^0.19.12",

14
pnpm-lock.yaml generated
View File

@@ -26,6 +26,7 @@ importers:
'@codemirror/lang-javascript': ^0.19.2 '@codemirror/lang-javascript': ^0.19.2
'@codemirror/lang-json': ^0.19.1 '@codemirror/lang-json': ^0.19.1
'@codemirror/language': ^0.19.3 '@codemirror/language': ^0.19.3
'@codemirror/lint': ^0.19.2
'@codemirror/state': ^0.19.3 '@codemirror/state': ^0.19.3
'@codemirror/text': ^0.19.5 '@codemirror/text': ^0.19.5
'@codemirror/view': ^0.19.12 '@codemirror/view': ^0.19.12
@@ -140,6 +141,7 @@ importers:
'@codemirror/lang-javascript': 0.19.2 '@codemirror/lang-javascript': 0.19.2
'@codemirror/lang-json': 0.19.1 '@codemirror/lang-json': 0.19.1
'@codemirror/language': 0.19.3 '@codemirror/language': 0.19.3
'@codemirror/lint': 0.19.2
'@codemirror/state': 0.19.3 '@codemirror/state': 0.19.3
'@codemirror/text': 0.19.5 '@codemirror/text': 0.19.5
'@codemirror/view': 0.19.12 '@codemirror/view': 0.19.12
@@ -3912,8 +3914,8 @@ packages:
ufo: 0.7.9 ufo: 0.7.9
dev: false dev: false
/@nuxt/kit-edge/3.0.0-27267816.6bd7186: /@nuxt/kit-edge/3.0.0-27268729.5b8e10f:
resolution: {integrity: sha512-OCinQR1TBeZmgU61of/YM55JvY+3emO6D4BwfTNYe8KwqIpynYcrZJxlxAYRYZKzqfZhtqLnD1B8DJ1f2b6thQ==} resolution: {integrity: sha512-m7bzSe8NRuR7ZcZqKwBQfOb1y3AlmGIiNMibZVO4r0ggIfT4fmkzVwfdZm+oWNhOYlZET7Kyk08rSjwShENukQ==}
engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0}
dependencies: dependencies:
consola: 2.15.3 consola: 2.15.3
@@ -3934,7 +3936,7 @@ packages:
std-env: 3.0.0 std-env: 3.0.0
ufo: 0.7.9 ufo: 0.7.9
unctx: 1.0.2 unctx: 1.0.2
untyped: 0.2.11 untyped: 0.2.12
dev: true dev: true
/@nuxt/loading-screen/2.0.4: /@nuxt/loading-screen/2.0.4:
@@ -14036,7 +14038,7 @@ packages:
/nuxt-windicss/2.0.11: /nuxt-windicss/2.0.11:
resolution: {integrity: sha512-/vAEmKLq1Iomuj4lz751dsoXdlGVAoiEGSh3JVxuZJMkqc/yrHTQrNhtMaOQzx5heuVsQ+E2bIF+Q/tfxicOFQ==} resolution: {integrity: sha512-/vAEmKLq1Iomuj4lz751dsoXdlGVAoiEGSh3JVxuZJMkqc/yrHTQrNhtMaOQzx5heuVsQ+E2bIF+Q/tfxicOFQ==}
dependencies: dependencies:
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27267816.6bd7186 '@nuxt/kit': /@nuxt/kit-edge/3.0.0-27268729.5b8e10f
defu: 5.0.0 defu: 5.0.0
h3: 0.3.3 h3: 0.3.3
listhen: 0.2.5 listhen: 0.2.5
@@ -18167,8 +18169,8 @@ packages:
has-value: 0.3.1 has-value: 0.3.1
isobject: 3.0.1 isobject: 3.0.1
/untyped/0.2.11: /untyped/0.2.12:
resolution: {integrity: sha512-KVNcu9jB+mlnQJiunAzmqpnnn9R+yniT+AkOk9ZgCIsThwh0nlP6wO+O7mJjHM7Y2yplEu3v6NNtRvb82+uGxw==} resolution: {integrity: sha512-mdMpwUHnJUQDpEmuByMuLxYdrPVlA98a1/b8MgoFoasR5tJTfsNbhAPfceAgFqMd/E05427T7MXgJGqdtDF/bQ==}
dev: true dev: true
/upath/1.2.0: /upath/1.2.0: