• 用ACE来写代码


    写在前面

    在很多时候,我们想用一个支持高亮的WEB编辑器来做规则配置、代码编辑等,此时ACE应该是一个不错的选择,简单的用法如下:

    <!DOCTYPE html>
    <html lang="cn">
    <head>
    <title>ACE in Action</title>
    <style type="text/css" media="screen">
        #editor { 
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
        }
    </style>
    </head>
    <body>
    
    <div id="editor">function foo(items) {
        var x = "All this is syntax highlighted";
        return x;
    }</div>
        
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js" type="text/javascript" charset="utf-8"></script>
    <script>
        var editor = ace.edit("editor");
        editor.setTheme("ace/theme/monokai");
    </script>
    </body>
    </html>
    

    打开这个网页会发现整个网页都是一个编辑器,不过此时没有任何高亮效果,需要自己来编辑(当然大部分情况下可以用现成的)。

    个性化

    在ACE中设置个性化时需要考虑三个方面:

    1. 高亮
    2. 折叠
    3. 缩进
    4. 代码提示

    这三块在ACE中保存在一个Mode中,这里是一个JavaScript的例子,如果想在代码中使用那么需要:

    editor.getSession().setMode("ace/mode/javascript");

    那么接下来的任务就是学习如何设置了。

    高亮

    在ACE中通过状态机来配置高亮,而高亮的实现则是将文本放在<span class="ace_token_name">标签中,文字展示成什么样子可以自己来进行修改:

    执行过程中不断地从当前状态的规则集中找到匹配的regex,之后会跳转到next状态,如果要将多个token合并处理可以用merge:true来实现。在大部分的语言中有N多的关键字,如果一个一个写的话会比较辛苦,此时可以考虑使用createKeywordMapper来做。在ACE中没有Drools现成的模板,自己定义一个如下:

    ace.define("ace/mode/drools_highlight_rules", function(require, exports, module) {
    	"use strict";
    	var oop = require("../lib/oop");
    	var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
    	var DroolsHighlightRules = function(){
    		var keywordMapper = this.createKeywordMapper({
    			"keyword":
    				"when|then|rule|end|salience"
    		}, "identifier");
    		this.$rules = {
    			"start" :[{
    				token : keywordMapper,
    				regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\b"
    			}]
    		};
    	};
    	oop.inherits(DroolsHighlightRules, TextHighlightRules);
    	exports.DroolsHighlightRules = DroolsHighlightRules;
    });
    
    ace.define("ace/mode/drools", function(require, exports, module) {
    	"use strict";
    	var oop = require("../lib/oop");
    	var TextMode = require("./text").Mode;
    	var DroolsHighlightRules = require("./drools_highlight_rules").DroolsHighlightRules;
    	var DroolsMode = function(){
    		this.HighlightRules = DroolsHighlightRules;
    	};
    	oop.inherits(DroolsMode, TextMode);
    	(function() {
    		this.$id = "ace/mode/drools"
    	}).call(DroolsMode.prototype),
    	exports.Mode = DroolsMode;
    });
    

    在HTML代码中引入写的文件(当然也可以使用require来做),如果想要关键字加粗在页头加入.ace_keyword{font-weight:bold}即可,效果如下:

    这里有一个完整的JSON的高亮配置。

    缩进

    自定义缩进是通过自定义Mode中的getNextLineIndent方法来实现的,如果要实现类似C/C++/JAVA这种在后面有{的时候下面缩进,那么加上下面这段即可:

    	(function(){
    		this.getNextLineIndent = function(state, line, tab) {// 状态、当前行、缩进符号
    			var indent = this.$getIndent(line);
    			if (state == "start") {
    				var match = line.match(/^.*[{([]s*$/); // 如果是{[(结尾的,那么下一行的缩进加一
    				if (match) {
    					indent += tab;
    				}
    			}
    			return indent;
    		};
    	}).call(DroolsMode.prototype);
    

    每次有新的一行产生getNextLineIndent的返回值会被放在前面,从而形成缩进的效果。

    折叠

    在ACE中定义了一个对象Range用来标记范围:new Range(Number startRow, Number startColumn, Number endRow, Number endColumn)。其中:

    1. startRow、startColumn:开始位置。
    2. endRow、endColumn:结束位置。

    那么在实现折叠方法的时候只要实现两个方法即可:getFoldWidget折叠开始的地方)和getFoldWidgetRange折叠范围),在drools中比较简单的一种折叠是将rule....end之间的部分隐藏掉,那么可以创建一个FoldMode如下:

    ace.define("ace/mode/folding/drools_fold", function(require, exports, module) {
    	"use strict";
    	var Range = require("../../range").Range;
    	var FoldMode = exports.FoldMode = function() {};
    	(function() {
    		this.getFoldWidget = function(session, foldStyle, row) {
    			var line = session.getLine(row);
    			if (line == "rule")
    				return "start";
    			return "";
    		};
    		this.getFoldWidgetRange = function(session, foldStyle, row) {
    			var startRow = row, startColumn = 4;
    			var endRow = row+1, endColumn = 3;
    			while(session.getLine(endRow) != "end"){
    				endRow += 1;
    			}
    			return new Range(startRow, startColumn, endRow, endColumn);
    		};
    	}).call(FoldMode.prototype);
    });
    

    然后要让其生效的话需要drools对应的总Mode中设置其为foldingRules即可,如下:

    var DroolsFoldMode = require("ace/mode/folding/drools_fold").FoldMode;
    var DroolsMode = function(){
    	this.foldingRules = new DroolsFoldMode();
    };
    

    在ace中提供了一个基本的折叠模块:fold_mode支持折叠相同的缩进部分等,如果需要直接继承即可。

    代码提示

    ----- update -----

  • 相关阅读:
    Ubuntu16.04 Jupyter安装(Ipython Notebook安装)
    爬虫.requests.exceptions.ConnectionErro
    预习非数值数据的编码方式
    预习(原码,补码,移码)+作业
    C语言ll作业01
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
    C语言1博客作业12
  • 原文地址:https://www.cnblogs.com/antispam/p/4222337.html
Copyright © 2020-2023  润新知