@@ -1,3 +1,13 @@
(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("http", function() {
function failFirstLine(stream, state) {
stream.skipToEnd();
@@ -96,3 +106,5 @@ CodeMirror.defineMode("http", function() {
});

CodeMirror.defineMIME("message/http", "http");

});
@@ -29,7 +29,7 @@ <h2>Language modes</h2>
option.</p>

<div style="-webkit-columns: 100px 2; -moz-columns: 100px 2; columns: 100px 2;">
<ul>
<ul style="margin-top: 0">
<li><a href="apl/index.html">APL</a></li>
<li><a href="asterisk/index.html">Asterisk dialplan</a></li>
<li><a href="clike/index.html">C, C++, C#</a></li>
@@ -81,7 +81,7 @@ <h2>Language modes</h2>
<li><a href="python/index.html">Python</a></li>
<li><a href="q/index.html">Q</a></li>
<li><a href="r/index.html">R</a></li>
<li>RPM <a href="rpm/spec/index.html">spec</a> and <a href="rpm/changes/index.html">changelog</a></li>
<li><a href="rpm/index.html">RPM</a></li>
<li><a href="rst/index.html">reStructuredText</a></li>
<li><a href="ruby/index.html">Ruby</a></li>
<li><a href="rust/index.html">Rust</a></li>
@@ -1,3 +1,13 @@
(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("jade", function () {
var symbol_regex1 = /^(?:~|!|%|\^|\*|\+|=|\\|:|;|,|\/|\?|&|<|>|\|)/;
var open_paren_regex = /^(\(|\[)/;
@@ -88,3 +98,5 @@ CodeMirror.defineMode("jade", function () {
});

CodeMirror.defineMIME('text/x-jade', 'jade');

});
@@ -1,5 +1,15 @@
// TODO actually recognize syntax of TypeScript constructs

(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("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent;
@@ -301,11 +311,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
poplex.lex = true;

function expect(wanted) {
return function(type) {
function exp(type) {
if (type == wanted) return cont();
else if (wanted == ";") return pass();
else return cont(arguments.callee);
else return cont(exp);
};
return exp;
}

function statement(type, value) {
@@ -637,3 +648,5 @@ CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });

});
@@ -1,4 +1,14 @@
CodeMirror.defineMode("jinja2", function() {
(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("jinja2", function() {
var keywords = ["and", "as", "block", "endblock", "by", "cycle", "debug", "else", "elif",
"extends", "filter", "endfilter", "firstof", "for",
"endfor", "if", "endif", "ifchanged", "endifchanged",
@@ -15,38 +25,39 @@ CodeMirror.defineMode("jinja2", function() {
keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");

function tokenBase (stream, state) {
var ch = stream.next();
if (ch == "{") {
if (ch = stream.eat(/\{|%|#/)) {
stream.eat("-");
state.tokenize = inTag(ch);
return "tag";
}
var ch = stream.next();
if (ch == "{") {
if (ch = stream.eat(/\{|%|#/)) {
stream.eat("-");
state.tokenize = inTag(ch);
return "tag";
}
}
}
function inTag (close) {
if (close == "{") {
close = "}";
if (close == "{") {
close = "}";
}
return function (stream, state) {
var ch = stream.next();
if ((ch == close || (ch == "-" && stream.eat(close)))
&& stream.eat("}")) {
state.tokenize = tokenBase;
return "tag";
}
return function (stream, state) {
var ch = stream.next();
if ((ch == close || (ch == "-" && stream.eat(close)))
&& stream.eat("}")) {
state.tokenize = tokenBase;
return "tag";
}
if (stream.match(keywords)) {
return "keyword";
}
return close == "#" ? "comment" : "string";
};
if (stream.match(keywords)) {
return "keyword";
}
return close == "#" ? "comment" : "string";
};
}
return {
startState: function () {
return {tokenize: tokenBase};
},
token: function (stream, state) {
return state.tokenize(stream, state);
}
startState: function () {
return {tokenize: tokenBase};
},
token: function (stream, state) {
return state.tokenize(stream, state);
}
};
});
});
@@ -1,3 +1,13 @@
(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("julia", function(_conf, parserConf) {
var ERRORCLASS = 'error';

@@ -284,3 +294,5 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {


CodeMirror.defineMIME("text/x-julia", "julia");

});

This file was deleted.

This file was deleted.

@@ -2,6 +2,17 @@
* Link to the project's GitHub page:
* https://github.com/duralog/CodeMirror
*/

(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() {
CodeMirror.defineMode('livescript', function(){
var tokenBase, external;
@@ -265,3 +276,5 @@
})();

CodeMirror.defineMIME('text/x-livescript', 'livescript');

});
@@ -2,6 +2,16 @@
// CodeMirror 1 mode.
// highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting

(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("lua", function(config, parserConfig) {
var indentUnit = config.indentUnit;

@@ -142,3 +152,5 @@ CodeMirror.defineMode("lua", function(config, parserConfig) {
});

CodeMirror.defineMIME("text/x-lua", "lua");

});
@@ -1,3 +1,13 @@
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror", require("../xml/xml")));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {

var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
@@ -746,3 +756,5 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}, "xml");

CodeMirror.defineMIME("text/x-markdown", "markdown");

});
@@ -1,3 +1,13 @@
(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.modeInfo = [
{name: 'APL', mime: 'text/apl', mode: 'apl'},
{name: 'Asterisk', mime: 'text/x-asterisk', mode: 'asterisk'},
@@ -40,7 +50,7 @@ CodeMirror.modeInfo = [
{name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'},
{name: 'Jinja2', mime: null, mode: 'jinja2'},
{name: 'Julia', mime: 'text/x-julia', mode: 'julia'},
{name: 'LESS', mime: 'text/x-less', mode: 'less'},
{name: 'LESS', mime: 'text/x-less', mode: 'css'},
{name: 'LiveScript', mime: 'text/x-livescript', mode: 'livescript'},
{name: 'Lua', mime: 'text/x-lua', mode: 'lua'},
{name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'},
@@ -88,8 +98,9 @@ CodeMirror.modeInfo = [
{name: 'Velocity', mime: 'text/velocity', mode: 'velocity'},
{name: 'Verilog', mime: 'text/x-verilog', mode: 'verilog'},
{name: 'XML', mime: 'application/xml', mode: 'xml'},
{name: 'HTML', mime: 'text/html', mode: 'xml'},
{name: 'XQuery', mime: 'application/xquery', mode: 'xquery'},
{name: 'YAML', mime: 'text/x-yaml', mode: 'yaml'},
{name: 'Z80', mime: 'text/x-z80', mode: 'z80'}
];

});
@@ -1,4 +1,15 @@
//mIRC mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara

(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.defineMIME("text/mirc", "mirc");
CodeMirror.defineMode("mirc", function() {
function parseWords(str) {
@@ -175,3 +186,5 @@ CodeMirror.defineMode("mirc", function() {
}
};
});

});
@@ -1,5 +1,14 @@
CodeMirror.defineMode('mllike', function(_config, parserConfig) {
(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('mllike', function(_config, parserConfig) {
var words = {
'let': 'keyword',
'rec': 'keyword',
@@ -189,3 +198,5 @@ CodeMirror.defineMIME('text/x-fsharp', {
},
slashComments: true
});

});
@@ -1,3 +1,13 @@
(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("nginx", function(config) {

function words(str) {
@@ -161,3 +171,5 @@ CodeMirror.defineMode("nginx", function(config) {
});

CodeMirror.defineMIME("text/nginx", "text/x-nginx-conf");

});
@@ -25,6 +25,17 @@
-> ERROR
}
*/

(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("ntriples", function() {

var Location = {
@@ -168,3 +179,5 @@ CodeMirror.defineMode("ntriples", function() {
});

CodeMirror.defineMIME("text/n-triples", "ntriples");

});
@@ -1,3 +1,13 @@
(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("octave", function() {
function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b");
@@ -118,3 +128,5 @@ CodeMirror.defineMode("octave", function() {
});

CodeMirror.defineMIME("text/x-octave", "octave");

});
@@ -1,3 +1,13 @@
(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("pascal", function() {
function words(str) {
var obj = {}, words = str.split(" ");
@@ -92,3 +102,5 @@ CodeMirror.defineMode("pascal", function() {
});

CodeMirror.defineMIME("text/x-pascal", "pascal");

});
@@ -1,3 +1,13 @@
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../javascript/javascript"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../javascript/javascript"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("pegjs", function (config) {
var jsMode = CodeMirror.getMode(config, "javascript");

@@ -97,3 +107,5 @@ CodeMirror.defineMode("pegjs", function (config) {
}
};
}, "javascript");

});

Large diffs are not rendered by default.

@@ -1,4 +1,13 @@
(function() {
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

function keywords(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
@@ -128,4 +137,4 @@
CodeMirror.defineMIME("application/x-httpd-php", "php");
CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
CodeMirror.defineMIME("text/x-php", phpConfig);
})();
});
@@ -4,6 +4,16 @@
* @link https://github.com/prasanthj/pig-codemirror-2
* This implementation is adapted from PL/SQL mode in CodeMirror 2.
*/
(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("pig", function(_config, parserConfig) {
var keywords = parserConfig.keywords,
builtins = parserConfig.builtins,
@@ -171,3 +181,5 @@ CodeMirror.defineMode("pig", function(_config, parserConfig) {

CodeMirror.registerHelper("hintWords", "pig", (pBuiltins + pTypes + pKeywords).split(" "));
}());

});
@@ -1,3 +1,13 @@
(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("properties", function() {
return {
token: function(stream, state) {
@@ -61,3 +71,5 @@ CodeMirror.defineMode("properties", function() {

CodeMirror.defineMIME("text/x-properties", "properties");
CodeMirror.defineMIME("text/x-ini", "properties");

});
@@ -1,3 +1,13 @@
(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("puppet", function () {
// Stores the words from the define method
var words = {};
@@ -201,4 +211,7 @@ CodeMirror.defineMode("puppet", function () {
}
};
});

CodeMirror.defineMIME("text/x-puppet", "puppet");

});
@@ -1,3 +1,14 @@
(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("python", function(conf, parserConf) {
var ERRORCLASS = 'error';

@@ -365,14 +376,13 @@ CodeMirror.defineMode("python", function(conf, parserConf) {

CodeMirror.defineMIME("text/x-python", "python");

(function() {
"use strict";
var words = function(str){return str.split(' ');};

CodeMirror.defineMIME("text/x-cython", {
name: "python",
extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
"extern gil include nogil property public"+
"readonly struct union DEF IF ELIF ELSE")
});
})();
var words = function(str){return str.split(' ');};

CodeMirror.defineMIME("text/x-cython", {
name: "python",
extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
"extern gil include nogil property public"+
"readonly struct union DEF IF ELIF ELSE")
});

});
@@ -1,3 +1,13 @@
(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("q",function(config){
var indentUnit=config.indentUnit,
curPunc,
@@ -122,3 +132,5 @@ CodeMirror.defineMode("q",function(config){
};
});
CodeMirror.defineMIME("text/x-q","q");

});
@@ -1,3 +1,13 @@
(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("r", function(config) {
function wordObj(str) {
var words = str.split(" "), res = {};
@@ -143,3 +153,5 @@ CodeMirror.defineMode("r", function(config) {
});

CodeMirror.defineMIME("text/x-rsrc", "r");

});

This file was deleted.

@@ -1,34 +1,70 @@
<!doctype html>

<title>CodeMirror: RPM spec mode</title>
<title>CodeMirror: RPM changes 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="spec.js"></script>
<link rel="stylesheet" href="spec.css">
<link rel="stylesheet" href="../../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="rpm.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>

<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../../../doc/logo.png"></a>
<a href="http://codemirror.net"><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="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../../index.html">Language modes</a>
<li><a class=active href="#">RPM spec</a>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">RPM</a>
</ul>
</div>

<article>
<h2>RPM changes mode</h2>

<div><textarea id="code" name="code">
-------------------------------------------------------------------
Tue Oct 18 13:58:40 UTC 2011 - misterx@example.com

- Update to r60.3
- Fixes bug in the reflect package
* disallow Interface method on Value obtained via unexported name

-------------------------------------------------------------------
Thu Oct 6 08:14:24 UTC 2011 - misterx@example.com

- Update to r60.2
- Fixes memory leak in certain map types

-------------------------------------------------------------------
Wed Oct 5 14:34:10 UTC 2011 - misterx@example.com

- Tweaks for gdb debugging
- go.spec changes:
- move %go_arch definition to %prep section
- pass correct location of go specific gdb pretty printer and
functions to cpp as HOST_EXTRA_CFLAGS macro
- install go gdb functions & printer
- gdb-printer.patch
- patch linker (src/cmd/ld/dwarf.c) to emit correct location of go
gdb functions and pretty printer
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "rpm-changes"},
lineNumbers: true,
indentUnit: 4
});
</script>

<h2>RPM spec mode</h2>

<div><textarea id="code" name="code">
<div><textarea id="code2" name="code2">
#
# spec file for package minidlna
#
@@ -102,13 +138,12 @@ <h2>RPM spec mode</h2>

%changelog</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "spec"},
var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
mode: {name: "rpm-spec"},
lineNumbers: true,
indentUnit: 4
});
</script>

<p><strong>MIME types defined:</strong> <code>text/x-rpm-spec</code>.</p>

<p><strong>MIME types defined:</strong> <code>text/x-rpm-spec</code>, <code>text/x-rpm-changes</code>.</p>
</article>
@@ -1,6 +1,36 @@
(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("rpm-changes", function() {
var headerSeperator = /^-+$/;
var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /;
var simpleEmail = /^[\w+.-]+@[\w.-]+/;

return {
token: function(stream) {
if (stream.sol()) {
if (stream.match(headerSeperator)) { return 'tag'; }
if (stream.match(headerLine)) { return 'tag'; }
}
if (stream.match(simpleEmail)) { return 'string'; }
stream.next();
return null;
}
};
});

CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");

// Quick and dirty spec file highlighting

CodeMirror.defineMode("spec", function() {
CodeMirror.defineMode("rpm-spec", function() {
var arch = /^(i386|i586|i686|x86_64|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;

var preamble = /^(Name|Version|Release|License|Summary|Url|Group|Source|BuildArch|BuildRequires|BuildRoot|AutoReqProv|Provides|Requires(\(\w+\))?|Obsoletes|Conflicts|Recommends|Source\d*|Patch\d*|ExclusiveArch|NoSource|Supplements):/;
@@ -63,4 +93,6 @@ CodeMirror.defineMode("spec", function() {
};
});

CodeMirror.defineMIME("text/x-rpm-spec", "spec");
CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");

});

This file was deleted.

@@ -1,3 +1,13 @@
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../python/python"), require("../stex/stex"), require("../../addon/mode/overlay"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../python/python", "../stex/stex", "../../addon/mode/overlay"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode('rst', function (config, options) {

var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/;
@@ -561,3 +571,5 @@ CodeMirror.defineMIME('text/x-rst', 'rst');

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

});
@@ -1,3 +1,13 @@
(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("ruby", function(config) {
function wordObj(words) {
var o = {};
@@ -248,3 +258,4 @@ CodeMirror.defineMode("ruby", function(config) {

CodeMirror.defineMIME("text/x-ruby", "ruby");

});
@@ -1,3 +1,13 @@
(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("rust", function() {
var indentUnit = 4, altIndentUnit = 2;
var valKeywords = {
@@ -434,3 +444,5 @@ CodeMirror.defineMode("rust", function() {
});

CodeMirror.defineMIME("text/x-rustsrc", "rust");

});
@@ -1,3 +1,13 @@
(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("sass", function(config) {
var tokenRegexp = function(words){
return new RegExp("^" + words.join("|"));
@@ -328,3 +338,5 @@ CodeMirror.defineMode("sass", function(config) {
});

CodeMirror.defineMIME("text/x-sass", "sass");

});
@@ -1,6 +1,17 @@
/**
* Author: Koh Zi Han, based on implementation by Koh Zi Chun
*/

(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("scheme", function () {
var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
ATOM = "atom", NUMBER = "number", BRACKET = "bracket";
@@ -230,3 +241,5 @@ CodeMirror.defineMode("scheme", function () {
});

CodeMirror.defineMIME("text/x-scheme", "scheme");

});
@@ -1,3 +1,13 @@
(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('shell', function() {

var words = {};
@@ -116,3 +126,5 @@ CodeMirror.defineMode('shell', function() {
});

CodeMirror.defineMIME('text/x-sh', 'shell');

});
@@ -1,7 +1,12 @@
/*
* See LICENSE in this directory for the license under which this code
* is released.
*/
(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("sieve", function(config) {
function words(str) {
@@ -181,3 +186,5 @@ CodeMirror.defineMode("sieve", function(config) {
});

CodeMirror.defineMIME("application/sieve", "sieve");

});
@@ -1,3 +1,13 @@
(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('smalltalk', function(config) {

var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
@@ -151,3 +161,5 @@ CodeMirror.defineMode('smalltalk', function(config) {
});

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

});
@@ -1,6 +1,17 @@
/**
* Smarty 2 and 3 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("smarty", function(config) {
"use strict";

@@ -203,3 +214,5 @@ CodeMirror.defineMode("smarty", function(config) {
});

CodeMirror.defineMIME("text/x-smarty", "smarty");

});
@@ -5,6 +5,17 @@
* @version 3.0
* @date 05.07.2013
*/

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../smarty/smarty"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../smarty/smarty"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("smartymixed", function(config) {
var settings, regs, helpers, parsers,
htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"),
@@ -166,8 +177,9 @@ CodeMirror.defineMode("smartymixed", function(config) {
};
}
};
},
"htmlmixed");
}, "htmlmixed", "smarty");

CodeMirror.defineMIME("text/x-smarty", "smartymixed");
// vim: et ts=2 sts=2 sw=2

});
@@ -1,3 +1,13 @@
(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("solr", function() {
"use strict";

@@ -87,3 +97,5 @@ CodeMirror.defineMode("solr", function() {
});

CodeMirror.defineMIME("text/x-solr", "solr");

});
@@ -1,3 +1,13 @@
(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("sparql", function(config) {
var indentUnit = config.indentUnit;
var curPunc;
@@ -143,3 +153,5 @@ CodeMirror.defineMode("sparql", function(config) {
});

CodeMirror.defineMIME("application/x-sparql-query", "sparql");

});
@@ -1,3 +1,13 @@
(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("sql", function(config, parserConfig) {
"use strict";

@@ -345,6 +355,8 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
});
}());

});

/*
How Properties of Mime Types are used by SQL Mode
=================================================
@@ -3,6 +3,16 @@
* Licence: MIT
*/

(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("stex", function() {
"use strict";

@@ -244,3 +254,5 @@ CodeMirror.defineMode("stex", function() {

CodeMirror.defineMIME("text/x-stex", "stex");
CodeMirror.defineMIME("text/x-latex", "stex");

});
@@ -1,4 +1,15 @@
//tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara

(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("tcl", function() {
function parseWords(str) {
var obj = {}, words = str.split(" ");
@@ -129,3 +140,5 @@ CodeMirror.defineMode("tcl", function() {
};
});
CodeMirror.defineMIME("text/x-tcl", "tcl");

});
@@ -14,6 +14,17 @@
CoreVersion parameter is needed for TiddlyWiki only!
***/
//{{{

(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("tiddlywiki", function () {
// Tokenizer
var textwords = {};
@@ -350,4 +361,6 @@ CodeMirror.defineMode("tiddlywiki", function () {
});

CodeMirror.defineMIME("text/x-tiddlywiki", "tiddlywiki");
});

//}}}
@@ -1,3 +1,13 @@
(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('tiki', function(config) {
function inBlock(style, terminator, returnTokenizer) {
return function(stream, state) {
@@ -306,3 +316,5 @@ return {
});

CodeMirror.defineMIME("text/tiki", "tiki");

});
@@ -1,3 +1,13 @@
(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("toml", function () {
return {
startState: function () {
@@ -71,3 +81,5 @@ CodeMirror.defineMode("toml", function () {
});

CodeMirror.defineMIME('text/x-toml', 'toml');

});
@@ -1,3 +1,13 @@
(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("turtle", function(config) {
var indentUnit = config.indentUnit;
var curPunc;
@@ -143,3 +153,5 @@ CodeMirror.defineMode("turtle", function(config) {
});

CodeMirror.defineMIME("text/turtle", "turtle");

});
@@ -1,3 +1,13 @@
(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("vb", function(conf, parserConf) {
var ERRORCLASS = 'error';

@@ -257,3 +267,5 @@ CodeMirror.defineMode("vb", function(conf, parserConf) {
});

CodeMirror.defineMIME("text/x-vb", "vb");

});
@@ -8,6 +8,17 @@ E.G.:
isASP: true
});
*/

(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("vbscript", function(conf, parserConf) {
var ERRORCLASS = 'error';

@@ -332,3 +343,5 @@ CodeMirror.defineMode("vbscript", function(conf, parserConf) {
});

CodeMirror.defineMIME("text/vbscript", "vbscript");

});
@@ -1,3 +1,13 @@
(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("velocity", function() {
function parseWords(str) {
var obj = {}, words = str.split(" ");
@@ -184,3 +194,5 @@ CodeMirror.defineMode("velocity", function() {
});

CodeMirror.defineMIME("text/velocity", "velocity");

});
@@ -1,3 +1,13 @@
(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("verilog", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = parserConfig.keywords || {},
@@ -146,7 +156,6 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
};
});

(function() {
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
@@ -179,4 +188,5 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
atoms: words("null"),
hooks: {"`": metaHook, "$": metaHook}
});
}());

});
@@ -1,3 +1,13 @@
(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("xml", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
@@ -223,6 +233,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
return baseState;
}
}

function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
@@ -334,3 +345,5 @@ CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});

});
@@ -1,3 +1,13 @@
(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("xquery", function() {

// The keywords object is set to the result of this self executing
@@ -430,3 +440,5 @@ CodeMirror.defineMode("xquery", function() {
});

CodeMirror.defineMIME("application/xquery", "xquery");

});
@@ -1,3 +1,13 @@
(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("yaml", function() {

var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
@@ -95,3 +105,5 @@ CodeMirror.defineMode("yaml", function() {
});

CodeMirror.defineMIME("text/x-yaml", "yaml");

});
@@ -1,3 +1,13 @@
(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('z80', function() {
var keywords1 = /^(exx?|(ld|cp|in)([di]r?)?|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|rst|[de]i|halt|im|ot[di]r|out[di]?)\b/i;
var keywords2 = /^(call|j[pr]|ret[in]?)\b/i;
@@ -83,3 +93,5 @@ CodeMirror.defineMode('z80', function() {
});

CodeMirror.defineMIME("text/x-z80", "z80");

});
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version":"3.22.1",
"version":"4.0.3",
"main": "lib/codemirror.js",
"description": "In-browser code editing made bearable",
"licenses": [{"type": "MIT",
@@ -320,6 +320,25 @@
eq(cleared, 1);
});

testDoc("sharedBookmark", "A='ab\ncd\nef\ngh' B<A C<~A/1-2", function(a, b, c) {
var mark = b.setBookmark(Pos(1, 1), {shared: true});
var found = a.findMarksAt(Pos(1, 1));
eq(found.length, 1);
eq(found[0], mark);
eq(c.findMarksAt(Pos(1, 1)).length, 1);
eqPos(mark.find(), Pos(1, 1));
b.replaceRange("x\ny\n", Pos(0, 0));
eqPos(mark.find(), Pos(3, 1));
var cleared = 0;
CodeMirror.on(mark, "clear", function() {++cleared;});
b.operation(function() {mark.clear();});
eq(a.findMarks(Pos(0, 0), Pos(5)).length, 0);
eq(b.findMarks(Pos(0, 0), Pos(5)).length, 0);
eq(c.findMarks(Pos(0, 0), Pos(5)).length, 0);
eq(mark.find(), null);
eq(cleared, 1);
});

testDoc("undoInSubview", "A='line 0\nline 1\nline 2\nline 3\nline 4' B<A/1-4", function(a, b) {
b.replaceRange("x", Pos(2, 0));
a.undo();
@@ -44,23 +44,25 @@ function testCM(name, run, opts, expectedFail) {
function runTests(callback) {
var totalTime = 0;
function step(i) {
if (i === tests.length){
running = false;
return callback("done");
}
var test = tests[i], expFail = test.expectedFail, startTime = +new Date;
if (filters.length) {
for (var j = 0; j < filters.length; j++) {
if (test.name.match(filters[j])) {
break;
}
for (;;) {
if (i === tests.length) {
running = false;
return callback("done");
}
var test = tests[i], skip = false;
if (filters.length) {
skip = true;
for (var j = 0; j < filters.length; j++)
if (test.name.match(filters[j])) skip = false;
}
if (j == filters.length) {
if (skip) {
callback("skipped", test.name, message);
return step(i + 1);
i++;
} else {
break;
}
}
var threw = false;
var expFail = test.expectedFail, startTime = +new Date, threw = false;
try {
var message = test.func();
} catch(e) {
@@ -69,6 +71,7 @@ function runTests(callback) {
else if (e instanceof Failure) callback("fail", test.name, e.message);
else {
var pos = /(?:\bat |@).*?([^\/:]+):(\d+)/.exec(e.stack);
if (pos) console["log"](e.stack);
callback("error", test.name, e.toString() + (pos ? " (" + pos[1] + ":" + pos[2] + ")" : ""));
}
}
@@ -99,6 +102,10 @@ function label(str, msg) {
function eq(a, b, msg) {
if (a != b) throw new Failure(label(a + " != " + b, msg));
}
function near(a, b, margin, msg) {
if (Math.abs(a - b) > margin)
throw new Failure(label(a + " is not close to " + b + " (" + margin + ")", msg));
}
function eqPos(a, b, msg) {
function str(p) { return "{line:" + p.line + ",ch:" + p.ch + "}"; }
if (a == b) return;
@@ -6,6 +6,7 @@

<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="mode_test.css">
<script src="../doc/activebookmark.js"></script>
<script src="../lib/codemirror.js"></script>
<script src="../addon/mode/overlay.js"></script>
<script src="../addon/mode/multiplex.js"></script>
@@ -17,6 +18,7 @@
<script src="../mode/xml/xml.js"></script>
<script src="../keymap/vim.js"></script>
<script src="../keymap/emacs.js"></script>
<script src="../keymap/sublime.js"></script>

<style type="text/css">
.ok {color: #090;}
@@ -71,6 +73,7 @@ <h2>Test Suite</h2>
<script src="driver.js"></script>
<script src="test.js"></script>
<script src="doc_test.js"></script>
<script src="multi_test.js"></script>
<script src="comment_test.js"></script>
<script src="search_test.js"></script>
<script src="mode_test.js"></script>
@@ -96,6 +99,7 @@ <h2>Test Suite</h2>
<script src="../addon/mode/multiplex_test.js"></script>
<script src="vim_test.js"></script>
<script src="emacs_test.js"></script>
<script src="sublime_test.js"></script>
<script>
window.onload = runHarness;
CodeMirror.on(window, 'hashchange', runHarness);

Large diffs are not rendered by default.

@@ -21,7 +21,8 @@ var topAllowedGlobals = Object.create(null);
"window document navigator prompt alert confirm console " +
"FileReader Worker postMessage importScripts " +
"setInterval clearInterval setTimeout clearTimeout " +
"CodeMirror test")
"CodeMirror " +
"test exports require module define")
.split(" ").forEach(function(n) { topAllowedGlobals[n] = true; });

var fs = require("fs"), acorn = require("./acorn.js"), walk = require("./walk.js");
@@ -49,7 +50,7 @@ function checkFile(fileName) {
ecmaVersion: 3,
strictSemicolons: true,
allowTrailingCommas: false,
forbidReserved: true,
forbidReserved: "everywhere",
sourceFile: fileName
});
} catch (e) {
@@ -95,19 +96,40 @@ function checkFile(fileName) {
},
FunctionExpression: function(node) {
if (node.id) fail("Named function expression", node.loc);
},
ForStatement: function(node) {
checkReusedIndex(node);
},
MemberExpression: function(node) {
if (node.object.type == "Identifier" && node.object.name == "console" && !node.computed)
fail("Found console." + node.property.name, node.loc);
},
DebuggerStatement: function(node) {
fail("Found debugger statement", node.loc);
}
}, scopePasser);

if (!globalsSeen.exports) {
var allowedGlobals = Object.create(topAllowedGlobals), m;
if (m = file.match(/\/\/ declare global:\s+(.*)/))
m[1].split(/,\s*/g).forEach(function(n) { allowedGlobals[n] = true; });
for (var glob in globalsSeen)
if (!(glob in allowedGlobals))
fail("Access to global variable " + glob + ". Add a '// declare global: " + glob +
"' comment or add this variable in test/lint/lint.js.", globalsSeen[glob]);
function checkReusedIndex(node) {
if (!node.init || node.init.type != "VariableDeclaration") return;
var name = node.init.declarations[0].id.name;
walk.recursive(node.body, null, {
Function: function() {},
VariableDeclaration: function(node, st, c) {
for (var i = 0; i < node.declarations.length; i++)
if (node.declarations[i].id.name == name)
fail("redefined loop variable", node.declarations[i].id.loc);
walk.base.VariableDeclaration(node, st, c);
}
});
}

var allowedGlobals = Object.create(topAllowedGlobals), m;
if (m = file.match(/\/\/ declare global:\s+(.*)/))
m[1].split(/,\s*/g).forEach(function(n) { allowedGlobals[n] = true; });
for (var glob in globalsSeen)
if (!(glob in allowedGlobals))
fail("Access to global variable " + glob + ". Add a '// declare global: " + glob +
"' comment or add this variable in test/lint/lint.js.", globalsSeen[glob]);

for (var i = 0; i < scopes.length; ++i) {
var scope = scopes[i];
@@ -1,6 +1,10 @@
// AST walker module for Mozilla Parser API compatible trees

(function(exports) {
(function(mod) {
if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS
if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD
mod((this.acorn || (this.acorn = {})).walk = {}); // Plain browser env
})(function(exports) {
"use strict";

// A simple walk is one where you simply specify callbacks to be
@@ -19,11 +23,11 @@
// walker, and state can be used to give this walked an initial
// state.
exports.simple = function(node, visitors, base, state) {
if (!base) base = exports;
if (!base) base = exports.base;
function c(node, st, override) {
var type = override || node.type, found = visitors[type];
if (found) found(node, st);
base[type](node, st, c);
if (found) found(node, st);
}
c(node, state);
};
@@ -34,51 +38,140 @@
// their child nodes (by calling their third argument on these
// nodes).
exports.recursive = function(node, state, funcs, base) {
var visitor = exports.make(funcs, base);
var visitor = funcs ? exports.make(funcs, base) : base;
function c(node, st, override) {
visitor[override || node.type](node, st, c);
}
c(node, state);
};

function makeTest(test) {
if (typeof test == "string")
return function(type) { return type == test; };
else if (!test)
return function() { return true; };
else
return test;
}

function Found(node, state) { this.node = node; this.state = state; }

// Find a node with a given start, end, and type (all are optional,
// null can be used as wildcard). Returns a {node, state} object, or
// undefined when it doesn't find a matching node.
exports.findNodeAt = function(node, start, end, test, base, state) {
test = makeTest(test);
try {
if (!base) base = exports.base;
var c = function(node, st, override) {
var type = override || node.type;
if ((start == null || node.start <= start) &&
(end == null || node.end >= end))
base[type](node, st, c);
if (test(type, node) &&
(start == null || node.start == start) &&
(end == null || node.end == end))
throw new Found(node, st);
};
c(node, state);
} catch (e) {
if (e instanceof Found) return e;
throw e;
}
};

// Find the innermost node of a given type that contains the given
// position. Interface similar to findNodeAt.
exports.findNodeAround = function(node, pos, test, base, state) {
test = makeTest(test);
try {
if (!base) base = exports.base;
var c = function(node, st, override) {
var type = override || node.type;
if (node.start > pos || node.end < pos) return;
base[type](node, st, c);
if (test(type, node)) throw new Found(node, st);
};
c(node, state);
} catch (e) {
if (e instanceof Found) return e;
throw e;
}
};

// Find the outermost matching node after a given position.
exports.findNodeAfter = function(node, pos, test, base, state) {
test = makeTest(test);
try {
if (!base) base = exports.base;
var c = function(node, st, override) {
if (node.end < pos) return;
var type = override || node.type;
if (node.start >= pos && test(type, node)) throw new Found(node, st);
base[type](node, st, c);
};
c(node, state);
} catch (e) {
if (e instanceof Found) return e;
throw e;
}
};

// Find the outermost matching node before a given position.
exports.findNodeBefore = function(node, pos, test, base, state) {
test = makeTest(test);
if (!base) base = exports.base;
var max;
var c = function(node, st, override) {
if (node.start > pos) return;
var type = override || node.type;
if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node))
max = new Found(node, st);
base[type](node, st, c);
};
c(node, state);
return max;
};

// Used to create a custom walker. Will fill in all missing node
// type properties with the defaults.
exports.make = function(funcs, base) {
if (!base) base = exports;
if (!base) base = exports.base;
var visitor = {};
for (var type in base)
visitor[type] = funcs.hasOwnProperty(type) ? funcs[type] : base[type];
for (var type in base) visitor[type] = base[type];
for (var type in funcs) visitor[type] = funcs[type];
return visitor;
};

function skipThrough(node, st, c) { c(node, st); }
function ignore(node, st, c) {}
function ignore(_node, _st, _c) {}

// Node walkers.

exports.Program = exports.BlockStatement = function(node, st, c) {
var base = exports.base = {};
base.Program = base.BlockStatement = function(node, st, c) {
for (var i = 0; i < node.body.length; ++i)
c(node.body[i], st, "Statement");
};
exports.Statement = skipThrough;
exports.EmptyStatement = ignore;
exports.ExpressionStatement = function(node, st, c) {
base.Statement = skipThrough;
base.EmptyStatement = ignore;
base.ExpressionStatement = function(node, st, c) {
c(node.expression, st, "Expression");
};
exports.IfStatement = function(node, st, c) {
base.IfStatement = function(node, st, c) {
c(node.test, st, "Expression");
c(node.consequent, st, "Statement");
if (node.alternate) c(node.alternate, st, "Statement");
};
exports.LabeledStatement = function(node, st, c) {
base.LabeledStatement = function(node, st, c) {
c(node.body, st, "Statement");
};
exports.BreakStatement = exports.ContinueStatement = ignore;
exports.WithStatement = function(node, st, c) {
base.BreakStatement = base.ContinueStatement = ignore;
base.WithStatement = function(node, st, c) {
c(node.object, st, "Expression");
c(node.body, st, "Statement");
};
exports.SwitchStatement = function(node, st, c) {
base.SwitchStatement = function(node, st, c) {
c(node.discriminant, st, "Expression");
for (var i = 0; i < node.cases.length; ++i) {
var cs = node.cases[i];
@@ -87,101 +180,104 @@
c(cs.consequent[j], st, "Statement");
}
};
exports.ReturnStatement = function(node, st, c) {
base.ReturnStatement = function(node, st, c) {
if (node.argument) c(node.argument, st, "Expression");
};
exports.ThrowStatement = function(node, st, c) {
base.ThrowStatement = function(node, st, c) {
c(node.argument, st, "Expression");
};
exports.TryStatement = function(node, st, c) {
base.TryStatement = function(node, st, c) {
c(node.block, st, "Statement");
for (var i = 0; i < node.handlers.length; ++i)
c(node.handlers[i].body, st, "ScopeBody");
if (node.handler) c(node.handler.body, st, "ScopeBody");
if (node.finalizer) c(node.finalizer, st, "Statement");
};
exports.WhileStatement = function(node, st, c) {
base.WhileStatement = function(node, st, c) {
c(node.test, st, "Expression");
c(node.body, st, "Statement");
};
exports.DoWhileStatement = exports.WhileStatement;
exports.ForStatement = function(node, st, c) {
base.DoWhileStatement = base.WhileStatement;
base.ForStatement = function(node, st, c) {
if (node.init) c(node.init, st, "ForInit");
if (node.test) c(node.test, st, "Expression");
if (node.update) c(node.update, st, "Expression");
c(node.body, st, "Statement");
};
exports.ForInStatement = function(node, st, c) {
base.ForInStatement = function(node, st, c) {
c(node.left, st, "ForInit");
c(node.right, st, "Expression");
c(node.body, st, "Statement");
};
exports.ForInit = function(node, st, c) {
base.ForInit = function(node, st, c) {
if (node.type == "VariableDeclaration") c(node, st);
else c(node, st, "Expression");
};
exports.DebuggerStatement = ignore;
base.DebuggerStatement = ignore;

exports.FunctionDeclaration = function(node, st, c) {
base.FunctionDeclaration = function(node, st, c) {
c(node, st, "Function");
};
exports.VariableDeclaration = function(node, st, c) {
base.VariableDeclaration = function(node, st, c) {
for (var i = 0; i < node.declarations.length; ++i) {
var decl = node.declarations[i];
if (decl.init) c(decl.init, st, "Expression");
}
};

exports.Function = function(node, st, c) {
base.Function = function(node, st, c) {
c(node.body, st, "ScopeBody");
};
exports.ScopeBody = function(node, st, c) {
base.ScopeBody = function(node, st, c) {
c(node, st, "Statement");
};

exports.Expression = skipThrough;
exports.ThisExpression = ignore;
exports.ArrayExpression = function(node, st, c) {
base.Expression = skipThrough;
base.ThisExpression = ignore;
base.ArrayExpression = function(node, st, c) {
for (var i = 0; i < node.elements.length; ++i) {
var elt = node.elements[i];
if (elt) c(elt, st, "Expression");
}
};
exports.ObjectExpression = function(node, st, c) {
base.ObjectExpression = function(node, st, c) {
for (var i = 0; i < node.properties.length; ++i)
c(node.properties[i].value, st, "Expression");
};
exports.FunctionExpression = exports.FunctionDeclaration;
exports.SequenceExpression = function(node, st, c) {
base.FunctionExpression = base.FunctionDeclaration;
base.SequenceExpression = function(node, st, c) {
for (var i = 0; i < node.expressions.length; ++i)
c(node.expressions[i], st, "Expression");
};
exports.UnaryExpression = exports.UpdateExpression = function(node, st, c) {
base.UnaryExpression = base.UpdateExpression = function(node, st, c) {
c(node.argument, st, "Expression");
};
exports.BinaryExpression = exports.AssignmentExpression = exports.LogicalExpression = function(node, st, c) {
base.BinaryExpression = base.AssignmentExpression = base.LogicalExpression = function(node, st, c) {
c(node.left, st, "Expression");
c(node.right, st, "Expression");
};
exports.ConditionalExpression = function(node, st, c) {
base.ConditionalExpression = function(node, st, c) {
c(node.test, st, "Expression");
c(node.consequent, st, "Expression");
c(node.alternate, st, "Expression");
};
exports.NewExpression = exports.CallExpression = function(node, st, c) {
base.NewExpression = base.CallExpression = function(node, st, c) {
c(node.callee, st, "Expression");
if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
c(node.arguments[i], st, "Expression");
};
exports.MemberExpression = function(node, st, c) {
base.MemberExpression = function(node, st, c) {
c(node.object, st, "Expression");
if (node.computed) c(node.property, st, "Expression");
};
exports.Identifier = exports.Literal = ignore;
base.Identifier = base.Literal = ignore;

// A custom walker that keeps track of the scope chain and the
// variables defined in it.
function makeScope(prev) {
return {vars: Object.create(null), prev: prev};
function makeScope(prev, isCatch) {
return {vars: Object.create(null), prev: prev, isCatch: isCatch};
}
function normalScope(scope) {
while (scope.isCatch) scope = scope.prev;
return scope;
}
exports.scopeVisitor = exports.make({
Function: function(node, scope, c) {
@@ -190,27 +286,28 @@
inner.vars[node.params[i].name] = {type: "argument", node: node.params[i]};
if (node.id) {
var decl = node.type == "FunctionDeclaration";
(decl ? scope : inner).vars[node.id.name] =
(decl ? normalScope(scope) : inner).vars[node.id.name] =
{type: decl ? "function" : "function name", node: node.id};
}
c(node.body, inner, "ScopeBody");
},
TryStatement: function(node, scope, c) {
c(node.block, scope, "Statement");
for (var i = 0; i < node.handlers.length; ++i) {
var handler = node.handlers[i], inner = makeScope(scope);
inner.vars[handler.param.name] = {type: "catch clause", node: handler.param};
c(handler.body, inner, "ScopeBody");
if (node.handler) {
var inner = makeScope(scope, true);
inner.vars[node.handler.param.name] = {type: "catch clause", node: node.handler.param};
c(node.handler.body, inner, "ScopeBody");
}
if (node.finalizer) c(node.finalizer, scope, "Statement");
},
VariableDeclaration: function(node, scope, c) {
var target = normalScope(scope);
for (var i = 0; i < node.declarations.length; ++i) {
var decl = node.declarations[i];
scope.vars[decl.id.name] = {type: "var", node: decl.id};
target.vars[decl.id.name] = {type: "var", node: decl.id};
if (decl.init) c(decl.init, scope, "Expression");
}
}
});

})(typeof exports == "undefined" ? acorn.walk = {} : exports);
});
@@ -0,0 +1,285 @@
(function() {
namespace = "multi_";

function hasSelections(cm) {
var sels = cm.listSelections();
var given = (arguments.length - 1) / 4;
if (sels.length != given)
throw new Failure("expected " + given + " selections, found " + sels.length);
for (var i = 0, p = 1; i < given; i++, p += 4) {
var anchor = Pos(arguments[p], arguments[p + 1]);
var head = Pos(arguments[p + 2], arguments[p + 3]);
eqPos(sels[i].anchor, anchor, "anchor of selection " + i);
eqPos(sels[i].head, head, "head of selection " + i);
}
}
function hasCursors(cm) {
var sels = cm.listSelections();
var given = (arguments.length - 1) / 2;
if (sels.length != given)
throw new Failure("expected " + given + " selections, found " + sels.length);
for (var i = 0, p = 1; i < given; i++, p += 2) {
eqPos(sels[i].anchor, sels[i].head, "something selected for " + i);
var head = Pos(arguments[p], arguments[p + 1]);
eqPos(sels[i].head, head, "selection " + i);
}
}

testCM("getSelection", function(cm) {
select(cm, {anchor: Pos(0, 0), head: Pos(1, 2)}, {anchor: Pos(2, 2), head: Pos(2, 0)});
eq(cm.getSelection(), "1234\n56\n90");
eq(cm.getSelection(false).join("|"), "1234|56|90");
eq(cm.getSelections().join("|"), "1234\n56|90");
}, {value: "1234\n5678\n90"});

testCM("setSelection", function(cm) {
select(cm, Pos(3, 0), Pos(0, 0), {anchor: Pos(2, 5), head: Pos(1, 0)});
hasSelections(cm, 0, 0, 0, 0,
2, 5, 1, 0,
3, 0, 3, 0);
cm.setSelection(Pos(1, 2), Pos(1, 1));
hasSelections(cm, 1, 2, 1, 1);
select(cm, {anchor: Pos(1, 1), head: Pos(2, 4)},
{anchor: Pos(0, 0), head: Pos(1, 3)},
Pos(3, 0), Pos(2, 2));
hasSelections(cm, 0, 0, 2, 4,
3, 0, 3, 0);
cm.setSelections([{anchor: Pos(0, 1), head: Pos(0, 2)},
{anchor: Pos(1, 1), head: Pos(1, 2)},
{anchor: Pos(2, 1), head: Pos(2, 2)}], 1);
eqPos(cm.getCursor("head"), Pos(1, 2));
eqPos(cm.getCursor("anchor"), Pos(1, 1));
eqPos(cm.getCursor("from"), Pos(1, 1));
eqPos(cm.getCursor("to"), Pos(1, 2));
cm.setCursor(Pos(1, 1));
hasCursors(cm, 1, 1);
}, {value: "abcde\nabcde\nabcde\n"});

testCM("somethingSelected", function(cm) {
select(cm, Pos(0, 1), {anchor: Pos(0, 3), head: Pos(0, 5)});
eq(cm.somethingSelected(), true);
select(cm, Pos(0, 1), Pos(0, 3), Pos(0, 5));
eq(cm.somethingSelected(), false);
}, {value: "123456789"});

testCM("extendSelection", function(cm) {
select(cm, Pos(0, 1), Pos(1, 1), Pos(2, 1));
cm.setExtending(true);
cm.extendSelections([Pos(0, 2), Pos(1, 0), Pos(2, 3)]);
hasSelections(cm, 0, 1, 0, 2,
1, 1, 1, 0,
2, 1, 2, 3);
cm.extendSelection(Pos(2, 4), Pos(2, 0));
hasSelections(cm, 2, 4, 2, 0);
}, {value: "1234\n1234\n1234"});

testCM("addSelection", function(cm) {
select(cm, Pos(0, 1), Pos(1, 1));
cm.addSelection(Pos(0, 0), Pos(0, 4));
hasSelections(cm, 0, 0, 0, 4,
1, 1, 1, 1);
cm.addSelection(Pos(2, 2));
hasSelections(cm, 0, 0, 0, 4,
1, 1, 1, 1,
2, 2, 2, 2);
}, {value: "1234\n1234\n1234"});

testCM("replaceSelection", function(cm) {
var selections = [{anchor: Pos(0, 0), head: Pos(0, 1)},
{anchor: Pos(0, 2), head: Pos(0, 3)},
{anchor: Pos(0, 4), head: Pos(0, 5)},
{anchor: Pos(2, 1), head: Pos(2, 4)},
{anchor: Pos(2, 5), head: Pos(2, 6)}];
var val = "123456\n123456\n123456";
cm.setValue(val);
cm.setSelections(selections);
cm.replaceSelection("ab", "around");
eq(cm.getValue(), "ab2ab4ab6\n123456\n1ab5ab");
hasSelections(cm, 0, 0, 0, 2,
0, 3, 0, 5,
0, 6, 0, 8,
2, 1, 2, 3,
2, 4, 2, 6);
cm.setValue(val);
cm.setSelections(selections);
cm.replaceSelection("", "around");
eq(cm.getValue(), "246\n123456\n15");
hasSelections(cm, 0, 0, 0, 0,
0, 1, 0, 1,
0, 2, 0, 2,
2, 1, 2, 1,
2, 2, 2, 2);
cm.setValue(val);
cm.setSelections(selections);
cm.replaceSelection("X\nY\nZ", "around");
hasSelections(cm, 0, 0, 2, 1,
2, 2, 4, 1,
4, 2, 6, 1,
8, 1, 10, 1,
10, 2, 12, 1);
cm.replaceSelection("a", "around");
hasSelections(cm, 0, 0, 0, 1,
0, 2, 0, 3,
0, 4, 0, 5,
2, 1, 2, 2,
2, 3, 2, 4);
cm.replaceSelection("xy", "start");
hasSelections(cm, 0, 0, 0, 0,
0, 3, 0, 3,
0, 6, 0, 6,
2, 1, 2, 1,
2, 4, 2, 4);
cm.replaceSelection("z\nf");
hasSelections(cm, 1, 1, 1, 1,
2, 1, 2, 1,
3, 1, 3, 1,
6, 1, 6, 1,
7, 1, 7, 1);
eq(cm.getValue(), "z\nfxy2z\nfxy4z\nfxy6\n123456\n1z\nfxy5z\nfxy");
});

function select(cm) {
var sels = [];
for (var i = 1; i < arguments.length; i++) {
var arg = arguments[i];
if (arg.head) sels.push(arg);
else sels.push({head: arg, anchor: arg});
}
cm.setSelections(sels, sels.length - 1);
}

testCM("indentSelection", function(cm) {
select(cm, Pos(0, 1), Pos(1, 1));
cm.indentSelection(4);
eq(cm.getValue(), " foo\n bar\nbaz");

select(cm, Pos(0, 2), Pos(0, 3), Pos(0, 4));
cm.indentSelection(-2);
eq(cm.getValue(), " foo\n bar\nbaz");

select(cm, {anchor: Pos(0, 0), head: Pos(1, 2)},
{anchor: Pos(1, 3), head: Pos(2, 0)});
cm.indentSelection(-2);
eq(cm.getValue(), "foo\n bar\nbaz");
}, {value: "foo\nbar\nbaz"});

testCM("killLine", function(cm) {
select(cm, Pos(0, 1), Pos(0, 2), Pos(1, 1));
cm.execCommand("killLine");
eq(cm.getValue(), "f\nb\nbaz");
cm.execCommand("killLine");
eq(cm.getValue(), "fbbaz");
cm.setValue("foo\nbar\nbaz");
select(cm, Pos(0, 1), {anchor: Pos(0, 2), head: Pos(2, 1)});
cm.execCommand("killLine");
eq(cm.getValue(), "faz");
}, {value: "foo\nbar\nbaz"});

testCM("deleteLine", function(cm) {
select(cm, Pos(0, 0),
{head: Pos(0, 1), anchor: Pos(2, 0)},
Pos(4, 0));
cm.execCommand("deleteLine");
eq(cm.getValue(), "4\n6\n7");
select(cm, Pos(2, 1));
cm.execCommand("deleteLine");
eq(cm.getValue(), "4\n6\n");
}, {value: "1\n2\n3\n4\n5\n6\n7"});

testCM("deleteH", function(cm) {
select(cm, Pos(0, 4), {anchor: Pos(1, 4), head: Pos(1, 5)});
cm.execCommand("delWordAfter");
eq(cm.getValue(), "foo bar baz\nabc ef ghi\n");
cm.execCommand("delWordAfter");
eq(cm.getValue(), "foo baz\nabc ghi\n");
cm.execCommand("delCharBefore");
cm.execCommand("delCharBefore");
eq(cm.getValue(), "fo baz\nab ghi\n");
select(cm, Pos(0, 3), Pos(0, 4), Pos(0, 5));
cm.execCommand("delWordAfter");
eq(cm.getValue(), "fo \nab ghi\n");
}, {value: "foo bar baz\nabc def ghi\n"});

testCM("goLineStart", function(cm) {
select(cm, Pos(0, 2), Pos(0, 3), Pos(1, 1));
cm.execCommand("goLineStart");
hasCursors(cm, 0, 0, 1, 0);
select(cm, Pos(1, 1), Pos(0, 1));
cm.setExtending(true);
cm.execCommand("goLineStart");
hasSelections(cm, 0, 1, 0, 0,
1, 1, 1, 0);
}, {value: "foo\nbar\nbaz"});

testCM("moveV", function(cm) {
select(cm, Pos(0, 2), Pos(1, 2));
cm.execCommand("goLineDown");
hasCursors(cm, 1, 2, 2, 2);
cm.execCommand("goLineUp");
hasCursors(cm, 0, 2, 1, 2);
cm.execCommand("goLineUp");
hasCursors(cm, 0, 0, 0, 2);
cm.execCommand("goLineUp");
hasCursors(cm, 0, 0);
select(cm, Pos(0, 2), Pos(1, 2));
cm.setExtending(true);
cm.execCommand("goLineDown");
hasSelections(cm, 0, 2, 2, 2);
}, {value: "12345\n12345\n12345"});

testCM("moveH", function(cm) {
select(cm, Pos(0, 1), Pos(0, 3), Pos(0, 5), Pos(2, 3));
cm.execCommand("goCharRight");
hasCursors(cm, 0, 2, 0, 4, 1, 0, 2, 4);
cm.execCommand("goCharLeft");
hasCursors(cm, 0, 1, 0, 3, 0, 5, 2, 3);
for (var i = 0; i < 15; i++)
cm.execCommand("goCharRight");
hasCursors(cm, 2, 4, 2, 5);
}, {value: "12345\n12345\n12345"});

testCM("newlineAndIndent", function(cm) {
select(cm, Pos(0, 5), Pos(1, 5));
cm.execCommand("newlineAndIndent");
hasCursors(cm, 1, 2, 3, 2);
eq(cm.getValue(), "x = [\n 1];\ny = [\n 2];");
cm.undo();
eq(cm.getValue(), "x = [1];\ny = [2];");
hasCursors(cm, 0, 5, 1, 5);
select(cm, Pos(0, 5), Pos(0, 6));
cm.execCommand("newlineAndIndent");
hasCursors(cm, 1, 2, 2, 0);
eq(cm.getValue(), "x = [\n 1\n];\ny = [2];");
}, {value: "x = [1];\ny = [2];", mode: "javascript"});

testCM("goDocStartEnd", function(cm) {
select(cm, Pos(0, 1), Pos(1, 1));
cm.execCommand("goDocStart");
hasCursors(cm, 0, 0);
select(cm, Pos(0, 1), Pos(1, 1));
cm.execCommand("goDocEnd");
hasCursors(cm, 1, 3);
select(cm, Pos(0, 1), Pos(1, 1));
cm.setExtending(true);
cm.execCommand("goDocEnd");
hasSelections(cm, 1, 1, 1, 3);
}, {value: "abc\ndef"});

testCM("selectionHistory", function(cm) {
for (var i = 0; i < 3; ++i)
cm.addSelection(Pos(0, i * 2), Pos(0, i * 2 + 1));
cm.execCommand("undoSelection");
eq(cm.getSelection(), "1\n2");
cm.execCommand("undoSelection");
eq(cm.getSelection(), "1");
cm.execCommand("undoSelection");
eq(cm.getSelection(), "");
eqPos(cm.getCursor(), Pos(0, 0));
cm.execCommand("redoSelection");
eq(cm.getSelection(), "1");
cm.execCommand("redoSelection");
eq(cm.getSelection(), "1\n2");
cm.execCommand("redoSelection");
eq(cm.getSelection(), "1\n2\n3");
}, {value: "1 2 3"});
})();
@@ -0,0 +1,297 @@
(function() {
"use strict";

var Pos = CodeMirror.Pos;
namespace = "sublime_";

function stTest(name) {
var actions = Array.prototype.slice.call(arguments, 1);
testCM(name, function(cm) {
for (var i = 0; i < actions.length; i++) {
var action = actions[i];
if (typeof action == "string" && i == 0)
cm.setValue(action);
else if (typeof action == "string")
cm.execCommand(action);
else if (action instanceof Pos)
cm.setCursor(action);
else
action(cm);
}
});
}

function at(line, ch, msg) {
return function(cm) {
eq(cm.listSelections().length, 1);
eqPos(cm.getCursor("head"), Pos(line, ch), msg);
eqPos(cm.getCursor("anchor"), Pos(line, ch), msg);
};
}

function val(content, msg) {
return function(cm) { eq(cm.getValue(), content, msg); };
}

function argsToRanges(args) {
if (args.length % 4) throw new Error("Wrong number of arguments for ranges.");
var ranges = [];
for (var i = 0; i < args.length; i += 4)
ranges.push({anchor: Pos(args[i], args[i + 1]),
head: Pos(args[i + 2], args[i + 3])});
return ranges;
}

function setSel() {
var ranges = argsToRanges(arguments);
return function(cm) { cm.setSelections(ranges, 0); };
}

function hasSel() {
var ranges = argsToRanges(arguments);
return function(cm) {
var sels = cm.listSelections();
if (sels.length != ranges.length)
throw new Failure("Expected " + ranges.length + " selections, but found " + sels.length);
for (var i = 0; i < sels.length; i++) {
eqPos(sels[i].anchor, ranges[i].anchor, "anchor " + i);
eqPos(sels[i].head, ranges[i].head, "head " + i);
}
};
}

stTest("bySubword", "the foo_bar DooDahBah \n a",
"goSubwordLeft", at(0, 0),
"goSubwordRight", at(0, 3),
"goSubwordRight", at(0, 7),
"goSubwordRight", at(0, 11),
"goSubwordRight", at(0, 15),
"goSubwordRight", at(0, 18),
"goSubwordRight", at(0, 21),
"goSubwordRight", at(0, 22),
"goSubwordRight", at(1, 0),
"goSubwordRight", at(1, 2),
"goSubwordRight", at(1, 2),
"goSubwordLeft", at(1, 1),
"goSubwordLeft", at(1, 0),
"goSubwordLeft", at(0, 22),
"goSubwordLeft", at(0, 18),
"goSubwordLeft", at(0, 15),
"goSubwordLeft", at(0, 12),
"goSubwordLeft", at(0, 8),
"goSubwordLeft", at(0, 4),
"goSubwordLeft", at(0, 0));

stTest("splitSelectionByLine", "abc\ndef\nghi",
setSel(0, 1, 2, 2),
"splitSelectionByLine",
hasSel(0, 1, 0, 3,
1, 0, 1, 3,
2, 0, 2, 2));

stTest("splitSelectionByLineMulti", "abc\ndef\nghi\njkl",
setSel(0, 1, 1, 1,
1, 2, 3, 2,
3, 3, 3, 3),
"splitSelectionByLine",
hasSel(0, 1, 0, 3,
1, 0, 1, 1,
1, 2, 1, 3,
2, 0, 2, 3,
3, 0, 3, 2,
3, 3, 3, 3));

stTest("selectLine", "abc\ndef\nghi",
setSel(0, 1, 0, 1,
2, 0, 2, 1),
"selectLine",
hasSel(0, 0, 1, 0,
2, 0, 2, 3),
setSel(0, 1, 1, 0),
"selectLine",
hasSel(0, 0, 2, 0));

stTest("insertLineAfter", "abcde\nfghijkl\nmn",
setSel(0, 1, 0, 1,
0, 3, 0, 3,
1, 2, 1, 2,
1, 3, 1, 5), "insertLineAfter",
hasSel(1, 0, 1, 0,
3, 0, 3, 0), val("abcde\n\nfghijkl\n\nmn"));

stTest("insertLineBefore", "abcde\nfghijkl\nmn",
setSel(0, 1, 0, 1,
0, 3, 0, 3,
1, 2, 1, 2,
1, 3, 1, 5), "insertLineBefore",
hasSel(0, 0, 0, 0,
2, 0, 2, 0), val("\nabcde\n\nfghijkl\nmn"));

stTest("selectNextOccurrence", "a foo bar\nfoobar foo",
setSel(0, 2, 0, 5),
"selectNextOccurrence", hasSel(0, 2, 0, 5,
1, 0, 1, 3),
"selectNextOccurrence", hasSel(0, 2, 0, 5,
1, 0, 1, 3,
1, 7, 1, 10),
"selectNextOccurrence", hasSel(0, 2, 0, 5,
1, 0, 1, 3,
1, 7, 1, 10),
Pos(0, 3), "selectNextOccurrence", hasSel(0, 2, 0, 5),
"selectNextOccurrence", hasSel(0, 2, 0, 5,
1, 7, 1, 10),
setSel(0, 6, 0, 9),
"selectNextOccurrence", hasSel(0, 6, 0, 9,
1, 3, 1, 6));

stTest("selectScope", "foo(a) {\n bar[1, 2];\n}",
"selectScope", hasSel(0, 0, 2, 1),
Pos(0, 4), "selectScope", hasSel(0, 4, 0, 5),
Pos(0, 5), "selectScope", hasSel(0, 4, 0, 5),
Pos(0, 6), "selectScope", hasSel(0, 0, 2, 1),
Pos(0, 8), "selectScope", hasSel(0, 8, 2, 0),
Pos(1, 2), "selectScope", hasSel(0, 8, 2, 0),
Pos(1, 6), "selectScope", hasSel(1, 6, 1, 10),
Pos(1, 9), "selectScope", hasSel(1, 6, 1, 10));

stTest("goToBracket", "foo(a) {\n bar[1, 2];\n}",
Pos(0, 0), "goToBracket", at(0, 0),
Pos(0, 4), "goToBracket", at(0, 5), "goToBracket", at(0, 4),
Pos(0, 8), "goToBracket", at(2, 0), "goToBracket", at(0, 8),
Pos(1, 2), "goToBracket", at(2, 0),
Pos(1, 7), "goToBracket", at(1, 10), "goToBracket", at(1, 6));

stTest("swapLine", "1\n2\n3---\n4\n5",
"swapLineDown", val("2\n1\n3---\n4\n5"),
"swapLineUp", val("1\n2\n3---\n4\n5"),
"swapLineUp", val("1\n2\n3---\n4\n5"),
Pos(4, 1), "swapLineDown", val("1\n2\n3---\n4\n5"),
setSel(0, 1, 0, 1,
1, 0, 2, 0,
2, 2, 2, 2),
"swapLineDown", val("4\n1\n2\n3---\n5"),
hasSel(1, 1, 1, 1,
2, 0, 3, 0,
3, 2, 3, 2),
"swapLineUp", val("1\n2\n3---\n4\n5"),
hasSel(0, 1, 0, 1,
1, 0, 2, 0,
2, 2, 2, 2));

stTest("swapLineUpFromEnd", "a\nb\nc",
Pos(2, 1), "swapLineUp",
hasSel(1, 1, 1, 1), val("a\nc\nb"));

stTest("joinLines", "abc\ndef\nghi\njkl",
"joinLines", val("abc def\nghi\njkl"), at(0, 4),
"undo",
setSel(0, 2, 1, 1), "joinLines",
val("abc def ghi\njkl"), hasSel(0, 2, 0, 8),
"undo",
setSel(0, 1, 0, 1,
1, 1, 1, 1,
3, 1, 3, 1), "joinLines",
val("abc def ghi\njkl"), hasSel(0, 4, 0, 4,
0, 8, 0, 8,
1, 3, 1, 3));

stTest("duplicateLine", "abc\ndef\nghi",
Pos(1, 0), "duplicateLine", val("abc\ndef\ndef\nghi"), at(2, 0),
"undo",
setSel(0, 1, 0, 1,
1, 1, 1, 1,
2, 1, 2, 1), "duplicateLine",
val("abc\nabc\ndef\ndef\nghi\nghi"), hasSel(1, 1, 1, 1,
3, 1, 3, 1,
5, 1, 5, 1));
stTest("duplicateLineSelection", "abcdef",
setSel(0, 1, 0, 1,
0, 2, 0, 4,
0, 5, 0, 5),
"duplicateLine",
val("abcdef\nabcdcdef\nabcdcdef"), hasSel(2, 1, 2, 1,
2, 4, 2, 6,
2, 7, 2, 7));

stTest("selectLinesUpward", "123\n345\n789\n012",
setSel(0, 1, 0, 1,
1, 1, 1, 3,
2, 0, 2, 0,
3, 0, 3, 0),
"selectLinesUpward",
hasSel(0, 1, 0, 1,
0, 3, 0, 3,
1, 0, 1, 0,
1, 1, 1, 3,
2, 0, 2, 0,
3, 0, 3, 0));

stTest("selectLinesDownward", "123\n345\n789\n012",
setSel(0, 1, 0, 1,
1, 1, 1, 3,
2, 0, 2, 0,
3, 0, 3, 0),
"selectLinesDownward",
hasSel(0, 1, 0, 1,
1, 1, 1, 3,
2, 0, 2, 0,
2, 3, 2, 3,
3, 0, 3, 0));

stTest("sortLines", "c\nb\na\nC\nB\nA",
"sortLines", val("A\nB\nC\na\nb\nc"),
"undo",
setSel(0, 0, 2, 0,
3, 0, 5, 0),
"sortLines", val("a\nb\nc\nA\nB\nC"),
hasSel(0, 0, 2, 1,
3, 0, 5, 1),
"undo",
setSel(1, 0, 4, 0), "sortLinesInsensitive", val("c\na\nB\nb\nC\nA"));

stTest("bookmarks", "abc\ndef\nghi\njkl",
Pos(0, 1), "toggleBookmark",
setSel(1, 1, 1, 2), "toggleBookmark",
setSel(2, 1, 2, 2), "toggleBookmark",
"nextBookmark", hasSel(0, 1, 0, 1),
"nextBookmark", hasSel(1, 1, 1, 2),
"nextBookmark", hasSel(2, 1, 2, 2),
"prevBookmark", hasSel(1, 1, 1, 2),
"prevBookmark", hasSel(0, 1, 0, 1),
"prevBookmark", hasSel(2, 1, 2, 2),
"prevBookmark", hasSel(1, 1, 1, 2),
"toggleBookmark",
"prevBookmark", hasSel(2, 1, 2, 2),
"prevBookmark", hasSel(0, 1, 0, 1),
"selectBookmarks", hasSel(0, 1, 0, 1,
2, 1, 2, 2),
"clearBookmarks",
Pos(0, 0), "selectBookmarks", at(0, 0));

stTest("upAndDowncaseAtCursor", "abc\ndef x\nghI",
setSel(0, 1, 0, 3,
1, 1, 1, 1,
1, 4, 1, 4), "upcaseAtCursor",
val("aBC\nDEF x\nghI"), hasSel(0, 1, 0, 3,
1, 3, 1, 3,
1, 4, 1, 4),
"downcaseAtCursor",
val("abc\ndef x\nghI"), hasSel(0, 1, 0, 3,
1, 3, 1, 3,
1, 4, 1, 4));

stTest("mark", "abc\ndef\nghi",
Pos(1, 1), "setSublimeMark",
Pos(2, 1), "selectToSublimeMark", hasSel(2, 1, 1, 1),
Pos(0, 1), "swapWithSublimeMark", at(1, 1), "swapWithSublimeMark", at(0, 1),
"deleteToSublimeMark", val("aef\nghi"),
"sublimeYank", val("abc\ndef\nghi"), at(1, 1));

stTest("findUnder", "foo foobar a",
"findUnder", hasSel(0, 4, 0, 7),
"findUnder", hasSel(0, 0, 0, 3),
"findUnderPrevious", hasSel(0, 4, 0, 7),
"findUnderPrevious", hasSel(0, 0, 0, 3),
Pos(0, 4), "findUnder", hasSel(0, 4, 0, 10),
Pos(0, 11), "findUnder", hasSel(0, 11, 0, 11));
})();

Large diffs are not rendered by default.

@@ -968,7 +968,12 @@ testVim('<<', function(cm, vim, helpers) {
// Edit tests
function testEdit(name, before, pos, edit, after) {
return testVim(name, function(cm, vim, helpers) {
cm.setCursor(0, before.search(pos));
var ch = before.search(pos)
var line = before.substring(0, ch).split('\n').length - 1;
if (line) {
ch = before.substring(0, ch).split('\n').pop().length;
}
cm.setCursor(line, ch);
helpers.doKeys.apply(this, edit.split(''));
eq(after, cm.getValue());
}, {value: before});
@@ -2243,7 +2248,7 @@ testVim('scrollMotion', function(cm, vim, helpers){
prevScrollInfo = cm.getScrollInfo();
helpers.doKeys('<C-e>');
eq(1, cm.getCursor().line);
eq(true, prevScrollInfo.top < cm.getScrollInfo().top);
is(prevScrollInfo.top < cm.getScrollInfo().top);
// Jump to the end of the sandbox.
cm.setCursor(1000, 0);
prevCursor = cm.getCursor();
@@ -2253,7 +2258,7 @@ testVim('scrollMotion', function(cm, vim, helpers){
prevScrollInfo = cm.getScrollInfo();
helpers.doKeys('<C-y>');
eq(prevCursor.line - 1, cm.getCursor().line);
eq(true, prevScrollInfo.top > cm.getScrollInfo().top);
is(prevScrollInfo.top > cm.getScrollInfo().top);
}, { value: scrollMotionSandbox});

var squareBracketMotionSandbox = ''+
@@ -2846,3 +2851,9 @@ testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 0);
eq('bc', cm.getValue());
}, { value: 'abc' });

// Test event handlers
testVim('beforeSelectionChange', function(cm, vim, helpers) {
cm.setCursor(0, 100);
eqPos(cm.getCursor('head'), cm.getCursor('anchor'));
}, { value: 'abc' });