codemirror
Advanced tools
Comparing version 3.19.0 to 3.20.0
@@ -13,7 +13,18 @@ // Open simple dialogs on top of an editor. Relies on dialog.css. | ||
} | ||
dialog.innerHTML = template; | ||
if (typeof template == "string") { | ||
dialog.innerHTML = template; | ||
} else { // Assuming it's a detached DOM element. | ||
dialog.appendChild(template); | ||
} | ||
return dialog; | ||
} | ||
function closeNotification(cm, newVal) { | ||
if (cm.state.currentNotificationClose) | ||
cm.state.currentNotificationClose(); | ||
cm.state.currentNotificationClose = newVal; | ||
} | ||
CodeMirror.defineExtension("openDialog", function(template, callback, options) { | ||
closeNotification(this, null); | ||
var dialog = dialogDiv(this, template, options && options.bottom); | ||
@@ -55,2 +66,3 @@ var closed = false, me = this; | ||
CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { | ||
closeNotification(this, null); | ||
var dialog = dialogDiv(this, template, options && options.bottom); | ||
@@ -82,2 +94,31 @@ var buttons = dialog.getElementsByTagName("button"); | ||
}); | ||
/* | ||
* openNotification | ||
* Opens a notification, that can be closed with an optional timer | ||
* (default 5000ms timer) and always closes on click. | ||
* | ||
* If a notification is opened while another is opened, it will close the | ||
* currently opened one and open the new one immediately. | ||
*/ | ||
CodeMirror.defineExtension("openNotification", function(template, options) { | ||
closeNotification(this, close); | ||
var dialog = dialogDiv(this, template, options && options.bottom); | ||
var duration = options && (options.duration === undefined ? 5000 : options.duration); | ||
var closed = false, doneTimer; | ||
function close() { | ||
if (closed) return; | ||
closed = true; | ||
clearTimeout(doneTimer); | ||
dialog.parentNode.removeChild(dialog); | ||
} | ||
CodeMirror.on(dialog, 'click', function(e) { | ||
CodeMirror.e_preventDefault(e); | ||
close(); | ||
}); | ||
if (duration) | ||
doneTimer = setTimeout(close, options.duration); | ||
}); | ||
})(); |
@@ -15,3 +15,4 @@ (function() { | ||
width: wrap.style.width, height: wrap.style.height}; | ||
wrap.style.width = wrap.style.height = ""; | ||
wrap.style.width = ""; | ||
wrap.style.height = "auto"; | ||
wrap.className += " CodeMirror-fullscreen"; | ||
@@ -18,0 +19,0 @@ document.documentElement.style.overflow = "hidden"; |
@@ -5,3 +5,2 @@ (function() { | ||
if (val && !prev) { | ||
cm.on("focus", onFocus); | ||
cm.on("blur", onBlur); | ||
@@ -11,3 +10,2 @@ cm.on("change", onChange); | ||
} else if (!val && prev) { | ||
cm.off("focus", onFocus); | ||
cm.off("blur", onBlur); | ||
@@ -38,5 +36,2 @@ cm.off("change", onChange); | ||
function onFocus(cm) { | ||
clearPlaceholder(cm); | ||
} | ||
function onBlur(cm) { | ||
@@ -49,3 +44,2 @@ if (isEmpty(cm)) setPlaceholder(cm); | ||
if (cm.hasFocus()) return; | ||
if (empty) setPlaceholder(cm); | ||
@@ -52,0 +46,0 @@ else clearPlaceholder(cm); |
@@ -27,12 +27,11 @@ /** | ||
CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { | ||
if (val && (old == CodeMirror.Init || !old)) { | ||
var map = {name: "autoCloseTags"}; | ||
if (typeof val != "object" || val.whenClosing) | ||
map["'/'"] = function(cm) { return autoCloseSlash(cm); }; | ||
if (typeof val != "object" || val.whenOpening) | ||
map["'>'"] = function(cm) { return autoCloseGT(cm); }; | ||
cm.addKeyMap(map); | ||
} else if (!val && (old != CodeMirror.Init && old)) { | ||
if (old != CodeMirror.Init && old) | ||
cm.removeKeyMap("autoCloseTags"); | ||
} | ||
if (!val) return; | ||
var map = {name: "autoCloseTags"}; | ||
if (typeof val != "object" || val.whenClosing) | ||
map["'/'"] = function(cm) { return autoCloseSlash(cm); }; | ||
if (typeof val != "object" || val.whenOpening) | ||
map["'>'"] = function(cm) { return autoCloseGT(cm); }; | ||
cm.addKeyMap(map); | ||
}); | ||
@@ -58,3 +57,4 @@ | ||
// Don't process the '>' at the end of an end-tag or self-closing tag | ||
if (tok.type == "tag" && state.type == "closeTag" || | ||
if (tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) || | ||
tok.type == "tag" && state.type == "closeTag" || | ||
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName /> | ||
@@ -77,3 +77,5 @@ dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1) | ||
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; | ||
if (tok.string.charAt(0) != "<" || tok.start != pos.ch - 1 || inner.mode.name != "xml") return CodeMirror.Pass; | ||
if (tok.type == "string" || tok.string.charAt(0) != "<" || | ||
tok.start != pos.ch - 1 || inner.mode.name != "xml") | ||
return CodeMirror.Pass; | ||
@@ -80,0 +82,0 @@ var tagName = state.context && state.context.tagName; |
@@ -11,2 +11,3 @@ (function() { | ||
var maxScanLen = (state && state.maxScanLineLength) || 10000; | ||
var maxScanLines = (state && state.maxScanLines) || 100; | ||
@@ -36,3 +37,3 @@ var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1; | ||
} | ||
for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) { | ||
for (var i = cur.line, found, e = forward ? Math.min(i + maxScanLines, cm.lineCount()) : Math.max(-1, i - maxScanLines); i != e; i+=d) { | ||
if (i == cur.line) found = scan(line, i, pos); | ||
@@ -39,0 +40,0 @@ else found = scan(cm.getLineHandle(i), i); |
@@ -91,10 +91,10 @@ (function() { | ||
function onChange(cm) { | ||
var state = cm.state.foldGutter; | ||
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options; | ||
state.from = state.to = 0; | ||
clearTimeout(state.changeUpdate); | ||
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, 600); | ||
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); | ||
} | ||
function onViewportChange(cm) { | ||
var state = cm.state.foldGutter; | ||
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options; | ||
clearTimeout(state.changeUpdate); | ||
@@ -117,3 +117,3 @@ state.changeUpdate = setTimeout(function() { | ||
} | ||
}, 400); | ||
}, opts.updateViewportTimeSpan || 400); | ||
} | ||
@@ -120,0 +120,0 @@ |
CodeMirror.registerHelper("fold", "indent", function(cm, start) { | ||
var lastLine = cm.lastLine(), | ||
tabSize = cm.getOption("tabSize"), | ||
firstLine = cm.getLine(start.line), | ||
myIndent = CodeMirror.countColumn(firstLine, null, tabSize); | ||
function foldEnded(curColumn, prevColumn) { | ||
return curColumn < myIndent || | ||
(curColumn == myIndent && prevColumn >= myIndent) || | ||
(curColumn > myIndent && i == lastLine); | ||
} | ||
for (var i = start.line + 1; i <= lastLine; i++) { | ||
var curColumn = CodeMirror.countColumn(cm.getLine(i), null, tabSize); | ||
var prevColumn = CodeMirror.countColumn(cm.getLine(i-1), null, tabSize); | ||
if (foldEnded(curColumn, prevColumn)) { | ||
var lastFoldLineNumber = curColumn > myIndent && i == lastLine ? i : i-1; | ||
var lastFoldLine = cm.getLine(lastFoldLineNumber); | ||
return {from: CodeMirror.Pos(start.line, firstLine.length), | ||
to: CodeMirror.Pos(lastFoldLineNumber, lastFoldLine.length)}; | ||
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); | ||
if (!/\S/.test(firstLine)) return; | ||
var getIndent = function(lineNum) { | ||
return CodeMirror.countColumn(lineNum, null, tabSize); | ||
}; | ||
var myIndent = getIndent(firstLine); | ||
var lastLineInFold = null; | ||
// Go through lines until we find a line that definitely doesn't belong in | ||
// the block we're folding, or to the end. | ||
for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { | ||
var curLine = cm.getLine(i); | ||
var curIndent = getIndent(curLine); | ||
if (curIndent > myIndent) { | ||
// Lines with a greater indent are considered part of the block. | ||
lastLineInFold = i; | ||
} else if (!/\S/.test(curLine)) { | ||
// Empty lines might be breaks within the block we're trying to fold. | ||
} else { | ||
// A non-empty line at an indent equal to or less than ours marks the | ||
// start of another block. | ||
break; | ||
} | ||
} | ||
if (lastLineInFold) return { | ||
from: CodeMirror.Pos(start.line, firstLine.length), | ||
to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) | ||
}; | ||
}); | ||
CodeMirror.indentRangeFinder = CodeMirror.fold.indent; // deprecated |
@@ -24,2 +24,3 @@ (function () { | ||
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; | ||
if (/\b(?:string|comment)\b/.test(token.type)) return; | ||
token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; | ||
@@ -26,0 +27,0 @@ |
(function() { | ||
"use strict"; | ||
var HINT_ELEMENT_CLASS = "CodeMirror-hint"; | ||
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; | ||
CodeMirror.showHint = function(cm, getHints, options) { | ||
@@ -143,2 +146,9 @@ // We want a single cursor position. | ||
function getHintElement(stopAt, el) { | ||
while (el && el != stopAt) { | ||
if (el.nodeName.toUpperCase() === "LI") return el; | ||
el = el.parentNode; | ||
} | ||
} | ||
function Widget(completion, data) { | ||
@@ -151,3 +161,3 @@ this.completion = completion; | ||
hints.className = "CodeMirror-hints"; | ||
this.selectedHint = 0; | ||
this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0; | ||
@@ -157,3 +167,3 @@ var completions = data.list; | ||
var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; | ||
var className = "CodeMirror-hint" + (i ? "" : " CodeMirror-hint-active"); | ||
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); | ||
if (cur.className != null) className = cur.className + " " + className; | ||
@@ -222,9 +232,11 @@ elt.className = className; | ||
CodeMirror.on(hints, "dblclick", function(e) { | ||
var t = e.target || e.srcElement; | ||
if (t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} | ||
var t = getHintElement(hints, e.target || e.srcElement); | ||
if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} | ||
}); | ||
CodeMirror.on(hints, "click", function(e) { | ||
var t = e.target || e.srcElement; | ||
if (t.hintId != null) widget.changeActive(t.hintId); | ||
var t = getHintElement(hints, e.target || e.srcElement); | ||
if (t && t.hintId != null) widget.changeActive(t.hintId); | ||
}); | ||
CodeMirror.on(hints, "mousedown", function() { | ||
@@ -264,5 +276,5 @@ setTimeout(function(){cm.focus();}, 20); | ||
var node = this.hints.childNodes[this.selectedHint]; | ||
node.className = node.className.replace(" CodeMirror-hint-active", ""); | ||
node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); | ||
node = this.hints.childNodes[this.selectedHint = i]; | ||
node.className += " CodeMirror-hint-active"; | ||
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; | ||
if (node.offsetTop < this.hints.scrollTop) | ||
@@ -269,0 +281,0 @@ this.hints.scrollTop = node.offsetTop - 3; |
@@ -99,3 +99,3 @@ // Glue code between CodeMirror and Tern. | ||
showType: function(cm) { showType(this, cm); }, | ||
showType: function(cm, pos) { showType(this, cm, pos); }, | ||
@@ -110,6 +110,6 @@ updateArgHints: function(cm) { updateArgHints(this, cm); }, | ||
request: function (cm, query, c) { | ||
request: function (cm, query, c, pos) { | ||
var self = this; | ||
var doc = findDoc(this, cm.getDoc()); | ||
var request = buildRequest(this, doc, query); | ||
var request = buildRequest(this, doc, query, pos); | ||
@@ -226,3 +226,3 @@ this.server.request(request, function (error, data) { | ||
function showType(ts, cm) { | ||
function showType(ts, cm, pos) { | ||
ts.request(cm, "type", function(error, data) { | ||
@@ -242,3 +242,3 @@ if (error) return showError(ts, cm, error); | ||
tempTooltip(cm, tip); | ||
}); | ||
}, pos); | ||
} | ||
@@ -457,3 +457,3 @@ | ||
function buildRequest(ts, doc, query) { | ||
function buildRequest(ts, doc, query, pos) { | ||
var files = [], offsetLines = 0, allowFragments = !query.fullDocs; | ||
@@ -464,3 +464,3 @@ if (!allowFragments) delete query.fullDocs; | ||
if (query.end == null) { | ||
query.end = doc.doc.getCursor("end"); | ||
query.end = pos || doc.doc.getCursor("end"); | ||
if (doc.doc.somethingSelected()) | ||
@@ -467,0 +467,0 @@ query.start = doc.doc.getCursor("start"); |
@@ -216,2 +216,4 @@ /** | ||
alignOffset = stream.column() + stream.current().length; | ||
} else if (state.scope.align) { | ||
state.scope.align = false; | ||
} | ||
@@ -272,3 +274,2 @@ state.scope = { | ||
!state.lambda && | ||
state.scope.type == "coffee" && | ||
!stream.peek()) | ||
@@ -297,5 +298,6 @@ || style === "indent") { | ||
if (delimiter_index !== -1) { | ||
if (dedent(stream, state)) { | ||
return ERRORCLASS; | ||
} | ||
while (state.scope.type == "coffee" && state.scope.prev) | ||
state.scope = state.scope.prev; | ||
if (state.scope.type == current) | ||
state.scope = state.scope.prev; | ||
} | ||
@@ -339,7 +341,10 @@ if (state.dedent > 0 && stream.eol() && state.scope.type == "coffee") { | ||
if (state.tokenize != tokenBase) return 0; | ||
var closes = state.scope.type === (text && text.charAt(0)); | ||
if (state.scope.align) | ||
return state.scope.alignOffset - (closes ? 1 : 0); | ||
var scope = state.scope; | ||
var closer = text && "])}".indexOf(text.charAt(0)) > -1; | ||
if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev; | ||
var closes = closer && scope.type === text.charAt(0); | ||
if (scope.align) | ||
return scope.alignOffset - (closes ? 1 : 0); | ||
else | ||
return (closes ? state.scope.prev : state.scope).offset; | ||
return (closes ? scope.prev : scope).offset; | ||
}, | ||
@@ -346,0 +351,0 @@ |
@@ -265,3 +265,3 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | ||
var removed = state.stack.pop(); | ||
if(removed.indexOf("{") > -1){ | ||
if(removed.indexOf("{") > -1 || removed == "block" || removed == "rule"){ | ||
break; | ||
@@ -613,4 +613,4 @@ } | ||
}, | ||
",": function(_stream, state) { | ||
if (state.stack[state.stack.length - 1] == "propertyValue") { | ||
",": function(stream, state) { | ||
if (state.stack[state.stack.length - 1] == "propertyValue" && stream.match(/^ *\$/, false)) { | ||
return ["operator", ";"]; | ||
@@ -617,0 +617,0 @@ } |
@@ -84,2 +84,11 @@ (function() { | ||
"@mixin container[1 (][2 $a: 10][1 , ][2 $b: 10][1 , ][2 $c: 10]) [1 {]}"); | ||
IT('nested', | ||
"foo [1 { bar ][2 { ][1 } ]}"); | ||
IT('comma', | ||
"foo [1 { font-family][2 : verdana, sans-serif][1 ; ]}"); | ||
IT('parentheses', | ||
"foo [1 { color][2 : darken][3 ($blue, 9%][2 )][1 ; ]}"); | ||
})(); |
@@ -130,2 +130,14 @@ (function() { | ||
"strong, em [1 { background][2 : rgba][3 (255, 255, 0, .2][2 )][1 ;]}"); | ||
IT("atMedia", | ||
"[1 @media { foo ][2 { ][1 } ]}"); | ||
IT("comma", | ||
"foo [1 { font-family][2 : verdana, sans-serif][1 ; ]}"); | ||
IT("parentheses", | ||
"foo [1 { background][2 : url][3 (\"bar\"][2 )][1 ; ]}"); | ||
IT("pseudo", | ||
"foo:before [1 { ]}"); | ||
})(); |
@@ -161,3 +161,3 @@ CodeMirror.defineMode("go", function(config) { | ||
electricChars: "{}:", | ||
electricChars: "{}):", | ||
blockCommentStart: "/*", | ||
@@ -164,0 +164,0 @@ blockCommentEnd: "*/", |
@@ -240,3 +240,3 @@ CodeMirror.defineMode("haskell", function(_config, modeConfig) { | ||
var w = stream.current(); | ||
return (w in wellKnownWords) ? wellKnownWords[w] : t; | ||
return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t; | ||
}, | ||
@@ -243,0 +243,0 @@ |
@@ -47,3 +47,3 @@ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { | ||
stream.backUp(cur.length); | ||
if (!stream.match(pat, false)) stream.match(cur[0]); | ||
if (!stream.match(pat, false)) stream.match(cur); | ||
} | ||
@@ -50,0 +50,0 @@ return style; |
@@ -24,3 +24,4 @@ // TODO actually recognize syntax of TypeScript constructs | ||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, | ||
"this": kw("this") | ||
"this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), | ||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C | ||
}; | ||
@@ -34,3 +35,2 @@ | ||
"interface": kw("interface"), | ||
"class": kw("class"), | ||
"extends": kw("extends"), | ||
@@ -45,4 +45,2 @@ "constructor": kw("constructor"), | ||
"super": kw("super"), | ||
// types | ||
@@ -62,7 +60,2 @@ "string": type, "number": type, "bool": type, "any": type | ||
function chain(stream, state, f) { | ||
state.tokenize = f; | ||
return f(stream, state); | ||
} | ||
function nextUntilUnescaped(stream, end) { | ||
@@ -85,46 +78,47 @@ var escaped = false, next; | ||
} | ||
function jsTokenBase(stream, state) { | ||
function tokenBase(stream, state) { | ||
var ch = stream.next(); | ||
if (ch == '"' || ch == "'") | ||
return chain(stream, state, jsTokenString(ch)); | ||
else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) | ||
if (ch == '"' || ch == "'") { | ||
state.tokenize = tokenString(ch); | ||
return state.tokenize(stream, state); | ||
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { | ||
return ret("number", "number"); | ||
else if (/[\[\]{}\(\),;\:\.]/.test(ch)) | ||
} else if (ch == "." && stream.match("..")) { | ||
return ret("spread", "meta"); | ||
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { | ||
return ret(ch); | ||
else if (ch == "0" && stream.eat(/x/i)) { | ||
} else if (ch == "=" && stream.eat(">")) { | ||
return ret("=>"); | ||
} else if (ch == "0" && stream.eat(/x/i)) { | ||
stream.eatWhile(/[\da-f]/i); | ||
return ret("number", "number"); | ||
} | ||
else if (/\d/.test(ch)) { | ||
} else if (/\d/.test(ch)) { | ||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); | ||
return ret("number", "number"); | ||
} | ||
else if (ch == "/") { | ||
} else if (ch == "/") { | ||
if (stream.eat("*")) { | ||
return chain(stream, state, jsTokenComment); | ||
} | ||
else if (stream.eat("/")) { | ||
state.tokenize = tokenComment; | ||
return tokenComment(stream, state); | ||
} else if (stream.eat("/")) { | ||
stream.skipToEnd(); | ||
return ret("comment", "comment"); | ||
} | ||
else if (state.lastType == "operator" || state.lastType == "keyword c" || | ||
/^[\[{}\(,;:]$/.test(state.lastType)) { | ||
} else if (state.lastType == "operator" || state.lastType == "keyword c" || | ||
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { | ||
nextUntilUnescaped(stream, "/"); | ||
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla | ||
return ret("regexp", "string-2"); | ||
} | ||
else { | ||
} else { | ||
stream.eatWhile(isOperatorChar); | ||
return ret("operator", null, stream.current()); | ||
} | ||
} | ||
else if (ch == "#") { | ||
} else if (ch == "`") { | ||
state.tokenize = tokenQuasi; | ||
return tokenQuasi(stream, state); | ||
} else if (ch == "#") { | ||
stream.skipToEnd(); | ||
return ret("error", "error"); | ||
} | ||
else if (isOperatorChar.test(ch)) { | ||
} else if (isOperatorChar.test(ch)) { | ||
stream.eatWhile(isOperatorChar); | ||
return ret("operator", null, stream.current()); | ||
} | ||
else { | ||
} else { | ||
stream.eatWhile(/[\w\$_]/); | ||
@@ -137,6 +131,6 @@ var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; | ||
function jsTokenString(quote) { | ||
function tokenString(quote) { | ||
return function(stream, state) { | ||
if (!nextUntilUnescaped(stream, quote)) | ||
state.tokenize = jsTokenBase; | ||
state.tokenize = tokenBase; | ||
return ret("string", "string"); | ||
@@ -146,7 +140,7 @@ }; | ||
function jsTokenComment(stream, state) { | ||
function tokenComment(stream, state) { | ||
var maybeEnd = false, ch; | ||
while (ch = stream.next()) { | ||
if (ch == "/" && maybeEnd) { | ||
state.tokenize = jsTokenBase; | ||
state.tokenize = tokenBase; | ||
break; | ||
@@ -159,2 +153,46 @@ } | ||
function tokenQuasi(stream, state) { | ||
var escaped = false, next; | ||
while ((next = stream.next()) != null) { | ||
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { | ||
state.tokenize = tokenBase; | ||
break; | ||
} | ||
escaped = !escaped && next == "\\"; | ||
} | ||
return ret("quasi", "string-2", stream.current()); | ||
} | ||
var brackets = "([{}])"; | ||
// This is a crude lookahead trick to try and notice that we're | ||
// parsing the argument patterns for a fat-arrow function before we | ||
// actually hit the arrow token. It only works if the arrow is on | ||
// the same line as the arguments and there's no strange noise | ||
// (comments) in between. Fallback is to only notice when we hit the | ||
// arrow, and not declare the arguments as locals for the arrow | ||
// body. | ||
function findFatArrow(stream, state) { | ||
if (state.fatArrowAt) state.fatArrowAt = null; | ||
var arrow = stream.string.indexOf("=>", stream.start); | ||
if (arrow < 0) return; | ||
var depth = 0, sawSomething = false; | ||
for (var pos = arrow - 1; pos >= 0; --pos) { | ||
var ch = stream.string.charAt(pos); | ||
var bracket = brackets.indexOf(ch); | ||
if (bracket >= 0 && bracket < 3) { | ||
if (!depth) { ++pos; break; } | ||
if (--depth == 0) break; | ||
} else if (bracket >= 3 && bracket < 6) { | ||
++depth; | ||
} else if (/[$\w]/.test(ch)) { | ||
sawSomething = true; | ||
} else if (sawSomething && !depth) { | ||
++pos; | ||
break; | ||
} | ||
} | ||
if (sawSomething && !depth) state.fatArrowAt = pos; | ||
} | ||
// Parser | ||
@@ -176,2 +214,6 @@ | ||
if (v.name == varname) return true; | ||
for (var cx = state.context; cx; cx = cx.prev) { | ||
for (var v = cx.vars; v; v = v.next) | ||
if (v.name == varname) return true; | ||
} | ||
} | ||
@@ -223,3 +265,4 @@ | ||
if (inList(state.globalVars)) return; | ||
state.globalVars = {name: varname, next: state.globalVars}; | ||
if (parserConfig.globalVars) | ||
state.globalVars = {name: varname, next: state.globalVars}; | ||
} | ||
@@ -266,4 +309,4 @@ } | ||
function statement(type) { | ||
if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); | ||
function statement(type, value) { | ||
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); | ||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); | ||
@@ -275,4 +318,3 @@ if (type == "keyword b") return cont(pushlex("form"), statement, poplex); | ||
if (type == "function") return cont(functiondef); | ||
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), | ||
poplex, statement, poplex); | ||
if (type == "for") return cont(pushlex("form"), forspec, poplex, statement, poplex); | ||
if (type == "variable") return cont(pushlex("stat"), maybelabel); | ||
@@ -285,2 +327,6 @@ if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), | ||
statement, poplex, popcontext); | ||
if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); | ||
if (type == "class") return cont(pushlex("form"), className, objlit, poplex); | ||
if (type == "export") return cont(pushlex("form"), afterExport, poplex); | ||
if (type == "import") return cont(pushlex("form"), afterImport, poplex); | ||
return pass(pushlex("stat"), expression, expect(";"), poplex); | ||
@@ -295,2 +341,8 @@ } | ||
function expressionInner(type, noComma) { | ||
if (cx.state.fatArrowAt == cx.stream.start) { | ||
var body = noComma ? arrowBodyNoComma : arrowBody; | ||
if (type == "(") return cont(pushcontext, commasep(pattern, ")"), expect("=>"), body, popcontext); | ||
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); | ||
} | ||
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; | ||
@@ -300,6 +352,6 @@ if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); | ||
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); | ||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); | ||
if (type == "operator") return cont(noComma ? expressionNoComma : expression); | ||
if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop); | ||
if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop); | ||
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); | ||
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); | ||
if (type == "[") return cont(pushlex("]"), expressionNoComma, maybeArrayComprehension, poplex, maybeop); | ||
if (type == "{") return cont(commasep(objprop, "}"), maybeop); | ||
return cont(); | ||
@@ -323,2 +375,3 @@ } | ||
var expr = noComma == false ? expression : expressionNoComma; | ||
if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); | ||
if (type == "operator") { | ||
@@ -329,7 +382,30 @@ if (/\+\+|--/.test(value)) return cont(me); | ||
} | ||
if (type == "quasi") { cx.cc.push(me); return quasi(value); } | ||
if (type == ";") return; | ||
if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me); | ||
if (type == "(") return cont(commasep(expressionNoComma, ")", "call"), me); | ||
if (type == ".") return cont(property, me); | ||
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); | ||
} | ||
function quasi(value) { | ||
if (!value) debugger; | ||
if (value.slice(value.length - 2) != "${") return cont(); | ||
return cont(expression, continueQuasi); | ||
} | ||
function continueQuasi(type) { | ||
if (type == "}") { | ||
cx.marked = "string-2"; | ||
cx.state.tokenize = tokenQuasi; | ||
return cont(); | ||
} | ||
} | ||
function arrowBody(type) { | ||
findFatArrow(cx.stream, cx.state); | ||
if (type == "{") return pass(statement); | ||
return pass(expression); | ||
} | ||
function arrowBodyNoComma(type) { | ||
findFatArrow(cx.stream, cx.state); | ||
if (type == "{") return pass(statement); | ||
return pass(expressionNoComma); | ||
} | ||
function maybelabel(type) { | ||
@@ -348,12 +424,17 @@ if (type == ":") return cont(poplex, statement); | ||
cx.marked = type + " property"; | ||
} else if (type == "[") { | ||
return cont(expression, expect("]"), afterprop); | ||
} | ||
if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma); | ||
if (atomicTypes.hasOwnProperty(type)) return cont(afterprop); | ||
} | ||
function getterSetter(type) { | ||
if (type == ":") return cont(expression); | ||
if (type != "variable") return cont(expect(":"), expression); | ||
if (type != "variable") return pass(afterprop); | ||
cx.marked = "property"; | ||
return cont(functiondef); | ||
} | ||
function commasep(what, end) { | ||
function afterprop(type) { | ||
if (type == ":") return cont(expressionNoComma); | ||
if (type == "(") return pass(functiondef); | ||
} | ||
function commasep(what, end, info) { | ||
function proceed(type) { | ||
@@ -370,3 +451,4 @@ if (type == ",") { | ||
if (type == end) return cont(); | ||
else return pass(what, proceed); | ||
if (info === false) return pass(what, proceed); | ||
return pass(pushlex(end, info), what, proceed, poplex); | ||
}; | ||
@@ -379,31 +461,43 @@ } | ||
function maybetype(type) { | ||
if (type == ":") return cont(typedef); | ||
return pass(); | ||
if (isTS && type == ":") return cont(typedef); | ||
} | ||
function typedef(type) { | ||
if (type == "variable"){cx.marked = "variable-3"; return cont();} | ||
return pass(); | ||
} | ||
function vardef1(type, value) { | ||
if (type == "variable") { | ||
function vardef() { | ||
return pass(pattern, maybetype, maybeAssign, vardefCont); | ||
} | ||
function pattern(type, value) { | ||
if (type == "variable") { register(value); return cont(); } | ||
if (type == "[") return cont(commasep(pattern, "]")); | ||
if (type == "{") return cont(commasep(proppattern, "}")); | ||
} | ||
function proppattern(type, value) { | ||
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { | ||
register(value); | ||
return isTS ? cont(maybetype, vardef2) : cont(vardef2); | ||
return cont(maybeAssign); | ||
} | ||
return pass(); | ||
if (type == "variable") cx.marked = "property"; | ||
return cont(expect(":"), pattern, maybeAssign); | ||
} | ||
function vardef2(type, value) { | ||
if (value == "=") return cont(expressionNoComma, vardef2); | ||
if (type == ",") return cont(vardef1); | ||
function maybeAssign(_type, value) { | ||
if (value == "=") return cont(expressionNoComma); | ||
} | ||
function vardefCont(type) { | ||
if (type == ",") return cont(vardef); | ||
} | ||
function maybeelse(type, value) { | ||
if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex); | ||
} | ||
function forspec(type) { | ||
if (type == "(") return cont(pushlex(")"), forspec1, expect(")")); | ||
} | ||
function forspec1(type) { | ||
if (type == "var") return cont(vardef1, expect(";"), forspec2); | ||
if (type == "var") return cont(vardef, expect(";"), forspec2); | ||
if (type == ";") return cont(forspec2); | ||
if (type == "variable") return cont(formaybein); | ||
if (type == "variable") return cont(formaybeinof); | ||
return pass(expression, expect(";"), forspec2); | ||
} | ||
function formaybein(_type, value) { | ||
if (value == "in") return cont(expression); | ||
function formaybeinof(_type, value) { | ||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } | ||
return cont(maybeoperatorComma, forspec2); | ||
@@ -413,3 +507,3 @@ } | ||
if (type == ";") return cont(forspec3); | ||
if (value == "in") return cont(expression); | ||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } | ||
return pass(expression, expect(";"), forspec3); | ||
@@ -421,8 +515,49 @@ } | ||
function functiondef(type, value) { | ||
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} | ||
if (type == "variable") {register(value); return cont(functiondef);} | ||
if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); | ||
if (type == "(") return cont(pushcontext, commasep(funarg, ")"), statement, popcontext); | ||
} | ||
function funarg(type, value) { | ||
if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();} | ||
function funarg(type) { | ||
if (type == "spread") return cont(funarg); | ||
return pass(pattern, maybetype); | ||
} | ||
function className(type, value) { | ||
if (type == "variable") {register(value); return cont(classNameAfter);} | ||
} | ||
function classNameAfter(_type, value) { | ||
if (value == "extends") return cont(expression); | ||
} | ||
function objlit(type) { | ||
if (type == "{") return cont(commasep(objprop, "}")); | ||
} | ||
function afterModule(type, value) { | ||
if (type == "string") return cont(statement); | ||
if (type == "variable") { register(value); return cont(maybeFrom); } | ||
} | ||
function afterExport(_type, value) { | ||
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } | ||
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } | ||
return pass(statement); | ||
} | ||
function afterImport(type) { | ||
if (type == "string") return cont(); | ||
return pass(importSpec, maybeFrom); | ||
} | ||
function importSpec(type, value) { | ||
if (type == "{") return cont(commasep(importSpec, "}")); | ||
if (type == "variable") register(value); | ||
return cont(); | ||
} | ||
function maybeFrom(_type, value) { | ||
if (value == "from") { cx.marked = "keyword"; return cont(expression); } | ||
} | ||
function maybeArrayComprehension(type) { | ||
if (type == "for") return pass(comprehension); | ||
if (type == ",") return cont(commasep(expressionNoComma, "]", false)); | ||
return pass(commasep(expressionNoComma, "]", false)); | ||
} | ||
function comprehension(type) { | ||
if (type == "for") return cont(forspec, comprehension); | ||
if (type == "if") return cont(expression, comprehension); | ||
} | ||
@@ -433,12 +568,13 @@ // Interface | ||
startState: function(basecolumn) { | ||
return { | ||
tokenize: jsTokenBase, | ||
lastType: null, | ||
var state = { | ||
tokenize: tokenBase, | ||
lastType: "sof", | ||
cc: [], | ||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), | ||
localVars: parserConfig.localVars, | ||
globalVars: parserConfig.globalVars, | ||
context: parserConfig.localVars && {vars: parserConfig.localVars}, | ||
indented: 0 | ||
}; | ||
if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars; | ||
return state; | ||
}, | ||
@@ -451,4 +587,5 @@ | ||
state.indented = stream.indentation(); | ||
findFatArrow(stream, state); | ||
} | ||
if (state.tokenize != jsTokenComment && stream.eatSpace()) return null; | ||
if (state.tokenize != tokenComment && stream.eatSpace()) return null; | ||
var style = state.tokenize(stream, state); | ||
@@ -461,4 +598,4 @@ if (type == "comment") return style; | ||
indent: function(state, textAfter) { | ||
if (state.tokenize == jsTokenComment) return CodeMirror.Pass; | ||
if (state.tokenize != jsTokenBase) return 0; | ||
if (state.tokenize == tokenComment) return CodeMirror.Pass; | ||
if (state.tokenize != tokenBase) return 0; | ||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; | ||
@@ -469,3 +606,3 @@ // Kludge to prevent 'maybelse' from blocking lexical scope pops | ||
if (c == poplex) lexical = lexical.prev; | ||
else if (c != maybeelse || /^else\b/.test(textAfter)) break; | ||
else if (c != maybeelse) break; | ||
} | ||
@@ -477,3 +614,3 @@ if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; | ||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0); | ||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); | ||
else if (type == "form" && firstChar == "{") return lexical.indented; | ||
@@ -480,0 +617,0 @@ else if (type == "form") return lexical.indented + indentUnit; |
@@ -10,2 +10,64 @@ (function() { | ||
"[keyword function](){ [keyword var] [def x] = [number 1] + [number 2], [def y]; }"); | ||
MT("destructuring", | ||
"([keyword function]([def a], [[[def b], [def c] ]]) {", | ||
" [keyword let] {[def d], [property foo]: [def c]=[number 10], [def x]} = [variable foo]([variable-2 a]);", | ||
" [[[variable-2 c], [variable y] ]] = [variable-2 c];", | ||
"})();"); | ||
MT("class", | ||
"[keyword class] [variable Point] [keyword extends] [variable SuperThing] {", | ||
" [[ [string-2 /expr/] ]]: [number 24],", | ||
" [property constructor]([def x], [def y]) {", | ||
" [keyword super]([string 'something']);", | ||
" [keyword this].[property x] = [variable-2 x];", | ||
" }", | ||
"}"); | ||
MT("module", | ||
"[keyword module] [string 'foo'] {", | ||
" [keyword export] [keyword let] [def x] = [number 42];", | ||
" [keyword export] [keyword *] [keyword from] [string 'somewhere'];", | ||
"}"); | ||
MT("import", | ||
"[keyword function] [variable foo]() {", | ||
" [keyword import] [def $] [keyword from] [string 'jquery'];", | ||
" [keyword module] [def crypto] [keyword from] [string 'crypto'];", | ||
" [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];", | ||
"}"); | ||
MT("const", | ||
"[keyword function] [variable f]() {", | ||
" [keyword const] [[ [def a], [def b] ]] = [[ [number 1], [number 2] ]];", | ||
"}"); | ||
MT("for/of", | ||
"[keyword for]([keyword let] [variable of] [keyword of] [variable something]) {}"); | ||
MT("generator", | ||
"[keyword function*] [variable repeat]([def n]) {", | ||
" [keyword for]([keyword var] [def i] = [number 0]; [variable-2 i] < [variable-2 n]; ++[variable-2 i])", | ||
" [keyword yield] [variable-2 i];", | ||
"}"); | ||
MT("fatArrow", | ||
"[variable array].[property filter]([def a] => [variable-2 a] + [number 1]);", | ||
"[variable a];", // No longer in scope | ||
"[keyword let] [variable f] = ([[ [def a], [def b] ]], [def c]) => [variable-2 a] + [variable-2 c];", | ||
"[variable c];"); | ||
MT("spread", | ||
"[keyword function] [variable f]([def a], [meta ...][def b]) {", | ||
" [variable something]([variable-2 a], [meta ...][variable-2 b]);", | ||
"}"); | ||
MT("comprehension", | ||
"[keyword function] [variable f]() {", | ||
" [[ [variable x] + [number 1] [keyword for] ([keyword var] [def x] [keyword in] [variable y]) [keyword if] [variable pred]([variable-2 x]) ]];", | ||
" ([variable u] [keyword for] ([keyword var] [def u] [keyword of] [variable generateValues]()) [keyword if] ([variable-2 u].[property color] === [string 'blue']));", | ||
"}"); | ||
MT("quasi", | ||
"[variable re][string-2 `fofdlakj${][variable x] + ([variable re][string-2 `foo`]) + [number 1][string-2 }fdsa`] + [number 2]"); | ||
})(); |
@@ -73,3 +73,5 @@ /* | ||
if(stream.peek() === ")" || type === ":")return ret("number", "unit");//rgba(0,0,0,.25); | ||
else if(state.stack[state.stack.length-1] === "rule" && stream.peek().match(/{|,|\+|\(/) === null)return ret("number", "unit"); | ||
else if(stream.current().length >1){ | ||
if(state.stack[state.stack.length-1] === "rule" && stream.peek().match(/{|,|\+|\(/) === null)return ret("number", "unit"); | ||
} | ||
return ret("tag", "tag"); | ||
@@ -208,3 +210,3 @@ } else if (ch == "#") { | ||
else if(type === ")" && state.stack[state.stack.length-1] === "rule")return ret(null, "unit"); | ||
else if(type.match("@") !== null && state.stack[state.stack.length-1] === "rule")return ret(null, "unit"); | ||
else if(type && type.match("@") !== null && state.stack[state.stack.length-1] === "rule")return ret(null, "unit"); | ||
//else if(type === "unit" && state.stack[state.stack.length-1] === "rule")return ret(null, stream.current()); | ||
@@ -211,0 +213,0 @@ |
@@ -77,3 +77,4 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { | ||
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE | ||
, headerRE = /^(?:\={1,}|-{1,})$/ | ||
, atxHeaderRE = /^#+/ | ||
, setextHeaderRE = /^(?:\={1,}|-{1,})$/ | ||
, textRE = /^[^!\[\]*_\\<>` "'(]+/; | ||
@@ -131,2 +132,3 @@ | ||
var match = null; | ||
if (state.indentationDiff >= 4) { | ||
@@ -138,4 +140,6 @@ state.indentation -= 4; | ||
return null; | ||
} else if (stream.peek() === '#' || (state.prevLineHasContent && stream.match(headerRE)) ) { | ||
state.header = true; | ||
} else if (match = stream.match(atxHeaderRE)) { | ||
state.header = match[0].length <= 6 ? match[0].length : 6; | ||
} else if (state.prevLineHasContent && (match = stream.match(setextHeaderRE))) { | ||
state.header = match[0].charAt(0) == '=' ? 1 : 2; | ||
} else if (stream.eat('>')) { | ||
@@ -213,3 +217,3 @@ state.indentation++; | ||
if (state.header) { styles.push(header); } | ||
if (state.header) { styles.push(header); styles.push(header + state.header); } | ||
if (state.quote) { styles.push(state.quote % 2 ? quote1 : quote2); } | ||
@@ -264,2 +268,5 @@ if (state.list !== false) { | ||
// Get sol() value now, before character is consumed | ||
var sol = stream.sol(); | ||
var ch = stream.next(); | ||
@@ -363,3 +370,5 @@ | ||
if (ch === '*' || (ch === '_' && !ignoreUnderscore)) { | ||
if (state.strong === ch && stream.eat(ch)) { // Remove STRONG | ||
if (sol && stream.peek() === ' ') { | ||
// Do nothing, surrounded by newline and space | ||
} else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG | ||
state.strong = false; | ||
@@ -475,3 +484,3 @@ return t; | ||
strong: false, | ||
header: false, | ||
header: 0, | ||
taskList: false, | ||
@@ -527,3 +536,3 @@ list: false, | ||
// Reset state.header | ||
state.header = false; | ||
state.header = 0; | ||
@@ -530,0 +539,0 @@ // Reset state.taskList |
@@ -90,18 +90,18 @@ (function() { | ||
MT("atxH1", | ||
"[header # foo]"); | ||
"[header&header1 # foo]"); | ||
MT("atxH2", | ||
"[header ## foo]"); | ||
"[header&header2 ## foo]"); | ||
MT("atxH3", | ||
"[header ### foo]"); | ||
"[header&header3 ### foo]"); | ||
MT("atxH4", | ||
"[header #### foo]"); | ||
"[header&header4 #### foo]"); | ||
MT("atxH5", | ||
"[header ##### foo]"); | ||
"[header&header5 ##### foo]"); | ||
MT("atxH6", | ||
"[header ###### foo]"); | ||
"[header&header6 ###### foo]"); | ||
@@ -111,4 +111,8 @@ // H6 - 7x '#' should still be H6, per Dingus | ||
MT("atxH6NotH7", | ||
"[header ####### foo]"); | ||
"[header&header6 ####### foo]"); | ||
// Inline styles should be parsed inside headers | ||
MT("atxH1inline", | ||
"[header&header1 # foo ][header&header1&em *bar*]"); | ||
// Setext headers - H1, H2 | ||
@@ -124,3 +128,3 @@ // Per documentation, "Any number of underlining =’s or -’s will work." | ||
"foo", | ||
"[header =]"); | ||
"[header&header1 =]"); | ||
@@ -130,3 +134,3 @@ // Check if 3+ ='s work | ||
"foo", | ||
"[header ===]"); | ||
"[header&header1 ===]"); | ||
@@ -136,3 +140,3 @@ // Check if single underlining - works | ||
"foo", | ||
"[header -]"); | ||
"[header&header2 -]"); | ||
@@ -142,3 +146,3 @@ // Check if 3+ -'s work | ||
"foo", | ||
"[header ---]"); | ||
"[header&header2 ---]"); | ||
@@ -586,2 +590,6 @@ // Single-line blockquote with trailing space | ||
MT("emEscapedByNewline", | ||
"foo", | ||
"_ bar[em _hello_]world"); | ||
// Unclosed emphasis characters | ||
@@ -588,0 +596,0 @@ // Instead of simply marking as EM / STRONG, it would be nice to have an |
@@ -39,3 +39,4 @@ CodeMirror.modeInfo = [ | ||
{name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'}, | ||
{name: 'Jinja2', mime: 'jinja2', mode: 'jinja2'}, | ||
{name: 'Jinja2', mime: null, mode: 'jinja2'}, | ||
{name: 'Julia', mime: 'text/x-julia', mode: 'julia'}, | ||
{name: 'LESS', mime: 'text/x-less', mode: 'less'}, | ||
@@ -51,2 +52,3 @@ {name: 'LiveScript', mime: 'text/x-livescript', mode: 'livescript'}, | ||
{name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'}, | ||
{name: 'PEG.js', mime: null, mode: 'pegjs'}, | ||
{name: 'Perl', mime: 'text/x-perl', mode: 'perl'}, | ||
@@ -53,0 +55,0 @@ {name: 'PHP', mime: 'text/x-php', mode: 'php'}, |
@@ -160,3 +160,3 @@ /* | ||
+ "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE " | ||
+ "NEQ MATCHES TRUE FALSE "; | ||
+ "NEQ MATCHES TRUE FALSE DUMP"; | ||
@@ -163,0 +163,0 @@ // data types |
{ | ||
"name": "codemirror", | ||
"version":"3.19.0", | ||
"version":"3.20.0", | ||
"main": "lib/codemirror.js", | ||
@@ -5,0 +5,0 @@ "description": "In-browser code editing made bearable", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2399074
337
39333