What is is for? Gary
On Fri, Jul 24, 2026, 06:29 <[email protected]> wrote: > This is an automated email from the ASF dual-hosted git repository. > > henrib pushed a commit to branch master > in repository https://gitbox.apache.org/repos/asf/commons-jexl.git > > > The following commit(s) were added to refs/heads/master by this push: > new 5f294331 JEXL-467: TextMate JEXL bundle; > 5f294331 is described below > > commit 5f294331c45f140c8f012659ebec768bf5d4f6fa > Author: Henrib <[email protected]> > AuthorDate: Fri Jul 24 12:28:47 2026 +0200 > > JEXL-467: TextMate JEXL bundle; > --- > tools/JEXL.tmbundle/Syntaxes/JEXL.tmLanguage | 383 > ++++++++++++++++++++++++ > tools/JEXL.tmbundle/info.plist | 10 + > tools/JEXL.tmbundle/language-configuration.json | 28 ++ > tools/JEXL.tmbundle/package.json | 30 ++ > 4 files changed, 451 insertions(+) > > diff --git a/tools/JEXL.tmbundle/Syntaxes/JEXL.tmLanguage > b/tools/JEXL.tmbundle/Syntaxes/JEXL.tmLanguage > new file mode 100644 > index 00000000..4fc1fba5 > --- /dev/null > +++ b/tools/JEXL.tmbundle/Syntaxes/JEXL.tmLanguage > @@ -0,0 +1,383 @@ > +<?xml version="1.0" encoding="UTF-8"?> > +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" " > http://www.apple.com/DTDs/PropertyList-1.0.dtd"> > +<plist version="1.0"> > +<dict> > + <key>fileTypes</key> > + <array> > + <string>jexl</string> > + </array> > + <key>name</key> > + <string>JEXL</string> > + <key>scopeName</key> > + <string>source.jexl</string> > + <key>uuid</key> > + <string>3C5D7E9F-A1B2-4C6D-8E0F-123456789ABC</string> > + <key>patterns</key> > + <array> > + <dict><key>include</key><string>#comments</string></dict> > + <dict><key>include</key><string>#pragma</string></dict> > + <dict><key>include</key><string>#annotations</string></dict> > + <dict><key>include</key><string>#template-string</string></dict> > + <dict><key>include</key><string>#regexp</string></dict> > + <dict><key>include</key><string>#strings</string></dict> > + <dict><key>include</key><string>#numbers</string></dict> > + <dict><key>include</key><string>#constants</string></dict> > + <dict><key>include</key><string>#keywords-control</string></dict> > + > <dict><key>include</key><string>#keywords-declaration</string></dict> > + > <dict><key>include</key><string>#keywords-operators-word</string></dict> > + <dict><key>include</key><string>#builtins</string></dict> > + <dict><key>include</key><string>#operators</string></dict> > + <dict><key>include</key><string>#spread</string></dict> > + > <dict><key>include</key><string>#collection-punctuation</string></dict> > + <dict><key>include</key><string>#namespace-call</string></dict> > + > <dict><key>include</key><string>#function-definition-name</string></dict> > + <dict><key>include</key><string>#function-call</string></dict> > + <dict><key>include</key><string>#variable</string></dict> > + </array> > + <key>repository</key> > + <dict> > + > + <!-- ═══ Comments > ═══════════════════════════════════════════════════════ --> > + <key>comments</key> > + <dict> > + <key>patterns</key> > + <array> > + <dict> > + <key>name</key><string>comment.block.jexl</string> > + <key>begin</key><string>/\*</string> > + <key>end</key><string>\*/</string> > + <key>beginCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.comment.begin.jexl</string></dict> > + </dict> > + <key>endCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.comment.end.jexl</string></dict> > + </dict> > + </dict> > + <dict> > + > <key>name</key><string>comment.line.number-sign.jexl</string> > + <key>match</key><string>##.*$</string> > + </dict> > + <dict> > + > <key>name</key><string>comment.line.double-slash.jexl</string> > + <key>match</key><string>//.*$</string> > + </dict> > + </array> > + </dict> > + > + <!-- ═══ Pragma > ══════════════════════════════════════════════════════════ --> > + <!-- #pragma key value (## comment would already have consumed > ##, so a > + single # here is safe; only #pragma lines start with one #) > --> > + <key>pragma</key> > + <dict> > + <key>name</key><string>meta.pragma.jexl</string> > + > <key>match</key><string>(#pragma)\s+([a-zA-Z_$][a-zA-Z0-9_$.]*)(?:\s+(.+))?$</string> > + <key>captures</key> > + <dict> > + > <key>1</key><dict><key>name</key><string>keyword.control.pragma.jexl</string></dict> > + > <key>2</key><dict><key>name</key><string>entity.name.tag.jexl</string></dict> > + > <key>3</key><dict><key>name</key><string>string.unquoted.jexl</string></dict> > + </dict> > + </dict> > + > + <!-- ═══ Annotations > ═════════════════════════════════════════════════════ --> > + <!-- @lenient @synchronized(x) etc. > --> > + <key>annotations</key> > + <dict> > + <key>name</key><string>entity.name.decorator.jexl</string> > + <key>match</key><string>@[a-zA-Z_$][a-zA-Z0-9_$]*</string> > + </dict> > + > + <!-- ═══ Template / backtick string ─ with ${…} and #{…} > interpolation ══ --> > + <key>template-string</key> > + <dict> > + <key>name</key><string>string.template.jexl</string> > + <key>begin</key><string>`</string> > + <key>end</key><string>`</string> > + <key>beginCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.begin.jexl</string></dict> > + </dict> > + <key>endCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.end.jexl</string></dict> > + </dict> > + <key>patterns</key> > + <array> > + <!-- immediate interpolation: ${expr} --> > + <dict> > + > <key>name</key><string>meta.interpolation.immediate.jexl</string> > + <key>begin</key><string>\$\{</string> > + <key>end</key><string>\}</string> > + <key>beginCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.section.interpolation.begin.jexl</string></dict> > + </dict> > + <key>endCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.section.interpolation.end.jexl</string></dict> > + </dict> > + <key>patterns</key> > + <array> > + > <dict><key>include</key><string>$self</string></dict> > + </array> > + </dict> > + <!-- deferred interpolation: #{expr} --> > + <dict> > + > <key>name</key><string>meta.interpolation.deferred.jexl</string> > + <key>begin</key><string>#\{</string> > + <key>end</key><string>\}</string> > + <key>beginCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.section.interpolation.begin.jexl</string></dict> > + </dict> > + <key>endCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.section.interpolation.end.jexl</string></dict> > + </dict> > + <key>patterns</key> > + <array> > + > <dict><key>include</key><string>$self</string></dict> > + </array> > + </dict> > + <!-- escape sequences \n \t \uXXXX \` etc. --> > + <dict> > + > <key>name</key><string>constant.character.escape.jexl</string> > + > <key>match</key><string>\\(u[0-9A-Fa-f]{4}|[nrtfb\\`])</string> > + </dict> > + </array> > + </dict> > + > + <!-- ═══ Regex literal ~/pattern/ > ════════════════════════════════════ --> > + <key>regexp</key> > + <dict> > + <key>name</key><string>string.regexp.jexl</string> > + <key>begin</key><string>~/</string> > + <key>end</key><string>/</string> > + <key>beginCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.begin.jexl</string></dict> > + </dict> > + <key>endCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.end.jexl</string></dict> > + </dict> > + <key>patterns</key> > + <array> > + <dict> > + > <key>name</key><string>constant.character.escape.jexl</string> > + <key>match</key><string>\\/</string> > + </dict> > + </array> > + </dict> > + > + <!-- ═══ String literals '…' "…" > ════════════════════════════════════ --> > + <key>strings</key> > + <dict> > + <key>patterns</key> > + <array> > + <dict> > + > <key>name</key><string>string.quoted.single.jexl</string> > + <key>begin</key><string>'</string> > + <key>end</key><string>'</string> > + <key>beginCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.begin.jexl</string></dict> > + </dict> > + <key>endCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.end.jexl</string></dict> > + </dict> > + <key>patterns</key> > + <array> > + <dict> > + > <key>name</key><string>constant.character.escape.jexl</string> > + > <key>match</key><string>\\(u[0-9A-Fa-f]{4}|[nrtfb\\'])</string> > + </dict> > + </array> > + </dict> > + <dict> > + > <key>name</key><string>string.quoted.double.jexl</string> > + <key>begin</key><string>"</string> > + <key>end</key><string>"</string> > + <key>beginCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.begin.jexl</string></dict> > + </dict> > + <key>endCaptures</key> > + <dict> > + > <key>0</key><dict><key>name</key><string>punctuation.definition.string.end.jexl</string></dict> > + </dict> > + <key>patterns</key> > + <array> > + <dict> > + > <key>name</key><string>constant.character.escape.jexl</string> > + > <key>match</key><string>\\(u[0-9A-Fa-f]{4}|[nrtfb\\"])</string> > + </dict> > + </array> > + </dict> > + </array> > + </dict> > + > + <!-- ═══ Numeric literals > ════════════════════════════════════════════════ --> > + <!-- Order matters: hex before octal before float before int > --> > + <key>numbers</key> > + <dict> > + <key>patterns</key> > + <array> > + <!-- Hexadecimal: 0xFF 0xABh etc. --> > + <dict> > + > <key>name</key><string>constant.numeric.hex.jexl</string> > + > <key>match</key><string>\b0[xX][0-9A-Fa-f]+[lLhH]?\b</string> > + </dict> > + <!-- Float / Double / BigDecimal: 3.14 1.0f 42.0d > 1e-3B etc. --> > + <dict> > + > <key>name</key><string>constant.numeric.float.jexl</string> > + > <key>match</key><string>\b\d+\.\d+(?:[eE][+-]?\d+)?[fFdDbB]?\b</string> > + </dict> > + <!-- Octal: 010 0777 etc. --> > + <dict> > + > <key>name</key><string>constant.numeric.octal.jexl</string> > + <key>match</key><string>\b0[0-7]+[lLhH]?\b</string> > + </dict> > + <!-- Integer / Long / BigInteger: 42 100l 7h etc. --> > + <dict> > + > <key>name</key><string>constant.numeric.integer.jexl</string> > + <key>match</key><string>\b\d+[lLhH]?\b</string> > + </dict> > + </array> > + </dict> > + > + <!-- ═══ Language constants > ══════════════════════════════════════════════ --> > + <key>constants</key> > + <dict> > + <key>name</key><string>constant.language.jexl</string> > + <key>match</key><string>\b(true|false|null|NaN)\b</string> > + </dict> > + > + <!-- ═══ Control-flow keywords > ════════════════════════════════════════════ --> > + <key>keywords-control</key> > + <dict> > + <key>name</key><string>keyword.control.jexl</string> > + > <key>match</key><string>\b(if|else|for|do|while|break|continue|return|switch|case|default|throw|try|catch|finally)\b</string> > + </dict> > + > + <!-- ═══ Declaration keywords > ════════════════════════════════════════════ --> > + <key>keywords-declaration</key> > + <dict> > + <key>name</key><string>keyword.declaration.jexl</string> > + > <key>match</key><string>\b(var|let|const|function|import)\b</string> > + </dict> > + > + <!-- ═══ Word-form operators > ══════════════════════════════════════════════ --> > + <key>keywords-operators-word</key> > + <dict> > + <key>name</key><string>keyword.operator.word.jexl</string> > + > <key>match</key><string>\b(and|or|not|eq|ne|lt|gt|le|ge|div|mod|instanceof)\b</string> > + </dict> > + > + <!-- ═══ Built-in functions / special forms > ══════════════════════════════ --> > + <key>builtins</key> > + <dict> > + <key>name</key><string>support.function.builtin.jexl</string> > + <key>match</key><string>\b(empty|size|new)\b</string> > + </dict> > + > + <!-- ═══ Symbolic operators (longest-match first) > ════════════════════════ --> > + <!-- XML-encoded: < for <, & for & > --> > + <key>operators</key> > + <dict> > + <key>name</key><string>keyword.operator.jexl</string> > + > <key>match</key><string>>>>=|===|!==|=~|!~|=\^|!\^|=\$|!\$|<<=|>>=|&&|\|\||>>>|<<|>>|\+\+|--|&=|\|=|\^=|\+=|-=|\*=|/=|%=|==|!=|<=|>=|\?\?|\?:|\?\.|\.\.\.|\.\.|->|\*|/|%|&|\||\^|~|\+|-|!|=|<|>|\?</string> > + </dict> > + > + <!-- ═══ Spread ... (list literal marker) > ═══════════════════════════════ --> > + <!-- [1, 2, 3, ...] or [...] – three dots create an ArrayList > --> > + <key>spread</key> > + <dict> > + <key>name</key><string>keyword.operator.spread.jexl</string> > + <key>match</key><string>\.\.\.</string> > + </dict> > + > + <!-- ═══ Collection punctuation [ ] { } , > ══════════════════════════════ --> > + <!-- [1,2,3] [...] {a,b} {k:v} {k:v,...} {;} {:} > --> > + <key>collection-punctuation</key> > + <dict> > + <key>patterns</key> > + <array> > + <dict> > + > <key>name</key><string>punctuation.definition.array.begin.jexl</string> > + <key>match</key><string>\[</string> > + </dict> > + <dict> > + > <key>name</key><string>punctuation.definition.array.end.jexl</string> > + <key>match</key><string>\]</string> > + </dict> > + <!-- empty map literal {:} — must precede the generic { > rule --> > + <dict> > + > <key>name</key><string>meta.literal.map.empty.jexl</string> > + <key>match</key><string>\{:\}</string> > + </dict> > + <dict> > + > <key>name</key><string>punctuation.definition.block.begin.jexl</string> > + <key>match</key><string>\{</string> > + </dict> > + <dict> > + > <key>name</key><string>punctuation.definition.block.end.jexl</string> > + <key>match</key><string>\}</string> > + </dict> > + <dict> > + > <key>name</key><string>punctuation.separator.jexl</string> > + <key>match</key><string>,</string> > + </dict> > + <!-- map key-value separator : (Elvis ?: and ns:func > already consumed upstream) --> > + <dict> > + > <key>name</key><string>punctuation.separator.key-value.jexl</string> > + <key>match</key><string>:</string> > + </dict> > + </array> > + </dict> > + > + <!-- ═══ Namespace-qualified function call ns:func( > ════════════════════ --> > + <!-- Matches the namespace prefix and function name in > math:cos(x) --> > + <key>namespace-call</key> > + <dict> > + > <key>match</key><string>(?<![a-zA-Z0-9_$])([a-zA-Z_$][a-zA-Z0-9_$]*):([a-zA-Z_$][a-zA-Z0-9_$]*)(?=\s*\()</string> > + <key>captures</key> > + <dict> > + <key>1</key><dict><key>name</key><string>entity.name > .namespace.jexl</string></dict> > + <key>2</key><dict><key>name</key><string>entity.name > .function.jexl</string></dict> > + </dict> > + </dict> > + > + <!-- ═══ Named function declaration function foo( > ═════════════════════ --> > + <!-- Must precede function-call so the declared name gets the > richer scope --> > + <key>function-definition-name</key> > + <dict> > + > <key>match</key><string>\bfunction\b\s+([a-zA-Z_$][a-zA-Z0-9_$]*)</string> > + <key>captures</key> > + <dict> > + <key>1</key><dict><key>name</key><string>entity.name > .function.definition.jexl</string></dict> > + </dict> > + </dict> > + > + <!-- ═══ Function / method call foo( > ══════════════════════════════════ --> > + <!-- identifier immediately before ( — covers calls, > constructors, methods --> > + <key>function-call</key> > + <dict> > + <key>name</key><string>entity.name.function.jexl</string> > + > <key>match</key><string>(?<![a-zA-Z0-9_$])[a-zA-Z_$][a-zA-Z0-9_$]*(?=\s*\()</string> > + </dict> > + > + <!-- ═══ Variables — catch-all for remaining identifiers > ═════════════════ --> > + <!-- Keywords, constants, builtins, and function names are > consumed above --> > + <key>variable</key> > + <dict> > + <key>name</key><string>variable.other.jexl</string> > + > <key>match</key><string>(?<![a-zA-Z0-9_$])[a-zA-Z_$][a-zA-Z0-9_$]*(?![a-zA-Z0-9_$])</string> > + </dict> > + > + </dict> > +</dict> > +</plist> > diff --git a/tools/JEXL.tmbundle/info.plist > b/tools/JEXL.tmbundle/info.plist > new file mode 100644 > index 00000000..fc29891f > --- /dev/null > +++ b/tools/JEXL.tmbundle/info.plist > @@ -0,0 +1,10 @@ > +<?xml version="1.0" encoding="UTF-8"?> > +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" " > http://www.apple.com/DTDs/PropertyList-1.0.dtd"> > +<plist version="1.0"> > +<dict> > + <key>name</key> > + <string>JEXL</string> > + <key>uuid</key> > + <string>7A2E4F6C-8D3B-4E9A-B5C1-2F0E8D7A3B6C</string> > +</dict> > +</plist> > diff --git a/tools/JEXL.tmbundle/language-configuration.json > b/tools/JEXL.tmbundle/language-configuration.json > new file mode 100644 > index 00000000..c36c19e8 > --- /dev/null > +++ b/tools/JEXL.tmbundle/language-configuration.json > @@ -0,0 +1,28 @@ > +{ > + "comments": { > + "lineComment": "//", > + "blockComment": ["/*", "*/"] > + }, > + "brackets": [ > + ["(", ")"], > + ["[", "]"], > + ["{", "}"] > + ], > + "autoClosingPairs": [ > + { "open": "(", "close": ")" }, > + { "open": "[", "close": "]" }, > + { "open": "{", "close": "}" }, > + { "open": "'", "close": "'", "notIn": ["string", "comment"] }, > + { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, > + { "open": "`", "close": "`", "notIn": ["string", "comment"] }, > + { "open": "/*", "close": " */" } > + ], > + "surroundingPairs": [ > + ["(", ")"], > + ["[", "]"], > + ["{", "}"], > + ["'", "'"], > + ["\"", "\""], > + ["`", "`"] > + ] > +} > diff --git a/tools/JEXL.tmbundle/package.json > b/tools/JEXL.tmbundle/package.json > new file mode 100644 > index 00000000..67c4ad48 > --- /dev/null > +++ b/tools/JEXL.tmbundle/package.json > @@ -0,0 +1,30 @@ > +{ > + "name": "jexl", > + "displayName": "JEXL", > + "description": "Syntax highlighting for JEXL (Apache Commons JEXL) > files", > + "version": "1.0.0", > + "publisher": "apache-commons", > + "engines": { > + "vscode": "^1.50.0" > + }, > + "categories": [ > + "Programming Languages" > + ], > + "contributes": { > + "languages": [ > + { > + "id": "jexl", > + "aliases": ["JEXL", "jexl"], > + "extensions": [".jexl"], > + "configuration": "./language-configuration.json" > + } > + ], > + "grammars": [ > + { > + "language": "jexl", > + "scopeName": "source.jexl", > + "path": "./Syntaxes/JEXL.tmLanguage" > + } > + ] > + } > +} > >
