<template>
<div class="in-coder-panel">
<textarea ref="codeform" v-model="code" class="codemirror"></textarea>
</div>
</template>
<script>
import { watch, onMounted, onBeforeUnmount, ref } from "vue";
import _CodeMirror from "codemirror";
import "codemirror/lib/codemirror.css";
import "codemirror/addon/hint/show-hint.css";
const themList = [];
const requireModules = require.context("codemirror/theme/", false, /.css$/);
requireModules.keys().forEach((value) => {
const newValue = value.replace(/^.\//, "").replace(/.css$/, "");
themList.push(newValue);
});
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/css/css.js";
import "codemirror/mode/xml/xml.js";
import "codemirror/mode/clike/clike.js";
import "codemirror/mode/markdown/markdown.js";
import "codemirror/mode/python/python.js";
import "codemirror/mode/r/r.js";
import "codemirror/mode/shell/shell.js";
import "codemirror/mode/sql/sql.js";
import "codemirror/mode/swift/swift.js";
import "codemirror/mode/vue/vue.js";
import "codemirror/mode/yaml/yaml.js";
require("codemirror/addon/edit/matchbrackets");
require("codemirror/addon/selection/active-line");
require("codemirror/addon/lint/yaml-lint");
require("codemirror/addon/hint/show-hint");
require("codemirror/addon/hint/anyword-hint");
require("codemirror/addon/display/autorefresh");
const CodeMirror = window.CodeMirror || _CodeMirror;
export default {
emits: ["onUpdate:value"],
props: {
id: {
type: Number,
default: 0,
},
value: {
type: String,
default: "",
},
readonly: {
type: Boolean,
default: false,
},
eventType: {
type: String,
default: "blur",
},
language: {
type: String,
default: "x-yaml",
},
theme: {
type: String,
default: "mbo",
},
},
setup(props, { emit }) {
const codeform = ref(null);
const code = ref(props.value);
let editor = null;
let options = {};
let modes = {};
options = {
mode: "text/x-yaml",
tabSize: 1,
indentWithTabs: true,
smartIndent: true,
lineWrapping: true,
lineNumbers: true,
matchBrackets: true,
indentUnit: 4,
autoRefresh: true,
theme: props.theme ? props.theme : "mbo",
lint: false,
lineWiseCopyCut:false,
readOnly: props.readonly === false ? false : "nocursor",
extraKeys: { Ctrl: "autocomplete" },
hintOptions: {},
};
modes = {
css: "text/css",
javascript: "text/javascript",
"xml/html": "text/html",
yaml: "text/x-yaml",
java: "text/x-java",
"objective-c": "text/x-objectivec",
python: "text/x-python",
r: "text/x-rsrc",
shell: "text/x-sh",
sql: "text/x-sql",
swift: "text/x-swift",
vue: "text/x-vue",
markdown: "text/markdown",
};
function initialize() {
if (editor) {
editor.toTextArea();
}
if (props.language) {
let lan = props.language.toLowerCase();
let modeObj = modes[lan] ? modes[lan] : "";
options.mode = modeObj ? modeObj : options.mode;
}
editor = CodeMirror.fromTextArea(codeform.value, options);
editor.on(props.eventType, (coder) => {
if (emit) {
emit("onUpdate:value", coder.getValue());
}
});
}
function themeImport() {
return new Promise((resolve) => {
themList.forEach((value) => {
if (props.theme === value) {
import(`codemirror/theme/${props.theme}.css`);
resolve();
}
});
});
}
watch(
() => props.id,
() => {
themeImport().then(() => {
initialize();
});
}
);
watch(
() => props.value,
(newProps) => {
code.value = editor ? editor.setValue(newProps) : "";
editor.refresh();
}
);
onMounted(() => {
themeImport().then(() => {
initialize();
});
});
onBeforeUnmount(() => {
editor.off(props.eventType);
});
return {
code,
codeform,
initialize,
};
},
};
</script>