CodeMirror实现自定义提示功能增强版(支持搜索、调用接口查询提示内容)

之前在《CodeMirror实现自定义提示功能》中介绍过CodeMirror实现自定义提示功能的一种实现方式,但是之前的实现有一些局限性,主要是:1、需要提示的内容是从variablePool中读取的,需要先确定variablePool;2、提示的内容需要一个个去选择,不支持搜索功能。

本文提供了一种解决上述两个问题的实现方式,不同的主要是handleShowHint这个方法,修改了一些提示逻辑。具体代码如下:

handleShowHint() {
  const {modelData, modelPointsAttributes} = this.props.configureStore;
  const modelDataList = modelData.map(item => (item.modelId));
  const codeMirrorInstance = this.codeEditorRef.getCodeMirrorInstance();
  const cur = this.codeEditor.getCursor();
  const curLine = this.codeEditor.getLine(cur.line);
  const end = cur.ch;
  const start = end;
  let list = [];
  // 根据不同情况给list赋值,默认为[],即不显示提示框。
  const cursorTwoCharactersBefore = `${curLine.charAt(start - 2)}${curLine.charAt(start - 1)}`;
  if (cursorTwoCharactersBefore === '${') {
    list = modelDataList;
  } else if (cursorTwoCharactersBefore === '::') {
    const lastIndex = curLine.lastIndexOf('${', start);
    const modelId = curLine.substring(lastIndex + 2, start - 2);
    if (modelPointsAttributes[modelId]) {
      list = modelPointsAttributes[modelId];
    } else {
      list = [];
      this.props.configureStore.getModelPointsAttributes(modelId, this.handleHint);
    }
  } else {
    const lastStartIndex = curLine.lastIndexOf('${', start);
    const lastEndIndex = curLine.lastIndexOf('}', start);
    const lastColonIndex = curLine.lastIndexOf('::', start);

    if (start > lastStartIndex && (start <= lastColonIndex || lastColonIndex < lastStartIndex)) {
      const modelId = curLine.substring(lastStartIndex + 2, start);
      list = modelDataList.filter(item => (item.indexOf(modelId) !== -1));
      // eslint-disable-next-line
      return {list, from: codeMirrorInstance.Pos(cur.line, lastStartIndex + 2), to: codeMirrorInstance.Pos(cur.line, end)};
    } else if (start > lastStartIndex && start > lastColonIndex && (start <= lastEndIndex || (lastEndIndex < lastColonIndex && lastEndIndex < lastStartIndex))) {
      const modelId = curLine.substring(lastStartIndex + 2, lastColonIndex);
      const pointAttrId = curLine.substring(lastColonIndex + 2, start);
      if (modelPointsAttributes[modelId]) {
        list = modelPointsAttributes[modelId].filter(item => (item.indexOf(pointAttrId) !== -1));
        // eslint-disable-next-line
        return {list, from: codeMirrorInstance.Pos(cur.line, lastColonIndex + 2), to: codeMirrorInstance.Pos(cur.line, end)};
      }
    }
  }
  // eslint-disable-next-line
  return {list, from: codeMirrorInstance.Pos(cur.line, start), to: codeMirrorInstance.Pos(cur.line, end)};
}

实现中使用如下代码请求所选模型下点:

this.props.configureStore.getModelPointsAttributes(modelId, this.handleHint);

具体实现在mobx的store中,不再贴相应代码。

需要注意的是:

  • 我在项目里使用了mobx管理state,发请求的位置在store中,不在组件内,所以通过回调函数的形式当接口数据成功返回后调用this.handleHint来进行提示;
  • 需要注意提供正确的提示框的位置,类似于下边的形式:
{list, from: codeMirrorInstance.Pos(cur.line, lastColonIndex + 2), to: codeMirrorInstance.Pos(cur.line, end)};
  • codemirror提供了一种基于Promise的异步提示方式,因为我发请求的操作不在组件里,所以没有使用,在可以的情况下,Promise的实现应该会更合适。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在Vue-Codemirror实现代码提示,你需要使用Codemirror的autocomplete插件。首先,你需要在你的Vue组件中引入Codemirror和autocomplete插件: ```javascript import 'codemirror/lib/codemirror.css' import 'codemirror/theme/material.css' import 'codemirror/mode/javascript/javascript.js' import 'codemirror/addon/hint/show-hint.css' import 'codemirror/addon/hint/show-hint.js' import 'codemirror/addon/hint/javascript-hint.js' ``` 接着,在你的组件模板中,你需要在codemirror标签中添加一个v-on:keyup事件,以便触发自动完成: ```html <template> <div> <codemirror v-model="code" :options="editorOptions" @keyup="handleKeyup"></codemirror> </div> </template> ``` 在你的组件中,你需要添加一个handleKeyup方法,该方法将检查光标位置,并在需要时显示自动完成建议: ```javascript methods: { handleKeyup(cm, event) { const cursor = cm.getCursor() const token = cm.getTokenAt(cursor) if (token.type === 'tag') { cm.showHint({ hint: CodeMirror.hint.javascript, completeSingle: false }) } } } ``` 这个方法检查光标位置的token类型,如果是一个标签,就显示自动完成建议。在这个例子中,我们使用了javascript-hint插件,它提供了JavaScript的自动完成建议。你可以根据你的代码语言使用不同的自动完成插件。 最后,你需要定义一个editorOptions对象,该对象将包含Codemirror的选项和autocomplete选项: ```javascript data() { return { code: '', editorOptions: { mode: 'javascript', theme: 'material', lineNumbers: true, extraKeys: { 'Ctrl-Space': 'autocomplete' } } } } ``` 在这个例子中,我们将Codemirror的mode设置为JavaScript,使用了material主题,启用了行号,并为Ctrl-Space键绑定了自动完成功能。 希望这能帮助你在Vue-Codemirror实现代码提示

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值