Skip to content

Commit

Permalink
feat: add highlight mode for Apache JEXL (#4979)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkslanc authored Nov 2, 2022
1 parent 0c49167 commit 4e8926e
Show file tree
Hide file tree
Showing 5 changed files with 338 additions and 0 deletions.
20 changes: 20 additions & 0 deletions demo/kitchen-sink/docs/jexl.jexl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma execution.option 42

##
## This is a test script
##

/* This is
a multi-line
comment
*/
if (out != null and result == null) out.println("The result is " + result);
x = ~/\w+\/test/;
y = 2;
result = x * y + 5;
if (out != null) out.println("The result is " + result);

@lenient @silent x.someMethod();

`multi-line string
with ${var interpolation = "Hey!"} and \escap\u00E9 chars`
1 change: 1 addition & 0 deletions src/ext/modelist.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ var supportedModes = {
Jade: ["jade|pug"],
Java: ["java"],
JavaScript: ["js|jsm|jsx|cjs|mjs"],
JEXL: ["jexl"],
JSON: ["json"],
JSON5: ["json5"],
JSONiq: ["jq"],
Expand Down
156 changes: 156 additions & 0 deletions src/mode/_test/tokens_jexl.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
[[
"start",
["comment","#pragma"],
["text"," execution.option 42"]
],[
"start"
],[
"start",
["comment","##"]
],[
"start",
["comment","## This is a test script"]
],[
"start",
["comment","##"]
],[
"start"
],[
"comment",
["comment","/* This is"]
],[
"comment",
["comment","a multi-line"]
],[
"comment",
["comment","comment"]
],[
"start",
["comment","*/"]
],[
"start",
["keyword","if"],
["text"," "],
["lparen","("],
["identifier","out"],
["text"," "],
["keyword.operator","!="],
["text"," "],
["constant.language","null"],
["text"," "],
["keyword","and"],
["text"," "],
["identifier","result"],
["text"," "],
["keyword.operator","=="],
["text"," "],
["constant.language","null"],
["rparen",")"],
["text"," "],
["identifier","out"],
["punctuation","."],
["identifier","println"],
["lparen","("],
["string","\"The result is \""],
["text"," "],
["keyword.operator","+"],
["text"," "],
["identifier","result"],
["rparen",")"],
["text",";"]
],[
"start",
["identifier","x"],
["text"," "],
["keyword.operator","="],
["text"," "],
["string.regexp","~/\\w+"],
["constant.language.escape","\\/"],
["string.regexp","test/"],
["text",";"]
],[
"start",
["identifier","y"],
["text"," "],
["keyword.operator","="],
["text"," "],
["constant.numeric","2"],
["text",";"]
],[
"start",
["identifier","result"],
["text"," "],
["keyword.operator","="],
["text"," "],
["identifier","x"],
["text"," "],
["keyword.operator","*"],
["text"," "],
["identifier","y"],
["text"," "],
["keyword.operator","+"],
["text"," "],
["constant.numeric","5"],
["text",";"]
],[
"start",
["keyword","if"],
["text"," "],
["lparen","("],
["identifier","out"],
["text"," "],
["keyword.operator","!="],
["text"," "],
["constant.language","null"],
["rparen",")"],
["text"," "],
["identifier","out"],
["punctuation","."],
["identifier","println"],
["lparen","("],
["string","\"The result is \""],
["text"," "],
["keyword.operator","+"],
["text"," "],
["identifier","result"],
["rparen",")"],
["text",";"]
],[
"start"
],[
"start",
["storage.type.annotation","@lenient"],
["text"," "],
["storage.type.annotation","@silent"],
["text"," "],
["identifier","x"],
["punctuation","."],
["identifier","someMethod"],
["lparen","("],
["rparen",")"],
["text",";"]
],[
"start"
],[
"string",
["string","`multi-line string"]
],[
"start",
["string","with "],
["lparen","${"],
["keyword","var"],
["text"," "],
["identifier","interpolation"],
["text"," "],
["keyword.operator","="],
["text"," "],
["string","\"Hey!\""],
["rparen","}"],
["string"," and "],
["constant.language.escape","\\"],
["string","escap"],
["constant.language.escape","\\u00E9"],
["string"," chars`"]
],[
"start"
]]
23 changes: 23 additions & 0 deletions src/mode/jexl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use strict";

var oop = require("../lib/oop");
var JexlHighlightRules = require("./jexl_highlight_rules").JexlHighlightRules;
var TextMode = require("./text").Mode;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;

var Mode = function () {
this.HighlightRules = JexlHighlightRules;
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);

(function () {
this.lineCommentStart = ["//", "##"];
this.blockComment = {start: "/*", end: "*/"};

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

exports.Mode = Mode;
138 changes: 138 additions & 0 deletions src/mode/jexl_highlight_rules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"use strict";

var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var JexlHighlightRules = function () {

var keywords = "return|var|function|and|or|not|if|for|while|do|continue|break";
var buildinConstants = "null";
var supportFunc = "empty|size|new";

var keywordMapper = this.createKeywordMapper({
"keyword": keywords,
"constant.language": buildinConstants,
"support.function": supportFunc
}, "identifier");

var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex
"u[0-9a-fA-F]{4}|" + // unicode
"u{[0-9a-fA-F]{1,6}}|" + // es6 unicode
"|.)";

// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used

this.$rules = {
"start": [
{
token: "comment",
regex: "\\/\\/.*$"
}, {
token: "comment",
regex: "##.*$"
}, {
token: "comment", // multi line comment
regex: "\\/\\*",
next: "comment"
}, {
token: ["comment", "text"],
regex: "(#pragma)(\\s.*$)"
}, {
token: "string", // single line
regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
}, {
token: "string", // single line
regex: "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
}, {
token: "string", // multi line string
regex: "`",
push: [
{
token: "constant.language.escape",
regex: escapedRe
}, {
token: "string",
regex: "`",
next: "pop"
}, {
token: "lparen", //interpolation
regex: "\\${",
push: [
{
token: "rparen",
regex: "}",
next: "pop"
}, {
include: "start"
}
]
}, {
defaultToken: "string"
}
]
}, {
token: "constant.numeric", // hex
regex: /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\b/
}, {
token: "constant.numeric", // float
regex: /[+-]?\d[\d_]*(?:(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?)?[LlSsDdFfYy]?\b/
}, {
token: "constant.language.boolean",
regex: "(?:true|false)\\b"
}, {
token: "string.regexp",
regex: "~/",
push: [
{
token: "constant.language.escape",
regex: "\\\\/"
}, {
token: "string.regexp",
regex: "$|/",
next: "pop"
}, {
defaultToken: "string.regexp"
}
]
}, {
token: keywordMapper,
regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
}, {
token: "keyword.operator",
regex: "&&|\\|\\||!|&|\\||\\^|~|\\?|:|\\?\\?|==|!=|<|<=|>|>=|=~|!~|=\\^|=\\$|!\\$|\\+|\\-|\\*|%|\\/|="
}, {
token: "lparen",
regex: "[[({]"
}, {
token: "rparen",
regex: "[\\])}]"
}, {
token: "text",
regex: "\\s+"
}, {
token: "punctuation",
regex: "[,.]"
}, {
token: "storage.type.annotation",
regex: "@[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
}
],
"comment": [
{
token: "comment",
regex: "\\*\\/",
next: "start"
}, {
defaultToken: "comment"
}
]
};


this.normalizeRules();
};

oop.inherits(JexlHighlightRules, TextHighlightRules);

exports.JexlHighlightRules = JexlHighlightRules;

0 comments on commit 4e8926e

Please sign in to comment.