CodeMirror实现自定义提示功能

我之前在文章《CodeMirror基本使用及实现关键词高亮、自定义主题》中简单介绍了CodeMirror实现自动提示的功能,但是使用的是CodeMirror中封装好的几种指定语法的提示功能,如css、html、js、sql、xml,对应文件如下列表:

现在我开发中有需求做自定义语法的自动提示功能,并没有现成的mode可以使用,学习CodeMirror API和上述几个文件的实现方式之后找到了实现方法,记录一下我的实现方式。

本文以${model::point}为例,需求是输入${后直接出现下拉框,提示内容是所有的model,当选择或输入model后,输入::直接出现下拉框,提示内容为${后::前model里所有的point和attribute,在${和::后点击Ctrl,也出现和上面相同的提示信息。

要提示的数据举例如下:

 

{
    "model_a":{
        "points":[
            "point_a1",
            "point_a2",
            "point_a3"
        ],
        "attributes":[
            "attribute_a1",
            "attribute_a2",
            "attribute_a3"
        ]
    },
    "model_b":{
        "points":[
            "point_b1",
            "point_b2",
            "point_b3"
        ],
        "attributes":[
            "attribute_b1",
            "attribute_b2",
            "attribute_b3"
        ]
    }
}

 要实现的效果如下:

实现方式:

import React, {Component} from 'react';
import autobind from 'class-autobind';
import {inject, observer} from 'mobx-react';
import CodeMirror from 'react-codemirror';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/anyword-hint.js';
import 'codemirror/lib/codemirror.css';
import './index.less';

@inject('configureStore')
@observer
export default class CodeEditor extends Component {
    constructor(props) {
        super(props);
        autobind(this, CodeEditor.prototype);
        this.options = {
            lineNumbers: false,
            // mode: {name: "text/x-mysql"},
            extraKeys: {"Ctrl": "autocomplete"},
            theme: 'sqlTheme',
            lineWrapping:true,
            hintOptions: {hint: this.handleShowHint, completeSingle: false}
        };
    }
    componentDidMount(){
        this.codeEditor = this.codeEditorRef.getCodeMirror();
    }

    handleShowHint(){
        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)}`;
        const {activeItem, openedItemsData} = this.props.configureStore;
        const {variablePool} = openedItemsData[activeItem].config;
        const variablePoolKeys = variablePool ? Object.keys(variablePool): [];
        if(cursorTwoCharactersBefore === '${'){
            list = variablePoolKeys;
        }else if(cursorTwoCharactersBefore === '::'){
            const lastIndex = curLine.lastIndexOf('${', start);
            const modelId = curLine.substring(lastIndex + 2, start - 2);
            if(lastIndex !== -1 && modelId && variablePool[modelId]){
                list = variablePool[modelId].attributes.concat(variablePool[modelId].points);
            }else {
                list = [];
            }
        }
        return {list: list, from: codeMirrorInstance.Pos(cur.line, start), to: codeMirrorInstance.Pos(cur.line, end)};
    }
    handleCodeChange(value){
        this.codeEditor.closeHint();
        this.codeEditor.showHint();
        this.props.onChange(value);
    }

    render() {
        return (
            <CodeMirror
                ref={ref => this.codeEditorRef = ref}
                value={this.props.value}
                onChange={this.handleCodeChange}
                options={this.options}
            />
        );
    }
}

demo中使用了mobx管理state,variablePool是从configureStore中读取的。

更新:这里介绍的方式需要提前准备好提示的内容,且不支持搜索,只能选择。在《CodeMirror实现自定义提示功能增强版(支持搜索、调用接口查询提示内容)》里更新了一个增强版,可以支持所有和调用接口查询提示数据。

 

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
vue-codemirror6是一个基于Vue.js的代码编辑器组件,它内置了一些默认的代码补全功能,但如果想要进行自定义代码补全,可以按照以下步骤进行操作。 首先,需要明确自定义代码补全的需求,确定需要补全的关键字、语法以及对应的代码片段。 然后,在Vue组件中引入vue-codemirror6,并配置相应的属性和事件。可以通过设置"options"属性来添加自定义代码补全功能。在"options"中,可以使用"hintOptions"属性来设置代码补全提示的选项。可以设置"hint"为一个函数,该函数将在触发代码补全时被调用。在这个函数中,可以编写逻辑来根据输入的关键字返回相应的补全列表。 接下来,在"hint"函数中,可以使用CodeMirror提供的API来实现自定义代码补全功能。例如使用CodeMirror的registerHelper方法来注册一个自定义代码补全帮助函数,用于提供自定义的补全列表。 在自定义代码补全帮助函数中,可以根据输入的关键字和语法,进行匹配和筛选,返回需要补全的代码片段列表。可以根据需要,展示提示头、提示详情等信息,并对选择的补全项进行相应的处理和插入。 最后,在Vue组件中监听相应的事件,例如"input"事件,根据用户输入的关键字,触发代码补全的逻辑。可以借助CodeMirror提供的API来显示和隐藏代码补全的列表,并根据用户选择的补全项进行相应的插入操作。 综上所述,通过以上步骤可以在vue-codemirror6中实现自定义代码补全功能。根据具体需求,可以定制补全的关键字、语法代码片段,提升代码编辑的效率和准确性。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值