feat: early codemirror v6 implementation

This commit is contained in:
Andrew Bastin
2021-11-05 00:33:15 +05:30
parent dbd39ba0d8
commit e83dbc2e5c
4 changed files with 365 additions and 5 deletions

View File

@@ -86,7 +86,7 @@ import { reactive, ref, useContext } from "@nuxtjs/composition-api"
import { usePreRequestScript } from "~/newstore/RESTSession"
import snippets from "~/helpers/preRequestScriptSnippets"
import "codemirror/mode/javascript/javascript"
import { useCodemirror } from "~/helpers/editor/codemirror"
import { useNewCodemirror as useCodemirror } from "~/helpers/editor/codemirror"
import linter from "~/helpers/editor/linting/preRequest"
import completer from "~/helpers/editor/completion/preRequest"

View File

@@ -26,8 +26,15 @@ import "codemirror/addon/dialog/dialog"
import "codemirror/addon/selection/active-line"
import { watch, onMounted, ref, Ref, useContext } from "@nuxtjs/composition-api"
import { LinterDefinition } from "./linting/linter"
import { EditorState, Compartment, StateField } from "@codemirror/state"
import { EditorView, keymap, ViewPlugin, ViewUpdate } from "@codemirror/view"
import { defaultKeymap } from "@codemirror/commands"
import { basicSetup } from "@codemirror/basic-setup"
import { javascript } from "@codemirror/lang-javascript"
import { onBeforeUnmount } from "@vue/runtime-dom"
import { Completer } from "./completion"
import { LinterDefinition } from "./linting/linter"
type CodeMirrorOptions = {
extendedEditorConfig: Omit<CodeMirror.EditorConfiguration, "value">
@@ -213,3 +220,108 @@ export function useCodemirror(
cursor,
}
}
const getEditorLanguage = (mode: string) => {
if (mode === "application/javascript") {
return javascript()
} else {
return StateField.define({
create() {
return null
},
update() {},
})
}
}
export function useNewCodemirror(
el: Ref<any | null>,
value: Ref<string>,
options: CodeMirrorOptions
): { cursor: Ref<{ line: number; ch: number }> } {
const language = new Compartment()
const cursor = ref({
line: 0,
ch: 0,
})
const cachedValue = ref(value.value)
const state = EditorState.create({
doc: value.value,
extensions: [
basicSetup,
ViewPlugin.fromClass(
class {
update(update: ViewUpdate) {
if (update.selectionSet) {
const cursorPos = update.state.selection.main.head
const line = update.state.doc.lineAt(cursorPos)
cursor.value = {
line: line.number,
ch: cursorPos - line.from + 1,
}
}
if (update.docChanged) {
// Expensive on big files ?
cachedValue.value = update.state.doc
.toJSON()
.join(update.state.lineBreak)
value.value = cachedValue.value
}
}
}
),
language.of(
getEditorLanguage((options.extendedEditorConfig.mode as any) ?? "")
),
keymap.of(defaultKeymap),
],
})
const view = ref<EditorView>()
onMounted(() => {
view.value = new EditorView({
state,
parent: el.value,
})
})
onBeforeUnmount(() => {
if (view.value) view.value.destroy()
})
watch(el, (newEl) => {
if (view.value) {
view.value.destroy()
view.value = undefined
}
if (newEl) {
view.value = new EditorView({
state,
parent: newEl,
})
}
})
watch(value, (newVal) => {
if (cachedValue.value !== newVal) {
state.update({
changes: {
from: 0,
to: state.doc.length,
insert: newVal,
},
})
}
})
return {
cursor,
}
}

View File

@@ -34,6 +34,14 @@
},
"dependencies": {
"@apollo/client": "^3.4.16",
"@codemirror/basic-setup": "^0.19.0",
"@codemirror/commands": "^0.19.5",
"@codemirror/gutter": "^0.19.4",
"@codemirror/lang-javascript": "^0.19.2",
"@codemirror/language": "^0.19.3",
"@codemirror/state": "^0.19.3",
"@codemirror/text": "^0.19.5",
"@codemirror/view": "^0.19.12",
"@hoppscotch/js-sandbox": "workspace:^1.0.0",
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/composition-api": "^0.29.3",