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
    评论
`CodeMirror` 和 `react-codemirror2` 是两个用于创建交互式代码编辑器的库,结合使用它们可以在 React 应用中实现强大的代码提示功能。以下是使用这两个库实现代码提示的一般步骤: 1. 安装依赖: - 首先,你需要安装 `codemirror` 和 `react-codemirror2`,可以通过 npm 或 yarn 进行安装: ``` npm install codemirror react-codemirror2 ``` 2. 引入组件: 在你的 React 组件中,引入 `CodeMirror` 和 `Editor` 组件: ```jsx import { Editor } from 'react-codemirror2'; import 'codemirror/mode/javascript/javascript'; import 'codemirror/addon/lint/lint'; import 'codemirror/addon/lint/javascript-lint'; ``` 3. 设置配置选项: 创建一个 CodeMirror 的配置对象,其中包含 `lint` 和 `autocompletion` 配置: ```jsx const CodeEditor = ({ value, onChange }) => { const options = { lineNumbers: true, mode: 'javascript', theme: 'abcdef', // 选择你喜欢的主题 lintWith: 'eslint', // 使用 ESLint 作为 lint 工具 completion: { hint: CodeMirror.hint.bracketedCompletion, // 自动补全功能 }, }; return ( <Editor value={value} options={options} onChange={onChange} spellCheck={true} // 如果需要启用拼写检查 /> ); }; ``` 4. 实现自动提示: - `completion` 配置中的 `hint` 属性指定了 CodeMirror 使用哪种类型的提示。`bracketedCompletion` 是一种常用的提示类型,它会在输入后显示可能的代码片段。 5. 使用和初始化: 在你的组件中初始化 `CodeEditor` 组件,并提供初始代码值和 onChange 回调,用于处理用户输入改变后的操作: ```jsx const [code, setCode] = useState(''); // 初始化代码 const handleCodeChange = (newCode) => { setCode(newCode); // 如果需要,你可以在这里处理自动补全结果或发送到服务器进行实时建议 }; return ( <CodeEditor value={code} onChange={handleCodeChange} /> ); ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值