71 changes: 71 additions & 0 deletions mode/webidl/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!doctype html>

<title>CodeMirror: Web IDL mode</title>
<meta charset="utf-8">
<link rel="stylesheet" href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="webidl.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>

<div id="nav">
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id="logo" src="../../doc/logo.png"></a>

<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class="active" href="#">Web IDL</a>
</ul>
</div>

<article>
<h2>Web IDL mode</h2>

<div>
<textarea id="code" name="code">
[NamedConstructor=Image(optional unsigned long width, optional unsigned long height)]
interface HTMLImageElement : HTMLElement {
attribute DOMString alt;
attribute DOMString src;
attribute DOMString srcset;
attribute DOMString sizes;
attribute DOMString? crossOrigin;
attribute DOMString useMap;
attribute boolean isMap;
attribute unsigned long width;
attribute unsigned long height;
readonly attribute unsigned long naturalWidth;
readonly attribute unsigned long naturalHeight;
readonly attribute boolean complete;
readonly attribute DOMString currentSrc;

// also has obsolete members
};

partial interface HTMLImageElement {
attribute DOMString name;
attribute DOMString lowsrc;
attribute DOMString align;
attribute unsigned long hspace;
attribute unsigned long vspace;
attribute DOMString longDesc;

[TreatNullAs=EmptyString] attribute DOMString border;
};
</textarea>
</div>

<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true
});
</script>

<p><strong>MIME type defined:</strong> <code>text/x-webidl</code>.</p>
</article>
195 changes: 195 additions & 0 deletions mode/webidl/webidl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(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";

function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b");
};

var builtinArray = [
"Clamp",
"Constructor",
"EnforceRange",
"Exposed",
"ImplicitThis",
"Global", "PrimaryGlobal",
"LegacyArrayClass",
"LegacyUnenumerableNamedProperties",
"LenientThis",
"NamedConstructor",
"NewObject",
"NoInterfaceObject",
"OverrideBuiltins",
"PutForwards",
"Replaceable",
"SameObject",
"TreatNonObjectAsNull",
"TreatNullAs",
"EmptyString",
"Unforgeable",
"Unscopeable"
];
var builtins = wordRegexp(builtinArray);

var typeArray = [
"unsigned", "short", "long", // UnsignedIntegerType
"unrestricted", "float", "double", // UnrestrictedFloatType
"boolean", "byte", "octet", // Rest of PrimitiveType
"Promise", // PromiseType
"ArrayBuffer", "DataView", "Int8Array", "Int16Array", "Int32Array",
"Uint8Array", "Uint16Array", "Uint32Array", "Uint8ClampedArray",
"Float32Array", "Float64Array", // BufferRelatedType
"ByteString", "DOMString", "USVString", "sequence", "object", "RegExp",
"Error", "DOMException", "FrozenArray", // Rest of NonAnyType
"any", // Rest of SingleType
"void" // Rest of ReturnType
];
var types = wordRegexp(typeArray);

var keywordArray = [
"attribute", "callback", "const", "deleter", "dictionary", "enum", "getter",
"implements", "inherit", "interface", "iterable", "legacycaller", "maplike",
"partial", "required", "serializer", "setlike", "setter", "static",
"stringifier", "typedef", // ArgumentNameKeyword except
// "unrestricted"
"optional", "readonly", "or"
];
var keywords = wordRegexp(keywordArray);

var atomArray = [
"true", "false", // BooleanLiteral
"Infinity", "NaN", // FloatLiteral
"null" // Rest of ConstValue
];
var atoms = wordRegexp(atomArray);

CodeMirror.registerHelper("hintWords", "webidl",
builtinArray.concat(typeArray).concat(keywordArray).concat(atomArray));

var startDefArray = ["callback", "dictionary", "enum", "interface"];
var startDefs = wordRegexp(startDefArray);

var endDefArray = ["typedef"];
var endDefs = wordRegexp(endDefArray);

var singleOperators = /^[:<=>?]/;
var integers = /^-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/;
var floats = /^-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/;
var identifiers = /^_?[A-Za-z][0-9A-Z_a-z-]*/;
var identifiersEnd = /^_?[A-Za-z][0-9A-Z_a-z-]*(?=\s*;)/;
var strings = /^"[^"]*"/;
var multilineComments = /^\/\*.*?\*\//;
var multilineCommentsStart = /^\/\*.*/;
var multilineCommentsEnd = /^.*?\*\//;

function readToken(stream, state) {
// whitespace
if (stream.eatSpace()) return null;

// comment
if (state.inComment) {
if (stream.match(multilineCommentsEnd)) {
state.inComment = false;
return "comment";
}
stream.skipToEnd();
return "comment";
}
if (stream.match("//")) {
stream.skipToEnd();
return "comment";
}
if (stream.match(multilineComments)) return "comment";
if (stream.match(multilineCommentsStart)) {
state.inComment = true;
return "comment";
}

// integer and float
if (stream.match(/^-?[0-9\.]/, false)) {
if (stream.match(integers) || stream.match(floats)) return "number";
}

// string
if (stream.match(strings)) return "string";

// identifier
if (state.startDef && stream.match(identifiers)) return "def";

if (state.endDef && stream.match(identifiersEnd)) {
state.endDef = false;
return "def";
}

if (stream.match(keywords)) return "keyword";

if (stream.match(types)) {
var lastToken = state.lastToken;
var nextToken = (stream.match(/^\s*(.+?)\b/, false) || [])[1];

if (lastToken === ":" || lastToken === "implements" ||
nextToken === "implements" || nextToken === "=") {
// Used as identifier
return "builtin";
} else {
// Used as type
return "variable-3";
}
}

if (stream.match(builtins)) return "builtin";
if (stream.match(atoms)) return "atom";
if (stream.match(identifiers)) return "variable";

// other
if (stream.match(singleOperators)) return "operator";

// unrecognized
stream.next();
return null;
};

CodeMirror.defineMode("webidl", function() {
return {
startState: function() {
return {
// Is in multiline comment
inComment: false,
// Last non-whitespace, matched token
lastToken: "",
// Next token is a definition
startDef: false,
// Last token of the statement is a definition
endDef: false
};
},
token: function(stream, state) {
var style = readToken(stream, state);

if (style) {
var cur = stream.current();
state.lastToken = cur;
if (style === "keyword") {
state.startDef = startDefs.test(cur);
state.endDef = state.endDef || endDefs.test(cur);
} else {
state.startDef = false;
}
}

return style;
}
};
});

CodeMirror.defineMIME("text/x-webidl", "webidl");
});
2 changes: 1 addition & 1 deletion mode/xquery/xquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ CodeMirror.defineMode("xquery", function() {
// function. Each keyword is a property of the keywords object whose
// value is {type: atype, style: astyle}
var keywords = function(){
// conveinence functions used to build keywords object
// convenience functions used to build keywords object
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a")
, B = kw("keyword b")
Expand Down
87 changes: 87 additions & 0 deletions mode/yacas/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!doctype html>

<title>CodeMirror: yacas mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">

<link rel=stylesheet href=../../lib/codemirror.css>
<script src=../../lib/codemirror.js></script>
<script src=../../addon/edit/matchbrackets.js></script>
<script src=yacas.js></script>
<style type=text/css>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>

<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">yacas</a>
</ul>
</div>

<article>
<h2>yacas mode</h2>


<textarea id="yacasCode">
// example yacas code
Graph(edges_IsList) <-- [
Local(v, e, f, t);

vertices := {};

ForEach (e, edges) [
If (IsList(e), e := Head(e));
{f, t} := Tail(Listify(e));

DestructiveAppend(vertices, f);
DestructiveAppend(vertices, t);
];

Graph(RemoveDuplicates(vertices), edges);
];

10 # IsGraph(Graph(vertices_IsList, edges_IsList)) <-- True;
20 # IsGraph(_x) <-- False;

Edges(Graph(vertices_IsList, edges_IsList)) <-- edges;
Vertices(Graph(vertices_IsList, edges_IsList)) <-- vertices;

AdjacencyList(g_IsGraph) <-- [
Local(l, vertices, edges, e, op, f, t);

l := Association'Create();

vertices := Vertices(g);
ForEach (v, vertices)
Association'Set(l, v, {});

edges := Edges(g);

ForEach(e, edges) [
If (IsList(e), e := Head(e));
{op, f, t} := Listify(e);
DestructiveAppend(Association'Get(l, f), t);
If (String(op) = "<->", DestructiveAppend(Association'Get(l, t), f));
];

l;
];
</textarea>

<script>
var yacasEditor = CodeMirror.fromTextArea(document.getElementById('yacasCode'), {
mode: 'text/x-yacas',
lineNumbers: true,
matchBrackets: true
});
</script>

<p><strong>MIME types defined:</strong> <code>text/x-yacas</code> (yacas).</p>
</article>
204 changes: 204 additions & 0 deletions mode/yacas/yacas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Yacas mode copyright (c) 2015 by Grzegorz Mazur
// Loosely based on mathematica mode by Calin Barbat

(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('yacas', function(_config, _parserConfig) {

function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}

var bodiedOps = words("Assert BackQuote D Defun Deriv For ForEach FromFile " +
"FromString Function Integrate InverseTaylor Limit " +
"LocalSymbols Macro MacroRule MacroRulePattern " +
"NIntegrate Rule RulePattern Subst TD TExplicitSum " +
"TSum Taylor Taylor1 Taylor2 Taylor3 ToFile " +
"ToStdout ToString TraceRule Until While");

// patterns
var pFloatForm = "(?:(?:\\.\\d+|\\d+\\.\\d*|\\d+)(?:[eE][+-]?\\d+)?)";
var pIdentifier = "(?:[a-zA-Z\\$'][a-zA-Z0-9\\$']*)";

// regular expressions
var reFloatForm = new RegExp(pFloatForm);
var reIdentifier = new RegExp(pIdentifier);
var rePattern = new RegExp(pIdentifier + "?_" + pIdentifier);
var reFunctionLike = new RegExp(pIdentifier + "\\s*\\(");

function tokenBase(stream, state) {
var ch;

// get next character
ch = stream.next();

// string
if (ch === '"') {
state.tokenize = tokenString;
return state.tokenize(stream, state);
}

// comment
if (ch === '/') {
if (stream.eat('*')) {
state.tokenize = tokenComment;
return state.tokenize(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}

// go back one character
stream.backUp(1);

// update scope info
var m = stream.match(/^(\w+)\s*\(/, false);
if (m !== null && bodiedOps.hasOwnProperty(m[1]))
state.scopes.push('bodied');

var scope = currentScope(state);

if (scope === 'bodied' && ch === '[')
state.scopes.pop();

if (ch === '[' || ch === '{' || ch === '(')
state.scopes.push(ch);

scope = currentScope(state);

if (scope === '[' && ch === ']' ||
scope === '{' && ch === '}' ||
scope === '(' && ch === ')')
state.scopes.pop();

if (ch === ';') {
while (scope === 'bodied') {
state.scopes.pop();
scope = currentScope(state);
}
}

// look for ordered rules
if (stream.match(/\d+ *#/, true, false)) {
return 'qualifier';
}

// look for numbers
if (stream.match(reFloatForm, true, false)) {
return 'number';
}

// look for placeholders
if (stream.match(rePattern, true, false)) {
return 'variable-3';
}

// match all braces separately
if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {
return 'bracket';
}

// literals looking like function calls
if (stream.match(reFunctionLike, true, false)) {
stream.backUp(1);
return 'variable';
}

// all other identifiers
if (stream.match(reIdentifier, true, false)) {
return 'variable-2';
}

// operators; note that operators like @@ or /; are matched separately for each symbol.
if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {
return 'operator';
}

// everything else is an error
return 'error';
}

function tokenString(stream, state) {
var next, end = false, escaped = false;
while ((next = stream.next()) != null) {
if (next === '"' && !escaped) {
end = true;
break;
}
escaped = !escaped && next === '\\';
}
if (end && !escaped) {
state.tokenize = tokenBase;
}
return 'string';
};

function tokenComment(stream, state) {
var prev, next;
while((next = stream.next()) != null) {
if (prev === '*' && next === '/') {
state.tokenize = tokenBase;
break;
}
prev = next;
}
return 'comment';
}

function currentScope(state) {
var scope = null;
if (state.scopes.length > 0)
scope = state.scopes[state.scopes.length - 1];
return scope;
}

return {
startState: function() {
return {
tokenize: tokenBase,
scopes: []
};
},
token: function(stream, state) {
if (stream.eatSpace()) return null;
return state.tokenize(stream, state);
},
indent: function(state, textAfter) {
if (state.tokenize !== tokenBase && state.tokenize !== null)
return CodeMirror.Pass;

var delta = 0;
if (textAfter === ']' || textAfter === '];' ||
textAfter === '}' || textAfter === '};' ||
textAfter === ');')
delta = -1;

return (state.scopes.length + delta) * _config.indentUnit;
},
electricChars: "{}[]();",
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//"
};
});

CodeMirror.defineMIME('text/x-yacas', {
name: 'yacas'
});

});
2 changes: 1 addition & 1 deletion mode/yaml-frontmatter/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ <h2>YAML front matter mode</h2>
GFM adds syntax to strikethrough text, which is missing from standard Markdown.

~~Mistaken text.~~
~~**works with other fomatting**~~
~~**works with other formatting**~~

~~spans across
lines~~
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version":"5.13.3",
"version":"5.14.0",
"main": "lib/codemirror.js",
"description": "In-browser code editing made bearable",
"license": "MIT",
Expand Down
5 changes: 5 additions & 0 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<link rel="stylesheet" href="mode_test.css">
<script src="../doc/activebookmark.js"></script>
<script src="../lib/codemirror.js"></script>
<script src="../mode/meta.js"></script>
<script src="../addon/mode/overlay.js"></script>
<script src="../addon/mode/multiplex.js"></script>
<script src="../addon/search/searchcursor.js"></script>
Expand All @@ -26,6 +27,8 @@
<script src="../mode/jsx/jsx.js"></script>
<script src="../mode/markdown/markdown.js"></script>
<script src="../mode/php/php.js"></script>
<script src="../mode/python/python.js"></script>
<script src="../mode/powershell/powershell.js"></script>
<script src="../mode/ruby/ruby.js"></script>
<script src="../mode/shell/shell.js"></script>
<script src="../mode/slim/slim.js"></script>
Expand Down Expand Up @@ -112,6 +115,7 @@ <h2>Test Suite</h2>
<script src="../mode/jsx/test.js"></script>
<script src="../mode/markdown/test.js"></script>
<script src="../mode/php/test.js"></script>
<script src="../mode/powershell/test.js"></script>
<script src="../mode/ruby/test.js"></script>
<script src="../mode/shell/test.js"></script>
<script src="../mode/slim/test.js"></script>
Expand All @@ -120,6 +124,7 @@ <h2>Test Suite</h2>
<script src="../mode/verilog/test.js"></script>
<script src="../mode/xml/test.js"></script>
<script src="../mode/xquery/test.js"></script>
<script src="../mode/python/test.js"></script>
<script src="../mode/rust/test.js"></script>
<script src="../mode/mscgen/mscgen_test.js"></script>
<script src="../mode/mscgen/xu_test.js"></script>
Expand Down
16 changes: 12 additions & 4 deletions test/vim_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,10 @@ testJumplist('jumplist_repeat_<c-i>', ['*', '*', '*', '3', '<C-o>', '2', '<C-i>'
testJumplist('jumplist_repeated_motion', ['3', '*', '<C-o>'], [2,3], [2,3]);
testJumplist('jumplist_/', ['/', '<C-o>'], [2,3], [2,3], 'dialog');
testJumplist('jumplist_?', ['?', '<C-o>'], [2,3], [2,3], 'dialog');
testJumplist('jumplist_skip_delted_mark<c-o>',
testJumplist('jumplist_skip_deleted_mark<c-o>',
['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-o>', '<C-o>'],
[0,2], [0,2]);
testJumplist('jumplist_skip_delted_mark<c-i>',
testJumplist('jumplist_skip_deleted_mark<c-i>',
['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-i>', '<C-i>'],
[1,0], [0,2]);

Expand Down Expand Up @@ -482,7 +482,7 @@ testVim('gj_gk', function(cm, vim, helpers) {
var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
var endingCharCoords = cm.charCoords(endingPos);
is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');
},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentiallylongtotestmovementofgjandgkoverwrappedlines.' });
},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentionallylongtotestmovementofgjandgkoverwrappedlines.' });
testVim('}', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('}');
Expand Down Expand Up @@ -3682,7 +3682,7 @@ function testSubstituteConfirm(name, command, initialValue, expectedValue, keys,
} catch(e) {
throw e
} finally {
// Restore overriden functions.
// Restore overridden functions.
CodeMirror.keyName = savedKeyName;
cm.openDialog = savedOpenDialog;
}
Expand Down Expand Up @@ -3725,6 +3725,14 @@ testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {
helpers.doKeys('n');
helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting');
}, { value: 'match nope match \n nope Match' });
testVim('ex_yank', function (cm, vim, helpers) {
var curStart = makeCursor(3, 0);
cm.setCursor(curStart);
helpers.doEx('y');
var register = helpers.getRegisterController().getRegister();
var line = cm.getLine(3);
eq(line + '\n', register.toString());
});
testVim('set_boolean', function(cm, vim, helpers) {
CodeMirror.Vim.defineOption('testoption', true, 'boolean');
// Test default value is set.
Expand Down
8 changes: 4 additions & 4 deletions theme/icecoder.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
ICEcoder default theme by Matt Pass, used in code editor available at https://icecoder.net
*/

.cm-s-icecoder { color: #666; background: #141612; }
.cm-s-icecoder { color: #666; background: #1d1d1b; }

.cm-s-icecoder span.cm-keyword { color: #eee; font-weight:bold; } /* off-white 1 */
.cm-s-icecoder span.cm-atom { color: #e1c76e; } /* yellow */
Expand Down Expand Up @@ -37,7 +37,7 @@ ICEcoder default theme by Matt Pass, used in code editor available at https://ic

.cm-s-icecoder .CodeMirror-cursor { border-left: 1px solid white; }
.cm-s-icecoder div.CodeMirror-selected { color: #fff; background: #037; }
.cm-s-icecoder .CodeMirror-gutters { background: #141612; min-width: 41px; border-right: 0; }
.cm-s-icecoder .CodeMirror-gutters { background: #1d1d1b; min-width: 41px; border-right: 0; }
.cm-s-icecoder .CodeMirror-linenumber { color: #555; cursor: default; }
.cm-s-icecoder .CodeMirror-matchingbracket { border: 1px solid grey; color: black !important; }
.cm-s-icecoder .CodeMirror-activeline-background { background: #000; }
.cm-s-icecoder .CodeMirror-matchingbracket { color: #fff !important; background: #555 !important; }
.cm-s-icecoder .CodeMirror-activeline-background { background: #000; }