I try to write my owm module, for our own script language for codemirror.Right know I am hanging on our keywords.
I have this test-code:
Window(EditWin, SELECT_MULTIPLE, NO_SIZE, 310, 87, 500, 60, T("Sitzungsdatum", "Session date"))
{
Prompt(SessionDatePmt, 11, 4, T("Sitzungsdatum", "Session date"))
Date(SessionDate, 175, 4, 88)
Button(SystemDateAsSessionDateBtn, 290, 3, 190, 10, T("Übernehme Systemdatum", "Get system date"))
[ SELECT: SystemObject Call(SystemDate) PutObject(, SessionDate) ]
}
And some of our Keywords are:
For my regular expression, I use an array, called cons, with all keywords.
Then i join all the array entrys like this:
var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))\\b");
Till there everything works fine. The regular expression i get, does work in normal javascript match(). I even fetched the text of my site using jQuery, and than used the regular expression, and got what I wanted.
But, when I do:
if (stream.match(keywordRegex)) return 'keyword';
in Codemirror, the Date of SessionDate is matched too.
Here is my whole Codemirror mode:
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("testmode", function() {
var cons = ['Window', 'SELECT_MULTIPLE', 'NO_SIZE', 'PROMPT', 'Date', 'Button', 'Select', 'SystemObject', 'Call', 'PutObject'];
var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))\\b");
var numLiteral = /(-|\+)?([0-9]+(\.[0-9]*)?|0x[0-9a-f]+)/;
return {
token: function(stream, state) {
if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
return "string";
if (stream.match(keywordRegex)) return 'keyword';
if (stream.match(/({|})/)) return "bracket";
if (stream.match(numLiteral)) return "number";
if (stream.match(/(->)/)) return "arrow";
stream.next();
return null;
},
startState: function() {
return {
pair: false,
pairStart: false,
keyCol: 0,
inlinePairs: 0,
inlineList: 0,
literal: false,
escaped: false
};
}
};
});
CodeMirror.defineMIME("application/testmode", "testmode");
});
As asked for, here is a working plunker:
http://plnkr.co/edit/bPyuJd?p=preview
There you can see, I don't have a keyword "SessionDate", but because of the Keyword "Date", the "Date" of "SessionDate" gets highlighted too.
It seems I have found a way to solve it. There is no support for anchors in Code Mirror:
(The
^
regexp marker doesn't work as you'd expect in this context because of limitations in JavaScript's RegExp API.)
Thus, use 2 regexps for the beginning of string condition and a mid-string position, and for the start-of-string position, check the position with stream.sol()
:
var keywordRegex = new RegExp("("+cons.join("|")+")(?=\\W)");
var midkeywordRegex = new RegExp("\\W("+cons.join("|")+")(?=\\W)");
...
if (stream.sol() && stream.match(/('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
return "iv-string";
if (stream.sol() && stream.match(keywordRegex)) return 'keyword';
if (stream.match(midkeywordRegex)) return 'keyword';
See Updated plunker