如何使用自定义模式在 Ace Editor 中集成语法检查?

Posted

技术标签:

【中文标题】如何使用自定义模式在 Ace Editor 中集成语法检查?【英文标题】:How to integrate syntax check in Ace Editor using custom mode? 【发布时间】:2015-09-07 14:01:00 【问题描述】:

我是 ace-editor 的新手,我已经包含自定义模式来验证我的代码,并且每一行都应该以分号结尾,如果分号错误地出现在我的查询中,那么编辑器应该放弃类似“缺少分号”。

define('ace/mode/javascript-custom', [], function(require, exports, module) 

  var oop = require("ace/lib/oop");
  var TextMode = require("ace/mode/text").Mode;
  var Tokenizer = require("ace/tokenizer").Tokenizer;
  var ExampleHighlightRules = require("ace/mode/example_highlight_rules").ExampleHighlightRules;

  var Mode = function() 
    this.HighlightRules = ExampleHighlightRules;
  ;
  oop.inherits(Mode, TextMode);

  (function() 
    this.lineCommentStart = "--";
    this.blockComment = 
      start: "->",
      end: "<-"
    ;
  ).call(Mode.prototype);

  exports.Mode = Mode;
);

define('ace/mode/example_highlight_rules', [], function(require, exports, module) 
  var oop = require("ace/lib/oop");
  var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;

  var ExampleHighlightRules = function() 

    var keywordMapper = this.createKeywordMapper(
      "variable.language": "this",
      "keyword": "one|two",
      "constant.language": "true|false|null"
    , "text", true);

    this.$rules = 
      "start": [
        token: "comment",
        regex: "->",
        next: [
          regex: "<-",
          token: "comment",
          next: "start"
        , 
          defaultToken: "comment"
        ]
      , 
        regex: "\\w+\\b",
        token: keywordMapper
      , 
        token: "comment",
        regex: "--.*"
      , 
        token: "string",
        regex: '"',
        next: [
          regex: /\\./,
          token: "escape.character"
        , 
          regex: '"',
          token: "string",
          next: "start"
        , 
          defaultToken: "string"
        ]
      , 
        token: "numbers",
        regex: /\d+(?:[.](\d)*)?|[.]\d+/
      ]
    ;
    this.normalizeRules()
  ;

  oop.inherits(ExampleHighlightRules, TextHighlightRules);

  exports.ExampleHighlightRules = ExampleHighlightRules;

);

var langTools = ace.require("ace/ext/language_tools");
var editor = ace.edit("editor");

editor.session.setMode("ace/mode/javascript-custom");
editor.setOptions(
  enableBasicAutocompletion: true,
  enableLiveAutocompletion: true
);
editor.setTheme("ace/theme/monokai");
var lines = editor.session.doc.getAllLines();
var errors = [];

for (var i = 0; i < lines.length; i++) 
  if (/[\w\d(['"]/.test(lines[i])) 
    alert("hello");
    errors.push(
      row: i,
      column: lines[i].length,
      text: "Missing Semicolon",
      type: "error"
    );
  
<script src="https://ajaxorg.github.io/ace-builds/src/ext-language_tools.js"></script>
<script src="https://ajaxorg.github.io/ace-builds/src/ace.js"></script>
<div id="editor" style="height: 200px; width: 400px"></div>
<div id="commandline" style="position: absolute; bottom: 10px; height: 20px; width: 800px;"></div>

更新:

以下 js 文件从 ace 生成并添加到我的 rails 应用程序中,这些文件已加载到 rails 应用程序中,但功能(分号检查)似乎不起作用。

worker-semicolonlineend - http://pastebin.com/2kZ2fYr9 模式分号线结束 - http://pastebin.com/eBY5VvNK

更新:

    在 ace 编辑器中,分别在第 1 行和第 2 行输入 query1、query2 第三行留空 现在在第四行,键入一个末尾不带分号的查询,x 标记出现在第三行 5 并且当第五行也没有分号时,则在第四次查询时显示x标记

【问题讨论】:

【参考方案1】:

Ace 编辑器默认广泛支持 JavaScript 的这种分析:

#editor 
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
<div id="editor">function foo()  ; // unnessesary semicolon
    var x = "bar" // missing semicolon 
    return x; // semicolon in place

</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.9/ace.js" type="text/javascript"></script>
<script>
 var editor = ace.edit("editor");
 editor.setTheme("ace/theme/monokai");
 editor.getSession().setMode("ace/mode/javascript");
</script>

只需确保工作文件worker-javascript.js 可用于您的代码。在上面的代码 sn-p 中,我使用 CDN 来构建 Ace,因此 worker 始终可用。可以配置JSHintvia worker options。

更新:但如果真的需要除此之外的东西,您将需要按照我的理解执行以下操作:

    Create Worker and Mode 给你分析一下 下载Ace source code并安装NodeJS 将新文件放入对应的 Ace 源代码文件夹中 Build Ace 将构建文件添加到您的项目中 使用新模式:editor.getSession().setMode("ace/mode/semicolonlineend");

执行行尾检查的工人看起来像这样:

define(function(require, exports, module) 
"use strict";

var oop = require("../lib/oop");
var Mirror = require("../worker/mirror").Mirror;

var SemicolonLineEndCheckWorker = exports.SemicolonLineEndCheckWorker = function (sender) 
    Mirror.call(this, sender);
    this.setTimeout(500);
    this.setOptions();
;

oop.inherits(SemicolonLineEndCheckWorker, Mirror);

(function() 

    this.onUpdate = function () 
        var text = this.doc.getValue();
        var lines = text.replace(/^#!.*\n/, "\n").match(/[^\r\n]+/g);

        var errors = [];

        for (var i = 0; i < lines.length; i++) 
            var lastLineCharacter = lines[i].trim().slice(-1);
            if (lastLineCharacter === ';')
                continue;

            errors.push(
                row: i,
                column: lines[i].length-1,
                text: "Missing semicolon at the end of the line",
                type: "warning",
                raw: "Missing semicolon"
            );

        

        this.sender.emit("annotate", errors);
    ;

).call(SemicolonLineEndCheckWorker.prototype);

);

使用工作者的新模式:

define(function(require, exports, module) 
"use strict";

var oop = require("../lib/oop");
var TextMode = require("./text").Mode;

var Mode = function()  ;
oop.inherits(Mode, TextMode);

(function() 

    this.createWorker = function(session) 
        var worker = new WorkerClient(["ace"], "ace/mode/semicolonlineend_worker", 
            "SemicolonLineEndCheckWorker");
        worker.attachToDocument(session.getDocument());

        worker.on("annotate", function(results) 
            session.setAnnotations(results.data);
        );

        worker.on("terminate", function() 
            session.clearAnnotations();
        );

        return worker;
    ;

    this.$id = "ace/mode/semicolonlineend";
).call(Mode.prototype);

exports.Mode = Mode;
);

【讨论】:

我尝试将js文件加载到rails assets中,出现404 not found错误,如何在rails assets pipeline中加载这些文件? @M.R 什么文件没有找到?您包含的文件是否在 RoR 应用程序之外工作?有detailed guide和相关的SOquestion 我尝试从公用文件夹加载 js 文件,出现以下错误 NetworkError: 404 Not Found -localhost:3000/javascripts/mode-semicolonlineend.js" but precompiled assets file ("/assets/mode-semicolonlineend.self-95f9750784a4318e4229fe5c5fb2188a4952fa721854c4d06c24de6 body=1") 存在查看页面:ace.config.set("basePath", "/javascripts"); editor.session.setMode("semicolonlineend"); @M.R 为什么需要从公用文件夹加载它?您提供指向不同文件的链接,第二个文件的名称末尾包含哈希。链接到您的 js 文件需要由 Sprockets 解析 现在我将构建 js 文件添加到 assets 文件夹中,并调用了 basePath,例如“ace.config.set("basePath", "/assets/javascripts");"现在在视图文件中加载了 js 文件,但分号功能似乎不起作用

以上是关于如何使用自定义模式在 Ace Editor 中集成语法检查?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Ace 代码编辑器在运行时添加新的突出显示规则?

如何在 iOS 的自定义 ViewController 中集成 Firebase 通知?

Laravel:在自定义登录中集成 Throttle

Ace-Editor JSON 自动格式/缩进

给定文件扩展名,如何为 Ace Editor 自动选择“模式”

微服务专题之.Net6中集成消息队列-RabbitMQ中直接路由模式