<!--
 * @Author: Jason Liu
 * @Date: 2021-11-09 16:46:46
 * @Desc: sql语法只能提示控件
-->

<template>
  <div class="javascript_editor">
    <textarea ref="mycode" class="codesql" v-model="value"> </textarea>
  </div>
</template>
<script>
require("codemirror/theme/ambiance.css");

require("codemirror/lib/codemirror.css");

let CodeMirror = require("codemirror/lib/codemirror");

require("codemirror/addon/edit/matchbrackets"); //括号匹配
require("codemirror/addon/selection/active-line");

require("codemirror/mode/javascript/javascript");
require("codemirror/mode/sql/sql");

//自动补全
require("codemirror/addon/hint/show-hint.css");
require("codemirror/addon/hint/show-hint");
require("codemirror/addon/hint/javascript-hint");
require("codemirror/addon/hint/sql-hint");

export default {
  props: {
    value: {
      type: String,
      default: "",
    },
    tables: {
      type: Object,
      default: undefined,
    },
    readOnly: {
      type: Boolean,
      default: false,
    },
    startParas: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      editor: null,
    };
  },
  watch: {
    newVal(newV, oldV) {
      if (this.editor) {
        if (this.startParas) {
          this.setSqlParas(this.newVal);
        }

        this.$emit("input", this.newVal);
      } else {
        this.init();
      }
    },
    tables() {
      this.setTables();
    },
  },
  computed: {
    newVal() {
      if (this.editor) {
        return this.editor.getValue();
      }
    },
  },
  created() {},
  mounted() {
    this.$nextTick(() => {
      this.init();
    });
  },
  methods: {
    /**
     * @Author: Jason Liu
     * @description: 初始化
     */
    init() {
      //let theme = 'ambiance'//设置主题，不设置的会使用默认主题
      this.editor = CodeMirror.fromTextArea(this.$refs.mycode, {
        value: this.value,
        mode: "text/javascript", //选择对应代码编辑器的语言，我这边选的是数据库，根据个人情况自行设置即可
        indentWithTabs: true,
        smartIndent: true,
        lineNumbers: true,
        matchBrackets: true,
        cursorHeight: 1,
        lineWrapping: true,
        readOnly: this.readOnly,
        // autofocus: true,
        extraKeys: { Ctrl: "autocomplete" }, //自定义快捷键
        styleActiveLine: true,
        hintOptions: {
          //自定义提示选项
          // 当匹配只有一项的时候是否自动补全
          completeSingle: false,
          tables: this.tables,
        },
      });

      setTimeout(() => {
        this.setValue();
      }, 300);

      //代码自动提示功能，记住使用cursorActivity事件不要使用change事件，这是一个坑，那样页面直接会卡死
      this.editor.on("inputRead", () => {
        this.editor.showHint();
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 设置内容值
     */
    setValue(val) {
      if (this.editor) {
        if (val) {
          this.editor.setValue(val);
        } else if (this.value === "") {
          this.editor.setValue("");
        } else {
          this.editor.setValue(this.value);
        }
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 设置sql占位符
     */
    setSqlParas(sqlscript) {
      let paras = [];
      if (sqlscript) {
        var reg = /[^\{\}]+(?=\})/g;
        var res = sqlscript.match(reg) || [];
        paras = Array.unique(res);
      }

      this.$emit(
        "glParas",
        paras.filter((item) => {
          return item != '"';
        })
      );
    },
    /**
     * @Author: Jason Liu
     * @description: 设置表格读取
     */
    setTables() {
      if (this.editor && this.tables) {
        this.editor.options.hintOptions.tables = this.tables;
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 格式化sql语句
     */
    sqlFormat() {
      if (this.editor) {
        this.editor.setValue(this.newVal.sqlFormatter());
      }
    },
  },
};
</script>
<style>
.CodeMirror {
  color: black;
  /* direction: ltr; */
  height: 100%;
  line-height: 22px;
}
.CodeMirror-hints {
  z-index: 9999 !important;
}

.javascript_editor {
  height: 100%;
}
</style>
