1,311 changes: 1,016 additions & 295 deletions keymap/vim.js

Large diffs are not rendered by default.

76 changes: 52 additions & 24 deletions lib/codemirror.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ window.CodeMirror = (function() {
var phantom = /PhantomJS/.test(navigator.userAgent);

var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
// This is woefully incomplete. Suggestions for alternative methods welcome.
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|IEMobile/i.test(navigator.userAgent);
var mac = ios || /Mac/.test(navigator.platform);

// Optimize some code when these features are not used
Expand All @@ -40,7 +42,7 @@ window.CodeMirror = (function() {
var display = this.display = makeDisplay(place);
display.wrapper.CodeMirror = this;
updateGutters(this);
if (options.autofocus) focusInput(this);
if (options.autofocus && !mobile) focusInput(this);

this.view = makeView(new BranchChunk([new LeafChunk([makeLine("", null, textHeight(display))])]));
this.nextOpId = 0;
Expand All @@ -60,7 +62,7 @@ window.CodeMirror = (function() {
// IE throws unspecified error in certain cases, when
// trying to access activeElement before onload
var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
if (hasFocus || options.autofocus) setTimeout(bind(onFocus, this), 20);
if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
else onBlur(this);

operation(this, function() {
Expand Down Expand Up @@ -214,8 +216,8 @@ window.CodeMirror = (function() {
});
}
regChange(cm, 0, doc.size);
clearMeasureLineCache(cm);
setTimeout(bind(updateScrollbars, cm.display), 100);
clearCaches(cm);
setTimeout(function(){updateScrollbars(cm.display, cm.view.doc.height);}, 100);
}

function keyMapChanged(cm) {
Expand All @@ -227,6 +229,7 @@ window.CodeMirror = (function() {
function themeChanged(cm) {
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
clearCaches(cm);
}

function guttersChanged(cm) {
Expand Down Expand Up @@ -752,6 +755,7 @@ window.CodeMirror = (function() {
var on = true;
display.cursor.style.visibility = display.otherCursor.style.visibility = "";
display.blinker = setInterval(function() {
if (!display.cursor.offsetHeight) return;
display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
}, cm.options.cursorBlinkRate);
}
Expand Down Expand Up @@ -881,7 +885,7 @@ window.CodeMirror = (function() {
// doesn't work when wrapping is on, but in that case the
// situation is slightly better, since IE does cache line-wrapping
// information and only recomputes per-line.
if (ie && !cm.options.lineWrapping && pre.childNodes.length > 100) {
if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
var fragment = document.createDocumentFragment();
var chunk = 10, n = pre.childNodes.length;
for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
Expand Down Expand Up @@ -923,8 +927,10 @@ window.CodeMirror = (function() {
return data;
}

function clearMeasureLineCache(cm) {
function clearCaches(cm) {
cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
cm.view.maxLineChanged = true;
}

// Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
Expand Down Expand Up @@ -1259,7 +1265,7 @@ window.CodeMirror = (function() {
on(window, "resize", function resizeHandler() {
// Might be a text scaling operation, clear size caches.
d.cachedCharWidth = d.cachedTextHeight = null;
clearMeasureLineCache(cm);
clearCaches(cm);
if (d.wrapper.parentNode) updateDisplay(cm, true);
else off(window, "resize", resizeHandler);
});
Expand Down Expand Up @@ -1398,14 +1404,19 @@ window.CodeMirror = (function() {
return;
}
e_preventDefault(e);
if (type == "single") extendSelection(cm, start);
if (type == "single") extendSelection(cm, clipPos(doc, start));

var startstart = sel.from, startend = sel.to;

function doSelect(cur) {
if (type == "single") {
extendSelection(cm, start, cur);
} else if (type == "double") {
extendSelection(cm, clipPos(doc, start), cur);
return;
}

startstart = clipPos(doc, startstart);
startend = clipPos(doc, startend);
if (type == "double") {
var word = findWordAt(getLine(doc, cur.line).text, cur);
if (posLess(cur, startstart)) extendSelection(cm, word.from, startend);
else extendSelection(cm, startstart, word.to);
Expand Down Expand Up @@ -1537,7 +1548,8 @@ window.CodeMirror = (function() {
e.dataTransfer.setData("Text", txt);

// Use dummy image instead of default browsers image.
if (e.dataTransfer.setDragImage)
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
if (e.dataTransfer.setDragImage && !safari)
e.dataTransfer.setDragImage(elt('img'), 0, 0);
}

Expand Down Expand Up @@ -2124,8 +2136,8 @@ window.CodeMirror = (function() {
// SCROLLING

function scrollCursorIntoView(cm) {
var view = cm.view, coords = cursorCoords(cm, view.sel.head);
scrollIntoView(cm, coords.left, coords.top, coords.left, coords.bottom);
var view = cm.view;
var coords = scrollPosIntoView(cm, view.sel.head);
if (!view.focused) return;
var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
if (coords.top + box.top < 0) doScroll = true;
Expand All @@ -2142,6 +2154,23 @@ window.CodeMirror = (function() {
}
}

function scrollPosIntoView(cm, pos) {
for (;;) {
var changed = false, coords = cursorCoords(cm, pos);
var scrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
var startTop = cm.view.scrollTop, startLeft = cm.view.scrollLeft;
if (scrollPos.scrollTop != null) {
setScrollTop(cm, scrollPos.scrollTop);
if (Math.abs(cm.view.scrollTop - startTop) > 1) changed = true;
}
if (scrollPos.scrollLeft != null) {
setScrollLeft(cm, scrollPos.scrollLeft);
if (Math.abs(cm.view.scrollLeft - startLeft) > 1) changed = true;
}
if (!changed) return coords;
}
}

function scrollIntoView(cm, x1, y1, x2, y2) {
var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
Expand Down Expand Up @@ -2703,9 +2732,9 @@ window.CodeMirror = (function() {
},

scrollIntoView: function(pos) {
if (typeof pos == "number") pos = {line: pos, ch: 0};
pos = pos ? clipPos(this.view.doc, pos) : this.view.sel.head;
var coords = cursorCoords(this, pos);
scrollIntoView(this, coords.left, coords.top, coords.left, coords.bottom);
scrollPosIntoView(this, pos);
},

setSize: function(width, height) {
Expand All @@ -2723,7 +2752,7 @@ window.CodeMirror = (function() {
operation: function(f){return operation(this, f)();},

refresh: function() {
clearMeasureLineCache(this);
clearCaches(this);
if (this.display.scroller.scrollHeight > this.view.scrollTop)
this.display.scrollbarV.scrollTop = this.display.scroller.scrollTop = this.view.scrollTop;
updateDisplay(this, true);
Expand Down Expand Up @@ -2760,13 +2789,12 @@ window.CodeMirror = (function() {
option("smartIndent", true);
option("tabSize", 4, function(cm) {
loadMode(cm);
clearMeasureLineCache(cm);
clearCaches(cm);
updateDisplay(cm, true);
}, true);
option("electricChars", true);

option("theme", "default", function(cm) {
clearMeasureLineCache(cm);
themeChanged(cm);
guttersChanged(cm);
}, true);
Expand Down Expand Up @@ -3075,13 +3103,13 @@ window.CodeMirror = (function() {
if (textarea.form) {
// Deplorable hack to make the submit method do the right thing.
on(textarea.form, "submit", save);
var realSubmit = textarea.form.submit;
var form = textarea.form, realSubmit = form.submit;
try {
textarea.form.submit = function wrappedSubmit() {
form.submit = function wrappedSubmit() {
save();
textarea.form.submit = realSubmit;
textarea.form.submit();
textarea.form.submit = wrappedSubmit;
form.submit = realSubmit;
form.submit();
form.submit = wrappedSubmit;
};
} catch(e) {}
}
Expand Down Expand Up @@ -4517,7 +4545,7 @@ window.CodeMirror = (function() {

// THE END

CodeMirror.version = "3.0 rc2";
CodeMirror.version = "3.0";

return CodeMirror;
})();
29 changes: 29 additions & 0 deletions lib/util/colorize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
CodeMirror.colorize = (function() {

var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;

function textContent(node, out) {
if (node.nodeType == 3) return out.push(node.nodeValue);
for (var ch = node.firstChild; ch; ch = ch.nextSibling) {
textContent(ch, out);
if (isBlock.test(node.nodeType)) out.push("\n");
}
}

return function(collection, defaultMode) {
if (!collection) collection = document.body.getElementsByTagName("pre");

for (var i = 0; i < collection.length; ++i) {
var node = collection[i];
var mode = node.getAttribute("data-lang") || defaultMode;
if (!mode) continue;

var text = [];
textContent(node, text);
node.innerHTML = "";
CodeMirror.runMode(text.join(""), mode, node);

node.className += " cm-s-default";
}
};
})();
28 changes: 28 additions & 0 deletions lib/util/continuelist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(function() {
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
var pos = cm.getCursor(), token = cm.getTokenAt(pos);
var space;
if (token.className == "string") {
var full = cm.getRange({line: pos.line, ch: 0}, {line: pos.line, ch: token.end});
var listStart = /\*|\d+\./, listContinue;
if (token.string.search(listStart) == 0) {
var reg = /^[\W]*(\d+)\./g;
var matches = reg.exec(full);
if(matches)
listContinue = (parseInt(matches[1]) + 1) + ". ";
else
listContinue = "* ";
space = full.slice(0, token.start);
if (!/^\s*$/.test(space)) {
space = "";
for (var i = 0; i < token.start; ++i) space += " ";
}
}
}

if (space != null)
cm.replaceSelection("\n" + space + listContinue, "end");
else
cm.execCommand("newlineAndIndent");
};
})();
19 changes: 12 additions & 7 deletions lib/util/dialog.css
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
.CodeMirror-dialog {
position: relative;
}

.CodeMirror-dialog > div {
position: absolute;
top: 0; left: 0; right: 0;
left: 0; right: 0;
background: white;
border-bottom: 1px solid #eee;
z-index: 15;
padding: .1em .8em;
overflow: hidden;
color: #333;
}

.CodeMirror-dialog-top {
border-bottom: 1px solid #eee;
top: 0;
}

.CodeMirror-dialog-bottom {
border-top: 1px solid #eee;
bottom: 0;
}

.CodeMirror-dialog input {
border: none;
outline: none;
Expand All @@ -24,4 +29,4 @@

.CodeMirror-dialog button {
font-size: 70%;
}
}
23 changes: 14 additions & 9 deletions lib/util/dialog.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
// Open simple dialogs on top of an editor. Relies on dialog.css.

(function() {
function dialogDiv(cm, template) {
function dialogDiv(cm, template, bottom) {
var wrap = cm.getWrapperElement();
var dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
dialog.className = "CodeMirror-dialog";
dialog.innerHTML = '<div>' + template + '</div>';
var dialog;
dialog = wrap.appendChild(document.createElement("div"));
if (bottom) {
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
} else {
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
}
dialog.innerHTML = template;
return dialog;
}

CodeMirror.defineExtension("openDialog", function(template, callback) {
var dialog = dialogDiv(this, template);
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
var dialog = dialogDiv(this, template, options && options.bottom);
var closed = false, me = this;
function close() {
if (closed) return;
Expand Down Expand Up @@ -40,8 +45,8 @@
return close;
});

CodeMirror.defineExtension("openConfirm", function(template, callbacks) {
var dialog = dialogDiv(this, template);
CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
var dialog = dialogDiv(this, template, options && options.bottom);
var buttons = dialog.getElementsByTagName("button");
var closed = false, me = this, blurring = 1;
function close() {
Expand All @@ -67,4 +72,4 @@
CodeMirror.on(b, "focus", function() { ++blurring; });
}
});
})();
})();
27 changes: 15 additions & 12 deletions lib/util/javascript-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
return arr.indexOf(item) != -1;
}

function scriptHint(editor, keywords, getToken) {
function scriptHint(editor, keywords, getToken, options) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
// If it's not a 'word-style' token, ignore the token.
Expand Down Expand Up @@ -47,14 +47,15 @@
if (!context) var context = [];
context.push(tprop);
}
return {list: getCompletions(token, context, keywords),
return {list: getCompletions(token, context, keywords, options),
from: {line: cur.line, ch: token.start},
to: {line: cur.line, ch: token.end}};
}

CodeMirror.javascriptHint = function(editor) {
CodeMirror.javascriptHint = function(editor, options) {
return scriptHint(editor, javascriptKeywords,
function (e, cur) {return e.getTokenAt(cur);});
function (e, cur) {return e.getTokenAt(cur);},
options);
};

function getCoffeeScriptToken(editor, cur) {
Expand All @@ -75,8 +76,8 @@
return token;
}

CodeMirror.coffeescriptHint = function(editor) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
CodeMirror.coffeescriptHint = function(editor, options) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
};

var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
Expand All @@ -89,7 +90,7 @@
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");

function getCompletions(token, context, keywords) {
function getCompletions(token, context, keywords, options) {
var found = [], start = token.string;
function maybeAdd(str) {
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
Expand All @@ -105,13 +106,15 @@
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop(), base;
if (obj.type == "variable")
base = window[obj.string];
else if (obj.type == "string")
if (obj.type == "variable") {
if (options && options.additionalContext)
base = options.additionalContext[obj.string];
base = base || window[obj.string];
} else if (obj.type == "string") {
base = "";
else if (obj.type == "atom")
} else if (obj.type == "atom") {
base = 1;
else if (obj.type == "function") {
} else if (obj.type == "function") {
if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
(typeof window.jQuery == 'function'))
base = window.jQuery();
Expand Down
18 changes: 18 additions & 0 deletions lib/util/multiplex.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
},

blankLine: function(state) {
var mode = state.innerActive ? state.innerActive.mode : outer;
if (mode.blankLine) {
mode.blankLine(state.innerActive ? state.inner : state.outer);
}
if (!state.innerActive) {
for (var i = 0; i < n_others; ++i) {
var other = others[i];
if (other.open === "\n") {
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0);
}
}
} else if (mode.close === "\n") {
state.innerActive = state.inner = null;
}
},

electricChars: outer.electricChars,

innerMode: function(state) {
Expand Down
39 changes: 19 additions & 20 deletions lib/util/runmode.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
CodeMirror.runMode = function(string, modespec, callback, options) {
function esc(str) {
return str.replace(/[<&]/g, function(ch) { return ch == "<" ? "&lt;" : "&amp;"; });
}

var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var isNode = callback.nodeType == 1;
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
if (isNode) {
var node = callback, accum = [], col = 0;

if (callback.nodeType == 1) {
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
if (text == "\n") {
accum.push("<br>");
node.appendChild(document.createElement("br"));
col = 0;
return;
}
var escaped = "";
// HTML-escape and replace tabs
var content = "";
// replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
escaped += esc(text.slice(pos));
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
escaped += esc(text.slice(pos, idx));
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) escaped += " ";
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}

if (style)
accum.push("<span class=\"cm-" + esc(style) + "\">" + escaped + "</span>");
else
accum.push(escaped);
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}

var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
Expand All @@ -48,6 +49,4 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
stream.start = stream.pos;
}
}
if (isNode)
node.innerHTML = accum.join("");
};
2 changes: 1 addition & 1 deletion lib/util/simple-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
return;
}

var result = getHints(editor);
var result = getHints(editor, givenOptions);
if (!result || !result.list.length) return;
var completions = result.list;
function insert(str) {
Expand Down
8 changes: 6 additions & 2 deletions mode/clike/clike.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CodeMirror.defineMode("clike", function(config, parserConfig) {
var indentUnit = config.indentUnit,
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
keywords = parserConfig.keywords || {},
builtin = parserConfig.builtin || {},
blockKeywords = parserConfig.blockKeywords || {},
Expand Down Expand Up @@ -89,7 +90,10 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
this.prev = prev;
}
function pushContext(state, col, type) {
return state.context = new Context(state.indented, col, type, null, state.context);
var indent = state.indented;
if (state.context && state.context.type == "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
Expand Down Expand Up @@ -144,7 +148,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
var closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
},
Expand Down
23 changes: 20 additions & 3 deletions mode/css/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ CodeMirror.defineMode("css", function(config) {
else if (/[;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
}
else if (ch == "u" && stream.match("rl(")) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "variable");
}
else {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "variable");
Expand Down Expand Up @@ -267,19 +272,31 @@ CodeMirror.defineMode("css", function(config) {
return ret("comment", "comment");
}

function tokenString(quote) {
function tokenString(quote, nonInclusive) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped)
break;
escaped = !escaped && ch == "\\";
}
if (!escaped) state.tokenize = tokenBase;
if (!escaped) {
if (nonInclusive) stream.backUp(1);
state.tokenize = tokenBase;
}
return ret("string", "string");
};
}

function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
if (!stream.match(/\s*[\"\']/, false))
state.tokenize = tokenString(")", true);
else
state.tokenize = tokenBase;
return ret(null, "(");
}

return {
startState: function(base) {
return {tokenize: tokenBase,
Expand Down Expand Up @@ -335,7 +352,7 @@ CodeMirror.defineMode("css", function(config) {
// sequence of selectors:
// One or more of the named type of selector chained with commas.

if (stream.eatSpace()) return null;
if (state.tokenize == tokenBase && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);

// Changing style returned based on context
Expand Down
384 changes: 192 additions & 192 deletions mode/ecl/ecl.js

Large diffs are not rendered by default.

78 changes: 39 additions & 39 deletions mode/ecl/index.html
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
<!doctype html>
<html>
<head>
<title>CodeMirror: ECL mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="ecl.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: ECL mode</h1>
<form><textarea id="code" name="code">
/*
sample useless code to demonstrate ecl syntax highlighting
this is a multiline comment!
*/

// this is a singleline comment!

import ut;
r :=
record
string22 s1 := '123';
integer4 i1 := 123;
end;
#option('tmp', true);
d := dataset('tmp::qb', r, thor);
output(d);
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>

<p>Based on CodeMirror's clike mode. For more information see <a href="http://hpccsystems.com">HPCC Systems</a> web site.</p>
<p><strong>MIME types defined:</strong> <code>text/x-ecl</code>.</p>

</body>
</html>
<!doctype html>
<html>
<head>
<title>CodeMirror: ECL mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="ecl.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: ECL mode</h1>
<form><textarea id="code" name="code">
/*
sample useless code to demonstrate ecl syntax highlighting
this is a multiline comment!
*/

// this is a singleline comment!

import ut;
r :=
record
string22 s1 := '123';
integer4 i1 := 123;
end;
#option('tmp', true);
d := dataset('tmp::qb', r, thor);
output(d);
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>

<p>Based on CodeMirror's clike mode. For more information see <a href="http://hpccsystems.com">HPCC Systems</a> web site.</p>
<p><strong>MIME types defined:</strong> <code>text/x-ecl</code>.</p>

</body>
</html>
6 changes: 3 additions & 3 deletions mode/htmlembedded/htmlembedded.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
return {
token : parserConfig.startOpen ? scriptingDispatch : htmlDispatch,
htmlState : htmlMixedMode.startState(),
scriptState : scriptingMode.startState()
htmlState : CodeMirror.startState(htmlMixedMode),
scriptState : CodeMirror.startState(scriptingMode)
};
},

Expand All @@ -46,7 +46,7 @@ CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
indent: function(state, textAfter) {
if (state.token == htmlDispatch)
return htmlMixedMode.indent(state.htmlState, textAfter);
else
else if (scriptingMode.indent)
return scriptingMode.indent(state.scriptState, textAfter);
},

Expand Down
4 changes: 3 additions & 1 deletion mode/markdown/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<title>CodeMirror: Markdown mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../lib/util/continuelist.js"></script>
<script src="../xml/xml.js"></script>
<script src="markdown.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
Expand Down Expand Up @@ -328,7 +329,8 @@ <h1>CodeMirror: Markdown mode</h1>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: 'markdown',
lineNumbers: true,
theme: "default"
theme: "default",
extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
});
</script>

Expand Down
2 changes: 1 addition & 1 deletion mode/php/php.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"die echo empty exit eval include include_once isset list require require_once return " +
"print unset __halt_compiler self static parent"),
blockKeywords: keywords("catch do else elseif for foreach if switch try while"),
atoms: keywords("true false null TRUE FALSE NULL"),
atoms: keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__"),
builtin: keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport echo print global static exit array empty eval isset unset die include require include_once require_once"),
multiLineStrings: true,
hooks: {
Expand Down
Empty file modified mode/properties/index.html
100755 → 100644
Empty file.
Empty file modified mode/properties/properties.js
100755 → 100644
Empty file.
364 changes: 182 additions & 182 deletions mode/verilog/verilog.js
Original file line number Diff line number Diff line change
@@ -1,182 +1,182 @@
CodeMirror.defineMode("verilog", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = parserConfig.keywords || {},
blockKeywords = parserConfig.blockKeywords || {},
atoms = parserConfig.atoms || {},
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings;
var isOperatorChar = /[&|~><!\)\(*#%@+\/=?\:;}{,\.\^\-\[\]]/;

var curPunc;

function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == '"') {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (/[\d']/.test(ch)) {
stream.eatWhile(/[\w\.']/);
return "number";
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "keyword";
}
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}

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

function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}

function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
return state.context = new Context(state.indented, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}

// Interface

return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},

token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;

if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},

indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return 0;
var firstChar = textAfter && textAfter.charAt(0), ctx = state.context, closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
},

electricChars: "{}"
};
});

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

var verilogKeywords = "always and assign automatic begin buf bufif0 bufif1 case casex casez cell cmos config " +
"deassign default defparam design disable edge else end endcase endconfig endfunction endgenerate endmodule " +
"endprimitive endspecify endtable endtask event for force forever fork function generate genvar highz0 " +
"highz1 if ifnone incdir include initial inout input instance integer join large liblist library localparam " +
"macromodule medium module nand negedge nmos nor noshowcancelled not notif0 notif1 or output parameter pmos " +
"posedge primitive pull0 pull1 pulldown pullup pulsestyle_onevent pulsestyle_ondetect rcmos real realtime " +
"reg release repeat rnmos rpmos rtran rtranif0 rtranif1 scalared showcancelled signed small specify specparam " +
"strong0 strong1 supply0 supply1 table task time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg " +
"unsigned use vectored wait wand weak0 weak1 while wire wor xnor xor";

var verilogBlockKeywords = "begin bufif0 bufif1 case casex casez config else end endcase endconfig endfunction " +
"endgenerate endmodule endprimitive endspecify endtable endtask for forever function generate if ifnone " +
"macromodule module primitive repeat specify table task while";

function metaHook(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
}

CodeMirror.defineMIME("text/x-verilog", {
name: "verilog",
keywords: words(verilogKeywords),
blockKeywords: words(verilogBlockKeywords),
atoms: words("null"),
hooks: {"`": metaHook, "$": metaHook}
});
}());
CodeMirror.defineMode("verilog", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = parserConfig.keywords || {},
blockKeywords = parserConfig.blockKeywords || {},
atoms = parserConfig.atoms || {},
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings;
var isOperatorChar = /[&|~><!\)\(*#%@+\/=?\:;}{,\.\^\-\[\]]/;

var curPunc;

function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == '"') {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (/[\d']/.test(ch)) {
stream.eatWhile(/[\w\.']/);
return "number";
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "keyword";
}
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}

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

function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}

function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
return state.context = new Context(state.indented, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}

// Interface

return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},

token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;

if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},

indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return 0;
var firstChar = textAfter && textAfter.charAt(0), ctx = state.context, closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
},

electricChars: "{}"
};
});

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

var verilogKeywords = "always and assign automatic begin buf bufif0 bufif1 case casex casez cell cmos config " +
"deassign default defparam design disable edge else end endcase endconfig endfunction endgenerate endmodule " +
"endprimitive endspecify endtable endtask event for force forever fork function generate genvar highz0 " +
"highz1 if ifnone incdir include initial inout input instance integer join large liblist library localparam " +
"macromodule medium module nand negedge nmos nor noshowcancelled not notif0 notif1 or output parameter pmos " +
"posedge primitive pull0 pull1 pulldown pullup pulsestyle_onevent pulsestyle_ondetect rcmos real realtime " +
"reg release repeat rnmos rpmos rtran rtranif0 rtranif1 scalared showcancelled signed small specify specparam " +
"strong0 strong1 supply0 supply1 table task time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg " +
"unsigned use vectored wait wand weak0 weak1 while wire wor xnor xor";

var verilogBlockKeywords = "begin bufif0 bufif1 case casex casez config else end endcase endconfig endfunction " +
"endgenerate endmodule endprimitive endspecify endtable endtask for forever function generate if ifnone " +
"macromodule module primitive repeat specify table task while";

function metaHook(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
}

CodeMirror.defineMIME("text/x-verilog", {
name: "verilog",
keywords: words(verilogKeywords),
blockKeywords: words(verilogBlockKeywords),
atoms: words("null"),
hooks: {"`": metaHook, "$": metaHook}
});
}());
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":"3.0.12",
"version":"3.0.2",
"main": "codemirror.js",
"description": "In-browser code editing made bearable",
"licenses": [{"type": "MIT",
Expand Down
1 change: 1 addition & 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="../lib/codemirror.js"></script>
<script src="../lib/util/overlay.js"></script>
<script src="../lib/util/searchcursor.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../keymap/vim.js"></script>
Expand Down
7 changes: 4 additions & 3 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function byClassName(elt, cls) {
var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
var mac = /Mac/.test(navigator.platform);
var phantom = /PhantomJS/.test(navigator.userAgent);
var opera_lt10 = /Opera\/[1-9]\./.test(navigator.userAgent);

test("core_fromTextArea", function() {
var te = document.getElementById("code");
Expand Down Expand Up @@ -674,7 +675,7 @@ testCM("wrappingAndResizing", function(cm) {
cm.setValue(doc);
for (var step = 10, w = cm.charCoords({line: 0, ch: 18}, "div").right;; w += step) {
cm.setSize(w);
if (wrap.offsetHeight <= h0 * 1.5) {
if (wrap.offsetHeight <= h0 * (opera_lt10 ? 1.2 : 1.5)) {
if (step == 10) { w -= 10; step = 1; }
else break;
}
Expand Down Expand Up @@ -715,7 +716,7 @@ testCM("measureEndOfLine", function(cm) {
is(endPos.left > w - 20, "not at right");
endPos = cm.charCoords({line: 0, ch: 18});
eqPos(cm.coordsChar({left: endPos.left, top: endPos.top + 5}), {line: 0, ch: 18});
}, {mode: "text/html", value: "<!-- foo barrr -->", lineWrapping: true}, ie_lt8);
}, {mode: "text/html", value: "<!-- foo barrr -->", lineWrapping: true}, ie_lt8 || opera_lt10);

testCM("scrollVerticallyAndHorizontally", function(cm) {
cm.setSize(100, 100);
Expand All @@ -740,7 +741,7 @@ testCM("moveVstuck", function(cm) {
cm.setCursor({line: 0, ch: val.length - 1});
cm.moveV(-1, "line");
eqPos(cm.getCursor(), {line: 0, ch: 26});
}, {lineWrapping: true}, ie_lt8);
}, {lineWrapping: true}, ie_lt8 || opera_lt10);

testCM("clickTab", function(cm) {
var p0 = cm.charCoords({line: 0, ch: 0});
Expand Down
453 changes: 416 additions & 37 deletions test/vim_test.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions theme/ambiance.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion theme/blackboard.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Port of TextMate's Blackboard theme */

.cm-s-blackboard { background: #0C1021; color: #F8F8F8; }
.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; }
.cm-s-blackboard .CodeMirror-selected { background: #253B76 !important; }
.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; }
.cm-s-blackboard .CodeMirror-linenumber { color: #888; }
Expand Down
2 changes: 1 addition & 1 deletion theme/cobalt.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.cm-s-cobalt { background: #002240; color: white; }
.cm-s-cobalt.CodeMirror { background: #002240; color: white; }
.cm-s-cobalt div.CodeMirror-selected { background: #b36539 !important; }
.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; }
Expand Down
2 changes: 1 addition & 1 deletion theme/erlang-dark.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.cm-s-erlang-dark { background: #002240; color: white; }
.cm-s-erlang-dark.CodeMirror { background: #002240; color: white; }
.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539 !important; }
.cm-s-erlang-dark .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
.cm-s-erlang-dark .CodeMirror-linenumber { color: #d0d0d0; }
Expand Down
2 changes: 1 addition & 1 deletion theme/lesser-dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Ported to CodeMirror by Peter Kroon
font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Monaco', Courier, monospace !important;
}

.cm-s-lesser-dark { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; }
.cm-s-lesser-dark.CodeMirror { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; }
.cm-s-lesser-dark div.CodeMirror-selected {background: #45443B !important;} /* 33322B*/
.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white !important; }
.cm-s-lesser-dark pre { padding: 0 8px; }/*editable code holder*/
Expand Down
2 changes: 1 addition & 1 deletion theme/monokai.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Based on Sublime Text's Monokai theme */

.cm-s-monokai {background: #272822; color: #f8f8f2;}
.cm-s-monokai.CodeMirror {background: #272822; color: #f8f8f2;}
.cm-s-monokai div.CodeMirror-selected {background: #49483E !important;}
.cm-s-monokai .CodeMirror-gutters {background: #272822; border-right: 0px;}
.cm-s-monokai .CodeMirror-linenumber {color: #d0d0d0;}
Expand Down
2 changes: 1 addition & 1 deletion theme/night.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Loosely based on the Midnight Textmate theme */

.cm-s-night { background: #0a001f; color: #f8f8f8; }
.cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; }
.cm-s-night div.CodeMirror-selected { background: #447 !important; }
.cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
.cm-s-night .CodeMirror-linenumber { color: #f8f8f8; }
Expand Down
2 changes: 1 addition & 1 deletion theme/rubyblue.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.cm-s-rubyblue { font:13px/1.4em Trebuchet, Verdana, sans-serif; } /* - customized editor font - */

.cm-s-rubyblue { background: #112435; color: white; }
.cm-s-rubyblue.CodeMirror { background: #112435; color: white; }
.cm-s-rubyblue div.CodeMirror-selected { background: #38566F !important; }
.cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; }
.cm-s-rubyblue .CodeMirror-linenumber { color: white; }
Expand Down
2 changes: 1 addition & 1 deletion theme/twilight.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.cm-s-twilight { background: #141414; color: #f7f7f7; } /**/
.cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/
.cm-s-twilight .CodeMirror-selected { background: #323232 !important; } /**/

.cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; }
Expand Down
2 changes: 1 addition & 1 deletion theme/vibrant-ink.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Taken from the popular Visual Studio Vibrant Ink Schema */

.cm-s-vibrant-ink { background: black; color: white; }
.cm-s-vibrant-ink.CodeMirror { background: black; color: white; }
.cm-s-vibrant-ink .CodeMirror-selected { background: #35493c !important; }

.cm-s-vibrant-ink .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
Expand Down
2 changes: 1 addition & 1 deletion theme/xq-dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
.cm-s-xq-dark { background: #0a001f; color: #f8f8f8; }
.cm-s-xq-dark.CodeMirror { background: #0a001f; color: #f8f8f8; }
.cm-s-xq-dark span.CodeMirror-selected { background: #a8f !important; }
.cm-s-xq-dark .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
.cm-s-xq-dark .CodeMirror-linenumber { color: #f8f8f8; }
Expand Down