+
+
-
-
diff --git a/index.html b/index.html
index 2f2ba05096..96e2eecd24 100644
--- a/index.html
+++ b/index.html
@@ -1,480 +1,188 @@
-
-
-
-
-
CodeMirror is a JavaScript component that
- provides a code editor in the browser. When a mode is available for
- the language you are coding in, it will color your code, and
- optionally help with indentation.
-
-
A rich programming API and a CSS
- theming system are available for customizing CodeMirror to fit your
- application, and extending it with new functionality.
-
-
-
-
Supported modes:
-
-
-
-
-
-
Usage demos:
-
-
-
-
Real-world uses:
-
-
-
-
-
-
Getting the code
-
-
All of CodeMirror is released under a MIT-style license. To get it, you can download
- the latest
- release or the current development
- snapshot as zip files. To create a custom minified script file,
- you can use the compression API.
-
-
We use git for version control.
- The main repository can be fetched in this way:
-
-
git clone http://marijnhaverbeke.nl/git/codemirror
-
-
CodeMirror can also be found on GitHub at marijnh/CodeMirror.
- If you plan to hack on the code and contribute patches, the best way
- to do it is to create a GitHub fork, and send pull requests.
-
-
Documentation
-
-
The manual is your first stop for
- learning how to use this library. It starts with a quick explanation
- of how to use the editor, and then describes the API in detail.
+
+
+
+
+
+
+
+
-
For those who want to learn more about the code, there is
- a series of
- posts on CodeMirror on my blog, and the
- old overview of the editor
- internals.
- The source code
- itself is, for the most part, also very readable.
+
-
Support and bug reports
+
-
Community discussion, questions, and informal bug reporting is
- done on
- the CodeMirror
- Google group. There is a separate
- group, CodeMirror-announce,
- which is lower-volume, and is only used for major announcements—new
- versions and such. These will be cross-posted to both groups, so you
- don't need to subscribe to both.
-
-
Though bug reports through e-mail are responded to, the preferred
- way to report bugs is to use
- the GitHub
- issue tracker. Before reporting a
- bug, read these pointers. Also,
- the issue tracker is for bugs, not requests for help.
-
-
When none of these seem fitting, you can
- simply e-mail the maintainer
- directly.
-
-
Supported browsers
-
-
The following desktop browsers are able to run CodeMirror:
+
+
- - Firefox 3 or higher
- - Chrome, any version
- - Safari 5.2 or higher
- - Opera 9 or higher (with some key-handling problems on OS X)
- - Internet Explorer 8 or higher
- - Internet Explorer 7 (standards mode) is usable, but buggy. It
- has a z-index
- bug that prevents CodeMirror from working properly.
+ - Home
+
- Manual
+
- Code
-
-
Note that CodeMirror is only supported in
- standards mode. So not quirks mode,
- but also not the quasi-standards mode that IE gives you
- when you specify a transitional doctype. Simply using the
- HTML5-style <!doctype html> is recommended.
-
-
Mobile browsers mostly kind of work, but, because of limitations
- and their fundamentally different UI assumptions, show a lot of
- quirks that are hard to work around.
-
-
Commercial support
-
-
CodeMirror is developed and maintained by me, Marijn Haverbeke,
- in my own time. If your company is getting value out of CodeMirror,
- please consider purchasing a support contract.
-
- - You'll be funding further work on CodeMirror.
- - You ensure that you get a quick response when you have a
- problem, even when I am otherwise busy.
+ - Features
+
- Community
+
- Browser support
-
-
CodeMirror support contracts exist in two
- forms—basic at €100 per month,
- and premium at €500 per
- month. Contact me for further
- information.
-
-
-
-
Download the latest release
-
-
Support CodeMirror
-
+
+
+
+ CodeMirror is a versatile text editor
+ implemented in JavaScript for the browser. It is specialized for
+ editing code, and comes with a number of language modes and addons
+ that implement more advanced editing functionaly.
+
+ A rich programming API and a
+ CSS theming system are
+ available for customizing CodeMirror to fit your application, and
+ extending it with new functionality.
+
+
+
+ This is CodeMirror
+
+
+
+
DOWNLOAD LATEST RELEASE
+
+
+
+
DONATE WITH PAYPAL
+
+ or
Bank,
+
Gittip,
+
Flattr
+
+ ×
+ Bank: Rabobank
+ Country: Netherlands
+ SWIFT: RABONL2U
+ Account: 147850770
+ Name: Marijn Haverbeke
+ IBAN: NL26 RABO 0147 8507 70
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
A list of CodeMirror-related software that is not part of the
+ main distribution is maintained
+ on our
+ wiki. Feel free to add your project.
+
+
+
+ Browser support
+ The desktop versions of the following browsers,
+ in standards mode (HTML5 <!doctype html>
+ recommended) are supported:
+
+ | Firefox | version 3 and up |
+ | Chrome | any version |
+ | Safari | version 5.2 and up |
+ | Internet Explorer | version 8 and up |
+ | Opera | version 9 and up |
+
+ Modern mobile browsers tend to partly work. Bug reports and
+ patches for mobile support are welcome, but the maintainer does not
+ have the time or budget to actually work on it himself.
+
+
+
diff --git a/keymap/vim.js b/keymap/vim.js
index 8db2767a9e..9c9454d6c8 100644
--- a/keymap/vim.js
+++ b/keymap/vim.js
@@ -1104,6 +1104,11 @@
if (vim.visualLine) {
if (cursorIsBefore(selectionStart, selectionEnd)) {
selectionStart.ch = 0;
+
+ var lastLine = cm.lastLine();
+ if (selectionEnd.line > lastLine) {
+ selectionEnd.line = lastLine;
+ }
selectionEnd.ch = lineLength(cm, selectionEnd.line);
} else {
selectionEnd.ch = 0;
diff --git a/lib/codemirror.css b/lib/codemirror.css
index 584eecbfd3..c95db6445c 100644
--- a/lib/codemirror.css
+++ b/lib/codemirror.css
@@ -95,6 +95,7 @@
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
diff --git a/lib/codemirror.js b/lib/codemirror.js
index 9451b6dbaf..be262913b4 100644
--- a/lib/codemirror.js
+++ b/lib/codemirror.js
@@ -24,7 +24,7 @@ window.CodeMirror = (function() {
// This is woefully incomplete. Suggestions for alternative methods welcome.
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
var mac = ios || /Mac/.test(navigator.platform);
- var windows = /windows/i.test(navigator.platform);
+ var windows = /win/i.test(navigator.platform);
var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
if (opera_version) opera_version = Number(opera_version[1]);
@@ -332,13 +332,19 @@ window.CodeMirror = (function() {
d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
d.scrollbarV.firstChild.style.height =
(scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
- } else d.scrollbarV.style.display = "";
+ } else {
+ d.scrollbarV.style.display = "";
+ d.scrollbarV.firstChild.style.height = "0";
+ }
if (needsH) {
d.scrollbarH.style.display = "block";
d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
d.scrollbarH.firstChild.style.width =
(d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
- } else d.scrollbarH.style.display = "";
+ } else {
+ d.scrollbarH.style.display = "";
+ d.scrollbarH.firstChild.style.width = "0";
+ }
if (needsH && needsV) {
d.scrollbarFiller.style.display = "block";
d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
@@ -455,7 +461,7 @@ window.CodeMirror = (function() {
var positionsChangedFrom = Infinity;
if (cm.options.lineNumbers)
for (var i = 0; i < changes.length; ++i)
- if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; }
+ if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; }
var end = doc.first + doc.size;
var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
@@ -612,7 +618,7 @@ window.CodeMirror = (function() {
if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
if (lineIsHidden(cm.doc, line)) {
if (line.height != 0) updateLineHeight(line, 0);
- if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
+ if (line.widgets && cur && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
var w = line.widgets[i];
if (w.showIfHidden) {
var prev = cur.previousSibling;
@@ -871,9 +877,10 @@ window.CodeMirror = (function() {
clearInterval(display.blinker);
var on = true;
display.cursor.style.visibility = display.otherCursor.style.visibility = "";
- display.blinker = setInterval(function() {
- display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
- }, cm.options.cursorBlinkRate);
+ if (cm.options.cursorBlinkRate > 0)
+ display.blinker = setInterval(function() {
+ display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
+ }, cm.options.cursorBlinkRate);
}
// HIGHLIGHT WORKER
@@ -924,8 +931,8 @@ window.CodeMirror = (function() {
// smallest indentation, which tends to need the least context to
// parse correctly.
function findStartLine(cm, n, precise) {
- var minindent, minline, doc = cm.doc;
- for (var search = n, lim = n - 100; search > lim; --search) {
+ var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100;
+ for (var search = n, lim = n - maxScan; search > lim; --search) {
if (search <= doc.first) return doc.first;
var line = getLine(doc, search - 1);
if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
@@ -940,7 +947,7 @@ window.CodeMirror = (function() {
function getStateBefore(cm, n, precise) {
var doc = cm.doc, display = cm.display;
- if (!doc.mode.startState) return true;
+ if (!doc.mode.startState) return true;
var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
if (!state) state = startState(doc.mode);
else state = copyState(doc.mode, state);
@@ -1090,6 +1097,7 @@ window.CodeMirror = (function() {
if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
}
+ removeChildren(cm.display.measure);
for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
finishRect(cur);
if (cur.leftSide) finishRect(cur.leftSide);
@@ -1442,6 +1450,10 @@ window.CodeMirror = (function() {
function readInput(cm) {
var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
+ if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
+ input.value = input.value.substring(0, input.value.length - 1);
+ cm.state.fakedLastChar = false;
+ }
var text = input.value;
if (text == prevInput && posEq(sel.from, sel.to)) return false;
if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
@@ -1588,12 +1600,22 @@ window.CodeMirror = (function() {
on(d.scroller, "dragover", drag_);
on(d.scroller, "drop", operation(cm, onDrop));
}
- on(d.scroller, "paste", function(e){
+ on(d.scroller, "paste", function(e) {
if (eventInWidget(d, e)) return;
focusInput(cm);
fastPoll(cm);
});
on(d.input, "paste", function() {
+ // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
+ // Add a char to the end of textarea before paste occur so that
+ // selection doesn't span to the end of textarea.
+ if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
+ var start = d.input.selectionStart, end = d.input.selectionEnd;
+ d.input.value += "$";
+ d.input.selectionStart = start;
+ d.input.selectionEnd = end;
+ cm.state.fakedLastChar = true;
+ }
cm.state.pasteIncoming = true;
fastPoll(cm);
});
@@ -1657,6 +1679,7 @@ window.CodeMirror = (function() {
if (captureMiddleClick) onContextMenu.call(cm, cm, e);
return;
case 2:
+ if (webkit) cm.state.lastMiddleDown = +new Date;
if (start) extendSelection(cm.doc, start);
setTimeout(bind(focusInput, cm), 20);
e_preventDefault(e);
@@ -2060,8 +2083,8 @@ window.CodeMirror = (function() {
function onKeyDown(e) {
var cm = this;
if (!cm.state.focused) onFocus(cm);
- if (ie && e.keyCode == 27) { e.returnValue = false; }
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
+ if (ie && e.keyCode == 27) e.returnValue = false;
var code = e.keyCode;
// IE does strange things with escape.
cm.doc.sel.shift = code == 16 || e.shiftKey;
@@ -2098,7 +2121,10 @@ window.CodeMirror = (function() {
cm.state.focused = true;
if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
cm.display.wrapper.className += " CodeMirror-focused";
- resetInput(cm, true);
+ if (!cm.curOp) {
+ resetInput(cm, true);
+ if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
+ }
}
slowPoll(cm);
restartBlink(cm);
@@ -3729,9 +3755,10 @@ window.CodeMirror = (function() {
TextMarker.prototype.changed = function() {
var pos = this.find(), cm = this.doc.cm;
if (!pos || !cm) return;
- var line = getLine(this.doc, pos.from.line);
+ if (this.type != "bookmark") pos = pos.from;
+ var line = getLine(this.doc, pos.line);
clearCachedMeasurement(cm, line);
- if (pos.from.line >= cm.display.showingFrom && pos.from.line < cm.display.showingTo) {
+ if (pos.line >= cm.display.showingFrom && pos.line < cm.display.showingTo) {
for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
break;
@@ -4394,11 +4421,13 @@ window.CodeMirror = (function() {
if (size) {
builder.measure[builder.pos] = widget;
} else {
- var elt = builder.measure[builder.pos] = zeroWidthElement(builder.cm.display.measure);
- if (marker.type != "bookmark" || marker.insertLeft)
- builder.pre.insertBefore(elt, widget);
+ var elt = zeroWidthElement(builder.cm.display.measure);
+ if (marker.type == "bookmark" && !marker.insertLeft)
+ builder.measure[builder.pos] = builder.pre.appendChild(elt);
+ else if (builder.measure[builder.pos])
+ return;
else
- builder.pre.appendChild(elt);
+ builder.measure[builder.pos] = builder.pre.insertBefore(elt, widget);
}
builder.measuredSomething = true;
}
@@ -4422,7 +4451,7 @@ window.CodeMirror = (function() {
if (nextChange == pos) { // Update current marker set
spanStyle = spanEndStyle = spanStartStyle = title = "";
collapsed = null; nextChange = Infinity;
- var foundBookmark = null;
+ var foundBookmarks = [];
for (var j = 0; j < spans.length; ++j) {
var sp = spans[j], m = sp.marker;
if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
@@ -4436,14 +4465,15 @@ window.CodeMirror = (function() {
} else if (sp.from > pos && nextChange > sp.from) {
nextChange = sp.from;
}
- if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmark = m;
+ if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmarks.push(m);
}
if (collapsed && (collapsed.from || 0) == pos) {
buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
collapsed.marker, collapsed.from == null);
if (collapsed.to == null) return collapsed.marker.find();
}
- if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
+ if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
+ buildCollapsedSpan(builder, 0, foundBookmarks[j]);
}
if (pos >= len) break;
@@ -4739,11 +4769,11 @@ window.CodeMirror = (function() {
if (extend) extendSelection(this, pos);
else setSelection(this, pos, pos);
}),
- setSelection: docOperation(function(anchor, head) {
- setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor));
+ setSelection: docOperation(function(anchor, head, bias) {
+ setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), bias);
}),
- extendSelection: docOperation(function(from, to) {
- extendSelection(this, clipPos(this, from), to && clipPos(this, to));
+ extendSelection: docOperation(function(from, to, bias) {
+ extendSelection(this, clipPos(this, from), to && clipPos(this, to), bias);
}),
getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
@@ -5791,7 +5821,7 @@ window.CodeMirror = (function() {
// THE END
- CodeMirror.version = "3.15.0";
+ CodeMirror.version = "3.16.0";
return CodeMirror;
})();
diff --git a/mode/apl/index.html b/mode/apl/index.html
index 119ff17f19..f8282ac42f 100644
--- a/mode/apl/index.html
+++ b/mode/apl/index.html
@@ -1,20 +1,32 @@
-
-
-
-
CodeMirror: APL mode
-
-
-
-
-
-
-
-
-
CodeMirror: APL mode
+
+

+
+
+
+
+
+APL mode
diff --git a/mode/asterisk/index.html b/mode/asterisk/index.html
index 0a796a0119..6abdecb50d 100644
--- a/mode/asterisk/index.html
+++ b/mode/asterisk/index.html
@@ -1,20 +1,33 @@
-
-
-
-
CodeMirror: Asterisk dialplan mode
-
-
-
-
-
-
-
-
CodeMirror: Asterisk dialplan mode
-