12

I'm new to ace-editor and I have included custom mode to validate my code and every line should end up with semicolon, If semicolon is not present in my query by mistake then the editor should gives up the warning like "Missing Semicolon".

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>

UPDATE:

The following js files are generated from ace and added to my rails application, the files are loaded in rails app but the functionality (semicolon check) doesn't seem to be working.

worker-semicolonlineend - http://pastebin.com/2kZ2fYr9 mode-semicolonlineend - http://pastebin.com/eBY5VvNK

Update:

  1. In ace editor, type in a query1, query2 in line 1 and line 2 respectively
  2. Leave the third line blank
  3. Now in fourth line, type a query without semicolon in the end, x mark appears in third line 5 And when the fifth line is also without a semicolon, then the x mark is displayed at fourth query

enter image description here

M.R
  • 610
  • 2
  • 10
  • 34

1 Answers1

4

Ace editor widely support this kind analysis for JavaScript by default:

#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>

Just make sure that worker file worker-javascript.js is available for your code. In code snippet above I use CDN to get Ace build, so worker is always available. You can configure JSHint via worker options.

Update: But if really need something beyond that you will need to do the following as my understanding goes:

  1. Create Worker and Mode for you kind of analysis
  2. Download Ace source code and install NodeJS
  3. Put your new files within correspond Ace source code folders
  4. Build Ace
  5. Add build files to your project
  6. Use new mode: editor.getSession().setMode("ace/mode/semicolonlineend");

Worker that perform line ending check will look something like that:

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);

});

New mode that uses worker:

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;
});
Leonid Vasilev
  • 11,910
  • 4
  • 36
  • 50
  • I tried to load js files into rails assets, it gives 404 not found error, how to load those files in rails asset pipeline? – M.R Jul 18 '15 at 06:56
  • @M.R what file is not found? Do files that you include work outside of RoR application? There are [detailed guide](http://guides.rubyonrails.org/asset_pipeline.html) and related SO [question](http://stackoverflow.com/questions/22158464/ace-editor-with-rails-4-precompiled-assets-madness) – Leonid Vasilev Jul 18 '15 at 07:46
  • I tried to load js files from public folder, got following error NetworkError: 404 Not Found -http://localhost:3000/javascripts/mode-semicolonlineend.js" but precompiled asset file ("/assets/mode-semicolonlineend.self-95f9750784a4318e4229fe5c5fb2188a4952fa721854c4d06c246deb6c4c94dd.js?body=1") is present View page: ace.config.set("basePath", "/javascripts"); editor.session.setMode("semicolonlineend"); – M.R Jul 18 '15 at 08:39
  • @M.R why you need to load it from public folder? You provide links to different files, the second one contain hash at the end of the name. Link to your js-file need to be resolved by Sprockets – Leonid Vasilev Jul 18 '15 at 08:44
  • Now I added build js files into assets folder and I called basePath like "ace.config.set("basePath", "/assets/javascripts");" in view file now the js files get loaded but the semicolon functionality doesn't seems to be work – M.R Jul 18 '15 at 08:56
  • I suspect that the Update function doesn't called in mode-semicolonlineend.js if I type some text in editor – M.R Jul 18 '15 at 09:30
  • @M.R. I suggest you to use debugger to make sure what exactly is happening and post your new Ace initialization code – Leonid Vasilev Jul 18 '15 at 11:03
  • I found sample rails app here - https://github.com/phstc/putsreq, appreciate your help Thanks a lot – M.R Jul 21 '15 at 10:15
  • The ace editor functionality for semicolon missing is not working the following scenario: 1. Enter the text in first line 2. Enter a new line without text 3. Repeat the step 2 4. Now enter the text in third line Currently the X marker is shown in the second line instead of third line. I have attached the screenshot too. Kindly help me to sort this out. – M.R Jul 28 '15 at 06:46
  • I have updated the ticket. Please take a look at it. – M.R Jul 28 '15 at 06:52
  • @M.R it's not a ticket, it'a a question :) I will take a look at it a bit later, looks like similar issues occur in build syntax check – Leonid Vasilev Jul 29 '15 at 14:29
  • I got answer from another question which I have posted - http://stackoverflow.com/questions/31673978/empty-line-in-ace-editor-shows-x-mark-in-custom-mode – M.R Jul 30 '15 at 06:23
  • @LeonidVasilev - could you please take a look at https://stackoverflow.com/questions/60857214/uncaught-domexception-failed-to-execute-importscripts-on-workerglobalscope – Manu Chadha Mar 26 '20 at 10:12