codemirror自定义弹出提示框内容

2 篇文章 1 订阅
1 篇文章 0 订阅

效果如下:

一.引入codemirror库

import 'codemirror/theme/ambiance.css' // 主题样式
import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/show-hint.js'

let CodeMirror = require('codemirror/lib/codemirror')

二.使用codemirror

export default {
  name: 'codeMirror',
  data () {
    return {
      code: ''
    }
  },
  mounted () {
    var editor = CodeMirror.fromTextArea(document.getElementById('mycode'), {
      lineNumbers: true,
      extraKeys: {
        'Ctrl': 'autocomplete'
      },
      mode: {
        name: 'text/x-zzzz' // 自定义的hint库
      },
      // hintOptions: {// 自定义提示选项
      //   tables: {appp: ['name()', 'score()', 'birthDate'], abpppp: ['name', 'score', 'birthDate'], app: ['name', 'score', 'birthDate'], version: ['name', 'score', 'birthDate'], dbos: ['name', 'population', 'size']}
      // },
      theme: 'ambiance' // 主题
    })
    editor.on('cursorActivity', function () {
      editor.showHint()
    })
  }
}

三.textare界面

<template>
  <textarea id="mycode" class="codesql" v-model="code" style="height:200px;width:600px;border: red solid 2px;"></textarea>
</template>
<style>
  .codesql {
    font-size: 11pt;
    font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
  }
</style>

四.现在进入到自定义提示内容部分代码的编写

1.此js代码文件需要放在项目的node_modules\codemirror\addon\hint路径下,因为使用的相对路径引用依赖库。

(function (mod) {
  if (typeof exports === 'object' && typeof module === 'object') // CommonJS
  { mod(require('../../lib/codemirror')) } else if (typeof define === 'function' && define.amd) // AMD
  { define(['../../lib/codemirror'], mod) } else // Plain browser env
  { mod(CodeMirror) }
})(function (CodeMirror) {
  'use strict'

  CodeMirror.defineMode('zzzz', function (config, parserConfig) {
    var jsonldMode = parserConfig.jsonld
    var isOperatorChar = /[+\-*&%=<>!?|~^@]/

    function parseWords (str) {
      var obj = {},
        words = str.split(' ')
      for (var i = 0; i < words.length; ++i) obj[words[i]] = true
      return obj
    }

    // 关键字
    var keywords = parseWords('int numeric decimal date varchar char bigint float double bit binary text set timestamp toString primitive money real number integer asInt asText dataType cardinality asText asInt asTimestamp flatMap valueMap asByte asBlob asDouble asDate asFloat asLong valueSingle asBoolean valueList valueSet asUuid null Infinity NaN undefined')

    var type, content

    function ret (tp, style, cont) {
      type = tp
      content = cont
      return style
    }

    function tokenBase (stream, state) {
      var beforeParams = state.beforeParams
      state.beforeParams = false
      var ch = stream.next()

      if (ch == '"' || ch == "'") {
        state.tokenize = tokenString(ch)
        return state.tokenize(stream, state)
      } else if (ch == '.' && stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)) {
        return ret('number', 'number')
      } else if (ch == '[') {
        stream.skipTo(']')
        stream.eat(']')
        return ret('string', 'string')
      } else if (/\d/.test(ch)) {
        stream.eatWhile(/[\w\.]/)
        return 'number'
      } else {
        stream.eatWhile(/[\w\$_{}\xa1-\uffff]/)
        var word = stream.current()
        if (keywords && keywords.propertyIsEnumerable(word)) {
          state.beforeParams = true
          return 'keyword'
        }

        return null
      }
    }

    function tokenString (quote) {
      return function (stream, state) {
        var escaped = false,
          next
        if (jsonldMode && stream.peek() == '@' && stream.match(isJsonldKeyword)) {
          state.tokenize = tokenBase
          return ret('jsonld-keyword', 'meta')
        }
        while ((next = stream.next()) != null) {
          if (next == quote && !escaped) break
          escaped = !escaped && next == '\\'
        }
        if (!escaped) state.tokenize = tokenBase
        return ret('string', 'string')
      }
    }

    return {
      startState: function () {
        return {
          tokenize: tokenBase,
          beforeParams: false,
          inParams: false
        }
      },
      token: function (stream, state) {
        if (stream.eatSpace()) return null
        return state.tokenize(stream, state)
      }
    }
  })
  //是否包含中括号
  function getZKH (list,str) {
    let location = str.search(/[\w]+\[[\w\s,]*\]\.$/i);
    if (location != -1){
      str = str.substring(location,str.length);
      str = str.substring(0,str.search(/\[[\w\s,]*\]\.$/i))
      console.log(str)
      for (let key in list){
        if(key == str){
          return list[key];
        }
      }
    }
    return null;
  }
  //是否包含圆括号
  function getYKH (list,str) {
    let location = str.search(/[\w]+\([\w\s,]*\)\.$/i);
    if (location != -1){
      str = str.substring(location,str.length);
      str = str.substring(0,str.search(/\([\w\s,]*\)\.$/i))
      console.log(str)
      for (let key in list){
        if(key == str){
          return list[key];
        }
      }
    }
    return null;
  }
  function getNormal (list,str) {
    let location = str.search(/[\w]+\([\w\s,]*\)\.[\w]*$/i);
    let result = null;
    if (location != -1){  //匹配到有前缀方法   ()
      str = str.substring(location,str.length);
      if (str.search(/\.$/i)+1 == str.length){ //.后无字符
        return getYKH(list,str);
      }
      let tstr = str.substring(str.search(/\.[\w]+$/i)+1,str.length);
      str = str.substring(0,str.search(/\.[\w]+$/i));
      let res = getYKH(list,str);
      if(res != null){
        result = []
        for (let v in res){
          if (v.indexOf(tstr) == 0){
            result.push(v);
          }
        }
      }
      return result;
    }
    location = str.search(/[\w]+\[[\w\s]*\]\.[\w]*$/i);
    if (location != -1){  //匹配到有前缀方法   []
      str = str.substring(location,str.length);
      if (str.search(/\.$/i)+1 == str.length){ //.后无字符
        return getZKH(list,str);
      }
      let tstr = str.substring(str.search(/\.[\w]+$/i)+1,str.length);
      str = str.substring(0,str.search(/\.[\w]+$/i));
      let res = getYKH(list,str);
      if(res != null){
        result = []
        for (let v in res){
          if (v.indexOf(tstr) == 0){
            result.push(v);
          }
        }
      }
      return result;
    }
    location = str.search(/[\w]+\.$/i);
    if (location != -1){
      str = str.substring(location,str.length-1);
      result = []
      for (let v in list){
        if (v == str){
          result = list[v];
          break;
        }
      }
      return result;
    }
    location = str.search(/[\w]+$/i);
    if (location != -1){
      str = str.substring(location,str.length);
      result = []
      for (let v in list){
        if (v.indexOf(str) == 0){
          result.push(v);
        }
      }
      return result;
    }
    return result;
  }

  function dataList(cm){
    let customData = cm.options.hintOptions.tables;
    var hintList = { //提示的数据
      'g': ['V()','E()','has()','open()','close()','inV()','inE()','out()','outV()','outE()','label()','store()','next()','addVertex()','clazz()','limit()','traversal()','withBulk()','values()','schema()','except()','ifNotExist()','addEdge()','addVertex()','property()','io()','filter()','loops()','readGraph()','tree()','properties()','graph()','value()','bothE()','addV()','where()','hidden()','bothV()','withoutboth()','is()','path()','it()','get()','from()','to()','select()','otherV()','within()','inside()','outside()','withSack()'],
      'g()':[],
      'V':['limit()','length()'],
      'limit':['a()','b()','c()'],
      'targetLabel()':[],'sourceLabel()':[],'indexLabel()':[],'indexLabels()':[],'edgeLabel()':[],'vertexLabel()':[],'propertyKey()':[],'getPropertyKey()':[],'getVertexLabel()':[],'getEdgeLabel()':[],'getIndexLabel()':[],'getPropertyKeys()':[],'getVertexLabels()':[],'getEdgeLabels()':[],'getIndexLabels()':[],'coin()':[],'count()':[],'coalesce()':[],'createIndex()':[],'hasLabel()':[],'getLabelId()':[],'create()':[],'build()':[],'append()':[],'eliminate()':[],'remove()':[],'rebuildIndex()':[],'constant()':[],'isDirected()':[],'desc()':[],'inject()':[],'profile()':[],'simplePath()':[],'eq()':[],'neq()':[],'gt()':[],'gte()':[],'lt()':[],'lte()':[],'queryType()':[],'indexFields()':[],'frequency()':[],'links()':[],'type()':[],'in()':[],'on()':[],'by()':[],'checkDataType()':[],'checkValue()':[],'validValue()':[],'secondary()':[],'drop()':[],'search()':[],'makeEdgeLabel()':[],'cyclicPath()':[],'hasKey()':[],'match()':[],'sack()':[],'aggregate()':[],'between()':[],'baseType()':[],'baseValue()':[],'indexType()':[],'rebuild()':[],'choose()':[],'aggregate()':[],'iterate()':[],'lte()':[],'dedup()':[],'identity()':[],'groupCount()':[],'until()':[],'barrier()':[],'fold()':[],'unfold()':[],'schemaId()':[],'checkName()':[],'makeIndexLabel()':[],'makeVertexLabel()':[],'makePropertyKey()':[],'sideEffect()':[],'hasNext()':[],'toList()':[],'toSet()':[],'cap()':[],'option()':[],'branch()':[],'choose()':[],'repeat()':[],'emit()':[],'order()':[],'mean()':[],'withComputer()':[],'subgraph()':[],'getObjectsAtDepth()':[],'hasValue()':[],'hasNot()':[],'hasId()':[],'nullableKey()':[],'nullableKeys()':[],'sortKeys()':[],'link()':[],'singleTime()':[],'multiTimes()':[],'enableLabelIndex()':[],'userdata()':[],'checkExist()':[],'linkWithLabel()':[],'directed()':[],'idStrategy()':[],'primaryKeys()':[],'primaryKey()':[]
    }
    var cur = cm.getCursor(), token = cm.myGetTokenAt(cur) //重写getTokenAt()方法,返回一整行字符串
    let inputParam = token.text;
    let start = inputParam.search(/\.[\w]*$/i)
    let result = getNormal(hintList,inputParam);
    if (result != null) return [result,start];
    return []
  }

  CodeMirror.registerHelper('hint', 'zzzz', function (cm) {
    // 自动补全
    var list = dataList(cm)
    var cur = cm.getCursor(), //获取游标 eg.键盘输入aabb,cur的值为: {line: 0, ch: 4, sticky: null}
      token = cm.getTokenAt(cur); //示例token的值为: {start: 0, end: 4, string: "aabb", type: null, state: {…}}
    var start = token.start,
      end = cur.ch
    if (list.length>1){
      let v = list[1];
      list = list[0];
      if (v != -1)
        start = v + 1;
    }

    if (list.length) {
      return {
        list: list,
        from: CodeMirror.Pos(cur.line, start),
        to: CodeMirror.Pos(cur.line, end)
      }
    }
  })

  CodeMirror.defineMIME('text/x-zzzz', 'zzzz') //定义别名为text/x-zzzz
})

2.获取整行字符串 codemirror.js 文件。

3.如果匹配结果只剩下一个的时候,默认会自动填充。有些时候确实不是我们想要的操作。

修改操作,编辑show-hint.js文件,注释这几行代码。

代码项目:https://download.csdn.net/download/qq_38865022/12058109

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值