LingYanSi / blog

博客
https://github.com/LingYanSi/blog/issues
9 stars 0 forks source link

Code Editor Ace #34

Open LingYanSi opened 7 years ago

LingYanSi commented 7 years ago

ace is great!!!

fuck ace
LingYanSi commented 7 years ago

Ace

Ace作为比较流行的web编辑器,其使用也很简单:把相关文件clone到本地,然后按照教程,设置下相关配置即可。 不过这次,在mock项目中,不想使用requirejs,也不想把大量其他文件clone到本地,本着爱之求真的原则,一脚踩到坑,花费了几天时间,才配置好,真当是日了狗。 Fuck

LingYanSi commented 7 years ago

首先来说,Ace有两种类型的源文件,require类型(依赖requirejs),与非require类型(直接在html中引用相关js即可) qq 20160725115542

LingYanSi commented 7 years ago

这一次,我用的是非require类型文件 语法高亮/设置主题这些都很轻易的解决了,但是当面对语法校验的时候,却出现了问题 baidu/google/stackoverflow无果,貌似这是一个很简单,甚至很傻逼的问题

没办法,只有硬着头皮,尝试着去debug,终于发现Ace的语法校验使用的是web worker 通过Worker去加载相关的worker-json.js文件 然后又发现,文件路径是可以用户自己定义配置的

ace.require("ace/config").set("workerPath", '/js/ace/'); // 会自动添加后缀变成/ja/ace/worker-json.js

Mon Jul 10 2017 15:34:29 GMT+0800 (CST) 依据文档描述,ace也可以以非requrie形式引用 使用也很简单

git clone https://github.com/ajaxorg/ace.git
cnpm i
node ./Makefile.dryice.js -nc
cp -r build/src-noconflict/  /your/static/dir/path

附一个react组件

/**
* 使用ace的代码编辑器
* 已开启语法校验、自动补全、语言高亮、自带搜索、代码高度自动展开
*/

import { Component } from 'react'
import { loadScript } from 'ly'

export default class extends Component {
    static defaultProps = {
        language: 'javascript',
        content: '',
        readOnly: false,
        onChange: () => {},
        width: 'auto',
        height: 'auto',
    }
    componentDidMount() {
        this.setAce(this.props)
    }
    shouldComponentUpdate() {
        // 一直不更新
        return false
    }
    componentWillUnmount() {
        const { editor } = this
        if (editor) {
            editor.destroy();
            editor.container.remove();
        }
    }
    setAce(options) {
        loadScript('/lib/js/ace/ace.js').then(sucess => {
            loadScript(
                `/lib/js/ace/mode-${options.language}.js`, // 使用javascript
                '/lib/js/ace/theme-twilight.js', // 主题
                '/lib/js/ace/ext-searchbox.js', // 添加搜索扩展
                '/lib/js/ace/ext-language_tools.js',
            ).then(s => {
                const { ace } = window
                // 创建一个编辑器
                const editor = this.editor = ace.edit(this.refs.editor)

                // 使用js模式
                const JavaScriptMode = ace.require(`ace/mode/${options.language}`).Mode
                editor.session.setMode(new JavaScriptMode())

                editor.setTheme('ace/theme/twilight') // 设置主题

                editor.getSession().setTabSize(4)
                editor.getSession().setUseWrapMode(true)

                editor.renderer.setPadding(10, 10) // 设置padding
                editor.renderer.setScrollMargin(10, 10) // 设置margin
                // 设置行数
                editor.setOptions({
                    readOnly: options.readOnly, // 是否只读
                    minLines: 20, // 最小行数
                    maxLines: Infinity, //高度自适应
                    enableBasicAutocompletion: true, //开启基础自动补全
                    enableLiveAutocompletion: true, // 开启实时自动补全
                    enableSnippets: true, // 启用代码片段
                })

                editor.$blockScrolling = Infinity
                editor.setValue(options.content)

                editor.navigateFileEnd() // 设置光标到文件末尾
                editor.focus()

                !options.readOnly && editor.on('change', (e) => {
                    options.onChange(editor.getValue()) // 触发数据更新
                })
            })
        })
    }
    render() {
        const { width, height } = this.props
        return <div ref="editor" style={{width, height}}></div>
    }
}
LingYanSi commented 7 years ago
// ace编辑器设置
        var editor = ace.edit("editor")
        editor.setTheme("ace/theme/twilight")
        // mode/json依赖worker-json 因此需要在前面配置
        ace.require("ace/config").set("workerPath", '/js/ace/');

        editor.getSession().setMode('ace/mode/json')
        editor.$blockScrolling = Infinity

        // 编辑器配置 https://github.com/ajaxorg/ace/wiki/Configuring-Ace
        editor.setOptions({
                maxLines: Infinity, // 自适应高度
                minLines: 10, // 最小高度
                wrap: 'free', // 换行模式
            });

        let data = JSON.parse(this.state.data)
        // 4设置空格
        data = JSON.stringify(data, null , 4)
        editor.setValue(data)

        editor.focus()
        // 设置光标位置
        editor.gotoLine(6, 15)
        // 监听变化
        editor.session.on('change', ()=>{
            this.setState({
                data: editor.getValue()
            })
        })js
LingYanSi commented 7 years ago

codemirror

Github 这哥们儿看起来也不错,待考察