|
@@ -11,14 +11,16 @@ export function CodeEditorMode (CodeMirror) {
|
|
this.align = align;
|
|
this.align = align;
|
|
this.prev = prev;
|
|
this.prev = prev;
|
|
}
|
|
}
|
|
|
|
+
|
|
function pushContext(state, col, type, info) {
|
|
function pushContext(state, col, type, info) {
|
|
- var indent = state.indented;
|
|
|
|
|
|
+ let indent = state.indented;
|
|
if (state.context && state.context.type == "statement" && type != "statement")
|
|
if (state.context && state.context.type == "statement" && type != "statement")
|
|
indent = state.context.indented;
|
|
indent = state.context.indented;
|
|
return state.context = new Context(indent, col, type, info, null, state.context);
|
|
return state.context = new Context(indent, col, type, info, null, state.context);
|
|
}
|
|
}
|
|
|
|
+
|
|
function popContext(state) {
|
|
function popContext(state) {
|
|
- var t = state.context.type;
|
|
|
|
|
|
+ const t = state.context.type;
|
|
if (t == ")" || t == "]" || t == "}")
|
|
if (t == ")" || t == "]" || t == "}")
|
|
state.indented = state.context.indented;
|
|
state.indented = state.context.indented;
|
|
return state.context = state.context.prev;
|
|
return state.context = state.context.prev;
|
|
@@ -38,15 +40,35 @@ export function CodeEditorMode (CodeMirror) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ function contains(words, word) {
|
|
|
|
+ if (typeof words === "function") {
|
|
|
|
+ return words(word);
|
|
|
|
+ } else {
|
|
|
|
+ return Object.propertyIsEnumerable.call(words, word);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function tokenComment(stream, state) {
|
|
|
|
+ let maybeEnd = false, ch;
|
|
|
|
+ while ((ch = stream.next())) {
|
|
|
|
+ if (ch == "/" && maybeEnd) {
|
|
|
|
+ state.tokenize = null;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ maybeEnd = (ch == "*");
|
|
|
|
+ }
|
|
|
|
+ return "comment";
|
|
|
|
+ }
|
|
|
|
+
|
|
CodeMirror.defineMode("ivprog", function (config, parserConfig) {
|
|
CodeMirror.defineMode("ivprog", function (config, parserConfig) {
|
|
- var indentUnit = config.indentUnit,
|
|
|
|
|
|
+ const indentUnit = config.indentUnit,
|
|
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
|
|
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
|
|
dontAlignCalls = parserConfig.dontAlignCalls,
|
|
dontAlignCalls = parserConfig.dontAlignCalls,
|
|
keywords = parserConfig.keywords || {},
|
|
keywords = parserConfig.keywords || {},
|
|
switchKeyword = parserConfig.switchKeyword,
|
|
switchKeyword = parserConfig.switchKeyword,
|
|
caseKeyword = parserConfig.caseKeyword,
|
|
caseKeyword = parserConfig.caseKeyword,
|
|
defaultKeyword = parserConfig.defaultKeyword,
|
|
defaultKeyword = parserConfig.defaultKeyword,
|
|
- caseRegex = new RegExp(`^\s*(?:${caseKeyword} .*?:|${defaultKeyword}:|\{\}?|\})$`),////,
|
|
|
|
|
|
+ caseRegex = new RegExp(`^\\s*(?:${caseKeyword} .*?:|${defaultKeyword}:|\\{\\}?|\\})$`),////,
|
|
types = parserConfig.types || {},
|
|
types = parserConfig.types || {},
|
|
builtin = parserConfig.builtin || {},
|
|
builtin = parserConfig.builtin || {},
|
|
blockKeywords = parserConfig.blockKeywords || {},
|
|
blockKeywords = parserConfig.blockKeywords || {},
|
|
@@ -56,21 +78,21 @@ export function CodeEditorMode (CodeMirror) {
|
|
multiLineStrings = parserConfig.multiLineStrings,
|
|
multiLineStrings = parserConfig.multiLineStrings,
|
|
indentStatements = false,
|
|
indentStatements = false,
|
|
namespaceSeparator = null,
|
|
namespaceSeparator = null,
|
|
- isPunctuationChar = /[\[\]{}\(\),;\:\n]/,
|
|
|
|
- numberStart = /[\d\.]/,
|
|
|
|
- number = /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)/i,
|
|
|
|
- isOperatorChar = /[+\-*%=<>!\/]/,
|
|
|
|
|
|
+ isPunctuationChar = /[[\]{}(),;:\n]/,
|
|
|
|
+ numberStart = /[\d.]/,
|
|
|
|
+ number = /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)$/i,
|
|
|
|
+ isOperatorChar = /[+\-*%=<>!/&]/,
|
|
isIdentifierChar = /[a-zA-Z0-9_]/,
|
|
isIdentifierChar = /[a-zA-Z0-9_]/,
|
|
// An optional function that takes a {string} token and returns true if it
|
|
// An optional function that takes a {string} token and returns true if it
|
|
// should be treated as a builtin.
|
|
// should be treated as a builtin.
|
|
isReservedIdentifier = parserConfig.isReservedIdentifier || false;
|
|
isReservedIdentifier = parserConfig.isReservedIdentifier || false;
|
|
|
|
|
|
- var curPunc, isDefKeyword;
|
|
|
|
-
|
|
|
|
|
|
+ let curPunc, isDefKeyword;
|
|
|
|
+ let tokenString = function () { /*SKIP*/};
|
|
function tokenBase(stream, state) {
|
|
function tokenBase(stream, state) {
|
|
- var ch = stream.next();
|
|
|
|
|
|
+ const ch = stream.next();
|
|
if (hooks[ch]) {
|
|
if (hooks[ch]) {
|
|
- var result = hooks[ch](stream, state);
|
|
|
|
|
|
+ const result = hooks[ch](stream, state);
|
|
if (result !== false) return result;
|
|
if (result !== false) return result;
|
|
}
|
|
}
|
|
if (ch == '"') {
|
|
if (ch == '"') {
|
|
@@ -97,14 +119,14 @@ export function CodeEditorMode (CodeMirror) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (isOperatorChar.test(ch)) {
|
|
if (isOperatorChar.test(ch)) {
|
|
- while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) { }
|
|
|
|
|
|
+ while (!stream.match(/^\/[/*]/, false) && stream.eat(isOperatorChar)) { /* SKIP */}
|
|
return "operator";
|
|
return "operator";
|
|
}
|
|
}
|
|
stream.eatWhile(isIdentifierChar);
|
|
stream.eatWhile(isIdentifierChar);
|
|
if (namespaceSeparator) while (stream.match(namespaceSeparator))
|
|
if (namespaceSeparator) while (stream.match(namespaceSeparator))
|
|
stream.eatWhile(isIdentifierChar);
|
|
stream.eatWhile(isIdentifierChar);
|
|
|
|
|
|
- var cur = stream.current();
|
|
|
|
|
|
+ const cur = stream.current();
|
|
if (contains(keywords, cur)) {
|
|
if (contains(keywords, cur)) {
|
|
if (contains(blockKeywords, cur)) curPunc = "newstatement";
|
|
if (contains(blockKeywords, cur)) curPunc = "newstatement";
|
|
if (contains(defKeywords, cur)) isDefKeyword = true;
|
|
if (contains(defKeywords, cur)) isDefKeyword = true;
|
|
@@ -120,9 +142,9 @@ export function CodeEditorMode (CodeMirror) {
|
|
return "variable";
|
|
return "variable";
|
|
}
|
|
}
|
|
|
|
|
|
- function tokenString(quote) {
|
|
|
|
|
|
+ tokenString = function (quote) {
|
|
return function (stream, state) {
|
|
return function (stream, state) {
|
|
- var escaped = false, next, end = false;
|
|
|
|
|
|
+ let escaped = false, next, end = false;
|
|
while ((next = stream.next()) != null) {
|
|
while ((next = stream.next()) != null) {
|
|
if (next == quote && !escaped) { end = true; break; }
|
|
if (next == quote && !escaped) { end = true; break; }
|
|
escaped = !escaped && next == "\\";
|
|
escaped = !escaped && next == "\\";
|
|
@@ -133,18 +155,6 @@ export function CodeEditorMode (CodeMirror) {
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
- function tokenComment(stream, state) {
|
|
|
|
- var maybeEnd = false, ch;
|
|
|
|
- while (ch = stream.next()) {
|
|
|
|
- if (ch == "/" && maybeEnd) {
|
|
|
|
- state.tokenize = null;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- maybeEnd = (ch == "*");
|
|
|
|
- }
|
|
|
|
- return "comment";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
function maybeEOL(stream, state) {
|
|
function maybeEOL(stream, state) {
|
|
if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
|
|
if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
|
|
state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
|
|
state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
|
|
@@ -164,7 +174,7 @@ export function CodeEditorMode (CodeMirror) {
|
|
},
|
|
},
|
|
|
|
|
|
token: function (stream, state) {
|
|
token: function (stream, state) {
|
|
- var ctx = state.context;
|
|
|
|
|
|
+ let ctx = state.context;
|
|
if (stream.sol()) {
|
|
if (stream.sol()) {
|
|
if (ctx.align == null) ctx.align = false;
|
|
if (ctx.align == null) ctx.align = false;
|
|
state.indented = stream.indentation();
|
|
state.indented = stream.indentation();
|
|
@@ -172,7 +182,7 @@ export function CodeEditorMode (CodeMirror) {
|
|
}
|
|
}
|
|
if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
|
|
if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
|
|
curPunc = isDefKeyword = null;
|
|
curPunc = isDefKeyword = null;
|
|
- var style = (state.tokenize || tokenBase)(stream, state);
|
|
|
|
|
|
+ let style = (state.tokenize || tokenBase)(stream, state);
|
|
if (style == "comment" || style == "meta") return style;
|
|
if (style == "comment" || style == "meta") return style;
|
|
if (ctx.align == null) ctx.align = true;
|
|
if (ctx.align == null) ctx.align = true;
|
|
|
|
|
|
@@ -200,7 +210,7 @@ export function CodeEditorMode (CodeMirror) {
|
|
style = "def";
|
|
style = "def";
|
|
|
|
|
|
if (hooks.token) {
|
|
if (hooks.token) {
|
|
- var result = hooks.token(stream, state, style);
|
|
|
|
|
|
+ const result = hooks.token(stream, state, style);
|
|
if (result !== undefined) style = result;
|
|
if (result !== undefined) style = result;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -214,17 +224,18 @@ export function CodeEditorMode (CodeMirror) {
|
|
|
|
|
|
indent: function (state, textAfter) {
|
|
indent: function (state, textAfter) {
|
|
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
|
|
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
|
|
- var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
|
|
|
- var closing = firstChar == ctx.type;
|
|
|
|
|
|
+ let ctx = state.context;
|
|
|
|
+ const firstChar = textAfter && textAfter.charAt(0)
|
|
|
|
+ const closing = firstChar == ctx.type;
|
|
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
|
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
|
if (parserConfig.dontIndentStatements)
|
|
if (parserConfig.dontIndentStatements)
|
|
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
|
|
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
|
|
ctx = ctx.prev
|
|
ctx = ctx.prev
|
|
if (hooks.indent) {
|
|
if (hooks.indent) {
|
|
- var hook = hooks.indent(state, ctx, textAfter, indentUnit);
|
|
|
|
|
|
+ const hook = hooks.indent(state, ctx, textAfter, indentUnit);
|
|
if (typeof hook == "number") return hook
|
|
if (typeof hook == "number") return hook
|
|
}
|
|
}
|
|
- var switchBlock = ctx.prev && ctx.prev.info == switchKeyword;
|
|
|
|
|
|
+ const switchBlock = ctx.prev && ctx.prev.info == switchKeyword;
|
|
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
|
|
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
|
|
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
|
|
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
|
|
return ctx.indented
|
|
return ctx.indented
|
|
@@ -235,7 +246,7 @@ export function CodeEditorMode (CodeMirror) {
|
|
return ctx.column + (closing ? 0 : 1);
|
|
return ctx.column + (closing ? 0 : 1);
|
|
if (ctx.type == ")" && !closing)
|
|
if (ctx.type == ")" && !closing)
|
|
return ctx.indented + statementIndentUnit;
|
|
return ctx.indented + statementIndentUnit;
|
|
- var caseTestRegex = new RegExp(`^(?:${caseKeyword}|${defaultKeyword})\b`)
|
|
|
|
|
|
+ const caseTestRegex = new RegExp(`^(?:${caseKeyword}|${defaultKeyword})\b`)
|
|
return ctx.indented + (closing ? 0 : indentUnit) +
|
|
return ctx.indented + (closing ? 0 : indentUnit) +
|
|
(!closing && switchBlock && !caseTestRegex.test(textAfter) ? indentUnit : 0);
|
|
(!closing && switchBlock && !caseTestRegex.test(textAfter) ? indentUnit : 0);
|
|
},
|
|
},
|
|
@@ -250,24 +261,18 @@ export function CodeEditorMode (CodeMirror) {
|
|
});
|
|
});
|
|
|
|
|
|
function words(str) {
|
|
function words(str) {
|
|
- var obj = {}, words = str.split(" ");
|
|
|
|
- for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
|
|
|
|
|
+ const obj = {}, words = str.split(" ");
|
|
|
|
+ for (let i = 0; i < words.length; ++i) obj[words[i]] = true;
|
|
return obj;
|
|
return obj;
|
|
}
|
|
}
|
|
- function contains(words, word) {
|
|
|
|
- if (typeof words === "function") {
|
|
|
|
- return words(word);
|
|
|
|
- } else {
|
|
|
|
- return Object.propertyIsEnumerable.call(words, word);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
const codeConfig = getCodeEditorModeConfig();
|
|
const codeConfig = getCodeEditorModeConfig();
|
|
|
|
|
|
- var ivprogKeywords = codeConfig.keywords.join(" ");
|
|
|
|
|
|
+ const ivprogKeywords = codeConfig.keywords.join(" ");
|
|
|
|
|
|
// Do not use this. Use the cTypes function below. This is global just to avoid
|
|
// Do not use this. Use the cTypes function below. This is global just to avoid
|
|
// excessive calls when cTypes is being called multiple times during a parse.
|
|
// excessive calls when cTypes is being called multiple times during a parse.
|
|
- var basicTypes = words(codeConfig.types.join(" "));
|
|
|
|
|
|
+ const basicTypes = words(codeConfig.types.join(" "));
|
|
|
|
|
|
// Returns true if identifier is a "C" type.
|
|
// Returns true if identifier is a "C" type.
|
|
// C type is defined as those that are reserved by the compiler (basicTypes),
|
|
// C type is defined as those that are reserved by the compiler (basicTypes),
|
|
@@ -277,15 +282,18 @@ export function CodeEditorMode (CodeMirror) {
|
|
return contains(basicTypes, identifier);
|
|
return contains(basicTypes, identifier);
|
|
}
|
|
}
|
|
|
|
|
|
- var ivprogBlockKeywords = codeConfig.blocks.join(" ");
|
|
|
|
- var ivprogDefKeywords = "funcao const";
|
|
|
|
|
|
+ const ivprogBlockKeywords = codeConfig.blocks.join(" ");
|
|
|
|
+ const ivprogDefKeywords = "funcao const";
|
|
|
|
|
|
function def(mimes, mode) {
|
|
function def(mimes, mode) {
|
|
if (typeof mimes == "string") mimes = [mimes];
|
|
if (typeof mimes == "string") mimes = [mimes];
|
|
- var words = [];
|
|
|
|
|
|
+ const words = [];
|
|
function add(obj) {
|
|
function add(obj) {
|
|
- if (obj) for (var prop in obj) if (Object.hasOwnProperty.call(obj, prop))
|
|
|
|
- words.push(prop);
|
|
|
|
|
|
+ if (obj) {
|
|
|
|
+ for (const prop in obj) if (Object.hasOwnProperty.call(obj, prop)) {
|
|
|
|
+ words.push(prop);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
add(mode.keywords);
|
|
add(mode.keywords);
|
|
add(mode.types);
|
|
add(mode.types);
|
|
@@ -296,7 +304,7 @@ export function CodeEditorMode (CodeMirror) {
|
|
CodeMirror.registerHelper("hintWords", mimes[0], words);
|
|
CodeMirror.registerHelper("hintWords", mimes[0], words);
|
|
}
|
|
}
|
|
|
|
|
|
- for (var i = 0; i < mimes.length; ++i)
|
|
|
|
|
|
+ for (let i = 0; i < mimes.length; ++i)
|
|
CodeMirror.defineMIME(mimes[i], mode);
|
|
CodeMirror.defineMIME(mimes[i], mode);
|
|
}
|
|
}
|
|
|
|
|