添加 editor.

This commit is contained in:
lijiahang
2023-10-26 14:10:48 +08:00
parent d3825ab5b2
commit 03e18cc0e2
9 changed files with 327 additions and 16380 deletions

View File

@@ -0,0 +1,92 @@
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
/**
* 主题
*/
export type Theme = 'vs' | 'vs-dark'
/**
* 折叠方式
*/
export type FoldingStrategy = 'auto' | 'indentation'
/**
* 是否一直显示折叠
*/
export type ShowFoldingControls = 'always' | 'mouseover';
/**
* 行亮
*/
export type RenderLineHighlight = 'all' | 'line' | 'none' | 'gutter'
/**
* 配置项
*/
export interface Options {
// 自适应布局
automaticLayout?: boolean;
// 是否折叠
folding?: boolean;
// 折叠方式
foldingStrategy?: FoldingStrategy;
// 是否折叠等高线
foldingHighlight?: boolean;
// 是否一直显示折叠
showFoldingControls?: ShowFoldingControls;
// 等宽优化
disableLayerHinting?: boolean;
// 行亮
renderLineHighlight?: RenderLineHighlight;
// 显示行号
selectOnLineNumbers?: boolean;
placeholder?: string;
minimap?: {
// 关闭小地图
enabled?: boolean
};
fontSize?: number;
// 取消代码后面一大段空白
scrollBeyondLastLine?: boolean;
// 不要滚动条的边框
overviewRulerBorder?: boolean;
// 颜色装饰器
colorDecorators?: boolean;
[key: string]: unknown;
}
/**
* 创建默认配置
*/
export const createDefaultOptions = (): Options => {
return {
automaticLayout: true,
folding: true,
foldingHighlight: true,
foldingStrategy: 'indentation',
showFoldingControls: 'always',
renderLineHighlight: 'line',
selectOnLineNumbers: true,
disableLayerHinting: true,
minimap: {
enabled: false,
},
fontSize: 16,
scrollBeyondLastLine: false,
overviewRulerBorder: false,
colorDecorators: true,
suggest: true,
};
};
// worker 生成器
self.MonacoEnvironment = {
getWorker(_: string, label: string) {
if (label === 'json') {
return new JsonWorker();
}
return new EditorWorker();
},
};

View File

@@ -0,0 +1,141 @@
<template>
<div ref="editorContainer"
:class="{
'editor-wrapper': true,
[containerClass]: !!containerClass
}"
:style="{
...containerStyle
}" />
</template>
<script lang="ts">
export default {
name: 'index'
};
</script>
<script lang="ts" setup>
import type { Theme, Options } from './core';
import type { PropType } from 'vue';
import * as monaco from 'monaco-editor';
import { createDefaultOptions } from './core';
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { useAppStore } from '@/store';
const appStore = useAppStore();
const emits = defineEmits(['update:modelValue', 'change', 'editor-mounted']);
const props = defineProps({
modelValue: {
type: String,
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '100%'
},
readonly: {
type: Boolean,
default: false
},
language: {
type: String,
default: 'json',
},
containerClass: String,
containerStyle: Object,
theme: {
type: [String, Boolean] as PropType<Theme | boolean>,
default: true,
},
options: {
type: Object as PropType<Options>,
default: () => {
return {};
}
}
});
const editorContainer = ref();
let editor: any;
// 初始化
const init = () => {
const options = {
value: props.modelValue,
language: props.language,
readOnly: props.readonly,
theme: props.theme === true ? (appStore.theme === 'dark' ? 'vs-dark' : 'vs') : props.theme,
options: { ...createDefaultOptions(), ...props.options },
};
// 创建编辑器
editor = monaco.editor.create(editorContainer.value, options);
// 监听值的变化
editor.onDidChangeModelContent(() => {
const value = editor.getValue();
emits('update:modelValue', value);
emits('change', value);
});
emits('editor-mounted', editor);
};
// 监听主题变更
watch(() => appStore.theme, (v) => {
if (editor && props.theme === true) {
editor.updateOptions({ theme: v === 'dark' ? 'vs-dark' : 'vs' });
}
});
// 监听数据变更
watch(() => props.modelValue, (v) => {
if (editor) {
const value = editor.getValue();
if (v !== value) {
editor.setValue(v);
}
}
});
// 监听配置
watch(() => props.options, (v) => {
if (editor) {
editor.updateOptions(v);
}
}, { deep: true });
// 监听只读
watch(() => props.readonly, () => {
if (editor) {
editor.updateOptions({ readOnly: props.readonly });
}
});
// 修改语言
watch(() => props.language, (v) => {
if (editor) {
monaco.editor.setModelLanguage(editor?.getModel(), v as string);
}
});
onMounted(() => {
init();
});
onBeforeUnmount(() => {
editor?.dispose();
editor = undefined;
});
</script>
<style lang="less" scoped>
.editor-wrapper {
width: 100%;
height: 100%;
}
</style>

View File

@@ -0,0 +1,38 @@
// 代码提示
monaco.languages.registerCompletionItemProvider('java', {
provideCompletionItems() {
const suggestions: any = [];
// 这个keywords就是java.java文件中有的
javaLanguage.keywords?.forEach((item: any) => {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: item,
});
});
javaLanguage.operators?.forEach((item: any) => {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Operator,
insertText: item,
});
});
javaLanguage.builtinFunctions?.forEach((item: any) => {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Function,
insertText: item,
});
});
javaLanguage.builtinVariables?.forEach((item: any) => {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Variable,
insertText: item,
});
});
return {
suggestions,
};
},
});