41 changes: 24 additions & 17 deletions addon/fold/xml-fold.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
"use strict";

var Pos = CodeMirror.Pos;
function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }

var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");

function Iter(cm, line, ch) {
function Iter(cm, line, ch, range) {
this.line = line; this.ch = ch;
this.cm = cm; this.text = cm.getLine(line);
this.min = range ? range.from : cm.firstLine();
this.max = range ? range.to - 1 : cm.lastLine();
}

function tagAt(iter, ch) {
Expand All @@ -18,13 +21,13 @@
}

function nextLine(iter) {
if (iter.line >= iter.cm.lastLine()) return;
if (iter.line >= iter.max) return;
iter.ch = 0;
iter.text = iter.cm.getLine(++iter.line);
return true;
}
function prevLine(iter) {
if (iter.line <= iter.cm.firstLine()) return;
if (iter.line <= iter.min) return;
iter.text = iter.cm.getLine(--iter.line);
iter.ch = iter.text.length;
return true;
Expand All @@ -43,7 +46,7 @@
}
function toTagStart(iter) {
for (;;) {
var lt = iter.text.lastIndexOf("<", iter.ch - 1);
var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1;
if (lt == -1) { if (prevLine(iter)) continue; else return; }
if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }
xmlTagStart.lastIndex = lt;
Expand All @@ -65,7 +68,7 @@
}
function toPrevTag(iter) {
for (;;) {
var gt = iter.text.lastIndexOf(">", iter.ch - 1);
var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1;
if (gt == -1) { if (prevLine(iter)) continue; else return; }
if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }
var lastSlash = iter.text.lastIndexOf("/", gt);
Expand Down Expand Up @@ -121,7 +124,7 @@
}
}

CodeMirror.tagRangeFinder = function(cm, start) {
CodeMirror.registerHelper("fold", "xml", function(cm, start) {
var iter = new Iter(cm, start.line, 0);
for (;;) {
var openTag = toNextTag(iter), end;
Expand All @@ -132,27 +135,31 @@
return close && {from: start, to: close.from};
}
}
};
});
CodeMirror.tagRangeFinder = CodeMirror.fold.xml; // deprecated

CodeMirror.findMatchingTag = function(cm, pos) {
var iter = new Iter(cm, pos.line, pos.ch);
var end = toTagEnd(iter), start = toTagStart(iter);
if (!end || end == "selfClose" || !start) return;
CodeMirror.findMatchingTag = function(cm, pos, range) {
var iter = new Iter(cm, pos.line, pos.ch, range);
if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
var start = end && toTagStart(iter);
if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return;
var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};

if (start[1]) { // closing tag
return findMatchingOpen(iter, start[2]);
return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
} else { // opening tag
toTagEnd(iter);
return findMatchingClose(iter, start[2]);
iter = new Iter(cm, to.line, to.ch, range);
return {open: here, close: findMatchingClose(iter, start[2]), at: "open"};
}
};

CodeMirror.findEnclosingTag = function(cm, pos) {
var iter = new Iter(cm, pos.line, pos.ch);
CodeMirror.findEnclosingTag = function(cm, pos, range) {
var iter = new Iter(cm, pos.line, pos.ch, range);
for (;;) {
var open = findMatchingOpen(iter);
if (!open) break;
var forward = new Iter(cm, pos.line, pos.ch);
var forward = new Iter(cm, pos.line, pos.ch, range);
var close = findMatchingClose(forward, open.tag);
if (close) return {open: open, close: close};
}
Expand Down
34 changes: 34 additions & 0 deletions addon/hint/anyword-hint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
(function() {
"use strict";

var WORD = /[\w$]+/, RANGE = 500;

CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
var word = options && options.word || WORD;
var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
var start = cur.ch, end = start;
while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
while (start && word.test(curLine.charAt(start - 1))) --start;
var curWord = start != end && curLine.slice(start, end);

var list = [], seen = {};
function scan(dir) {
var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
for (; line != end; line += dir) {
var text = editor.getLine(line), m;
var re = new RegExp(word.source, "g");
while (m = re.exec(text)) {
if (line == cur.line && m[0] === curWord) continue;
if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) {
seen[m[0]] = true;
list.push(m[0]);
}
}
}
}
scan(-1);
scan(1);
return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
})();
8 changes: 5 additions & 3 deletions addon/hint/html-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,11 @@
populate(data[tag]);

CodeMirror.htmlSchema = data;
CodeMirror.htmlHint = function(cm, options) {
function htmlHint(cm, options) {
var local = {schemaInfo: data};
if (options) for (var opt in options) local[opt] = options[opt];
return CodeMirror.xmlHint(cm, local);
};
return CodeMirror.hint.xml(cm, local);
}
CodeMirror.htmlHint = htmlHint; // deprecated
CodeMirror.registerHelper("hint", "html", htmlHint);
})();
10 changes: 7 additions & 3 deletions addon/hint/javascript-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@
to: Pos(cur.line, token.end)};
}

CodeMirror.javascriptHint = function(editor, options) {
function javascriptHint(editor, options) {
return scriptHint(editor, javascriptKeywords,
function (e, cur) {return e.getTokenAt(cur);},
options);
};
CodeMirror.javascriptHint = javascriptHint; // deprecated
CodeMirror.registerHelper("hint", "javascript", javascriptHint);

function getCoffeeScriptToken(editor, cur) {
// This getToken, it is for coffeescript, imitates the behavior of
Expand All @@ -80,9 +82,11 @@
return token;
}

CodeMirror.coffeescriptHint = function(editor, options) {
function coffeescriptHint(editor, options) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
};
}
CodeMirror.coffeescriptHint = coffeescriptHint; // deprecated
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);

var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
"toUpperCase toLowerCase split concat match replace search").split(" ");
Expand Down
6 changes: 4 additions & 2 deletions addon/hint/pig-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
to: CodeMirror.Pos(cur.line, token.end)};
}

CodeMirror.pigHint = function(editor) {
function pigHint(editor) {
return scriptHint(editor, pigKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
};
}
CodeMirror.pigHint = pigHint; // deprecated
CodeMirror.registerHelper("hint", "pig", hinter);

var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
+ "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
Expand Down
6 changes: 4 additions & 2 deletions addon/hint/python-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
to: CodeMirror.Pos(cur.line, token.end)};
}

CodeMirror.pythonHint = function(editor) {
function pythonHint(editor) {
return scriptHint(editor, pythonKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
};
}
CodeMirror.pythonHint = pythonHint; // deprecated
CodeMirror.registerHelper("hint", "python", pythonHint);

var pythonKeywords = "and del from not while as elif global or with assert else if pass yield"
+ "break except import print class exec in raise continue finally is return def for lambda try";
Expand Down
8 changes: 6 additions & 2 deletions addon/hint/show-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
CodeMirror.showHint = function(cm, getHints, options) {
// We want a single cursor position.
if (cm.somethingSelected()) return;
if (getHints == null) getHints = cm.getHelper(cm.getCursor(), "hint");
if (getHints == null) return;

if (cm.state.completionActive) cm.state.completionActive.close();

Expand All @@ -25,10 +27,10 @@
Completion.prototype = {
close: function() {
if (!this.active()) return;
this.cm.state.completionActive = null;

if (this.widget) this.widget.close();
if (this.onClose) this.onClose();
this.cm.state.completionActive = null;
CodeMirror.signal(this.cm, "endCompletion", this.cm);
},

Expand Down Expand Up @@ -74,12 +76,14 @@

function update() {
if (isDone()) return;
CodeMirror.signal(data, "update");
if (completion.options.async)
completion.getHints(completion.cm, finishUpdate, completion.options);
else
finishUpdate(completion.getHints(completion.cm, completion.options));
}
function finishUpdate(data) {
function finishUpdate(data_) {
data = data_;
if (isDone()) return;
if (!data || !data.list.length) return done();
completion.widget.close();
Expand Down
7 changes: 5 additions & 2 deletions addon/hint/xml-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

var Pos = CodeMirror.Pos;

CodeMirror.xmlHint = function(cm, options) {
function getHints(cm, options) {
var tags = options && options.schemaInfo;
var quote = (options && options.quoteChar) || '"';
if (!tags) return;
Expand Down Expand Up @@ -61,5 +61,8 @@
from: replaceToken ? Pos(cur.line, token.start) : cur,
to: replaceToken ? Pos(cur.line, token.end) : cur
};
};
}

CodeMirror.xmlHint = getHints; // deprecated
CodeMirror.registerHelper("hint", "xml", getHints);
})();
5 changes: 3 additions & 2 deletions addon/lint/coffeescript-lint.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js

CodeMirror.coffeeValidator = function(text) {
CodeMirror.registerHelper("lint", "coffeescript", function(text) {
var found = [];
var parseError = function(err) {
var loc = err.lineNumber;
Expand All @@ -21,4 +21,5 @@ CodeMirror.coffeeValidator = function(text) {
message: e.message});
}
return found;
};
});
CodeMirror.coffeeValidator = CodeMirror.lint.coffeescript; // deprecated
9 changes: 3 additions & 6 deletions addon/lint/javascript-lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@
"Unmatched ", " and instead saw", " is not defined",
"Unclosed string", "Stopping, unable to continue" ];

function validator(options, text) {
function validator(text, options) {
JSHINT(text, options);
var errors = JSHINT.data().errors, result = [];
if (errors) parseErrors(errors, result);
return result;
}

CodeMirror.javascriptValidatorWithOptions = function(options) {
return function(text) { return validator(options, text); };
};

CodeMirror.javascriptValidator = CodeMirror.javascriptValidatorWithOptions(null);
CodeMirror.registerHelper("lint", "javascript", validator);
CodeMirror.javascriptValidator = CodeMirror.lint.javascript; // deprecated

function cleanup(error) {
// All problems are warnings by default
Expand Down
5 changes: 3 additions & 2 deletions addon/lint/json-lint.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Depends on jsonlint.js from https://github.com/zaach/jsonlint

CodeMirror.jsonValidator = function(text) {
CodeMirror.registerHelper("lint", "json", function(text) {
var found = [];
jsonlint.parseError = function(str, hash) {
var loc = hash.loc;
Expand All @@ -11,4 +11,5 @@ CodeMirror.jsonValidator = function(text) {
try { jsonlint.parse(text); }
catch(e) {}
return found;
};
});
CodeMirror.jsonValidator = CodeMirror.lint.json; // deprecated
18 changes: 12 additions & 6 deletions addon/lint/lint.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
CodeMirror.validate = (function() {
(function() {
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
var SEVERITIES = /^(?:error|warning)$/;

Expand Down Expand Up @@ -52,9 +53,11 @@ CodeMirror.validate = (function() {
this.onMouseOver = function(e) { onMouseOver(cm, e); };
}

function parseOptions(options) {
function parseOptions(cm, options) {
if (options instanceof Function) return {getAnnotations: options};
else if (!options || !options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
if (!options || options === true) options = {};
if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
return options;
}

Expand Down Expand Up @@ -175,7 +178,7 @@ CodeMirror.validate = (function() {
}
}

CodeMirror.defineOption("lintWith", false, function(cm, val, old) {
function optionHandler(cm, val, old) {
if (old && old != CodeMirror.Init) {
clearMarks(cm);
cm.off("change", onChange);
Expand All @@ -186,12 +189,15 @@ CodeMirror.validate = (function() {
if (val) {
var gutters = cm.getOption("gutters"), hasLintGutter = false;
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
var state = cm.state.lint = new LintState(cm, parseOptions(val), hasLintGutter);
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
cm.on("change", onChange);
if (state.options.tooltips != false)
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);

startLinting(cm);
}
});
}

CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated
CodeMirror.defineOption("lint", false, optionHandler); // deprecated
})();
68 changes: 39 additions & 29 deletions addon/merge/merge.css
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
.CodeMirror-diff {
.CodeMirror-merge {
position: relative;
border: 1px solid #ddd;
white-space: pre;
}

.CodeMirror-diff, .CodeMirror-diff .CodeMirror {
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
height: 350px;
}

.CodeMirror-diff-2pane .CodeMirror-diff-pane { width: 47%; }
.CodeMirror-diff-2pane .CodeMirror-diff-gap { width: 6%; }
.CodeMirror-diff-3pane .CodeMirror-diff-pane { width: 31%; }
.CodeMirror-diff-3pane .CodeMirror-diff-gap { width: 3.5%; }
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }

.CodeMirror-diff-pane {
float: left;
.CodeMirror-merge-pane {
display: inline-block;
white-space: normal;
vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
position: absolute;
right: 0px;
z-index: 1;
}

.CodeMirror-diff-gap {
float: left;
.CodeMirror-merge-gap {
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
border-left: 1px solid #ddd;
Expand All @@ -27,56 +37,56 @@
background: #f8f8f8;
}

.CodeMirror-diff-scrolllock-wrap {
.CodeMirror-merge-scrolllock-wrap {
position: absolute;
bottom: 0; left: 50%;
}
.CodeMirror-diff-scrolllock {
.CodeMirror-merge-scrolllock {
position: relative;
left: -50%;
cursor: pointer;
color: #555;
line-height: 1;
}

.CodeMirror-diff-copybuttons-left, .CodeMirror-diff-copybuttons-right {
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
position: absolute;
left: 0; top: 0;
right: 0; bottom: 0;
line-height: 1;
}

.CodeMirror-diff-copy {
.CodeMirror-merge-copy {
position: absolute;
cursor: pointer;
color: #44c;
}

.CodeMirror-diff-copybuttons-left .CodeMirror-diff-copy { left: 2px; }
.CodeMirror-diff-copybuttons-right .CodeMirror-diff-copy { right: 2px; }
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }

.CodeMirror-diff-r-inserted, .CodeMirror-diff-l-inserted {
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}

.CodeMirror-diff-r-deleted, .CodeMirror-diff-l-deleted {
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}

.CodeMirror-diff-r-chunk { background: #ffffe0; }
.CodeMirror-diff-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-diff-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-diff-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
.CodeMirror-merge-r-chunk { background: #ffffe0; }
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }

.CodeMirror-diff-l-chunk { background: #eef; }
.CodeMirror-diff-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-diff-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-diff-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }

.CodeMirror-diff-l-chunk.CodeMirror-diff-r-chunk { background: #dfd; }
.CodeMirror-diff-l-chunk-start.CodeMirror-diff-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-diff-l-chunk-end.CodeMirror-diff-r-chunk-end { border-bottom: 1px solid #4e4; }
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
64 changes: 40 additions & 24 deletions addon/merge/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
this.mv = mv;
this.type = type;
this.classes = type == "left"
? {chunk: "CodeMirror-diff-l-chunk",
start: "CodeMirror-diff-l-chunk-start",
end: "CodeMirror-diff-l-chunk-end",
insert: "CodeMirror-diff-l-inserted",
del: "CodeMirror-diff-l-deleted",
connect: "CodeMirror-diff-l-connect"}
: {chunk: "CodeMirror-diff-r-chunk",
start: "CodeMirror-diff-r-chunk-start",
end: "CodeMirror-diff-r-chunk-end",
insert: "CodeMirror-diff-r-inserted",
del: "CodeMirror-diff-r-deleted",
connect: "CodeMirror-diff-r-connect"};
? {chunk: "CodeMirror-merge-l-chunk",
start: "CodeMirror-merge-l-chunk-start",
end: "CodeMirror-merge-l-chunk-end",
insert: "CodeMirror-merge-l-inserted",
del: "CodeMirror-merge-l-deleted",
connect: "CodeMirror-merge-l-connect"}
: {chunk: "CodeMirror-merge-r-chunk",
start: "CodeMirror-merge-r-chunk-start",
end: "CodeMirror-merge-r-chunk-end",
insert: "CodeMirror-merge-r-inserted",
del: "CodeMirror-merge-r-deleted",
connect: "CodeMirror-merge-r-connect"};
}

DiffView.prototype = {
Expand Down Expand Up @@ -93,7 +93,21 @@
var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
var ratio = (midY - off.top) / (off.bot - off.top);
other.scrollTo(null, (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top));
var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top);

var botDist, mix;
// Some careful tweaking to make sure no space is left out of view
// when scrolling to top or bottom.
if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) {
targetPos = targetPos * mix + sInfo.top * (1 - mix);
} else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) {
var otherInfo = other.getScrollInfo();
var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos;
if (botDistOther > botDist && (mix = botDist / halfScreen) < 1)
targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix);
}

other.scrollTo(sInfo.left, targetPos);
other.state.scrollSetAt = now;
other.state.scrollSetBy = dv;
return true;
Expand Down Expand Up @@ -208,8 +222,8 @@
var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) {
if (topEdit >= vpEdit.to || botEdit < vpEdit.from ||
topOrig >= vpOrig.to || botOrig < vpOrig.from)
if (topEdit > vpEdit.to || botEdit < vpEdit.from ||
topOrig > vpOrig.to || botOrig < vpOrig.from)
return;
var topLpx = dv.orig.heightAtLine(topOrig, "local") - sTopOrig, top = topLpx;
if (dv.svg) {
Expand All @@ -225,7 +239,7 @@
"class", dv.classes.connect);
}
var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc",
"CodeMirror-diff-copy"));
"CodeMirror-merge-copy"));
copy.title = "Revert chunk";
copy.chunk = {topEdit: topEdit, botEdit: botEdit, topOrig: topOrig, botOrig: botOrig};
copy.style.top = top + "px";
Expand All @@ -250,23 +264,25 @@

if (hasLeft) {
left = this.left = new DiffView(this, "left");
var leftPane = elt("div", null, "CodeMirror-diff-pane");
var leftPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(leftPane);
wrap.push(buildGap(left));
}

var editPane = elt("div", null, "CodeMirror-diff-pane");
var editPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(editPane);

if (hasRight) {
right = this.right = new DiffView(this, "right");
wrap.push(buildGap(right));
var rightPane = elt("div", null, "CodeMirror-diff-pane");
var rightPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(rightPane);
}

(hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost";

wrap.push(elt("div", null, null, "height: 0; clear: both;"));
var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-diff CodeMirror-diff-" + panes + "pane"));
var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane"));
this.edit = CodeMirror(editPane, copyObj(options));

if (left) left.init(leftPane, origLeft, options);
Expand All @@ -284,11 +300,11 @@
};

function buildGap(dv) {
var lock = dv.lockButton = elt("div", null, "CodeMirror-diff-scrolllock");
var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
lock.title = "Toggle locked scrolling";
var lockWrap = elt("div", [lock], "CodeMirror-diff-scrolllock-wrap");
var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
dv.copyButtons = elt("div", null, "CodeMirror-diff-copybuttons-" + dv.type);
dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type);
CodeMirror.on(dv.copyButtons, "click", function(e) {
var node = e.target || e.srcElement;
if (node.chunk) copyChunk(dv, node.chunk);
Expand All @@ -299,7 +315,7 @@
dv.svg = svg;
if (svg) gapElts.push(svg);

return dv.gap = elt("div", gapElts, "CodeMirror-diff-gap");
return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap");
}

MergeView.prototype = {
Expand Down
4 changes: 3 additions & 1 deletion addon/runmode/runmode-standalone.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ StringStream.prototype = {
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
Expand Down
4 changes: 3 additions & 1 deletion addon/runmode/runmode.node.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ StringStream.prototype = {
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
Expand Down
20 changes: 11 additions & 9 deletions addon/search/match-highlighter.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@
cm.removeOverlay(state.overlay);
state.overlay = null;
}

if (!cm.somethingSelected() && state.showToken) {
var tok = cm.getTokenAt(cm.getCursor()).string;
if (/\w/.test(tok))
cm.addOverlay(state.overlay = makeOverlay(tok, true, state.style));
var re = state.showToken === true ? /[\w$]/ : state.showToken;
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
while (start && re.test(line.charAt(start - 1))) --start;
while (end < line.length && re.test(line.charAt(end))) ++end;
if (start < end)
cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style));
return;
}
if (cm.getCursor("head").line != cm.getCursor("anchor").line) return;
Expand All @@ -69,15 +71,15 @@
});
}

function boundariesAround(stream) {
return (stream.start || /.\b./.test(stream.string.slice(stream.start - 1, stream.start + 1))) &&
(stream.pos == stream.string.length || /.\b./.test(stream.string.slice(stream.pos - 1, stream.pos + 1)));
function boundariesAround(stream, re) {
return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
(stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
}

function makeOverlay(query, wordBoundaries, style) {
function makeOverlay(query, hasBoundary, style) {
return {token: function(stream) {
if (stream.match(query) &&
(!wordBoundaries || boundariesAround(stream)))
(!hasBoundary || boundariesAround(stream, hasBoundary)))
return style;
stream.next();
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
Expand Down
2 changes: 1 addition & 1 deletion addon/selection/active-line.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
}

function updateActiveLine(cm) {
var line = cm.getLineHandle(cm.getCursor().line);
var line = cm.getLineHandleVisualStart(cm.getCursor().line);
if (cm.state.activeLine == line) return;
clearActiveLine(cm);
cm.addLineClass(line, "wrap", WRAP_CLASS);
Expand Down
85 changes: 85 additions & 0 deletions addon/tern/tern.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
.CodeMirror-Tern-completion {
padding-left: 22px;
position: relative;
}
.CodeMirror-Tern-completion:before {
position: absolute;
left: 2px;
bottom: 2px;
border-radius: 50%;
font-size: 12px;
font-weight: bold;
height: 15px;
width: 15px;
line-height: 16px;
text-align: center;
color: white;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.CodeMirror-Tern-completion-unknown:before {
content: "?";
background: #4bb;
}
.CodeMirror-Tern-completion-object:before {
content: "O";
background: #77c;
}
.CodeMirror-Tern-completion-fn:before {
content: "F";
background: #7c7;
}
.CodeMirror-Tern-completion-array:before {
content: "A";
background: #c66;
}
.CodeMirror-Tern-completion-number:before {
content: "1";
background: #999;
}
.CodeMirror-Tern-completion-string:before {
content: "S";
background: #999;
}
.CodeMirror-Tern-completion-bool:before {
content: "B";
background: #999;
}

.CodeMirror-Tern-completion-guess {
color: #999;
}

.CodeMirror-Tern-tooltip {
border: 1px solid silver;
border-radius: 3px;
color: #444;
padding: 2px 5px;
font-size: 90%;
font-family: monospace;
background-color: white;
white-space: pre-wrap;

max-width: 40em;
position: absolute;
z-index: 10;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);

transition: opacity 1s;
-moz-transition: opacity 1s;
-webkit-transition: opacity 1s;
-o-transition: opacity 1s;
-ms-transition: opacity 1s;
}

.CodeMirror-Tern-hint-doc {
max-width: 25em;
}

.CodeMirror-Tern-fname { color: black; }
.CodeMirror-Tern-farg { color: #70a; }
.CodeMirror-Tern-farg-current { text-decoration: underline; }
.CodeMirror-Tern-type { color: #07c; }
.CodeMirror-Tern-fhint-guess { opacity: .7; }
608 changes: 608 additions & 0 deletions addon/tern/tern.js

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions addon/tern/worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
var server;

this.onmessage = function(e) {
var data = e.data;
switch (data.type) {
case "init": return startServer(data.defs, data.plugins, data.scripts);
case "add": return server.addFile(data.name, data.text);
case "del": return server.delFile(data.name);
case "req": return server.request(data.body, function(err, reqData) {
postMessage({id: data.id, body: reqData, err: err && String(err)});
});
case "getFile":
var c = pending[data.id];
delete pending[data.id];
return c(data.err, data.text);
default: throw new Error("Unknown message type: " + data.type);
}
};

var nextId = 0, pending = {};
function getFile(file, c) {
postMessage({type: "getFile", name: file, id: ++nextId});
pending[nextId] = c;
}

function startServer(defs, plugins, scripts) {
if (scripts) importScripts.apply(null, scripts);

server = new tern.Server({
getFile: getFile,
async: true,
defs: defs,
plugins: plugins
});
}

var console = {
log: function(v) { postMessage({type: "debug", message: v}); }
};
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "CodeMirror",
"version": "3.13.0",
"version": "3.15.0",
"main": ["lib/codemirror.js", "lib/codemirror.css"],
"ignore": [
"**/.*",
Expand Down
69 changes: 69 additions & 0 deletions demo/anywordhint.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Any Word Completion Demo</title>
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script>
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<script src="../addon/hint/anyword-hint.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<link rel="stylesheet" href="../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Any Word Completion Demo</h1>

<form><textarea id="code" name="code">
(function() {
"use strict";

var WORD = /[\w$]+/g, RANGE = 500;

CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
var word = options && options.word || WORD;
var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
var start = cur.ch, end = start;
while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
while (start && word.test(curLine.charAt(start - 1))) --start;
var curWord = start != end && curLine.slice(start, end);

var list = [], seen = {};
function scan(dir) {
var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
for (; line != end; line += dir) {
var text = editor.getLine(line), m;
word.lastIndex = 0;
while (m = word.exec(text)) {
if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) {
seen[m[0]] = true;
list.push(m[0]);
}
}
}
}
scan(-1);
scan(1);
return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
})();
</textarea></form>

<p>Press <strong>ctrl-space</strong> to activate autocompletion. The
completion uses
the <a href="../doc/manual.html#addon_anyword-hint">anyword-hint.js</a>
module, which simply looks at nearby words in the buffer and completes
to those.</p>

<script>
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.anyword);
}
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
extraKeys: {"Ctrl-Space": "autocomplete"}
});
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion demo/complete.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ <h1>CodeMirror: Autocomplete demo</h1>

<script>
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.javascriptHint);
CodeMirror.showHint(cm, CodeMirror.hint.javascript);
}
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
Expand Down
38 changes: 27 additions & 11 deletions demo/folding.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/fold/foldcode.js"></script>
<script src="../addon/fold/foldgutter.js"></script>
<script src="../addon/fold/brace-fold.js"></script>
<script src="../addon/fold/xml-fold.js"></script>
<script src="../mode/javascript/javascript.js"></script>
Expand All @@ -21,14 +22,29 @@
line-height: .3;
cursor: pointer;
}
.CodeMirror-foldgutter {
width: .7em;
}
.CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded {
color: #555;
cursor: pointer;
}
.CodeMirror-foldgutter-open:after {
content: "\25BE";
}
.CodeMirror-foldgutter-folded:after {
content: "\25B8";
}
</style>
</head>
<body>
<h1>CodeMirror: Code Folding Demo</h1>

<p>Demonstration of code folding using the code
in <a href="../addon/fold/foldcode.js"><code>foldcode.js</code></a>.
Press ctrl-q or click on the gutter to fold a block, again
in <a href="../doc/manual.html#addon_foldcode"><code>foldcode.js</code></a>
and <a href="../doc/manual.html#addon_foldgutter"><code>foldgutter.js</code></a>.
Press ctrl-q or click on the gutter markers to fold a block, again
to unfold.</p>
<form>
<div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br><textarea id="code" name="code"></textarea></div>
Expand All @@ -43,26 +59,26 @@ <h1>CodeMirror: Code Folding Demo</h1>
var te_html = document.getElementById("code-html");
te_html.value = "<html>\n " + document.documentElement.innerHTML + "\n</html>";

function foldJS(cm, where) { cm.foldCode(where, CodeMirror.braceRangeFinder); }
window.editor = CodeMirror.fromTextArea(te, {
mode: "javascript",
lineNumbers: true,
lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){foldJS(cm, cm.getCursor());}}
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
editor.on("gutterClick", foldJS);
foldJS(editor, 9);
editor.foldCode(CodeMirror.Pos(8, 0));

function foldHTML(cm, where) { cm.foldCode(where, CodeMirror.tagRangeFinder); }
window.editor_html = CodeMirror.fromTextArea(te_html, {
mode: "text/html",
lineNumbers: true,
lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){foldHTML(cm, cm.getCursor());}}
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
editor_html.on("gutterClick", foldHTML);
foldHTML(editor_html, 13);
foldHTML(editor_html, 1);
editor_html.foldCode(CodeMirror.Pos(13, 0));
editor_html.foldCode(CodeMirror.Pos(1, 0));
};
</script>
</body>
Expand Down
2 changes: 1 addition & 1 deletion demo/html5complete.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <h1>HTML completion demo</h1>

<script type="text/javascript">
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.htmlHint);
CodeMirror.showHint(cm, CodeMirror.hint.html);
}
window.onload = function() {
editor = CodeMirror(document.getElementById("code"), {
Expand Down
6 changes: 3 additions & 3 deletions demo/lint.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script>
<script src="https://raw.github.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script>
<script src="https://rawgithub.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script>
<link rel="stylesheet" href="../doc/docs.css">
<link rel="stylesheet" href="../addon/lint/lint.css">
<script src="../addon/lint/lint.js"></script>
Expand Down Expand Up @@ -75,14 +75,14 @@ <h1>CodeMirror: Linter Demo</h1>
lineNumbers: true,
mode: "javascript",
gutters: ["CodeMirror-lint-markers"],
lintWith: CodeMirror.javascriptValidator
lint: true
});

var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), {
lineNumbers: true,
mode: "application/json",
gutters: ["CodeMirror-lint-markers"],
lintWith: CodeMirror.jsonValidator
lint: true
});
</script>

Expand Down
2 changes: 1 addition & 1 deletion demo/matchhighlighter.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h1>CodeMirror: Match Highlighter Demo</h1>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
highlightSelectionMatches: true
highlightSelectionMatches: {showToken: /\w/}
});
</script>

Expand Down
38 changes: 38 additions & 0 deletions demo/matchtags.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Tag Matcher Demo</title>
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/fold/xml-fold.js"></script>
<script src="../addon/edit/matchtags.js"></script>
<script src="../mode/xml/xml.js"></script>
<link rel="stylesheet" href="../doc/docs.css">

<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
</style>
</head>
<body>
<h1>CodeMirror: Tag Matcher Demo</h1>

<div id="editor"></div>

<script>
window.onload = function() {
editor = CodeMirror(document.getElementById("editor"), {
value: "<html>\n " + document.documentElement.innerHTML + "\n</html>",
mode: "text/html",
matchTags: true,
extraKeys: {"Ctrl-J": "toMatchingTag"}
});
};
</script>

<p>Put the cursor on or inside a pair of tags to highlight them.
Press Ctrl-J to jump to the tag that matches the one under the
cursor.</p>
</body>
</html>
122 changes: 122 additions & 0 deletions demo/tern.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Tern Demo</title>
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<link rel="stylesheet" href="../doc/docs.css">
<script src="../addon/dialog/dialog.js"></script>
<link rel="stylesheet" href="../addon/dialog/dialog.css">
<script src="../addon/hint/show-hint.js"></script>
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<script src="../addon/tern/tern.js"></script>
<link rel="stylesheet" href="../addon/tern/tern.css">

<!-- NOTE: if you are going to actually deploy this in production,
DO NOT hot-link these files. Host them yourself. -->
<script src="http://marijnhaverbeke.nl/acorn/acorn.js"></script>
<script src="http://marijnhaverbeke.nl/acorn/acorn_loose.js"></script>
<script src="http://marijnhaverbeke.nl/acorn/util/walk.js"></script>
<script src="http://ternjs.net/lib/signal.js"></script>
<script src="http://ternjs.net/lib/tern.js"></script>
<script src="http://ternjs.net/lib/def.js"></script>
<script src="http://ternjs.net/lib/comment.js"></script>
<script src="http://ternjs.net/lib/infer.js"></script>
<script src="http://ternjs.net/plugin/doc_comment.js"></script>

<style>
.CodeMirror {border: 1px solid #ddd;}
</style>
</head>
<body>
<h1>CodeMirror: Tern Demo</h1>

<form><textarea id="code" name="code">// Use ctrl-space to complete something
// Put the cursor in or after an expression, press ctrl-i to
// find its type

var foo = ["array", "of", "strings"];
var bar = foo.slice(0, 2).join("").split("a")[0];

// Works for locally defined types too.

function CTor() { this.size = 10; }
CTor.prototype.hallo = "hallo";

var baz = new CTor;
baz.

// You can press ctrl-q when the cursor is on a variable name to
// rename it. Try it with CTor...

// When the cursor is in an argument list, the arguments are
// shown below the editor.

[1].reduce( );

// And a little more advanced code...

(function(exports) {
exports.randomElt = function(arr) {
return arr[Math.floor(arr.length * Math.random())];
};
exports.strList = "foo".split("");
exports.intList = exports.strList.map(function(s) { return s.charCodeAt(0); });
})(window.myMod = {});

var randomStr = myMod.randomElt(myMod.strList);
var randomInt = myMod.randomElt(myMod.intList);
</textarea></p>

<p>Demonstrates integration of <a href="http://ternjs.net/">Tern</a>
and CodeMirror. The following keys are bound:</p>

<dl>
<dt>Ctrl-Space</dt><dd>Autocomplete</dd>
<dt>Ctrl-I</dt><dd>Find type at cursor</dd>
<dt>Alt-.</dt><dd>Jump to definition (Alt-, to jump back)</dd>
<dt>Ctrl-Q</dt><dd>Rename variable</dd>
</dl>

<p>Documentation is sparse for now. See the top of
the <a href="../addon/tern/tern.js">script</a> for a rough API
overview.</p>

<script>
function getURL(url, c) {
var xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState != 4) return;
if (xhr.status < 400) return c(null, xhr.responseText);
var e = new Error(xhr.responseText || "No response");
e.status = xhr.status;
c(e);
};
}

var server;
getURL("http://ternjs.net/defs/ecma5.json", function(err, code) {
if (err) throw new Error("Request for ecma5.json: " + err);
server = new CodeMirror.TernServer({defs: [JSON.parse(code)]});
editor.setOption("extraKeys", {
"Ctrl-Space": function(cm) { server.complete(cm); },
"Ctrl-I": function(cm) { server.showType(cm); },
"Alt-.": function(cm) { server.jumpToDef(cm); },
"Alt-,": function(cm) { server.jumpBack(cm); },
"Ctrl-Q": function(cm) { server.rename(cm); },
})
editor.on("cursorActivity", function(cm) { server.updateArgHints(cm); });
});

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

</body>
</html>
10 changes: 10 additions & 0 deletions demo/theme.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
<link rel="stylesheet" href="../theme/solarized.css">
<link rel="stylesheet" href="../theme/twilight.css">
<link rel="stylesheet" href="../theme/midnight.css">
<link rel="stylesheet" href="../theme/3024-day.css">
<link rel="stylesheet" href="../theme/3024-night.css">
<link rel="stylesheet" href="../theme/base16-light.css">
<link rel="stylesheet" href="../theme/base16-dark.css">
<link rel="stylesheet" href="../theme/tomorrow-night-eighties.css">
<script src="../mode/javascript/javascript.js"></script>
<script src="../keymap/extra.js"></script>
<link rel="stylesheet" href="../doc/docs.css">
Expand Down Expand Up @@ -49,7 +54,11 @@ <h1>CodeMirror: Theme demo</h1>

<p>Select a theme: <select onchange="selectTheme()" id=select>
<option selected>default</option>
<option>3024-day</option>
<option>3024-night</option>
<option>ambiance</option>
<option>base16-dark</option>
<option>base16-light</option>
<option>blackboard</option>
<option>cobalt</option>
<option>eclipse</option>
Expand All @@ -63,6 +72,7 @@ <h1>CodeMirror: Theme demo</h1>
<option>rubyblue</option>
<option>solarized dark</option>
<option>solarized light</option>
<option>tomorrow-night-eighties</option>
<option>twilight</option>
<option>vibrant-ink</option>
<option>xq-dark</option>
Expand Down
4 changes: 2 additions & 2 deletions demo/vim.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ <h1>CodeMirror: Vim bindings demo</h1>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "text/x-csrc",
keyMap: "vim",
vimMode: true,
showCursorWhenSelecting: true
});
var editor2 = CodeMirror.fromTextArea(document.getElementById("code2"), {
lineNumbers: true,
mode: "text/x-csrc",
keyMap: "vim",
vimMode: true,
showCursorWhenSelecting: true
});
</script>
Expand Down
4 changes: 2 additions & 2 deletions demo/xmlcomplete.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ <h1>CodeMirror: XML Autocomplete demo</h1>
var cur = cm.getCursor();
if (!pred || pred()) setTimeout(function() {
if (!cm.state.completionActive)
CodeMirror.showHint(cm, CodeMirror.xmlHint, {schemaInfo: tags, completeSingle: false});
CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags, completeSingle: false});
}, 100);
return CodeMirror.Pass;
}
Expand Down Expand Up @@ -97,7 +97,7 @@ <h1>CodeMirror: XML Autocomplete demo</h1>
"' '": completeIfInTag,
"'='": completeIfInTag,
"Ctrl-Space": function(cm) {
CodeMirror.showHint(cm, CodeMirror.xmlHint, {schemaInfo: tags});
CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags});
}
}
});
Expand Down
49 changes: 29 additions & 20 deletions doc/compress.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<input type="hidden" id="download" name="download" value="codemirror-compressed.js"/>
<p>Version: <select id="version" onchange="setVersion(this);" style="padding: 1px">
<option value="http://codemirror.net/">HEAD</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.15.0;f=">3.15</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.14.0;f=">3.14</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.13.0;f=">3.13</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.12;f=">3.12</option>
Expand Down Expand Up @@ -93,13 +94,15 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<option value="http://codemirror.net/mode/htmlembedded/htmlembedded.js">htmlembedded.js</option>
<option value="http://codemirror.net/mode/htmlmixed/htmlmixed.js">htmlmixed.js</option>
<option value="http://codemirror.net/mode/http/http.js">http.js</option>
<option value="http://codemirror.net/mode/jade/jade.js">jade.js</option>
<option value="http://codemirror.net/mode/javascript/javascript.js">javascript.js</option>
<option value="http://codemirror.net/mode/jinja2/jinja2.js">jinja2.js</option>
<option value="http://codemirror.net/mode/less/less.js">less.js</option>
<option value="http://codemirror.net/mode/livescript/livescript.js">livescript.js</option>
<option value="http://codemirror.net/mode/lua/lua.js">lua.js</option>
<option value="http://codemirror.net/mode/markdown/markdown.js">markdown.js</option>
<option value="http://codemirror.net/mode/mirc/mirc.js">mirc.js</option>
<option value="http://codemirror.net/mode/nginx/nginx.js">nginx.js</option>
<option value="http://codemirror.net/mode/ntriples/ntriples.js">ntriples.js</option>
<option value="http://codemirror.net/mode/ocaml/ocaml.js">ocaml.js</option>
<option value="http://codemirror.net/mode/pascal/pascal.js">pascal.js</option>
Expand All @@ -122,6 +125,7 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<option value="http://codemirror.net/mode/sieve/sieve.js">sieve.js</option>
<option value="http://codemirror.net/mode/smalltalk/smalltalk.js">smalltalk.js</option>
<option value="http://codemirror.net/mode/smarty/smarty.js">smarty.js</option>
<option value="http://codemirror.net/mode/smartymixed/smartymixed.js">smartymixed.js</option>
<option value="http://codemirror.net/mode/sql/sql.js">sql.js</option>
<option value="http://codemirror.net/mode/sparql/sparql.js">sparql.js</option>
<option value="http://codemirror.net/mode/stex/stex.js">stex.js</option>
Expand All @@ -139,38 +143,43 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<option value="http://codemirror.net/mode/z80/z80.js">z80.js</option>
</optgroup>
<optgroup label="Add-ons">
<option value="http://codemirror.net/addon/dialog/dialog.js">dialog.js</option>
<option value="http://codemirror.net/addon/selection/active-line.js">active-line.js</option>
<option value="http://codemirror.net/addon/fold/brace-fold.js">brace-fold.js</option>
<option value="http://codemirror.net/addon/edit/closebrackets.js">closebrackets.js</option>
<option value="http://codemirror.net/addon/edit/closetag.js">closetag.js</option>
<option value="http://codemirror.net/addon/runmode/colorize.js">colorize.js</option>
<option value="http://codemirror.net/addon/edit/comment.js">comment.js</option>
<option value="http://codemirror.net/addon/edit/continuecomment.js">continuecomment.js</option>
<option value="http://codemirror.net/addon/edit/continuelist.js">continuelist.js</option>
<option value="http://codemirror.net/addon/edit/matchbrackets.js">matchbrackets.js</option>
<option value="http://codemirror.net/addon/edit/closebrackets.js">closebrackets.js</option>
<option value="http://codemirror.net/addon/dialog/dialog.js">dialog.js</option>
<option value="http://codemirror.net/addon/fold/foldcode.js">foldcode.js</option>
<option value="http://codemirror.net/addon/fold/xml-fold.js">xml-fold.js</option>
<option value="http://codemirror.net/addon/fold/brace-fold.js">brace-fold.js</option>
<option value="http://codemirror.net/addon/hint/html-hint.js">html-hint.js</option>
<option value="http://codemirror.net/addon/fold/indent-fold.js">indent-fold.js</option>
<option value="http://codemirror.net/addon/hint/show-hint.js">show-hint.js</option>
<option value="http://codemirror.net/addon/hint/javascript-hint.js">javascript-hint.js</option>
<option value="http://codemirror.net/addon/hint/xml-hint.js">xml-hint.js</option>
<option value="http://codemirror.net/addon/hint/html-hint.js">html-hint.js</option>
<option value="http://codemirror.net/addon/hint/pig-hint.js">pig-hint.js</option>
<option value="http://codemirror.net/addon/hint/python-hint.js">python-hint.js</option>
<option value="http://codemirror.net/addon/lint/javascript-lint.js">javascript-lint.js</option>
<option value="http://codemirror.net/addon/lint/json-lint.js">json-lint.js</option>
<option value="http://codemirror.net/addon/lint/lint.js">lint.js</option>
<option value="http://codemirror.net/addon/mode/loadmode.js">loadmode.js</option>
<option value="http://codemirror.net/addon/mode/overlay.js">overlay.js</option>
<option value="http://codemirror.net/addon/selection/mark-selection.js">mark-selection.js</option>
<option value="http://codemirror.net/addon/search/match-highlighter.js">match-highlighter.js</option>
<option value="http://codemirror.net/addon/edit/matchbrackets.js">matchbrackets.js</option>
<option value="http://codemirror.net/addon/edit/matchtags.js">matchtags.js</option>
<option value="http://codemirror.net/addon/merge/merge.js">merge.js</option>
<option value="http://codemirror.net/addon/mode/multiplex.js">multiplex.js</option>
<option value="http://codemirror.net/addon/runmode/colorize.js">colorize.js</option>
<option value="http://codemirror.net/addon/mode/overlay.js">overlay.js</option>
<option value="http://codemirror.net/addon/hint/pig-hint.js">pig-hint.js</option>
<option value="http://codemirror.net/addon/display/placeholder.js">placeholder.js</option>
<option value="http://codemirror.net/addon/hint/python-hint.js">python-hint.js</option>
<option value="http://codemirror.net/addon/runmode/runmode.js">runmode.js</option>
<option value="http://codemirror.net/addon/runmode/runmode-standalone.js">runmode-standalone.js</option>
<option value="http://codemirror.net/addon/runmode/runmode.node.js">runmode.node.js</option>
<option value="http://codemirror.net/addon/runmode/runmode-standalone.js">runmode-standalone.js</option>
<option value="http://codemirror.net/addon/search/search.js">search.js</option>
<option value="http://codemirror.net/addon/search/searchcursor.js">searchcursor.js</option>
<option value="http://codemirror.net/addon/search/match-highlighter.js">match-highlighter.js</option>
<option value="http://codemirror.net/addon/selection/mark-selection.js">mark-selection.js</option>
<option value="http://codemirror.net/addon/selection/active-line.js">active-line.js</option>
<option value="http://codemirror.net/addon/lint/lint.js">lint.js</option>
<option value="http://codemirror.net/addon/lint/javascript-lint.js">javascript-lint.js</option>
<option value="http://codemirror.net/addon/lint/json-lint.js">json-lint.js</option>
<option value="http://codemirror.net/addon/merge/merge.js">merge.js</option>
<option value="http://codemirror.net/addon/hint/show-hint.js">show-hint.js</option>
<option value="http://codemirror.net/addon/edit/trailingspace.js">trailingspace.js</option>
<option value="http://codemirror.net/addon/tern/tern.js">tern.js</option>
<option value="http://codemirror.net/addon/fold/xml-fold.js">xml-fold.js</option>
<option value="http://codemirror.net/addon/hint/xml-hint.js">xml-hint.js</option>
</optgroup>
<optgroup label="Keymaps">
<option value="http://codemirror.net/keymap/emacs.js">emacs.js</option>
Expand Down
215 changes: 161 additions & 54 deletions doc/manual.html

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions doc/modes.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<li><a href="../mode/coffeescript/index.html">CoffeeScript</a></li>
<li><a href="../mode/commonlisp/index.html">Common Lisp</a></li>
<li><a href="../mode/css/index.html">CSS</a></li>
<li><a href="../mode/python/index.html">Cython</a></li>
<li><a href="../mode/d/index.html">D</a></li>
<li><a href="../mode/diff/index.html">diff</a></li>
<li><a href="../mode/ecl/index.html">ECL</a></li>
Expand All @@ -45,13 +46,15 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<li><a href="../mode/htmlmixed/index.html">HTML mixed-mode</a></li>
<li><a href="../mode/http/index.html">HTTP</a></li>
<li><a href="../mode/clike/index.html">Java</a></li>
<li><a href="../mode/jade/index.html">Jade</a></li>
<li><a href="../mode/javascript/index.html">JavaScript</a></li>
<li><a href="../mode/jinja2/index.html">Jinja2</a></li>
<li><a href="../mode/less/index.html">LESS</a></li>
<li><a href="../mode/livescript/index.html">LiveScript</a></li>
<li><a href="../mode/lua/index.html">Lua</a></li>
<li><a href="../mode/markdown/index.html">Markdown</a> (<a href="../mode/gfm/index.html">GitHub-flavour</a>)</li>
<li><a href="../mode/mirc/index.html">mIRC</a></li>
<li><a href="../mode/nginx/index.html">Nginx</a></li>
<li><a href="../mode/ntriples/index.html">NTriples</a></li>
<li><a href="../mode/ocaml/index.html">OCaml</a></li>
<li><a href="../mode/pascal/index.html">Pascal</a></li>
Expand All @@ -74,6 +77,7 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<li><a href="../mode/sieve/index.html">Sieve</a></li>
<li><a href="../mode/smalltalk/index.html">Smalltalk</a></li>
<li><a href="../mode/smarty/index.html">Smarty</a></li>
<li><a href="../mode/smartymixed/index.html">Smarty/HTML mixed</a></li>
<li><a href="../mode/sql/index.html">SQL</a> (several dialects)</li>
<li><a href="../mode/sparql/index.html">SPARQL</a></li>
<li><a href="../mode/stex/index.html">sTeX, LaTeX</a></li>
Expand Down
12 changes: 12 additions & 0 deletions doc/oldrelease.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
</pre>
</div>

<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc2.zip">Version 3.0, release candidate 2</a>:</p>

<ul class="rel-note">
<li>New mode: <a href="../mode/http/index.html">HTTP</a>.</li>
<li>Improved handling of selection anchor position.</li>
<li>Improve IE performance on longer lines.</li>
<li>Reduce gutter glitches during horiz. scrolling.</li>
<li>Add <a href="manual.html#addKeyMap"><code>addKeyMap</code></a> and <a href="manual.html#removeKeyMap"><code>removeKeyMap</code></a> methods.</li>
<li>Rewrite <code>formatting</code> and <code>closetag</code> add-ons.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0rc1...v3.0rc2">list of patches</a>.</li>
</ul>

<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-2.36.zip">Version 2.36</a>:</p>

<ul class="rel-note">
Expand Down
6 changes: 6 additions & 0 deletions doc/realworld.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,21 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<li><a href="http://code-snippets.bungeshea.com/">Code Snippets</a> (WordPress snippet management plugin)</li>
<li><a href="http://antonmi.github.io/code_together/">Code together</a> (collaborative editing)</li>
<li><a href="http://codev.it/">Codev</a> (collaborative IDE)</li>
<li><a href="http://www.codezample.com">CodeZample</a> (code snippet sharing)</li>
<li><a href="http://ot.substance.io/demo/">Collaborative CodeMirror demo</a> (CodeMirror + operational transforms)</li>
<li><a href="http://www.communitycodecamp.com/">Community Code Camp</a> (code snippet sharing)</li>
<li><a href="http://www.ckwnc.com/">CKWNC</a> (UML editor)</li>
<li><a href="http://cssdeck.com/">CSSDeck</a> (CSS showcase)</li>
<li><a href="http://ireneros.com/deck/deck.js-codemirror/introduction/#textarea-code">Deck.js integration</a> (slides with editors)</li>
<li><a href="http://www.dbninja.com">DbNinja</a> (MySQL access interface)</li>
<li><a href="https://chat.echoplex.us/">Echoplexus</a> (chat and collaborative coding)</li>
<li><a href="http://elm-lang.org/Examples.elm">Elm language examples</a></li>
<li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</li>
<li><a href="http://emmet.io">Emmet</a> (fast XML editing)</li>
<li><a href="http://www.fastfig.com/">Fastfig</a> (online computation/math tool)</li>
<li><a href="https://metacpan.org/module/Farabi">Farabi</a> (modern Perl IDE)</li>
<li><a href="http://blog.pamelafox.org/2012/02/interactive-html5-slides-with-fathomjs.html">FathomJS integration</a> (slides with editors, again)</li>
<li><a href="http://fiddlesalad.com/">Fiddle Salad</a> (web development environment)</li>
<li><a href="http://www.firepad.io">Firepad</a> (collaborative text editor)</li>
<li><a href="http://tour.golang.org">Go language tour</a></li>
<li><a href="https://github.com/github/android">GitHub's Android app</a></li>
Expand All @@ -72,6 +75,7 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<li><a href="http://jumpseller.com/">Jumpseller</a> (online store builder)</li>
<li><a href="http://kl1p.com/cmtest/1">kl1p</a> (paste service)</li>
<li><a href="http://www.chris-granger.com/2012/04/12/light-table---a-new-ide-concept/">Light Table</a> (experimental IDE)</li>
<li><a href="http://marklighteditor.com/">Marklight editor</a> (lightweight markup editor)</li>
<li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
<li><a href="http://www.iunbug.com/mihtool">MIHTool</a> (iOS web-app debugging tool)</li>
<li><a href="http://mongo-mapreduce-webbrowser.opensagres.cloudbees.net/">Mongo MapReduce WebBrowser</a></li>
Expand All @@ -89,6 +93,7 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<li><a href="http://www.quivive-file-manager.com">Quivive File Manager</a></li>
<li><a href="http://rascalmicro.com/docs/basic-tutorial-getting-started.html">Rascal</a> (tiny computer)</li>
<li><a href="https://www.realtime.io/">RealTime.io</a> (Internet-of-Things infrastructure)</li>
<li><a href="https://www.shadertoy.com/">Shadertoy</a> (shader sharing)</li>
<li><a href="http://www.sketchpatch.net/labs/livecodelabIntro.html">sketchPatch Livecodelab</a></li>
<li><a href="http://www.skulpt.org/">Skulpt</a> (in-browser Python environment)</li>
<li><a href="http://snippets.pro/">Snippets.pro</a> (code snippet sharing)</li>
Expand All @@ -101,6 +106,7 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
<li><a href="http://turbopy.com/">TurboPY</a> (web publishing framework)</li>
<li><a href="http://cruise.eecs.uottawa.ca/umpleonline/">UmpleOnline</a> (model-oriented programming tool)</li>
<li><a href="https://upsource.jetbrains.com/#idea/view/923f30395f2603cd9f42a32bcafd13b6c28de0ff/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java">Upsource</a> (code viewer)</li>
<li><a href="http://www.webglacademy.com/">WebGL academy</a> (learning WebGL)</li>
<li><a href="http://webglplayground.net/">WebGL playground</a></li>
<li><a href="https://www.webkit.org/blog/2518/state-of-web-inspector/#source-code">WebKit Web inspector</a></li>
<li><a href="http://www.wescheme.org/">WeScheme</a> (learning tool)</li>
Expand Down
25 changes: 12 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ <h2 style="margin-top: 0">Supported modes:</h2>
<li><a href="mode/coffeescript/index.html">CoffeeScript</a></li>
<li><a href="mode/commonlisp/index.html">Common Lisp</a></li>
<li><a href="mode/css/index.html">CSS</a></li>
<li><a href="mode/python/index.html">Cython</a></li>
<li><a href="mode/d/index.html">D</a></li>
<li><a href="mode/diff/index.html">diff</a></li>
<li><a href="mode/ecl/index.html">ECL</a></li>
Expand Down Expand Up @@ -285,6 +286,17 @@ <h2>Reading material</h2>

<h2 id=releases>Releases</h2>

<p class="rel">29-07-2013: <a href="http://codemirror.net/codemirror-3.15.zip">Version 3.15</a>:</p>

<ul class="rel-note">
<li>New modes: <a href="mode/jade/index.html">Jade</a>, <a href="mode/nginx/index.html">Nginx</a>.</li>
<li>New addons: <a href="demo/tern.html">Tern</a>, <a href="doc/manual.html#addon_matchtags">matchtags</a>, and <a href="doc/manual.html#addon_foldgutter">foldgutter</a>.</li>
<li>Introduced <a href="doc/manual.html#getHelper"><em>helper</em></a> concept (<a href="https://groups.google.com/forum/#!msg/codemirror/cOc0xvUUEUU/nLrX1-qnidgJ">context</a>).</li>
<li>New method: <a href="doc/manual.html#getModeAt"><code>getModeAt</code></a>.</li>
<li>New themes: base16 <a href="demo/theme.html?base16-dark">dark</a>/<a href="demo/theme.html?base16-light">light</a>, 3024 <a href="demo/theme.html?3024-night">dark</a>/<a href="demo/theme.html?3024-day">light</a>, <a href="demo/theme.html?tomorrow-night-eighties">tomorrow-night</a>.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.14.0...3.15.0">list of patches</a>.</li>
</ul>

<p class="rel">20-06-2013: <a href="http://codemirror.net/codemirror-3.14.zip">Version 3.14</a>:</p>

<ul class="rel-note">
Expand Down Expand Up @@ -453,19 +465,6 @@ <h2 id=releases>Releases</h2>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0rc2...v3.0">list of patches</a>.</li>
</ul>


<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc2.zip">Version 3.0, release candidate 2</a>:</p>

<ul class="rel-note">
<li>New mode: <a href="mode/http/index.html">HTTP</a>.</li>
<li>Improved handling of selection anchor position.</li>
<li>Improve IE performance on longer lines.</li>
<li>Reduce gutter glitches during horiz. scrolling.</li>
<li>Add <a href="doc/manual.html#addKeyMap"><code>addKeyMap</code></a> and <a href="doc/manual.html#removeKeyMap"><code>removeKeyMap</code></a> methods.</li>
<li>Rewrite <code>formatting</code> and <code>closetag</code> add-ons.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0rc1...v3.0rc2">list of patches</a>.</li>
</ul>

<p><a href="doc/oldrelease.html">Older releases...</a></p>

</div></div>
Expand Down
221 changes: 120 additions & 101 deletions keymap/vim.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions lib/codemirror.css
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,16 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-code pre {
border-right: 30px solid transparent;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
}
.CodeMirror-wrap .CodeMirror-code pre {
border-right: none;
width: auto;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
Expand Down
270 changes: 177 additions & 93 deletions lib/codemirror.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion mode/clike/clike.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
electricChars: "{}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//"
lineComment: "//",
fold: "brace"
};
});

Expand Down
3 changes: 2 additions & 1 deletion mode/coffeescript/coffeescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ CodeMirror.defineMode('coffeescript', function(conf) {
return state.scopes[0].offset;
},

lineComment: "#"
lineComment: "#",
fold: "indent"
};
return external;
});
Expand Down
49 changes: 33 additions & 16 deletions mode/css/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
startState: function(base) {
return {tokenize: tokenBase,
baseIndent: base || 0,
stack: []};
stack: [],
lastToken: null};
},

token: function(stream, state) {
Expand Down Expand Up @@ -163,7 +164,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
var context = state.stack[state.stack.length-1];
if (style == "variable") {
if (type == "variable-definition") state.stack.push("propertyValue");
return "variable-2";
return state.lastToken = "variable-2";
} else if (style == "property") {
var word = stream.current().toLowerCase();
if (context == "propertyValue") {
Expand Down Expand Up @@ -251,7 +252,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
// Push/pop context stack
if (type == "{") {
if (context == "@media" || context == "@mediaType") {
state.stack.pop();
state.stack[state.stack.length-1] = "@media{";
}
else {
Expand All @@ -260,35 +260,52 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
}
}
else if (type == "}") {
var lastState = state.stack[state.stack.length - 1];
if (lastState == "interpolation") style = "operator";
if (context == "interpolation") style = "operator";
state.stack.pop();
if (context == "propertyValue") state.stack.pop();
}
else if (type == "interpolation") state.stack.push("interpolation");
else if (type == "@media") state.stack.push("@media");
else if (type == "@import") state.stack.push("@import");
else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
state.stack.push("@mediaType");
else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
else if (context == "@mediaType(" && type == ")") state.stack.pop();
else if ((context == "rule" || context == "block") && type == ":") state.stack.push("propertyValue");
state.stack[state.stack.length-1] = "@mediaType";
else if (context == "@mediaType" && stream.current() == ",")
state.stack[state.stack.length-1] = "@media";
else if (type == "(") {
if (context == "@media" || context == "@mediaType") {
// Make sure @mediaType is used to avoid error on {
state.stack[state.stack.length-1] = "@mediaType";
state.stack.push("@mediaType(");
}
}
else if (type == ")") {
if (context == "propertyValue" && state.stack[state.stack.length-2] == "@mediaType(") {
// In @mediaType( without closing ; after propertyValue
state.stack.pop();
state.stack.pop();
}
else if (context == "@mediaType(") {
state.stack.pop();
}
}
else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
else if (context == "propertyValue" && type == ";") state.stack.pop();
else if (context == "@import" && type == ";") state.stack.pop();
return style;

return state.lastToken = style;
},

indent: function(state, textAfter) {
var n = state.stack.length;
if (/^\}/.test(textAfter))
n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
return state.baseIndent + n * indentUnit;
},

electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/"
blockCommentEnd: "*/",
fold: "brace"
};
});

Expand Down Expand Up @@ -384,15 +401,15 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
"text-indent", "text-justify", "text-outline", "text-shadow",
"text-space-collapse", "text-transform", "text-underline-position",
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
"word-spacing", "word-wrap", "z-index",
"word-spacing", "word-wrap", "z-index", "zoom",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
Expand Down
2 changes: 1 addition & 1 deletion mode/css/scss_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"[tag p] { [tag a] { [property color][operator :][atom #000]; } }");

MT('interpolation_in_property',
"[tag foo] { [operator #{][variable-2 $hello][operator }:][atom #000]; }");
"[tag foo] { [operator #{][variable-2 $hello][operator }:][number 2]; }");

MT('interpolation_in_selector',
"[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }");
Expand Down
13 changes: 13 additions & 0 deletions mode/css/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
MT("atMediaCheckStack",
"[def @media] [attribute screen] ([property color]) { } [tag foo] { }");

MT("atMediaPropertyOnly",
"[def @media] ([property color]) { } [tag foo] { }");

MT("atMediaCheckStackInvalidAttribute",
"[def @media] [attribute&error foobarhello] { [tag foo] { } }");

MT("atMediaCheckStackInvalidAttribute",
"[def @media] [attribute&error foobarhello] { } [tag foo] { }");

Expand Down Expand Up @@ -53,6 +59,10 @@
MT("atMediaUnknownProperty",
"[def @media] [attribute screen] [operator and] ([property&error foobarhello]) { }");

// Make sure nesting works with media queries
MT("atMediaMaxWidthNested",
"[def @media] [attribute screen] [operator and] ([property max-width][operator :] [number 25px]) { [tag foo] { } }");

MT("tagSelector",
"[tag foo] { }");

Expand Down Expand Up @@ -108,6 +118,9 @@
MT("tagTwoProperties",
"[tag foo] { [property margin][operator :] [number 0]; [property padding][operator :] [number 0]; }");

MT("tagTwoPropertiesURL",
"[tag foo] { [property background][operator :] [string-2 url]([string //example.com/foo.png]); [property padding][operator :] [number 0]; }");

MT("commentSGML",
"[comment <!--comment-->]");
})();
3 changes: 2 additions & 1 deletion mode/groovy/groovy.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ CodeMirror.defineMode("groovy", function(config) {
else return ctx.indented + (closing ? 0 : config.indentUnit);
},

electricChars: "{}"
electricChars: "{}",
fold: "brace"
};
});

Expand Down
54 changes: 54 additions & 0 deletions mode/jade/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Jade Templating Mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="jade.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Jade Templating Mode</h1>
<form><textarea id="code" name="code">
doctype 5
html
head
title= "Jade Templating CodeMirror Mode Example"
link(rel='stylesheet', href='/css/bootstrap.min.css')
link(rel='stylesheet', href='/css/index.css')
script(type='text/javascript', src='/js/jquery-1.9.1.min.js')
script(type='text/javascript', src='/js/bootstrap.min.js')
body
div.header
h1 Welcome to this Example
div.spots
if locals.spots
each spot in spots
div.spot.well
div
if spot.logo
img.img-rounded.logo(src=spot.logo)
else
img.img-rounded.logo(src="img/placeholder.png")
h3
a(href=spot.hash) ##{spot.hash}
if spot.title
span.title #{spot.title}
if spot.desc
div #{spot.desc}
else
h3 There are no spots currently available.
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "jade", alignCDATA: true},
lineNumbers: true
});
</script>
<h3>The Jade Templating Mode</h3>
<p> Created by Drew Bratcher. Managed as part of an Adobe Brackets extension at <a href="https://github.com/dbratcher/brackets-jade">https://github.com/dbratcher/brackets-jade</a>.</p>
<p><strong>MIME type defined:</strong> <code>text/x-jade</code>.</p>
</body>
</html>
90 changes: 90 additions & 0 deletions mode/jade/jade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
CodeMirror.defineMode("jade", function () {
var symbol_regex1 = /^(?:~|!|%|\^|\*|\+|=|\\|:|;|,|\/|\?|&|<|>|\|)/;
var open_paren_regex = /^(\(|\[)/;
var close_paren_regex = /^(\)|\])/;
var keyword_regex1 = /^(if|else|return|var|function|include|doctype|each)/;
var keyword_regex2 = /^(#|{|}|\.)/;
var keyword_regex3 = /^(in)/;
var html_regex1 = /^(html|head|title|meta|link|script|body|br|div|input|span|a|img)/;
var html_regex2 = /^(h1|h2|h3|h4|h5|p|strong|em)/;
return {
startState: function () {
return {
inString: false,
stringType: "",
beforeTag: true,
justMatchedKeyword: false,
afterParen: false
};
},
token: function (stream, state) {
//check for state changes
if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
state.stringType = stream.peek();
stream.next(); // Skip quote
state.inString = true; // Update state
}

//return state
if (state.inString) {
if (stream.skipTo(state.stringType)) { // Quote found on this line
stream.next(); // Skip quote
state.inString = false; // Clear flag
} else {
stream.skipToEnd(); // Rest of line is string
}
state.justMatchedKeyword = false;
return "string"; // Token style
} else if (stream.sol() && stream.eatSpace()) {
if (stream.match(keyword_regex1)) {
state.justMatchedKeyword = true;
stream.eatSpace();
return "keyword";
}
if (stream.match(html_regex1) || stream.match(html_regex2)) {
state.justMatchedKeyword = true;
return "variable";
}
} else if (stream.sol() && stream.match(keyword_regex1)) {
state.justMatchedKeyword = true;
stream.eatSpace();
return "keyword";
} else if (stream.sol() && (stream.match(html_regex1) || stream.match(html_regex2))) {
state.justMatchedKeyword = true;
return "variable";
} else if (stream.eatSpace()) {
state.justMatchedKeyword = false;
if (stream.match(keyword_regex3) && stream.eatSpace()) {
state.justMatchedKeyword = true;
return "keyword";
}
} else if (stream.match(symbol_regex1)) {
state.justMatchedKeyword = false;
return "atom";
} else if (stream.match(open_paren_regex)) {
state.afterParen = true;
state.justMatchedKeyword = true;
return "def";
} else if (stream.match(close_paren_regex)) {
state.afterParen = false;
state.justMatchedKeyword = true;
return "def";
} else if (stream.match(keyword_regex2)) {
state.justMatchedKeyword = true;
return "keyword";
} else if (stream.eatSpace()) {
state.justMatchedKeyword = false;
} else {
stream.next();
if (state.justMatchedKeyword) {
return "property";
} else if (state.afterParen) {
return "property";
}
}
return null;
}
};
});

CodeMirror.defineMIME('text/x-jade', 'jade');
39 changes: 21 additions & 18 deletions mode/javascript/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,17 +258,17 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse(cx.state.indented));
if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
poplex, statement, poplex);
poplex, statement, poplex);
if (type == "variable") return cont(pushlex("stat"), maybelabel);
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
block, poplex, poplex);
block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
statement, poplex, popcontext);
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function expression(type) {
Expand Down Expand Up @@ -299,19 +299,20 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {

function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
return maybeoperatorNoComma(type, value, maybeoperatorComma);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, me) {
if (!me) me = maybeoperatorNoComma;
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me);
if (value == "?") return cont(expression, expect(":"), expression);
return cont(expression);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
if (type == ";") return;
if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
Expand Down Expand Up @@ -373,14 +374,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "=") return cont(expressionNoComma, vardef2);
if (type == ",") return cont(vardef1);
}
function maybeelse(indent) {
return function(type, value) {
if (type == "keyword b" && value == "else") {
cx.state.lexical = new JSLexical(indent, 0, "form", null, cx.state.lexical);
return cont(statement, poplex);
}
return pass();
};
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
}
function forspec1(type) {
if (type == "var") return cont(vardef1, expect(";"), forspec2);
Expand Down Expand Up @@ -441,6 +436,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
if (state.tokenize != jsTokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
// Kludge to prevent 'maybelse' from blocking lexical scope pops
for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
else if (c != maybeelse || /^else\b/.test(textAfter)) break;
}
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
Expand All @@ -461,7 +462,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
fold: "brace",

helperType: jsonMode ? "json" : "javascript",
jsonMode: jsonMode
};
});
Expand Down
10 changes: 10 additions & 0 deletions mode/javascript/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }

MT("locals",
"[keyword function] [variable foo]([def a], [def b]) { [keyword var] [def c] = [number 10]; [keyword return] [variable-2 a] + [variable-2 c] + [variable d]; }");

MT("comma-and-binop",
"[keyword function](){ [keyword var] [def x] = [number 1] + [number 2], [def y]; }");
})();
7 changes: 6 additions & 1 deletion mode/markdown/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
<script src="../../addon/edit/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>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default .cm-trailing-space-a:before,
.cm-s-default .cm-trailing-space-b:before {position: absolute; content: "\00B7"; color: #777;}
.cm-s-default .cm-trailing-space-new-line:before {position: absolute; content: "\21B5"; color: #777;}
</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
Expand Down
27 changes: 26 additions & 1 deletion mode/markdown/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.f = inlineNormal;
state.block = blockNormal;
}
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
// Mark this line as blank
state.thisLineHasContent = false;
return null;
Expand Down Expand Up @@ -217,6 +220,12 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}

if (state.trailingSpaceNewLine) {
styles.push("trailing-space-new-line");
} else if (state.trailingSpace) {
styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
}

return styles.length ? styles.join(' ') : null;
}

Expand Down Expand Up @@ -369,6 +378,14 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}

if (ch === ' ') {
if (stream.match(/ +$/, false)) {
state.trailingSpace++;
} else if (state.trailingSpace) {
state.trailingSpaceNewLine = true;
}
}

return getType(state);
}

Expand Down Expand Up @@ -453,7 +470,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
taskList: false,
list: false,
listDepth: 0,
quote: 0
quote: 0,
trailingSpace: 0,
trailingSpaceNewLine: false
};
},

Expand Down Expand Up @@ -481,6 +500,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
list: s.list,
listDepth: s.listDepth,
quote: s.quote,
trailingSpace: s.trailingSpace,
trailingSpaceNewLine: s.trailingSpaceNewLine,
md_inside: s.md_inside
};
},
Expand All @@ -504,6 +525,10 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
// Reset state.code
state.code = false;

// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;

state.f = state.block;
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
var difference = Math.floor((indentation - state.indentation) / 4) * 4;
Expand Down
14 changes: 14 additions & 0 deletions mode/markdown/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@
MT("plainText",
"foo");

// Don't style single trailing space
MT("trailingSpace1",
"foo ");

// Two or more trailing spaces should be styled with line break character
MT("trailingSpace2",
"foo[trailing-space-a ][trailing-space-new-line ]");

MT("trailingSpace3",
"foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]");

MT("trailingSpace4",
"foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]");

// Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
MT("codeBlocksUsing4Spaces",
" [comment foo]");
Expand Down
6 changes: 5 additions & 1 deletion mode/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ CodeMirror.modeInfo = [
{name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'},
{name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'},
{name: 'Gas', mime: 'text/x-gas', mode: 'gas'},
{name: 'GitHub Flavored Markdown', mode: 'gfm'},
{name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'},
{name: 'GO', mime: 'text/x-go', mode: 'go'},
{name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'},
{name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'},
Expand All @@ -26,6 +26,7 @@ CodeMirror.modeInfo = [
{name: 'JavaServer Pages', mime: 'application/x-jsp', mode: 'htmlembedded'},
{name: 'HTML', mime: 'text/html', mode: 'htmlmixed'},
{name: 'HTTP', mime: 'message/http', mode: 'http'},
{name: 'Jade', mime: 'text/x-jade', mode: 'jade'},
{name: 'JavaScript', mime: 'text/javascript', mode: 'javascript'},
{name: 'JSON', mime: 'application/x-json', mode: 'javascript'},
{name: 'JSON', mime: 'application/json', mode: 'javascript'},
Expand All @@ -36,6 +37,7 @@ CodeMirror.modeInfo = [
{name: 'Lua', mime: 'text/x-lua', mode: 'lua'},
{name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'},
{name: 'mIRC', mime: 'text/mirc', mode: 'mirc'},
{name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx'},
{name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'},
{name: 'OCaml', mime: 'text/x-ocaml', mode: 'ocaml'},
{name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'},
Expand All @@ -46,6 +48,7 @@ CodeMirror.modeInfo = [
{name: 'Plain Text', mime: 'text/plain', mode: 'null'},
{name: 'Properties files', mime: 'text/x-properties', mode: 'clike'},
{name: 'Python', mime: 'text/x-python', mode: 'python'},
{name: 'Cython', mime: 'text/x-cython', mode: 'python'},
{name: 'R', mime: 'text/x-rsrc', mode: 'r'},
{name: 'reStructuredText', mime: 'text/x-rst', mode: 'rst'},
{name: 'Ruby', mime: 'text/x-ruby', mode: 'ruby'},
Expand All @@ -57,6 +60,7 @@ CodeMirror.modeInfo = [
{name: 'Sieve', mime: 'application/sieve', mode: 'sieve'},
{name: 'Smalltalk', mime: 'text/x-stsrc', mode: 'smalltalk'},
{name: 'Smarty', mime: 'text/x-smarty', mode: 'smarty'},
{name: 'SmartyMixed', mime: 'text/x-smarty', mode: 'smartymixed'},
{name: 'SPARQL', mime: 'application/x-sparql-query', mode: 'sparql'},
{name: 'SQL', mime: 'text/x-sql', mode: 'sql'},
{name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql'},
Expand Down
167 changes: 167 additions & 0 deletions mode/nginx/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<!doctype html>
<html>
<head>
<title>CodeMirror: NGINX mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="nginx.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>

<style>
body {
margin: 0em auto;
}

.CodeMirror, .CodeMirror-scroll {
height: 600px;
}
</style>

<body>
<h1>CodeMirror: NGINX mode</h1>
<form><textarea id="code" name="code" style="height: 800px;">
server {
listen 173.255.219.235:80;
server_name website.com.au;
rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
}

server {
listen 173.255.219.235:443;
server_name website.com.au;
rewrite / $scheme://www.$host$request_uri permanent; ## Forcibly prepend a www
}

server {

listen 173.255.219.235:80;
server_name www.website.com.au;



root /data/www;
index index.html index.php;

location / {
index index.html index.php; ## Allow a static html file to be shown first
try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
expires 30d; ## Assume all files are cachable
}

## These locations would be hidden by .htaccess normally
location /app/ { deny all; }
location /includes/ { deny all; }
location /lib/ { deny all; }
location /media/downloadable/ { deny all; }
location /pkginfo/ { deny all; }
location /report/config.xml { deny all; }
location /var/ { deny all; }

location /var/export/ { ## Allow admins only to view export folder
auth_basic "Restricted"; ## Message shown in login window
auth_basic_user_file /rs/passwords/testfile; ## See /etc/nginx/htpassword
autoindex on;
}

location /. { ## Disable .htaccess and other hidden files
return 404;
}

location @handler { ## Magento uses a common front handler
rewrite / /index.php;
}

location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
rewrite ^/(.*.php)/ /$1 last;
}

location ~ \.php$ {
if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss

fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /rs/confs/nginx/fastcgi_params;
}

}


server {

listen 173.255.219.235:443;
server_name website.com.au www.website.com.au;

root /data/www;
index index.html index.php;

ssl on;
ssl_certificate /rs/ssl/ssl.crt;
ssl_certificate_key /rs/ssl/ssl.key;

ssl_session_timeout 5m;

ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;



location / {
index index.html index.php; ## Allow a static html file to be shown first
try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
expires 30d; ## Assume all files are cachable
}

## These locations would be hidden by .htaccess normally
location /app/ { deny all; }
location /includes/ { deny all; }
location /lib/ { deny all; }
location /media/downloadable/ { deny all; }
location /pkginfo/ { deny all; }
location /report/config.xml { deny all; }
location /var/ { deny all; }

location /var/export/ { ## Allow admins only to view export folder
auth_basic "Restricted"; ## Message shown in login window
auth_basic_user_file htpasswd; ## See /etc/nginx/htpassword
autoindex on;
}

location /. { ## Disable .htaccess and other hidden files
return 404;
}

location @handler { ## Magento uses a common front handler
rewrite / /index.php;
}

location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
rewrite ^/(.*.php)/ /$1 last;
}

location ~ .php$ { ## Execute PHP scripts
if (!-e $request_filename) { rewrite /index.php last; } ## Catch 404s that try_files miss

fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /rs/confs/nginx/fastcgi_params;

fastcgi_param HTTPS on;
}

}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>

<p><strong>MIME types defined:</strong> <code>text/nginx</code>.</p>

</body>
</html>
Loading