From c81178ae266c11cddbe4814cf3f8cc99fd3836b4 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Tue, 31 Aug 2021 22:20:42 +0530 Subject: [PATCH] refactor: extract common codemirror logic out to composable --- components/smart/CodeMirror.vue | 49 ++++------------------- helpers/editor/codemirror.ts | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 41 deletions(-) create mode 100644 helpers/editor/codemirror.ts diff --git a/components/smart/CodeMirror.vue b/components/smart/CodeMirror.vue index 292732f11..6068778c8 100644 --- a/components/smart/CodeMirror.vue +++ b/components/smart/CodeMirror.vue @@ -3,20 +3,10 @@ diff --git a/helpers/editor/codemirror.ts b/helpers/editor/codemirror.ts new file mode 100644 index 000000000..9a282979f --- /dev/null +++ b/helpers/editor/codemirror.ts @@ -0,0 +1,69 @@ +import CodeMirror from "codemirror" + +import "codemirror/theme/juejin.css" + +import "codemirror/lib/codemirror.css" + +import "codemirror/addon/fold/foldgutter.css" +import "codemirror/addon/fold/foldgutter" +import "codemirror/addon/fold/brace-fold" +import "codemirror/addon/fold/comment-fold" +import "codemirror/addon/fold/indent-fold" +import "codemirror/addon/display/autorefresh" + +import { watch, onMounted, ref, Ref } from "@nuxtjs/composition-api" + +const DEFAULT_THEME = "juejin" + +const DEFAULT_EDITOR_CONFIG: CodeMirror.EditorConfiguration = { + theme: DEFAULT_THEME, + autoRefresh: true, + lineNumbers: true, + foldGutter: true, + gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], +} + +/** + * A Vue composable to mount and use Codemirror + * + * NOTE: Make sure to import all the necessary Codemirror modules, + * as this function doesn't import any other than the core + * @param el Reference to the dom node to attach to + * @param value Reference to value to read/write to + * @param options CodeMirror options to pass + */ +export function useCodemirror( + el: Ref, + value: Ref, + options: CodeMirror.EditorConfiguration +) { + const cm = ref(null) + + // Boot-up CodeMirror, set the value and listeners + onMounted(() => { + cm.value = CodeMirror(el.value!, { ...DEFAULT_EDITOR_CONFIG, ...options }) + cm.value.setValue(value.value) + + cm.value.on("change", (instance) => { + // External update propagation (via watchers) should be ignored + if (instance.getValue() !== value.value) { + value.value = instance.getValue() + } + }) + }) + + // Watch value updates + watch(value, (newVal) => { + // Check if we are mounted + if (cm.value) { + // Don't do anything on internal updates + if (cm.value.getValue() !== newVal) { + cm.value.setValue(newVal) + } + } + }) + + return { + cm, + } +}