feat: cm 6 json mode + readonly + cursor update
This commit is contained in:
@@ -145,7 +145,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useNewCodemirror as useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import "codemirror/mode/javascript/javascript"
|
import "codemirror/mode/javascript/javascript"
|
||||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||||
|
|||||||
@@ -27,12 +27,20 @@ import "codemirror/addon/selection/active-line"
|
|||||||
|
|
||||||
import { watch, onMounted, ref, Ref, useContext } from "@nuxtjs/composition-api"
|
import { watch, onMounted, ref, Ref, useContext } from "@nuxtjs/composition-api"
|
||||||
|
|
||||||
import { EditorState, Compartment, StateField } from "@codemirror/state"
|
import {
|
||||||
|
EditorState,
|
||||||
|
Compartment,
|
||||||
|
StateField,
|
||||||
|
EditorSelection,
|
||||||
|
TransactionSpec,
|
||||||
|
} 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 { javascript } from "@codemirror/lang-javascript"
|
||||||
|
import { json } from "@codemirror/lang-json"
|
||||||
import { onBeforeUnmount } from "@vue/runtime-dom"
|
import { onBeforeUnmount } from "@vue/runtime-dom"
|
||||||
|
import { isJSONContentType } from "../utils/contenttypes"
|
||||||
import { Completer } from "./completion"
|
import { Completer } from "./completion"
|
||||||
import { LinterDefinition } from "./linting/linter"
|
import { LinterDefinition } from "./linting/linter"
|
||||||
|
|
||||||
@@ -222,7 +230,9 @@ export function useCodemirror(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getEditorLanguage = (mode: string) => {
|
const getEditorLanguage = (mode: string) => {
|
||||||
if (mode === "application/javascript") {
|
if (isJSONContentType(mode)) {
|
||||||
|
return json()
|
||||||
|
} else if (mode === "application/javascript") {
|
||||||
return javascript()
|
return javascript()
|
||||||
} else {
|
} else {
|
||||||
return StateField.define({
|
return StateField.define({
|
||||||
@@ -241,6 +251,10 @@ export function useNewCodemirror(
|
|||||||
): { cursor: Ref<{ line: number; ch: number }> } {
|
): { cursor: Ref<{ line: number; ch: number }> } {
|
||||||
const language = new Compartment()
|
const language = new Compartment()
|
||||||
|
|
||||||
|
const cachedCursor = ref({
|
||||||
|
line: 0,
|
||||||
|
ch: 0,
|
||||||
|
})
|
||||||
const cursor = ref({
|
const cursor = ref({
|
||||||
line: 0,
|
line: 0,
|
||||||
ch: 0,
|
ch: 0,
|
||||||
@@ -259,14 +273,19 @@ export function useNewCodemirror(
|
|||||||
|
|
||||||
const line = update.state.doc.lineAt(cursorPos)
|
const line = update.state.doc.lineAt(cursorPos)
|
||||||
|
|
||||||
|
cachedCursor.value = {
|
||||||
|
line: line.number - 1,
|
||||||
|
ch: cursorPos - line.from,
|
||||||
|
}
|
||||||
|
|
||||||
cursor.value = {
|
cursor.value = {
|
||||||
line: line.number,
|
line: cachedCursor.value.line,
|
||||||
ch: cursorPos - line.from + 1,
|
ch: cachedCursor.value.ch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update.docChanged) {
|
if (update.docChanged) {
|
||||||
// Expensive on big files ?
|
// Expensive on big files ?
|
||||||
|
console.log("doc change")
|
||||||
cachedValue.value = update.state.doc
|
cachedValue.value = update.state.doc
|
||||||
.toJSON()
|
.toJSON()
|
||||||
.join(update.state.lineBreak)
|
.join(update.state.lineBreak)
|
||||||
@@ -275,6 +294,7 @@ export function useNewCodemirror(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
EditorState.changeFilter.of(() => !options.extendedEditorConfig.readOnly),
|
||||||
language.of(
|
language.of(
|
||||||
getEditorLanguage((options.extendedEditorConfig.mode as any) ?? "")
|
getEditorLanguage((options.extendedEditorConfig.mode as any) ?? "")
|
||||||
),
|
),
|
||||||
@@ -284,6 +304,9 @@ export function useNewCodemirror(
|
|||||||
|
|
||||||
const view = ref<EditorView>()
|
const view = ref<EditorView>()
|
||||||
|
|
||||||
|
const dispatch = (t: TransactionSpec) =>
|
||||||
|
view.value ? view.value.dispatch(t) : state.update(t)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
view.value = new EditorView({
|
view.value = new EditorView({
|
||||||
state,
|
state,
|
||||||
@@ -295,6 +318,35 @@ export function useNewCodemirror(
|
|||||||
if (view.value) view.value.destroy()
|
if (view.value) view.value.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(cursor, (newPos) => {
|
||||||
|
if (
|
||||||
|
cachedCursor.value.line !== newPos.line ||
|
||||||
|
cachedCursor.value.ch !== newPos.ch
|
||||||
|
) {
|
||||||
|
const line = state.doc.line(newPos.line + 1)
|
||||||
|
const selUpdate = EditorSelection.cursor(line.from + newPos.ch - 1)
|
||||||
|
|
||||||
|
view.value?.focus()
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
scrollIntoView: true,
|
||||||
|
selection: selUpdate,
|
||||||
|
effects: EditorView.scrollTo.of(selUpdate),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => options.extendedEditorConfig.mode,
|
||||||
|
(newMode) => {
|
||||||
|
dispatch({
|
||||||
|
effects: language.reconfigure(
|
||||||
|
getEditorLanguage((newMode as any) ?? "")
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
watch(el, (newEl) => {
|
watch(el, (newEl) => {
|
||||||
if (view.value) {
|
if (view.value) {
|
||||||
view.value.destroy()
|
view.value.destroy()
|
||||||
@@ -311,7 +363,7 @@ export function useNewCodemirror(
|
|||||||
|
|
||||||
watch(value, (newVal) => {
|
watch(value, (newVal) => {
|
||||||
if (cachedValue.value !== newVal) {
|
if (cachedValue.value !== newVal) {
|
||||||
state.update({
|
dispatch({
|
||||||
changes: {
|
changes: {
|
||||||
from: 0,
|
from: 0,
|
||||||
to: state.doc.length,
|
to: state.doc.length,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
"@codemirror/commands": "^0.19.5",
|
"@codemirror/commands": "^0.19.5",
|
||||||
"@codemirror/gutter": "^0.19.4",
|
"@codemirror/gutter": "^0.19.4",
|
||||||
"@codemirror/lang-javascript": "^0.19.2",
|
"@codemirror/lang-javascript": "^0.19.2",
|
||||||
|
"@codemirror/lang-json": "^0.19.1",
|
||||||
"@codemirror/language": "^0.19.3",
|
"@codemirror/language": "^0.19.3",
|
||||||
"@codemirror/state": "^0.19.3",
|
"@codemirror/state": "^0.19.3",
|
||||||
"@codemirror/text": "^0.19.5",
|
"@codemirror/text": "^0.19.5",
|
||||||
|
|||||||
22
pnpm-lock.yaml
generated
22
pnpm-lock.yaml
generated
@@ -24,6 +24,7 @@ importers:
|
|||||||
'@codemirror/commands': ^0.19.5
|
'@codemirror/commands': ^0.19.5
|
||||||
'@codemirror/gutter': ^0.19.4
|
'@codemirror/gutter': ^0.19.4
|
||||||
'@codemirror/lang-javascript': ^0.19.2
|
'@codemirror/lang-javascript': ^0.19.2
|
||||||
|
'@codemirror/lang-json': ^0.19.1
|
||||||
'@codemirror/language': ^0.19.3
|
'@codemirror/language': ^0.19.3
|
||||||
'@codemirror/state': ^0.19.3
|
'@codemirror/state': ^0.19.3
|
||||||
'@codemirror/text': ^0.19.5
|
'@codemirror/text': ^0.19.5
|
||||||
@@ -137,6 +138,7 @@ importers:
|
|||||||
'@codemirror/commands': 0.19.5
|
'@codemirror/commands': 0.19.5
|
||||||
'@codemirror/gutter': 0.19.4
|
'@codemirror/gutter': 0.19.4
|
||||||
'@codemirror/lang-javascript': 0.19.2
|
'@codemirror/lang-javascript': 0.19.2
|
||||||
|
'@codemirror/lang-json': 0.19.1
|
||||||
'@codemirror/language': 0.19.3
|
'@codemirror/language': 0.19.3
|
||||||
'@codemirror/state': 0.19.3
|
'@codemirror/state': 0.19.3
|
||||||
'@codemirror/text': 0.19.5
|
'@codemirror/text': 0.19.5
|
||||||
@@ -1817,6 +1819,14 @@ packages:
|
|||||||
'@lezer/javascript': 0.15.0
|
'@lezer/javascript': 0.15.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@codemirror/lang-json/0.19.1:
|
||||||
|
resolution: {integrity: sha512-66K5TT9HO0ODtpjY+3Ub6t3r0OB1d27P+Kl5oygk4tDavHUBpsyHTJRFw/CdeRM2VwjbpBfctGm/cTrSthFDZg==}
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/highlight': 0.19.6
|
||||||
|
'@codemirror/language': 0.19.3
|
||||||
|
'@lezer/json': 0.15.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@codemirror/language/0.19.3:
|
/@codemirror/language/0.19.3:
|
||||||
resolution: {integrity: sha512-6vjkRYHRJg/z9wdAk75nU2fQwCJBsh2HpkIjKXIHfzISSgLt5qSDxVhPd8Uu8PD5WMmFFP8tX7I9kdIt873o0A==}
|
resolution: {integrity: sha512-6vjkRYHRJg/z9wdAk75nU2fQwCJBsh2HpkIjKXIHfzISSgLt5qSDxVhPd8Uu8PD5WMmFFP8tX7I9kdIt873o0A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3690,6 +3700,12 @@ packages:
|
|||||||
'@lezer/lr': 0.15.4
|
'@lezer/lr': 0.15.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@lezer/json/0.15.0:
|
||||||
|
resolution: {integrity: sha512-OsMjjBkTkeQ15iMCu5U1OiBubRC4V9Wm03zdIlUgNZ20aUPx5DWDRqUc5wG41JXVSj7Lxmo+idlFCfBBdxB8sw==}
|
||||||
|
dependencies:
|
||||||
|
'@lezer/lr': 0.15.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@lezer/lr/0.15.4:
|
/@lezer/lr/0.15.4:
|
||||||
resolution: {integrity: sha512-vwgG80sihEGJn6wJp6VijXrnzVai/KPva/OzYKaWvIx0IiXKjoMQ8UAwcgpSBwfS4Fbz3IKOX/cCNXU3r1FvpQ==}
|
resolution: {integrity: sha512-vwgG80sihEGJn6wJp6VijXrnzVai/KPva/OzYKaWvIx0IiXKjoMQ8UAwcgpSBwfS4Fbz3IKOX/cCNXU3r1FvpQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3896,8 +3912,8 @@ packages:
|
|||||||
ufo: 0.7.9
|
ufo: 0.7.9
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@nuxt/kit-edge/3.0.0-27267163.9b8d44d:
|
/@nuxt/kit-edge/3.0.0-27267816.6bd7186:
|
||||||
resolution: {integrity: sha512-Skw7Es5w+tCDX0K0oB/aX6OzyZ8zEFq3aUasv5rGjQlztAv/BtvBHEK1kprP2nR7xiXKMpyUphMOy3qFtHamfg==}
|
resolution: {integrity: sha512-OCinQR1TBeZmgU61of/YM55JvY+3emO6D4BwfTNYe8KwqIpynYcrZJxlxAYRYZKzqfZhtqLnD1B8DJ1f2b6thQ==}
|
||||||
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
|
||||||
@@ -14020,7 +14036,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-27267163.9b8d44d
|
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27267816.6bd7186
|
||||||
defu: 5.0.0
|
defu: 5.0.0
|
||||||
h3: 0.3.3
|
h3: 0.3.3
|
||||||
listhen: 0.2.5
|
listhen: 0.2.5
|
||||||
|
|||||||
Reference in New Issue
Block a user