@veltra/desktop 1.2.18 → 1.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/action/action-group.vue.d.ts +1 -1
- package/dist/components/action/action.vue.d.ts +1 -1
- package/dist/components/code-editor/code-editor.js +8 -13
- package/dist/components/code-editor/code-editor.js.map +1 -1
- package/dist/components/code-editor/lang-loaders.js +16 -0
- package/dist/components/code-editor/lang-loaders.js.map +1 -0
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
- package/dist/components/tip/tip.vue.d.ts +1 -1
- package/dist/node_modules/.bun/@codemirror_commands@6.10.4/node_modules/@codemirror/commands/dist/index.js +1 -1
- package/dist/node_modules/.bun/@codemirror_lang-java@6.0.2/node_modules/@codemirror/lang-java/dist/index.js +1 -1
- package/dist/node_modules/.bun/@codemirror_lang-javascript@6.2.5/node_modules/@codemirror/lang-javascript/dist/index.js +2 -2
- package/dist/node_modules/.bun/@codemirror_lang-sql@6.10.0/node_modules/@codemirror/lang-sql/dist/index.js +1 -1
- package/dist/node_modules/.bun/@codemirror_language@6.12.4/node_modules/@codemirror/language/dist/index.js +2 -2
- package/dist/node_modules/.bun/@codemirror_theme-one-dark@6.1.3/node_modules/@codemirror/theme-one-dark/dist/index.js +1 -1
- package/dist/node_modules/.bun/@lezer_java@1.1.3/node_modules/@lezer/java/dist/index.js +1 -1
- package/dist/node_modules/.bun/@lezer_javascript@1.5.4/node_modules/@lezer/javascript/dist/index.js +1 -1
- package/dist/node_modules/.bun/@lezer_json@1.0.3/node_modules/@lezer/json/dist/index.js +1 -1
- package/package.json +6 -6
- package/src/components/code-editor/code-editor.vue +11 -15
- package/src/components/code-editor/lang-loaders.ts +16 -0
|
@@ -9,9 +9,9 @@ declare const __VLS_base: import("vue").DefineComponent<ActionGroupProps, _Actio
|
|
|
9
9
|
type: import("@veltra/utils").ColorType;
|
|
10
10
|
text: boolean;
|
|
11
11
|
size: "small" | "default" | "large";
|
|
12
|
-
circle: boolean;
|
|
13
12
|
max: number;
|
|
14
13
|
loading: boolean;
|
|
14
|
+
circle: boolean;
|
|
15
15
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
16
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
17
17
|
declare const _default: typeof __VLS_export;
|
|
@@ -15,8 +15,8 @@ declare const __VLS_base: import("vue").DefineComponent<ActionProps, {}, {}, {},
|
|
|
15
15
|
type: ButtonType;
|
|
16
16
|
text: boolean;
|
|
17
17
|
size: import("@veltra/utils").ComponentSize;
|
|
18
|
-
circle: boolean;
|
|
19
18
|
loading: boolean;
|
|
19
|
+
circle: boolean;
|
|
20
20
|
inDropdown: boolean;
|
|
21
21
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
22
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import _sfc_main$1 from "../scroll/scroll.js";
|
|
2
2
|
import { Compartment, EditorState } from "../../node_modules/.bun/@codemirror_state@6.7.0/node_modules/@codemirror/state/dist/index.js";
|
|
3
3
|
import { EditorView, ViewPlugin, tooltips } from "../../node_modules/.bun/@codemirror_view@6.43.4/node_modules/@codemirror/view/dist/index.js";
|
|
4
|
-
import { java } from "../../node_modules/.bun/@codemirror_lang-java@6.0.2/node_modules/@codemirror/lang-java/dist/index.js";
|
|
5
|
-
import { javascript } from "../../node_modules/.bun/@codemirror_lang-javascript@6.2.5/node_modules/@codemirror/lang-javascript/dist/index.js";
|
|
6
|
-
import { json } from "../../node_modules/.bun/@codemirror_lang-json@6.0.2/node_modules/@codemirror/lang-json/dist/index.js";
|
|
7
|
-
import { sql } from "../../node_modules/.bun/@codemirror_lang-sql@6.10.0/node_modules/@codemirror/lang-sql/dist/index.js";
|
|
8
4
|
import { oneDark } from "../../node_modules/.bun/@codemirror_theme-one-dark@6.1.3/node_modules/@codemirror/theme-one-dark/dist/index.js";
|
|
9
5
|
import { basicSetup } from "./basic-setup.js";
|
|
6
|
+
import { loadLanguage } from "./lang-loaders.js";
|
|
10
7
|
import { computed, createBlock, createElementVNode, defineComponent, mergeModels, normalizeClass, normalizeStyle, onBeforeUnmount, openBlock, shallowRef, unref, useModel, useTemplateRef, watch, withCtx, withKeys, withModifiers } from "vue";
|
|
11
8
|
import { useFormFallbackProps } from "@veltra/compositions";
|
|
12
9
|
import { bem, injectFormContext, zIndex } from "@veltra/utils";
|
|
@@ -59,13 +56,6 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
59
56
|
const rootStyle = computed(() => ({ "--u-code-editor-default-lines": Math.max(1, props.defaultLines) }));
|
|
60
57
|
const containerRef = useTemplateRef("container");
|
|
61
58
|
const editor = shallowRef(null);
|
|
62
|
-
/** 静态导入语言包,避免动态 import 在打包/Vite 预构建下产生多份 @codemirror/* 实例 */
|
|
63
|
-
const langExtensions = {
|
|
64
|
-
js: javascript({ typescript: true }),
|
|
65
|
-
sql: sql(),
|
|
66
|
-
java: java(),
|
|
67
|
-
json: json()
|
|
68
|
-
};
|
|
69
59
|
const themeCompartment = new Compartment();
|
|
70
60
|
const editableCompartment = new Compartment();
|
|
71
61
|
const readOnlyCompartment = new Compartment();
|
|
@@ -130,12 +120,17 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
130
120
|
}
|
|
131
121
|
let editorToken = 0;
|
|
132
122
|
let langToken = 0;
|
|
133
|
-
function applyLanguage() {
|
|
123
|
+
async function applyLanguage() {
|
|
134
124
|
const view = editor.value;
|
|
135
125
|
if (!view) return;
|
|
136
126
|
const myToken = ++langToken;
|
|
137
127
|
const { language } = props;
|
|
138
|
-
|
|
128
|
+
if (!language) {
|
|
129
|
+
if (myToken !== langToken || editor.value !== view) return;
|
|
130
|
+
view.dispatch({ effects: langCompartment.reconfigure([]) });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const ext = await loadLanguage(language);
|
|
139
134
|
if (myToken !== langToken || editor.value !== view) return;
|
|
140
135
|
view.dispatch({ effects: langCompartment.reconfigure(ext) });
|
|
141
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-editor.js","names":[],"sources":["../../../src/components/code-editor/code-editor.vue"],"sourcesContent":["<template>\n <u-scroll :class=\"className\" :style=\"rootStyle\" @keyup.enter.stop>\n <div ref=\"container\"></div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { java } from '@codemirror/lang-java'\nimport { javascript } from '@codemirror/lang-javascript'\nimport { json } from '@codemirror/lang-json'\nimport { sql } from '@codemirror/lang-sql'\nimport { Compartment, EditorState, type Extension } from '@codemirror/state'\nimport { oneDark } from '@codemirror/theme-one-dark'\nimport { EditorView, ViewPlugin, tooltips, type ViewUpdate } from '@codemirror/view'\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { bem, zIndex } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n computed,\n onBeforeUnmount,\n shallowRef,\n useTemplateRef,\n watch,\n type CSSProperties\n} from 'vue'\n\nimport type { CodeEditorLang, CodeEditorProps } from '../../types'\nimport { UScroll } from '../scroll'\nimport { basicSetup } from './basic-setup'\n\ndefineOptions({ name: 'UCodeEditor' })\n\nconst props = withDefaults(defineProps<CodeEditorProps>(), {\n disabled: undefined,\n readonly: undefined,\n dark: false,\n defaultLines: 8\n})\n\nconst model = defineModel<string>()\n\nconst cls = bem('code-editor')\n\nconst { formProps } = injectFormContext()\n\nconst { disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n disabled: false,\n readonly: false\n})\n\nconst className = computed<string[]>(() => [\n cls.b,\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('dark', props.dark)\n])\n\nconst rootStyle = computed<CSSProperties>(() => ({\n '--u-code-editor-default-lines': Math.max(1, props.defaultLines)\n}))\n\nconst containerRef = useTemplateRef('container')\nconst editor = shallowRef<EditorView | null>(null)\n\n/** 静态导入语言包,避免动态 import 在打包/Vite 预构建下产生多份 @codemirror/* 实例 */\nconst langExtensions: Record<CodeEditorLang, Extension> = {\n js: javascript({ typescript: true }),\n sql: sql(),\n java: java(),\n json: json()\n}\n\nconst themeCompartment = new Compartment()\nconst editableCompartment = new Compartment()\nconst readOnlyCompartment = new Compartment()\nconst langCompartment = new Compartment()\n\nlet phantomGutter: HTMLElement | null = null\nlet phantomContainer: HTMLElement | null = null\nlet lastPhantomKey = ''\n\nfunction resetPhantomCache() {\n phantomGutter = null\n phantomContainer = null\n lastPhantomKey = ''\n}\n\n/**\n * 在 .cm-lineNumbers 末尾追加占位行号 DOM,使可视行号数量补齐到 defaultLines。\n * CodeMirror 的 lineNumbers() 仅为真实文档行渲染行号,超出部分由本逻辑补全。\n */\nfunction syncPhantomLineNumbers() {\n const view = editor.value\n if (!view) return\n\n if (!phantomGutter || !phantomGutter.isConnected) {\n phantomGutter = view.dom.querySelector<HTMLElement>('.cm-gutter.cm-lineNumbers')\n }\n if (!phantomGutter) return\n\n if (!phantomContainer) {\n phantomContainer = document.createElement('div')\n phantomContainer.className = 'cm-phantom-lines'\n }\n if (\n phantomContainer.parentElement !== phantomGutter ||\n phantomContainer !== phantomGutter.lastElementChild\n ) {\n phantomGutter.appendChild(phantomContainer)\n }\n\n const realLines = view.state.doc.lines\n const target = Math.max(0, Math.max(1, props.defaultLines) - realLines)\n const lineHeight = view.defaultLineHeight\n\n const key = `${realLines}|${target}|${lineHeight}`\n if (key === lastPhantomKey) return\n lastPhantomKey = key\n\n while (phantomContainer.children.length > target) {\n phantomContainer.lastElementChild!.remove()\n }\n while (phantomContainer.children.length < target) {\n const el = document.createElement('div')\n el.className = 'cm-gutterElement cm-gutterElement-phantom'\n phantomContainer.appendChild(el)\n }\n for (let i = 0; i < target; i++) {\n const el = phantomContainer.children[i] as HTMLElement\n const num = String(realLines + i + 1)\n if (el.textContent !== num) el.textContent = num\n if (lineHeight && el.style.height !== `${lineHeight}px`) {\n el.style.height = `${lineHeight}px`\n }\n }\n}\n\nconst phantomLineNumbersPlugin = ViewPlugin.fromClass(\n class {\n update(update: ViewUpdate) {\n if (update.docChanged || update.geometryChanged) {\n syncPhantomLineNumbers()\n }\n }\n }\n)\n\nfunction buildExtensions(): Extension[] {\n return [\n basicSetup,\n tooltips({ parent: document.body }),\n EditorView.theme({ '.cm-tooltip': { zIndex: zIndex() } }),\n themeCompartment.of(props.dark ? oneDark : []),\n editableCompartment.of(EditorView.editable.of(!disabled.value)),\n readOnlyCompartment.of(EditorState.readOnly.of(readonly.value)),\n langCompartment.of([]),\n phantomLineNumbersPlugin\n ]\n}\n\nlet editorToken = 0\nlet langToken = 0\n\nfunction applyLanguage() {\n const view = editor.value\n if (!view) return\n const myToken = ++langToken\n const { language } = props\n const ext = language ? langExtensions[language] : []\n if (myToken !== langToken || editor.value !== view) return\n view.dispatch({ effects: langCompartment.reconfigure(ext) })\n}\n\nfunction destroyEditor() {\n ++editorToken\n ++langToken\n editor.value?.destroy()\n editor.value = null\n resetPhantomCache()\n}\n\nfunction createEditor() {\n destroyEditor()\n const myToken = ++editorToken\n const parent = containerRef.value\n if (!parent) return\n\n const view = new EditorView({\n doc: model.value,\n extensions: buildExtensions(),\n parent,\n dispatch(tr) {\n view.update([tr])\n if (tr.docChanged) {\n model.value = tr.state.doc.toString()\n }\n }\n })\n\n if (myToken !== editorToken) {\n view.destroy()\n return\n }\n\n editor.value = view\n syncPhantomLineNumbers()\n applyLanguage()\n}\n\nwatch(\n containerRef,\n (el) => {\n if (el) createEditor()\n else destroyEditor()\n },\n { immediate: true, flush: 'post' }\n)\n\nwatch(() => props.language, applyLanguage)\n\nwatch(\n () => props.dark,\n (dark) => {\n editor.value?.dispatch({ effects: themeCompartment.reconfigure(dark ? oneDark : []) })\n }\n)\n\nwatch(disabled, (v) => {\n editor.value?.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!v)) })\n})\n\nwatch(readonly, (v) => {\n editor.value?.dispatch({ effects: readOnlyCompartment.reconfigure(EditorState.readOnly.of(v)) })\n})\n\nwatch(() => props.defaultLines, syncPhantomLineNumbers)\n\nwatch(\n [() => props.modelValue, editor],\n ([v, e]) => {\n if (!e) return\n if (e.composing) return\n const next = v ?? ''\n if (e.state.doc.toString() === next) return\n\n const valueLength = next.length\n const inRange = e.state.selection.ranges.every(\n (range) => range.anchor <= valueLength && range.head <= valueLength\n )\n e.dispatch({\n changes: { from: 0, to: e.state.doc.length, insert: next },\n selection: inRange ? e.state.selection : { anchor: 0, head: 0 },\n scrollIntoView: true\n })\n },\n { immediate: true }\n)\n\nonBeforeUnmount(destroyEditor)\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"code-editor.js","names":[],"sources":["../../../src/components/code-editor/code-editor.vue"],"sourcesContent":["<template>\n <u-scroll :class=\"className\" :style=\"rootStyle\" @keyup.enter.stop>\n <div ref=\"container\"></div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { Compartment, EditorState, type Extension } from '@codemirror/state'\nimport { oneDark } from '@codemirror/theme-one-dark'\nimport { EditorView, ViewPlugin, tooltips, type ViewUpdate } from '@codemirror/view'\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { bem, zIndex } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n computed,\n onBeforeUnmount,\n shallowRef,\n useTemplateRef,\n watch,\n type CSSProperties\n} from 'vue'\n\nimport type { CodeEditorProps } from '../../types'\nimport { UScroll } from '../scroll'\nimport { basicSetup } from './basic-setup'\nimport { loadLanguage } from './lang-loaders'\n\ndefineOptions({ name: 'UCodeEditor' })\n\nconst props = withDefaults(defineProps<CodeEditorProps>(), {\n disabled: undefined,\n readonly: undefined,\n dark: false,\n defaultLines: 8\n})\n\nconst model = defineModel<string>()\n\nconst cls = bem('code-editor')\n\nconst { formProps } = injectFormContext()\n\nconst { disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n disabled: false,\n readonly: false\n})\n\nconst className = computed<string[]>(() => [\n cls.b,\n bem.is('disabled', disabled.value),\n bem.is('readonly', readonly.value),\n bem.is('dark', props.dark)\n])\n\nconst rootStyle = computed<CSSProperties>(() => ({\n '--u-code-editor-default-lines': Math.max(1, props.defaultLines)\n}))\n\nconst containerRef = useTemplateRef('container')\nconst editor = shallowRef<EditorView | null>(null)\n\nconst themeCompartment = new Compartment()\nconst editableCompartment = new Compartment()\nconst readOnlyCompartment = new Compartment()\nconst langCompartment = new Compartment()\n\nlet phantomGutter: HTMLElement | null = null\nlet phantomContainer: HTMLElement | null = null\nlet lastPhantomKey = ''\n\nfunction resetPhantomCache() {\n phantomGutter = null\n phantomContainer = null\n lastPhantomKey = ''\n}\n\n/**\n * 在 .cm-lineNumbers 末尾追加占位行号 DOM,使可视行号数量补齐到 defaultLines。\n * CodeMirror 的 lineNumbers() 仅为真实文档行渲染行号,超出部分由本逻辑补全。\n */\nfunction syncPhantomLineNumbers() {\n const view = editor.value\n if (!view) return\n\n if (!phantomGutter || !phantomGutter.isConnected) {\n phantomGutter = view.dom.querySelector<HTMLElement>('.cm-gutter.cm-lineNumbers')\n }\n if (!phantomGutter) return\n\n if (!phantomContainer) {\n phantomContainer = document.createElement('div')\n phantomContainer.className = 'cm-phantom-lines'\n }\n if (\n phantomContainer.parentElement !== phantomGutter ||\n phantomContainer !== phantomGutter.lastElementChild\n ) {\n phantomGutter.appendChild(phantomContainer)\n }\n\n const realLines = view.state.doc.lines\n const target = Math.max(0, Math.max(1, props.defaultLines) - realLines)\n const lineHeight = view.defaultLineHeight\n\n const key = `${realLines}|${target}|${lineHeight}`\n if (key === lastPhantomKey) return\n lastPhantomKey = key\n\n while (phantomContainer.children.length > target) {\n phantomContainer.lastElementChild!.remove()\n }\n while (phantomContainer.children.length < target) {\n const el = document.createElement('div')\n el.className = 'cm-gutterElement cm-gutterElement-phantom'\n phantomContainer.appendChild(el)\n }\n for (let i = 0; i < target; i++) {\n const el = phantomContainer.children[i] as HTMLElement\n const num = String(realLines + i + 1)\n if (el.textContent !== num) el.textContent = num\n if (lineHeight && el.style.height !== `${lineHeight}px`) {\n el.style.height = `${lineHeight}px`\n }\n }\n}\n\nconst phantomLineNumbersPlugin = ViewPlugin.fromClass(\n class {\n update(update: ViewUpdate) {\n if (update.docChanged || update.geometryChanged) {\n syncPhantomLineNumbers()\n }\n }\n }\n)\n\nfunction buildExtensions(): Extension[] {\n return [\n basicSetup,\n tooltips({ parent: document.body }),\n EditorView.theme({ '.cm-tooltip': { zIndex: zIndex() } }),\n themeCompartment.of(props.dark ? oneDark : []),\n editableCompartment.of(EditorView.editable.of(!disabled.value)),\n readOnlyCompartment.of(EditorState.readOnly.of(readonly.value)),\n langCompartment.of([]),\n phantomLineNumbersPlugin\n ]\n}\n\nlet editorToken = 0\nlet langToken = 0\n\nasync function applyLanguage() {\n const view = editor.value\n if (!view) return\n const myToken = ++langToken\n const { language } = props\n\n if (!language) {\n if (myToken !== langToken || editor.value !== view) return\n view.dispatch({ effects: langCompartment.reconfigure([]) })\n return\n }\n\n const ext = await loadLanguage(language)\n if (myToken !== langToken || editor.value !== view) return\n view.dispatch({ effects: langCompartment.reconfigure(ext) })\n}\n\nfunction destroyEditor() {\n ++editorToken\n ++langToken\n editor.value?.destroy()\n editor.value = null\n resetPhantomCache()\n}\n\nfunction createEditor() {\n destroyEditor()\n const myToken = ++editorToken\n const parent = containerRef.value\n if (!parent) return\n\n const view = new EditorView({\n doc: model.value,\n extensions: buildExtensions(),\n parent,\n dispatch(tr) {\n view.update([tr])\n if (tr.docChanged) {\n model.value = tr.state.doc.toString()\n }\n }\n })\n\n if (myToken !== editorToken) {\n view.destroy()\n return\n }\n\n editor.value = view\n syncPhantomLineNumbers()\n applyLanguage()\n}\n\nwatch(\n containerRef,\n (el) => {\n if (el) createEditor()\n else destroyEditor()\n },\n { immediate: true, flush: 'post' }\n)\n\nwatch(() => props.language, applyLanguage)\n\nwatch(\n () => props.dark,\n (dark) => {\n editor.value?.dispatch({ effects: themeCompartment.reconfigure(dark ? oneDark : []) })\n }\n)\n\nwatch(disabled, (v) => {\n editor.value?.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!v)) })\n})\n\nwatch(readonly, (v) => {\n editor.value?.dispatch({ effects: readOnlyCompartment.reconfigure(EditorState.readOnly.of(v)) })\n})\n\nwatch(() => props.defaultLines, syncPhantomLineNumbers)\n\nwatch(\n [() => props.modelValue, editor],\n ([v, e]) => {\n if (!e) return\n if (e.composing) return\n const next = v ?? ''\n if (e.state.doc.toString() === next) return\n\n const valueLength = next.length\n const inRange = e.state.selection.ranges.every(\n (range) => range.anchor <= valueLength && range.head <= valueLength\n )\n e.dispatch({\n changes: { from: 0, to: e.state.doc.length, insert: next },\n selection: inRange ? e.state.selection : { anchor: 0, head: 0 },\n scrollIntoView: true\n })\n },\n { immediate: true }\n)\n\nonBeforeUnmount(destroyEditor)\n</script>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/components/code-editor/lang-loaders.ts
|
|
2
|
+
/** 语言包动态加载器,新增语言只需在此注册一条 */
|
|
3
|
+
const LANG_LOADERS = {
|
|
4
|
+
js: () => import("../../node_modules/.bun/@codemirror_lang-javascript@6.2.5/node_modules/@codemirror/lang-javascript/dist/index.js").then((m) => m.javascript({ typescript: true })),
|
|
5
|
+
sql: () => import("../../node_modules/.bun/@codemirror_lang-sql@6.10.0/node_modules/@codemirror/lang-sql/dist/index.js").then((m) => m.sql()),
|
|
6
|
+
java: () => import("../../node_modules/.bun/@codemirror_lang-java@6.0.2/node_modules/@codemirror/lang-java/dist/index.js").then((m) => m.java()),
|
|
7
|
+
json: () => import("../../node_modules/.bun/@codemirror_lang-json@6.0.2/node_modules/@codemirror/lang-json/dist/index.js").then((m) => m.json())
|
|
8
|
+
};
|
|
9
|
+
/** 按需加载语言扩展;模块缓存由运行时保证,重复切换同一语言不会重复下载 */
|
|
10
|
+
function loadLanguage(lang) {
|
|
11
|
+
return LANG_LOADERS[lang]();
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { loadLanguage };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=lang-loaders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lang-loaders.js","names":[],"sources":["../../../src/components/code-editor/lang-loaders.ts"],"sourcesContent":["import type { Extension } from '@codemirror/state'\n\nimport type { CodeEditorLang } from '../../types'\n\n/** 语言包动态加载器,新增语言只需在此注册一条 */\nconst LANG_LOADERS: Record<CodeEditorLang, () => Promise<Extension>> = {\n js: () => import('@codemirror/lang-javascript').then((m) => m.javascript({ typescript: true })),\n sql: () => import('@codemirror/lang-sql').then((m) => m.sql()),\n java: () => import('@codemirror/lang-java').then((m) => m.java()),\n json: () => import('@codemirror/lang-json').then((m) => m.json())\n}\n\n/** 按需加载语言扩展;模块缓存由运行时保证,重复切换同一语言不会重复下载 */\nexport function loadLanguage(lang: CodeEditorLang): Promise<Extension> {\n return LANG_LOADERS[lang]()\n}\n"],"mappings":";;AAKA,MAAM,eAAiE;CACrE,UAAU,OAAO,mHAA8B,CAAC,MAAM,MAAM,EAAE,WAAW,EAAE,YAAY,KAAK,CAAC,CAAC;CAC9F,WAAW,OAAO,sGAAuB,CAAC,MAAM,MAAM,EAAE,IAAI,CAAC;CAC7D,YAAY,OAAO,uGAAwB,CAAC,MAAM,MAAM,EAAE,KAAK,CAAC;CAChE,YAAY,OAAO,uGAAwB,CAAC,MAAM,MAAM,EAAE,KAAK,CAAC;AAClE;;AAGA,SAAgB,aAAa,MAA0C;CACrE,OAAO,aAAa,KAAK,CAAC;AAC5B"}
|
|
@@ -12,8 +12,8 @@ declare const __VLS_base: import("vue").DefineComponent<PopConfirmProps, {}, {},
|
|
|
12
12
|
onConfirm?: (() => any) | undefined;
|
|
13
13
|
onCancel?: (() => any) | undefined;
|
|
14
14
|
}>, {
|
|
15
|
-
direction: TipDirection;
|
|
16
15
|
trigger: "hover" | "click";
|
|
16
|
+
direction: TipDirection;
|
|
17
17
|
icon: import("vue").Component;
|
|
18
18
|
iconColor: string;
|
|
19
19
|
confirmText: string;
|
|
@@ -9,10 +9,10 @@ declare const __VLS_base: import("vue").DefineComponent<TipProps, {}, {}, {}, {}
|
|
|
9
9
|
}, string, import("vue").PublicProps, Readonly<TipProps> & Readonly<{
|
|
10
10
|
"onUpdate:visible"?: ((value: boolean) => any) | undefined;
|
|
11
11
|
}>, {
|
|
12
|
-
direction: TipDirection;
|
|
13
12
|
trigger: "hover" | "click";
|
|
14
13
|
contentTag: string;
|
|
15
14
|
visible: boolean;
|
|
15
|
+
direction: TipDirection;
|
|
16
16
|
content: string;
|
|
17
17
|
alignment: TipAlign;
|
|
18
18
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { NodeProp } from "../../../../../@lezer_common@1.5.2/node_modules/@lezer/common/dist/index.js";
|
|
2
1
|
import { Annotation, ChangeDesc, ChangeSet, EditorSelection, Facet, StateEffect, StateField, Text, Transaction, combineConfig, countColumn, findClusterBreak } from "../../../../../@codemirror_state@6.7.0/node_modules/@codemirror/state/dist/index.js";
|
|
3
2
|
import { Direction, EditorView } from "../../../../../@codemirror_view@6.43.4/node_modules/@codemirror/view/dist/index.js";
|
|
3
|
+
import { NodeProp } from "../../../../../@lezer_common@1.5.2/node_modules/@lezer/common/dist/index.js";
|
|
4
4
|
import { IndentContext, getIndentUnit, getIndentation, indentString, indentUnit, matchBrackets, syntaxTree } from "../../../../../@codemirror_language@6.12.4/node_modules/@codemirror/language/dist/index.js";
|
|
5
5
|
//#region ../../node_modules/.bun/@codemirror+commands@6.10.4/node_modules/@codemirror/commands/dist/index.js
|
|
6
6
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parser } from "../../../../../@lezer_java@1.1.3/node_modules/@lezer/java/dist/index.js";
|
|
2
1
|
import { LRLanguage, LanguageSupport, continuedIndent, delimitedIndent, flatIndent, foldInside, foldNodeProp, indentNodeProp } from "../../../../../@codemirror_language@6.12.4/node_modules/@codemirror/language/dist/index.js";
|
|
2
|
+
import { parser } from "../../../../../@lezer_java@1.1.3/node_modules/@lezer/java/dist/index.js";
|
|
3
3
|
//#region ../../node_modules/.bun/@codemirror+lang-java@6.0.2/node_modules/@codemirror/lang-java/dist/index.js
|
|
4
4
|
/**
|
|
5
5
|
A language provider based on the [Lezer Java
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { IterMode, NodeWeakMap } from "../../../../../@lezer_common@1.5.2/node_modules/@lezer/common/dist/index.js";
|
|
2
1
|
import { EditorSelection } from "../../../../../@codemirror_state@6.7.0/node_modules/@codemirror/state/dist/index.js";
|
|
3
2
|
import { EditorView } from "../../../../../@codemirror_view@6.43.4/node_modules/@codemirror/view/dist/index.js";
|
|
3
|
+
import { IterMode, NodeWeakMap } from "../../../../../@lezer_common@1.5.2/node_modules/@lezer/common/dist/index.js";
|
|
4
4
|
import { LRLanguage, LanguageSupport, continuedIndent, defineLanguageFacet, delimitedIndent, flatIndent, foldInside, foldNodeProp, indentNodeProp, sublanguageProp, syntaxTree } from "../../../../../@codemirror_language@6.12.4/node_modules/@codemirror/language/dist/index.js";
|
|
5
|
-
import { parser } from "../../../../../@lezer_javascript@1.5.4/node_modules/@lezer/javascript/dist/index.js";
|
|
6
5
|
import { completeFromList, ifNotIn, snippetCompletion } from "../../../../../@codemirror_autocomplete@6.20.3/node_modules/@codemirror/autocomplete/dist/index.js";
|
|
6
|
+
import { parser } from "../../../../../@lezer_javascript@1.5.4/node_modules/@lezer/javascript/dist/index.js";
|
|
7
7
|
//#region ../../node_modules/.bun/@codemirror+lang-javascript@6.2.5/node_modules/@codemirror/lang-javascript/dist/index.js
|
|
8
8
|
/**
|
|
9
9
|
A collection of JavaScript-related
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ExternalTokenizer, LRParser } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
2
1
|
import { styleTags, tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
3
2
|
import { LRLanguage, LanguageSupport, continuedIndent, foldNodeProp, indentNodeProp, syntaxTree } from "../../../../../@codemirror_language@6.12.4/node_modules/@codemirror/language/dist/index.js";
|
|
4
3
|
import { completeFromList, ifNotIn } from "../../../../../@codemirror_autocomplete@6.20.3/node_modules/@codemirror/autocomplete/dist/index.js";
|
|
4
|
+
import { ExternalTokenizer, LRParser } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
5
5
|
//#region ../../node_modules/.bun/@codemirror+lang-sql@6.10.0/node_modules/@codemirror/lang-sql/dist/index.js
|
|
6
6
|
const whitespace = 36, LineComment = 1, BlockComment = 2, String$1 = 3, Number = 4, Bool = 5, Null = 6, ParenL = 7, ParenR = 8, BraceL = 9, BraceR = 10, BracketL = 11, BracketR = 12, Semi = 13, Dot = 14, Operator = 15, Punctuation = 16, SpecialVar = 17, Identifier = 18, QuotedIdentifier = 19, Keyword = 20, Type = 21, Bits = 22, Bytes = 23, Builtin = 24;
|
|
7
7
|
function isAlpha(ch) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { IterMode, NodeProp, NodeType, Parser, Tree, TreeFragment } from "../../../../../@lezer_common@1.5.2/node_modules/@lezer/common/dist/index.js";
|
|
2
|
-
import { highlightTree, styleTags, tagHighlighter, tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
3
1
|
import { EditorState, Facet, Prec, RangeSet, RangeSetBuilder, StateEffect, StateField, combineConfig, countColumn } from "../../../../../@codemirror_state@6.7.0/node_modules/@codemirror/state/dist/index.js";
|
|
4
2
|
import { StyleModule } from "../../../../../style-mod@4.1.3/node_modules/style-mod/src/style-mod.js";
|
|
5
3
|
import { Decoration, Direction, EditorView, GutterMarker, ViewPlugin, WidgetType, gutter, logException } from "../../../../../@codemirror_view@6.43.4/node_modules/@codemirror/view/dist/index.js";
|
|
4
|
+
import { IterMode, NodeProp, NodeType, Parser, Tree, TreeFragment } from "../../../../../@lezer_common@1.5.2/node_modules/@lezer/common/dist/index.js";
|
|
5
|
+
import { highlightTree, styleTags, tagHighlighter, tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
6
6
|
//#region ../../node_modules/.bun/@codemirror+language@6.12.4/node_modules/@codemirror/language/dist/index.js
|
|
7
7
|
var _a;
|
|
8
8
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
2
1
|
import { EditorView } from "../../../../../@codemirror_view@6.43.4/node_modules/@codemirror/view/dist/index.js";
|
|
2
|
+
import { tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
3
3
|
import { HighlightStyle, syntaxHighlighting } from "../../../../../@codemirror_language@6.12.4/node_modules/@codemirror/language/dist/index.js";
|
|
4
4
|
//#region ../../node_modules/.bun/@codemirror+theme-one-dark@6.1.3/node_modules/@codemirror/theme-one-dark/dist/index.js
|
|
5
5
|
const chalky = "#e5c07b", coral = "#e06c75", cyan = "#56b6c2", invalid = "#ffffff", ivory = "#abb2bf", stone = "#7d8799", malibu = "#61afef", sage = "#98c379", whiskey = "#d19a66", violet = "#c678dd", darkBackground = "#21252b", highlightBackground = "#2c313a", background = "#282c34", tooltipBackground = "#353a42", selection = "#3E4451", cursor = "#528bff";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LRParser } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
2
1
|
import { styleTags, tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
2
|
+
import { LRParser } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
3
3
|
//#region ../../node_modules/.bun/@lezer+java@1.1.3/node_modules/@lezer/java/dist/index.js
|
|
4
4
|
const javaHighlighting = styleTags({
|
|
5
5
|
null: tags.null,
|
package/dist/node_modules/.bun/@lezer_javascript@1.5.4/node_modules/@lezer/javascript/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ContextTracker, ExternalTokenizer, LRParser, LocalTokenGroup } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
2
1
|
import { styleTags, tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
2
|
+
import { ContextTracker, ExternalTokenizer, LRParser, LocalTokenGroup } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
3
3
|
//#region ../../node_modules/.bun/@lezer+javascript@1.5.4/node_modules/@lezer/javascript/dist/index.js
|
|
4
4
|
const noSemi = 316, noSemiType = 317, incdec = 1, incdecPrefix = 2, questionDot = 3, JSXStartTag = 4, insertSemi = 318, spaces = 320, newline = 321, LineComment = 5, BlockComment = 6, Dialect_jsx = 0;
|
|
5
5
|
const space = [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LRParser } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
2
1
|
import { styleTags, tags } from "../../../../../@lezer_highlight@1.2.3/node_modules/@lezer/highlight/dist/index.js";
|
|
2
|
+
import { LRParser } from "../../../../../@lezer_lr@1.4.10/node_modules/@lezer/lr/dist/index.js";
|
|
3
3
|
//#region ../../node_modules/.bun/@lezer+json@1.0.3/node_modules/@lezer/json/dist/index.js
|
|
4
4
|
const jsonHighlighting = styleTags({
|
|
5
5
|
String: tags.string,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veltra/desktop",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.19",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"src"
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"@cat-kit/core": ">=1.1.8",
|
|
58
58
|
"@cat-kit/excel": ">=1.0.0",
|
|
59
59
|
"@cat-kit/fe": "^1.1.8",
|
|
60
|
-
"@veltra/compositions": "1.2.
|
|
61
|
-
"@veltra/directives": "1.2.
|
|
62
|
-
"@veltra/icons": "1.2.
|
|
63
|
-
"@veltra/styles": "1.2.
|
|
64
|
-
"@veltra/utils": "1.2.
|
|
60
|
+
"@veltra/compositions": "1.2.19",
|
|
61
|
+
"@veltra/directives": "1.2.19",
|
|
62
|
+
"@veltra/icons": "1.2.19",
|
|
63
|
+
"@veltra/styles": "1.2.19",
|
|
64
|
+
"@veltra/utils": "1.2.19",
|
|
65
65
|
"vue": ">=3.5.39"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
@@ -5,10 +5,6 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import { java } from '@codemirror/lang-java'
|
|
9
|
-
import { javascript } from '@codemirror/lang-javascript'
|
|
10
|
-
import { json } from '@codemirror/lang-json'
|
|
11
|
-
import { sql } from '@codemirror/lang-sql'
|
|
12
8
|
import { Compartment, EditorState, type Extension } from '@codemirror/state'
|
|
13
9
|
import { oneDark } from '@codemirror/theme-one-dark'
|
|
14
10
|
import { EditorView, ViewPlugin, tooltips, type ViewUpdate } from '@codemirror/view'
|
|
@@ -24,9 +20,10 @@ import {
|
|
|
24
20
|
type CSSProperties
|
|
25
21
|
} from 'vue'
|
|
26
22
|
|
|
27
|
-
import type {
|
|
23
|
+
import type { CodeEditorProps } from '../../types'
|
|
28
24
|
import { UScroll } from '../scroll'
|
|
29
25
|
import { basicSetup } from './basic-setup'
|
|
26
|
+
import { loadLanguage } from './lang-loaders'
|
|
30
27
|
|
|
31
28
|
defineOptions({ name: 'UCodeEditor' })
|
|
32
29
|
|
|
@@ -62,14 +59,6 @@ const rootStyle = computed<CSSProperties>(() => ({
|
|
|
62
59
|
const containerRef = useTemplateRef('container')
|
|
63
60
|
const editor = shallowRef<EditorView | null>(null)
|
|
64
61
|
|
|
65
|
-
/** 静态导入语言包,避免动态 import 在打包/Vite 预构建下产生多份 @codemirror/* 实例 */
|
|
66
|
-
const langExtensions: Record<CodeEditorLang, Extension> = {
|
|
67
|
-
js: javascript({ typescript: true }),
|
|
68
|
-
sql: sql(),
|
|
69
|
-
java: java(),
|
|
70
|
-
json: json()
|
|
71
|
-
}
|
|
72
|
-
|
|
73
62
|
const themeCompartment = new Compartment()
|
|
74
63
|
const editableCompartment = new Compartment()
|
|
75
64
|
const readOnlyCompartment = new Compartment()
|
|
@@ -161,12 +150,19 @@ function buildExtensions(): Extension[] {
|
|
|
161
150
|
let editorToken = 0
|
|
162
151
|
let langToken = 0
|
|
163
152
|
|
|
164
|
-
function applyLanguage() {
|
|
153
|
+
async function applyLanguage() {
|
|
165
154
|
const view = editor.value
|
|
166
155
|
if (!view) return
|
|
167
156
|
const myToken = ++langToken
|
|
168
157
|
const { language } = props
|
|
169
|
-
|
|
158
|
+
|
|
159
|
+
if (!language) {
|
|
160
|
+
if (myToken !== langToken || editor.value !== view) return
|
|
161
|
+
view.dispatch({ effects: langCompartment.reconfigure([]) })
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const ext = await loadLanguage(language)
|
|
170
166
|
if (myToken !== langToken || editor.value !== view) return
|
|
171
167
|
view.dispatch({ effects: langCompartment.reconfigure(ext) })
|
|
172
168
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Extension } from '@codemirror/state'
|
|
2
|
+
|
|
3
|
+
import type { CodeEditorLang } from '../../types'
|
|
4
|
+
|
|
5
|
+
/** 语言包动态加载器,新增语言只需在此注册一条 */
|
|
6
|
+
const LANG_LOADERS: Record<CodeEditorLang, () => Promise<Extension>> = {
|
|
7
|
+
js: () => import('@codemirror/lang-javascript').then((m) => m.javascript({ typescript: true })),
|
|
8
|
+
sql: () => import('@codemirror/lang-sql').then((m) => m.sql()),
|
|
9
|
+
java: () => import('@codemirror/lang-java').then((m) => m.java()),
|
|
10
|
+
json: () => import('@codemirror/lang-json').then((m) => m.json())
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** 按需加载语言扩展;模块缓存由运行时保证,重复切换同一语言不会重复下载 */
|
|
14
|
+
export function loadLanguage(lang: CodeEditorLang): Promise<Extension> {
|
|
15
|
+
return LANG_LOADERS[lang]()
|
|
16
|
+
}
|