110 changes: 74 additions & 36 deletions addon/hint/show-hint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand All @@ -11,28 +14,35 @@
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";

// This is the old interface, kept around for now to stay
// backwards-compatible.
CodeMirror.showHint = function(cm, getHints, options) {
if (!getHints) return cm.showHint(options);
if (options && options.async) getHints.async = true;
var newOpts = {hint: getHints};
if (options) for (var prop in options) newOpts[prop] = options[prop];
return cm.showHint(newOpts);
};

CodeMirror.defineExtension("showHint", function(options) {
// We want a single cursor position.
if (cm.listSelections().length > 1 || cm.somethingSelected()) return;
if (getHints == null) {
if (options && options.async) return;
else getHints = CodeMirror.hint.auto;
}
if (this.listSelections().length > 1 || this.somethingSelected()) return;

if (cm.state.completionActive) cm.state.completionActive.close();
if (this.state.completionActive) this.state.completionActive.close();
var completion = this.state.completionActive = new Completion(this, options);
var getHints = completion.options.hint;
if (!getHints) return;

var completion = cm.state.completionActive = new Completion(cm, getHints, options || {});
CodeMirror.signal(cm, "startCompletion", cm);
if (completion.options.async)
getHints(cm, function(hints) { completion.showHints(hints); }, completion.options);
CodeMirror.signal(this, "startCompletion", this);
if (getHints.async)
getHints(this, function(hints) { completion.showHints(hints); }, completion.options);
else
return completion.showHints(getHints(cm, completion.options));
};
return completion.showHints(getHints(this, completion.options));
});

function Completion(cm, getHints, options) {
function Completion(cm, options) {
this.cm = cm;
this.getHints = getHints;
this.options = options;
this.options = this.buildOptions(options);
this.widget = this.onClose = null;
}

Expand Down Expand Up @@ -62,7 +72,7 @@
showHints: function(data) {
if (!data || !data.list.length || !this.active()) return this.close();

if (this.options.completeSingle != false && data.list.length == 1)
if (this.options.completeSingle && data.list.length == 1)
this.pick(data, 0);
else
this.showWidget(data);
Expand All @@ -73,7 +83,7 @@
CodeMirror.signal(data, "shown");

var debounce = 0, completion = this, finished;
var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/;
var closeOn = this.options.closeCharacters;
var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;

var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
Expand All @@ -92,10 +102,11 @@
function update() {
if (finished) return;
CodeMirror.signal(data, "update");
if (completion.options.async)
completion.getHints(completion.cm, finishUpdate, completion.options);
var getHints = completion.options.hint;
if (getHints.async)
getHints(completion.cm, finishUpdate, completion.options);
else
finishUpdate(completion.getHints(completion.cm, completion.options));
finishUpdate(getHints(completion.cm, completion.options));
}
function finishUpdate(data_) {
data = data_;
Expand Down Expand Up @@ -126,6 +137,17 @@
}
this.cm.on("cursorActivity", activity);
this.onClose = done;
},

buildOptions: function(options) {
var editor = this.cm.options.hintOptions;
var out = {};
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
if (editor) for (var prop in editor)
if (editor[prop] !== undefined) out[prop] = editor[prop];
if (options) for (var prop in options)
if (options[prop] !== undefined) out[prop] = options[prop];
return out;
}
};

Expand All @@ -134,7 +156,7 @@
else return completion.text;
}

function buildKeyMap(options, handle) {
function buildKeyMap(completion, handle) {
var baseMap = {
Up: function() {handle.moveFocus(-1);},
Down: function() {handle.moveFocus(1);},
Expand All @@ -146,7 +168,8 @@
Tab: handle.pick,
Esc: handle.close
};
var ourMap = options.customKeys ? {} : baseMap;
var custom = completion.options.customKeys;
var ourMap = custom ? {} : baseMap;
function addBinding(key, val) {
var bound;
if (typeof val != "string")
Expand All @@ -158,12 +181,13 @@
bound = val;
ourMap[key] = bound;
}
if (options.customKeys)
for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key))
addBinding(key, options.customKeys[key]);
if (options.extraKeys)
for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key))
addBinding(key, options.extraKeys[key]);
if (custom)
for (var key in custom) if (custom.hasOwnProperty(key))
addBinding(key, custom[key]);
var extra = completion.options.extraKeys;
if (extra)
for (var key in extra) if (extra.hasOwnProperty(key))
addBinding(key, extra[key]);
return ourMap;
}

Expand All @@ -177,11 +201,11 @@
function Widget(completion, data) {
this.completion = completion;
this.data = data;
var widget = this, cm = completion.cm, options = completion.options;
var widget = this, cm = completion.cm;

var hints = this.hints = document.createElement("ul");
hints.className = "CodeMirror-hints";
this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0;
this.selectedHint = data.selectedHint || 0;

var completions = data.list;
for (var i = 0; i < completions.length; ++i) {
Expand All @@ -194,14 +218,14 @@
elt.hintId = i;
}

var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null);
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true;
hints.style.left = left + "px";
hints.style.top = top + "px";
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
(options.container || document.body).appendChild(hints);
(completion.options.container || document.body).appendChild(hints);
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = box.top - (pos.bottom - pos.top);
Expand All @@ -228,7 +252,7 @@
hints.style.left = (left = pos.left - overlapX) + "px";
}

cm.addKeyMap(this.keyMap = buildKeyMap(options, {
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
setFocus: function(n) { widget.changeActive(n); },
menuSize: function() { return widget.screenAmount(); },
Expand All @@ -238,7 +262,7 @@
data: data
}));

if (options.closeOnUnfocus !== false) {
if (completion.options.closeOnUnfocus) {
var closingOnBlur;
cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
Expand All @@ -264,7 +288,7 @@
var t = getHintElement(hints, e.target || e.srcElement);
if (t && t.hintId != null) {
widget.changeActive(t.hintId);
if (options.completeOnSingleClick) widget.pick();
if (completion.options.completeOnSingleClick) widget.pick();
}
});

Expand All @@ -284,7 +308,7 @@
this.completion.cm.removeKeyMap(this.keyMap);

var cm = this.completion.cm;
if (this.completion.options.closeOnUnfocus !== false) {
if (this.completion.options.closeOnUnfocus) {
cm.off("blur", this.onBlur);
cm.off("focus", this.onFocus);
}
Expand Down Expand Up @@ -348,4 +372,18 @@
});

CodeMirror.commands.autocomplete = CodeMirror.showHint;

var defaultOptions = {
hint: CodeMirror.hint.auto,
completeSingle: true,
alignWithWord: true,
closeCharacters: /[\s()\[\]{};:>,]/,
closeOnUnfocus: true,
completeOnSingleClick: false,
container: null,
customKeys: null,
extraKeys: null
};

CodeMirror.defineOption("hintOptions", null);
});
3 changes: 3 additions & 0 deletions addon/hint/sql-hint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
Expand Down
3 changes: 3 additions & 0 deletions addon/hint/xml-hint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions addon/lint/coffeescript-lint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js

// declare global: coffeelint
Expand Down
3 changes: 3 additions & 0 deletions addon/lint/css-lint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Depends on csslint.js from https://github.com/stubbornella/csslint

// declare global: CSSLint
Expand Down
3 changes: 3 additions & 0 deletions addon/lint/javascript-lint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions addon/lint/json-lint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Depends on jsonlint.js from https://github.com/zaach/jsonlint

// declare global: jsonlint
Expand Down
3 changes: 3 additions & 0 deletions addon/lint/lint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions addon/lint/yaml-lint.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
50 changes: 0 additions & 50 deletions addon/merge/dep/diff_match_patch.js

This file was deleted.

3 changes: 3 additions & 0 deletions addon/merge/merge.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions addon/mode/loadmode.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions addon/mode/multiplex.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions addon/mode/multiplex_test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
CodeMirror.defineMode("markdown_with_stex", function(){
var inner = CodeMirror.getMode({}, "stex");
Expand Down
15 changes: 12 additions & 3 deletions addon/mode/overlay.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true, in which case
// the styles are combined.
// overlay wins, unless the combine argument was true and not overridden,
// or state.overlay.combineTokens was true, in which case the styles are
// combined.

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
Expand Down Expand Up @@ -54,8 +58,13 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
}
stream.pos = Math.min(state.basePos, state.overlayPos);

// state.overlay.combineTokens always takes precedence over combine,
// unless set to null
if (state.overlayCur == null) return state.baseCur;
if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
else if (state.baseCur != null &&
state.overlay.combineTokens ||
combine && state.overlay.combineTokens == null)
return state.baseCur + " " + state.overlayCur;
else return state.overlayCur;
},

Expand Down
3 changes: 3 additions & 0 deletions addon/runmode/colorize.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./runmode"));
Expand Down
5 changes: 4 additions & 1 deletion addon/runmode/runmode-standalone.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

window.CodeMirror = {};

(function() {
Expand Down Expand Up @@ -139,7 +142,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine();
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
Expand Down
5 changes: 4 additions & 1 deletion addon/runmode/runmode.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down Expand Up @@ -57,7 +60,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine();
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
Expand Down
5 changes: 4 additions & 1 deletion addon/runmode/runmode.node.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/* Just enough of CodeMirror to run runMode under node.js */

// declare global: StringStream
Expand Down Expand Up @@ -107,7 +110,7 @@ exports.runMode = function(string, modespec, callback, options) {
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new exports.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine();
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
Expand Down
3 changes: 3 additions & 0 deletions addon/scroll/scrollpastend.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
8 changes: 6 additions & 2 deletions addon/search/match-highlighter.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Highlighting text that matches the selection
//
// Defines an option highlightSelectionMatches, which, when enabled,
Expand Down Expand Up @@ -76,8 +79,9 @@
cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style));
return;
}
if (cm.getCursor("head").line != cm.getCursor("anchor").line) return;
var selection = cm.getSelections()[0].replace(/^\s+|\s+$/g, "");
var from = cm.getCursor("from"), to = cm.getCursor("to");
if (from.line != to.line) return;
var selection = cm.getRange(from, to).replace(/^\s+|\s+$/g, "");
if (selection.length >= state.minChars)
cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style));
});
Expand Down
3 changes: 3 additions & 0 deletions addon/search/search.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.

Expand Down
3 changes: 3 additions & 0 deletions addon/search/searchcursor.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions addon/selection/active-line.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Because sometimes you need to style the cursor's line.
//
// Adds an option 'styleActiveLine' which, when enabled, gives the
Expand Down
3 changes: 3 additions & 0 deletions addon/selection/mark-selection.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Because sometimes you need to mark the selected *text*.
//
// Adds an option 'styleSelectedText' which, when enabled, gives
Expand Down
1 change: 1 addition & 0 deletions addon/tern/tern.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@

.CodeMirror-Tern-hint-doc {
max-width: 25em;
margin-top: -3px;
}

.CodeMirror-Tern-fname { color: black; }
Expand Down
39 changes: 23 additions & 16 deletions addon/tern/tern.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Glue code between CodeMirror and Tern.
//
// Create a CodeMirror.TernServer to wrap an actual Tern server,
Expand All @@ -14,7 +17,7 @@
// indicate that a file is not available.
// * fileFilter: A function(value, docName, doc) that will be applied
// to documents before passing them on to Tern.
// * switchToDoc: A function(name) that should, when providing a
// * switchToDoc: A function(name, doc) that should, when providing a
// multi-file view, switch the view or focus to the named file.
// * showError: A function(editor, message) that can be used to
// override the way errors are displayed.
Expand Down Expand Up @@ -72,6 +75,9 @@
this.cachedArgHints = null;
this.activeArgHints = null;
this.jumpStack = [];

this.getHint = function(cm, c) { return hint(self, cm, c); };
this.getHint.async = true;
};

CodeMirror.TernServer.prototype = {
Expand All @@ -82,27 +88,24 @@
return this.docs[name] = data;
},

delDoc: function(name) {
var found = this.docs[name];
delDoc: function(id) {
var found = resolveDoc(this, id);
if (!found) return;
CodeMirror.off(found.doc, "change", this.trackChange);
delete this.docs[name];
this.server.delFile(name);
delete this.docs[found.name];
this.server.delFile(found.name);
},

hideDoc: function(name) {
hideDoc: function(id) {
closeArgHints(this);
var found = this.docs[name];
var found = resolveDoc(this, id);
if (found && found.changed) sendDoc(this, found);
},

complete: function(cm) {
var self = this;
CodeMirror.showHint(cm, function(cm, c) { return hint(self, cm, c); }, {async: true});
cm.showHint({hint: this.getHint});
},

getHint: function(cm, c) { return hint(this, cm, c); },

showType: function(cm, pos) { showType(this, cm, pos); },

updateArgHints: function(cm) { updateArgHints(this, cm); },
Expand Down Expand Up @@ -154,6 +157,12 @@
return ts.addDoc(name, doc);
}

function resolveDoc(ts, id) {
if (typeof id == "string") return ts.docs[id];
if (id instanceof CodeMirror) id = id.getDoc();
if (id instanceof CodeMirror.Doc) return findDoc(ts, id);
}

function trackChange(ts, doc, change) {
var data = findDoc(ts, doc);

Expand Down Expand Up @@ -381,10 +390,10 @@
}

function moveTo(ts, curDoc, doc, start, end) {
doc.doc.setSelection(end, start);
doc.doc.setSelection(start, end);
if (curDoc != doc && ts.options.switchToDoc) {
closeArgHints(ts);
ts.options.switchToDoc(doc.name);
ts.options.switchToDoc(doc.name, doc.doc);
}
}

Expand Down Expand Up @@ -429,7 +438,7 @@

function rename(ts, cm) {
var token = cm.getTokenAt(cm.getCursor());
if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable");
if (!/\w/.test(token.string)) return showError(ts, cm, "Not at a variable");
dialog(cm, "New name for " + token.string, function(newName) {
ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) {
if (error) return showError(ts, cm, error);
Expand All @@ -439,8 +448,6 @@
}

function selectName(ts, cm) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable");
var name = findDoc(ts, cm.doc).name;
ts.request(cm, {type: "refs"}, function(error, data) {
if (error) return showError(ts, cm, error);
Expand Down
3 changes: 3 additions & 0 deletions addon/tern/worker.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// declare global: tern, server

var server;
Expand Down
3 changes: 3 additions & 0 deletions addon/wrap/hardwrap.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
2 changes: 1 addition & 1 deletion demo/anywordhint.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ <h2>Any Word Completion Demo</h2>

<script>
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.anyword);
cm.showHint({hint: CodeMirror.hint.anyword});
}
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
Expand Down
2 changes: 1 addition & 1 deletion demo/folding.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ <h2>Code Folding Demo</h2>
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
editor.foldCode(CodeMirror.Pos(11, 0));
editor.foldCode(CodeMirror.Pos(13, 0));

window.editor_html = CodeMirror.fromTextArea(te_html, {
mode: "text/html",
Expand Down
2 changes: 1 addition & 1 deletion demo/merge.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<link rel=stylesheet href="../addon/merge/merge.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../addon/merge/dep/diff_match_patch.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"></script>
<script src="../addon/merge/merge.js"></script>
<style>
.CodeMirror { line-height: 1.2; }
Expand Down
9 changes: 2 additions & 7 deletions demo/rulers.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@
<script src="../addon/display/rulers.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
.ruler1 { border-left: 1px solid #fcc; }
.ruler2 { border-left: 1px solid #f5f577; }
.ruler3 { border-left: 1px solid #cfc; }
.ruler4 { border-left: 1px solid #aff; }
.ruler5 { border-left: 1px solid #ccf; }
.ruler6 { border-left: 1px solid #fcf; }
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
Expand All @@ -34,9 +28,10 @@ <h2>Ruler Demo</h2>

<script type="text/javascript">
var nums = "0123456789", space = " ";
var colors = ["#fcc", "#f5f577", "#cfc", "#aff", "#ccf", "#fcf"];
var rulers = [], value = "";
for (var i = 1; i <= 6; i++) {
rulers.push({className: "ruler" + i, column: i * 10});
rulers.push({color: colors[i], column: i * 10, lineStyle: "dashed"});
for (var j = 1; j < i; j++) value += space;
value += nums + "\n";
}
Expand Down
2 changes: 2 additions & 0 deletions demo/theme.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<link rel="stylesheet" href="../theme/midnight.css">
<link rel="stylesheet" href="../theme/monokai.css">
<link rel="stylesheet" href="../theme/neat.css">
<link rel="stylesheet" href="../theme/neo.css">
<link rel="stylesheet" href="../theme/night.css">
<link rel="stylesheet" href="../theme/paraiso-dark.css">
<link rel="stylesheet" href="../theme/paraiso-light.css">
Expand Down Expand Up @@ -87,6 +88,7 @@ <h2>Theme Demo</h2>
<option>midnight</option>
<option>monokai</option>
<option>neat</option>
<option>neo</option>
<option>night</option>
<option>paraiso-dark</option>
<option>paraiso-light</option>
Expand Down
11 changes: 11 additions & 0 deletions demo/vim.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ <h2>Vim bindings demo</h2>
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
}
</textarea></form>
<div id="command-display" style="width: 300px; height: 30px;"></div>

<form><textarea id="code2" name="code2">
I am another file! You can yank from my neighbor and paste here.
Expand Down Expand Up @@ -75,6 +76,16 @@ <h2>Vim bindings demo</h2>
matchBrackets: true,
showCursorWhenSelecting: true
});
var commandDisplay = document.getElementById('command-display');
var keys = '';
CodeMirror.on(editor, 'vim-keypress', function(key) {
keys = keys + key;
commandDisplay.innerHTML = keys;
});
CodeMirror.on(editor, 'vim-command-done', function(e) {
keys = '';
commandDisplay.innerHTML = keys;
});
</script>

</article>
9 changes: 4 additions & 5 deletions demo/xmlcomplete.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ <h2>XML Autocomplete Demo</h2>
var cur = cm.getCursor();
if (!pred || pred()) setTimeout(function() {
if (!cm.state.completionActive)
CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags, completeSingle: false});
cm.showHint({completeSingle: false});
}, 100);
return CodeMirror.Pass;
}
Expand Down Expand Up @@ -111,10 +111,9 @@ <h2>XML Autocomplete Demo</h2>
"'/'": completeIfAfterLt,
"' '": completeIfInTag,
"'='": completeIfInTag,
"Ctrl-Space": function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags});
}
}
"Ctrl-Space": "autocomplete"
},
hintOptions: {schemaInfo: tags}
});
</script>
</article>
43 changes: 40 additions & 3 deletions doc/compress.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
<title>CodeMirror: Compression Helper</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<link rel=stylesheet href="../lib/codemirror.css">

<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
Expand All @@ -29,10 +32,11 @@ <h2>Script compression helper</h2>
click <strong>Compress</strong> to download the minified script
file.</p>

<form id="form" action="http://marijnhaverbeke.nl/uglifyjs" method="post">
<form id="form" action="http://marijnhaverbeke.nl/uglifyjs" method="post" onsubmit="generateHeader();">
<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=4.2.0;f=">4.2</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.1.0;f=">4.1</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.0.3;f=">4.0</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.23.0;f=">3.23</option>
Expand Down Expand Up @@ -92,6 +96,7 @@ <h2>Script compression helper</h2>
<option value="http://codemirror.net/mode/coffeescript/coffeescript.js">coffeescript.js</option>
<option value="http://codemirror.net/mode/commonlisp/commonlisp.js">commonlisp.js</option>
<option value="http://codemirror.net/mode/css/css.js">css.js</option>
<option value="http://codemirror.net/mode/cypher/cypher.js">cypher.js</option>
<option value="http://codemirror.net/mode/d/d.js">d.js</option>
<option value="http://codemirror.net/mode/diff/diff.js">diff.js</option>
<option value="http://codemirror.net/mode/django/django.js">django.js</option>
Expand Down Expand Up @@ -221,11 +226,13 @@ <h2>Script compression helper</h2>
<p>
<button type="submit">Compress</button> with <a href="http://github.com/mishoo/UglifyJS/">UglifyJS</a>
</p>

<p>Custom code to add to the compressed file:<textarea name="js_code" style="width: 100%; height: 15em;" class="field"></textarea></p>
<input type="hidden" id="header" name="header">
<p>Custom code to add to the compressed file:<textarea name="js_code" style="width: 100%; height: 15em;" class="field" id="js_code"></textarea></p>
</form>

<script type="text/javascript">
CodeMirror.fromTextArea(document.getElementById("js_code")).getWrapperElement().className += " field";

function setVersion(ver) {
var urlprefix = ver.options[ver.selectedIndex].value;
var select = document.getElementById("files"), m;
Expand All @@ -239,6 +246,36 @@ <h2>Script compression helper</h2>
opt.value = urlprefix + m[1];
}
}

function generateHeader() {
var versionNode = document.getElementById("version");
var version = versionNode.options[versionNode.selectedIndex].label
var filesNode = document.getElementById("files");
var optGroupHeaderIncluded;

// Generate the comment
var str = "/* CodeMirror - Minified & Bundled\n";
str += " Generated on " + new Date().toLocaleDateString() + " with http://codemirror.net/doc/compress.html\n";
str += " Version: " + version + "\n\n";

for (var group = filesNode.firstChild; group; group = group.nextSibling) {
optGroupHeaderIncluded = false;
for (var option = group.firstChild; option; option = option.nextSibling) {
if (option.nodeName !== "OPTION") {
continue;
} else if (option.selected) {
if (!optGroupHeaderIncluded) {
str += " " + group.label + ":\n";
optGroupHeaderIncluded = true;
}
str += " - " + option.label + "\n";
}
}
}
str += " */\n\n";

document.getElementById("header").value = str;
}
</script>

</article>
57 changes: 35 additions & 22 deletions doc/manual.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
<section class=first id=overview>
<h2 style="position: relative">
User manual and reference guide
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 4.1.0</span>
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 4.2.0</span>
</h2>

<p>CodeMirror is a code-editor component that can be embedded in
Expand Down Expand Up @@ -1228,6 +1228,14 @@ <h3 id="api_selection">Cursor and selection methods</h3>
old one. When it starts with <code>*</code>, it will always
replace the previous event (if that had the same origin).
Built-in motion uses the <code>"+move"</code> origin.</dd>
<dt id="selection_bias"><code><strong>bias</strong>: number</code></dt>
<dd>Determine the direction into which the selection endpoints
should be adjusted when they fall inside
an <a href="#mark_atomic">atomic</a> range. Can be either -1
(backward) or 1 (forward). When not given, the bias will be
based on the relative position of the old selection—the editor
will try to move further away from that, to prevent getting
stuck.</dd>
</dl></dd>

<dt id="setSelections"><code><strong>doc.setSelections</strong>(ranges: array&lt;{anchor, head}&gt;, ?primary: integer, ?options: object)</code></dt>
Expand Down Expand Up @@ -2157,8 +2165,9 @@ <h2>Addons</h2>
<dd>Override the <a href="#mode_comment">comment string
properties</a> of the mode with custom comment strings.</dd>
<dt><code><strong>padding</strong>: string</code></dt>
<dd>A string that will be inserted after opening and before
closing comment markers. Defaults to a single space.</dd>
<dd>A string that will be inserted after opening and leading
markers, and before closing comment markers. Defaults to a
single space.</dd>
<dt><code><strong>commentBlankLines</strong>: boolean</code></dt>
<dd>Whether, when adding line comments, to also comment lines
that contain only whitespace.</dd>
Expand Down Expand Up @@ -2254,6 +2263,8 @@ <h2>Addons</h2>
given, <a href="#helper_fold_auto"><code>CodeMirror.fold.auto</code></a>
will be used as default.</dd>
</dl>
The <code>foldOptions</code> editor option can be set to an
object to provide an editor-wide default configuration.
Demo <a href="../demo/folding.html">here</a>.</dd>

<dt id="addon_runmode"><a href="../addon/runmode/runmode.js"><code>runmode/runmode.js</code></a></dt>
Expand Down Expand Up @@ -2315,28 +2326,27 @@ <h2>Addons</h2>

<dt id="addon_show-hint"><a href="../addon/hint/show-hint.js"><code>hint/show-hint.js</code></a></dt>
<dd>Provides a framework for showing autocompletion hints.
Defines <code>CodeMirror.showHint</code>, which takes a
CodeMirror instance, a hinting function, and optionally an
Defines <code>editor.showHint</code>, which takes an optional
options object, and pops up a widget that allows the user to
select a completion. Hinting functions are function that take an
editor instance and an optional options object, and return
select a completion. Finding hints is done with a hinting
functions (the <code>hint</code> option), which is a function
that take an editor instance and options object, and return
a <code>{list, from, to}</code> object, where <code>list</code>
is an array of strings or objects (the completions),
and <code>from</code> and <code>to</code> give the start and end
of the token that is being completed as <code>{line, ch}</code>
objects.</dd>
<dd>If no hinting function is given, the addon will
use <code>CodeMirror.hint.auto</code>, with
use <code>CodeMirror.hint.auto</code>, which
calls <a href="#getHelpers"><code>getHelpers</code></a> with
the <code>"hint"</code> type to find applicable hinting
functions, and tries them one by one. If that fails, it looks
for a <code>"hintWords"</code> helper to fetch a list of
completable words for the mode, and
uses <code>CodeMirror.hint.fromList</code> to complete from
those.</dd>
<dd>When completions
aren't simple strings, they should be objects with the following
properties:
<dd>When completions aren't simple strings, they should be
objects with the following properties:
<dl>
<dt><code><strong>text</strong>: string</code></dt>
<dd>The completion text. This is the only required
Expand All @@ -2363,11 +2373,13 @@ <h2>Addons</h2>
will also be passed along to the hinting function, which may
understand additional options):
<dl>
<dt><code><strong>async</strong>: boolean</code></dt>
<dd>When set to true, the hinting function's signature should
be <code>(cm, callback, ?options)</code>, and the completion
interface will only be popped up when the hinting function
calls the callback, passing it the object holding the
<dt><code><strong>hint</strong>: function</code></dt>
<dd>A hinting function, as specified above. It is possible to
set the <code>async</code> property on a hinting function to
true, in which case it will be called with
arguments <code>(cm, callback, ?options)</code>, and the
completion interface will only be popped up when the hinting
function calls the callback, passing it the object holding the
completions.</dd>
<dt><code><strong>completeSingle</strong>: boolean</code></dt>
<dd>Determines whether, when only a single completion is
Expand Down Expand Up @@ -2555,12 +2567,13 @@ <h2>Addons</h2>
<dt id="addon_rulers"><a href="../addon/display/rulers.js"><code>display/rulers.js</code></a></dt>
<dd>Adds a <code>rulers</code> option, which can be used to show
one or more vertical rulers in the editor. The option, if
defined, should be given an array of <code>{column,
className}</code> objects or numbers. The ruler will be
displayed at the column indicated by the number or
the <code>column</code> property. The <code>className</code>
property can be used to assign a custom style to a
ruler. <a href="../demo/rulers.html">Demo here</a>.</dd>
defined, should be given an array of <code>{column [, className,
color, lineStyle, width]}</code> objects or numbers (wich
indicate a column). The ruler will be displayed at the column
indicated by the number or the <code>column</code> property.
The <code>className</code> property can be used to assign a
custom style to a ruler. <a href="../demo/rulers.html">Demo
here</a>.</dd>

<dt id="addon_hardwrap"><a href="../addon/wrap/hardwrap.js"><code>wrap/hardwrap.js</code></a></dt>
<dd>Addon to perform hard line wrapping/breaking for paragraphs
Expand Down
5 changes: 5 additions & 0 deletions doc/realworld.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ <h2>CodeMirror real-world uses</h2>
<ul>
<li><a href="http://brackets.io">Adobe Brackets</a> (code editor)</li>
<li><a href="http://amber-lang.net/">Amber</a> (JavaScript-based Smalltalk system)</li>
<li><a href="http://apachegui.ca/">Apache GUI</a></li>
<li><a href="http://apeye.org/">APEye</a> (tool for testing &amp; documenting APIs)</li>
<li><a href="https://chrome.google.com/webstore/detail/better-text-viewer/lcaidopdffhfemoefoaadecppnjdknkc">Better Text Viewer</a> (plain text reader app for Chrome)</li>
<li><a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a> (code hosting)</li>
<li><a href="http://buzz.blogger.com/2013/04/improvements-to-blogger-template-html.html">Blogger's template editor</a></li>
<li><a href="http://bluegriffon.org/">BlueGriffon</a> (HTML editor)</li>
<li><a href="http://cargocollective.com/">Cargo Collective</a> (creative publishing platform)</li>
<li><a href="https://developers.google.com/chrome-developer-tools/">Chrome DevTools</a></li>
<li><a href="http://clickhelp.co/">ClickHelp</a> (technical writing tool)</li>
<li><a href="http://complete-ly.appspot.com/playground/code.playground.html">Complete.ly playground</a></li>
<li><a href="http://www.crossui.com/">CrossUI</a> (cross-platform UI builder)</li>
<li><a href="http://rsnous.com/cruncher/">Cruncher</a> (notepad with calculation features)</li>
<li><a href="http://drupal.org/project/cpn">Code per Node</a> (Drupal module)</li>
<li><a href="http://www.codebugapp.com/">Codebug</a> (PHP Xdebug front-end)</li>
Expand All @@ -58,6 +61,7 @@ <h2>CodeMirror real-world uses</h2>
<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://www.ecsspert.com/">eCSSpert</a> (CSS demos and experiments)</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>
Expand Down Expand Up @@ -96,6 +100,7 @@ <h2>CodeMirror real-world uses</h2>
<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>
<li><a href="http://montagestudio.com/">Montage Studio</a> (web app creator suite)</li>
<li><a href="http://mvcplayground.apphb.com/">MVC Playground</a></li>
<li><a href="https://www.my2ndgeneration.com/">My2ndGeneration</a> (social coding)</li>
<li><a href="http://www.navigatecms.com">Navigate CMS</a></li>
Expand Down
17 changes: 17 additions & 0 deletions doc/releases.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ <h2>Release notes and version history</h2>

<h2 id="v4">Version 4.x</h2>

<p class="rel">19-05-2014: <a href="http://codemirror.net/codemirror-4.2.zip">Version 4.2</a>:</p>

<ul class="rel-note">
<li>Fix problem where some modes were broken by the fact that empty tokens were forbidden.</li>
<li>Several fixes to context menu handling.</li>
<li>On undo, scroll <em>change</em>, not cursor, into view.</li>
<li>Rewritten <a href="../mode/jade/index.html">Jade</a> mode.</li>
<li>Various improvements to <a href="../mode/shell/index.html">Shell</a> (support for more syntax) and <a href="../mode/python/index.html">Python</a> (better indentation) modes.</li>
<li>New mode: <a href="../mode/cypher/index.html">Cypher</a>.</li>
<li>New theme: <a href="../demo/theme.html?neo">Neo</a>.</li>
<li>Support direct styling options (color, line style, width) in the <a href="manual.html#addon_rulers">rulers</a> addon.</li>
<li>Recognize per-editor configuration for the <a href="manual.html#addon_show-hint">show-hint</a> and <a href="manual.html#addon_foldcode">foldcode</a> addons.</li>
<li>More intelligent scanning for existing close tags in <a href="manual.html#addon_closetag">closetag</a> addon.</li>
<li>In the <a href="../demo/vim.html">Vim bindings</a>: Fix bracket matching, support case conversion in visual mode, visual paste, append action.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/4.1.0...4.2.0">list of patches</a>.</li>
</ul>

<p class="rel">22-04-2014: <a href="http://codemirror.net/codemirror-4.1.zip">Version 4.1</a>:</p>

<ul class="rel-note">
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ <h2>This is CodeMirror</h2>
</script>
<div style="position: relative; margin: 1em 0;">
<a class="bigbutton left" href="http://codemirror.net/codemirror.zip">DOWNLOAD LATEST RELEASE</a>
<div><strong>version 4.1</strong> (<a href="doc/releases.html">Release notes</a>)</div>
<div><strong>version 4.2</strong> (<a href="doc/releases.html">Release notes</a>)</div>
<div>or use the <a href="doc/compress.html">minification helper</a></div>
<div style="position: absolute; top: 0; right: 0; text-align: right">
<span class="bigbutton right" onclick="document.getElementById('paypal').submit();">DONATE WITH PAYPAL</span>
Expand Down
11 changes: 4 additions & 7 deletions keymap/emacs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"));
Expand Down Expand Up @@ -324,13 +327,7 @@
},
"Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }),
"Ctrl-T": repeated(function(cm) {
var pos = cm.getCursor();
if (pos.ch < cm.getLine(pos.line).length) pos = Pos(pos.line, pos.ch + 1);
var from = cm.findPosH(pos, -2, "char");
var range = cm.getRange(from, pos);
if (range.length != 2) return;
cm.setSelection(from, pos);
cm.replaceSelection(range.charAt(1) + range.charAt(0), null, "+transpose");
cm.execCommand("transposeChars");
}),

"Alt-C": repeated(function(cm) {
Expand Down
19 changes: 11 additions & 8 deletions keymap/sublime.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// A rough approximation of Sublime Text's keybindings
// Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js

Expand Down Expand Up @@ -184,9 +187,12 @@
};

cmds[map["Shift-" + ctrl + "Up"] = "swapLineUp"] = function(cm) {
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1;
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], from = range.from().line - 1, to = range.to().line;
newSels.push({anchor: Pos(range.anchor.line - 1, range.anchor.ch),
head: Pos(range.head.line - 1, range.head.ch)});
if (range.to().ch == 0 && !range.empty()) --to;
if (from > at) linesToMove.push(from, to);
else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to;
at = to;
Expand All @@ -196,16 +202,12 @@
var from = linesToMove[i], to = linesToMove[i + 1];
var line = cm.getLine(from);
cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine");
if (to > cm.lastLine()) {
if (to > cm.lastLine())
cm.replaceRange("\n" + line, Pos(cm.lastLine()), null, "+swapLine");
var sels = cm.listSelections(), last = sels[sels.length - 1];
var head = last.head.line == to ? Pos(to - 1) : last.head;
var anchor = last.anchor.line == to ? Pos(to - 1) : last.anchor;
cm.setSelections(sels.slice(0, sels.length - 1).concat([{head: head, anchor: anchor}]));
} else {
else
cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine");
}
}
cm.setSelections(newSels);
cm.scrollIntoView();
});
};
Expand All @@ -214,6 +216,7 @@
var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
var range = ranges[i], from = range.to().line + 1, to = range.from().line;
if (range.to().ch == 0 && !range.empty()) from--;
if (from < at) linesToMove.push(from, to);
else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to;
at = to;
Expand Down
125 changes: 92 additions & 33 deletions keymap/vim.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* Supported keybindings:
*
Expand Down Expand Up @@ -271,6 +274,7 @@
actionArgs: { insertAt: 'charAfter' }},
{ keys: ['A'], type: 'action', action: 'enterInsertMode', isEdit: true,
actionArgs: { insertAt: 'eol' }},
{ keys: ['A'], type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' },
{ keys: ['i'], type: 'action', action: 'enterInsertMode', isEdit: true,
actionArgs: { insertAt: 'inplace' }},
{ keys: ['I'], type: 'action', action: 'enterInsertMode', isEdit: true,
Expand All @@ -297,6 +301,8 @@
{ keys: ['R'], type: 'action', action: 'enterInsertMode', isEdit: true,
actionArgs: { replace: true }},
{ keys: ['u'], type: 'action', action: 'undo' },
{ keys: ['u'], type: 'action', action: 'changeCase', actionArgs: {toLower: true}, context: 'visual', isEdit: true },
{ keys: ['U'],type: 'action', action: 'changeCase', actionArgs: {toLower: false}, context: 'visual', isEdit: true },
{ keys: ['<C-r>'], type: 'action', action: 'redo' },
{ keys: ['m', 'character'], type: 'action', action: 'setMark' },
{ keys: ['"', 'character'], type: 'action', action: 'setRegister' },
Expand Down Expand Up @@ -682,13 +688,13 @@
if (macroModeState.isRecording) {
if (key == 'q') {
macroModeState.exitMacroRecordMode();
vim.inputState = new InputState();
clearInputState(cm);
return;
}
}
if (key == '<Esc>') {
// Clear input state and get back to normal mode.
vim.inputState = new InputState();
clearInputState(cm);
if (vim.visualMode) {
exitVisualMode(cm);
}
Expand Down Expand Up @@ -766,6 +772,11 @@
return repeat;
};

function clearInputState(cm, reason) {
cm.state.vim.inputState = new InputState();
CodeMirror.signal(cm, 'vim-command-done', reason);
}

/*
* Register stores information about copy and paste registers. Besides
* text, a register must store whether it is linewise (i.e., when it is
Expand Down Expand Up @@ -1018,7 +1029,7 @@
return;
} else {
// 2 different operators in a row doesn't make sense.
vim.inputState = new InputState();
clearInputState(cm);
}
}
inputState.operator = command.operator;
Expand Down Expand Up @@ -1063,7 +1074,7 @@
actionArgs.repeat = repeat || 1;
actionArgs.repeatIsExplicit = repeatIsExplicit;
actionArgs.registerName = inputState.registerName;
vim.inputState = new InputState();
clearInputState(cm);
vim.lastMotion = null;
if (command.isEdit) {
this.recordLastEdit(vim, inputState, command);
Expand Down Expand Up @@ -1244,7 +1255,7 @@
inputState.selectedCharacter;
}
motionArgs.repeat = repeat;
vim.inputState = new InputState();
clearInputState(cm);
if (motion) {
var motionResult = motions[motion](cm, motionArgs, vim);
vim.lastMotion = motions[motion];
Expand Down Expand Up @@ -1550,10 +1561,7 @@
// will move the cursor to where it should be in the end.
var curStart = cm.getCursor();
var repeat = motionArgs.repeat;
cm.moveV((motionArgs.forward ? repeat : -repeat), 'page');
var curEnd = cm.getCursor();
cm.setCursor(curStart);
return curEnd;
return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page');
},
moveByParagraph: function(cm, motionArgs) {
var line = cm.getCursor().line;
Expand Down Expand Up @@ -1645,15 +1653,14 @@
do {
symbol = lineText.charAt(ch++);
if (symbol && isMatchableSymbol(symbol)) {
var ignoreStyle = ["string", "comment"];
var style = cm.getTokenTypeAt(Pos(line, ch));
if (ignoreStyle.indexOf(style) < 0) {
if (style !== "string" && style !== "comment") {
break;
}
}
} while (symbol);
if (symbol) {
var matched = cm.findMatchingBracket(Pos(line, ch-1));
var matched = cm.findMatchingBracket(Pos(line, ch));
return matched.to;
} else {
return cursor;
Expand Down Expand Up @@ -1916,6 +1923,12 @@
cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));
} else if (insertAt == 'firstNonBlank') {
cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm));
} else if (insertAt == 'endOfSelectedArea') {
var selectionEnd = cm.getCursor('head');
var selectionStart = cm.getCursor('anchor');
selectionEnd = cursorIsBefore(selectionStart, selectionEnd) ? Pos(selectionEnd.line, selectionEnd.ch+1) : (selectionEnd.line < selectionStart.line ? Pos(selectionStart.line, 0) : selectionEnd);
cm.setCursor(selectionEnd);
exitVisualMode(cm);
}
cm.setOption('keyMap', 'vim-insert');
cm.setOption('disableInput', false);
Expand Down Expand Up @@ -2053,7 +2066,7 @@
}
this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim);
},
paste: function(cm, actionArgs) {
paste: function(cm, actionArgs, vim) {
var cur = copyCursor(cm.getCursor());
var register = vimGlobalState.registerController.getRegister(
actionArgs.registerName);
Expand Down Expand Up @@ -2094,7 +2107,9 @@
}
var linewise = register.linewise;
if (linewise) {
if (actionArgs.after) {
if(vim.visualMode) {
text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n';
} else if (actionArgs.after) {
// Move the newline at the end to the start instead, and paste just
// before the newline character of the line we are on right now.
text = '\n' + text.slice(0, text.length - 1);
Expand All @@ -2105,24 +2120,35 @@
} else {
cur.ch += actionArgs.after ? 1 : 0;
}
cm.replaceRange(text, cur);
// Now fine tune the cursor to where we want it.
var curPosFinal;
var idx;
if (linewise && actionArgs.after) {
curPosFinal = Pos(
cur.line + 1,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1)));
} else if (linewise && !actionArgs.after) {
curPosFinal = Pos(
cur.line,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line)));
} else if (!linewise && actionArgs.after) {
idx = cm.indexFromPos(cur);
curPosFinal = cm.posFromIndex(idx + text.length - 1);
if (vim.visualMode) {
var selectedArea = getSelectedAreaRange(cm, vim);
var selectionStart = selectedArea[0];
var selectionEnd = selectedArea[1];
// push the previously selected text to unnamed register
vimGlobalState.registerController.unnamedRegister.setText(cm.getRange(selectionStart, selectionEnd));
cm.replaceRange(text, selectionStart, selectionEnd);
curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1);
if(linewise)curPosFinal.ch=0;
} else {
idx = cm.indexFromPos(cur);
curPosFinal = cm.posFromIndex(idx + text.length);
cm.replaceRange(text, cur);
// Now fine tune the cursor to where we want it.
if (linewise && actionArgs.after) {
curPosFinal = Pos(
cur.line + 1,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1)));
} else if (linewise && !actionArgs.after) {
curPosFinal = Pos(
cur.line,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line)));
} else if (!linewise && actionArgs.after) {
idx = cm.indexFromPos(cur);
curPosFinal = cm.posFromIndex(idx + text.length - 1);
} else {
idx = cm.indexFromPos(cur);
curPosFinal = cm.posFromIndex(idx + text.length);
}
}
cm.setCursor(curPosFinal);
},
Expand Down Expand Up @@ -2216,6 +2242,15 @@
repeat = vim.lastEditInputState.repeatOverride || repeat;
}
repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */);
},
changeCase: function(cm, actionArgs, vim) {
var selectedAreaRange = getSelectedAreaRange(cm, vim);
var selectionStart = selectedAreaRange[0];
var selectionEnd = selectedAreaRange[1];
var toLower = actionArgs.toLower;
var text = cm.getRange(selectionStart, selectionEnd);
cm.replaceRange(toLower ? text.toLowerCase() : text.toUpperCase(), selectionStart, selectionEnd);
cm.setCursor(selectionStart);
}
};

Expand Down Expand Up @@ -2298,6 +2333,29 @@
function escapeRegex(s) {
return s.replace(/([.?*+$\[\]\/\\(){}|\-])/g, '\\$1');
}
function getSelectedAreaRange(cm, vim) {
var selectionStart = cm.getCursor('anchor');
var selectionEnd = cm.getCursor('head');
var lastSelection = vim.lastSelection;
if (!vim.visualMode) {
var line = lastSelection.curEnd.line - lastSelection.curStart.line;
var ch = line ? lastSelection.curEnd.ch : lastSelection.curEnd.ch - lastSelection.curStart.ch;
selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch};
if (lastSelection.visualLine) {
return [{line: selectionStart.line, ch: 0}, {line: selectionEnd.line, ch: lineLength(cm, selectionEnd.line)}];
}
} else {
if (cursorIsBefore(selectionEnd, selectionStart)) {
var tmp = selectionStart;
selectionStart = selectionEnd;
selectionEnd = tmp;
} else {
selectionEnd = cm.clipPos(Pos(selectionEnd.line, selectionEnd.ch+1));
}
exitVisualMode(cm);
}
return [selectionStart, selectionEnd];
}

function exitVisualMode(cm) {
cm.off('mousedown', exitVisualMode);
Expand Down Expand Up @@ -2908,15 +2966,15 @@
// Translates a search string from ex (vim) syntax into javascript form.
function translateRegex(str) {
// When these match, add a '\' if unescaped or remove one if escaped.
var specials = ['|', '(', ')', '{'];
var specials = '|(){';
// Remove, but never add, a '\' for these.
var unescape = ['}'];
var unescape = '}';
var escapeNextChar = false;
var out = [];
for (var i = -1; i < str.length; i++) {
var c = str.charAt(i) || '';
var n = str.charAt(i+1) || '';
var specialComesNext = (specials.indexOf(n) != -1);
var specialComesNext = (n && specials.indexOf(n) != -1);
if (escapeNextChar) {
if (c !== '\\' || !specialComesNext) {
out.push(c);
Expand All @@ -2926,7 +2984,7 @@
if (c === '\\') {
escapeNextChar = true;
// Treat the unescape list as special for removing, but not adding '\'.
if (unescape.indexOf(n) != -1) {
if (n && unescape.indexOf(n) != -1) {
specialComesNext = true;
}
// Not passing this test means removing a '\'.
Expand Down Expand Up @@ -3901,6 +3959,7 @@
// Closure to bind CodeMirror, key, modifier.
function keyMapper(vimKey) {
return function(cm) {
CodeMirror.signal(cm, 'vim-keypress', vimKey);
CodeMirror.Vim.handleKey(cm, vimKey);
};
}
Expand Down
191 changes: 133 additions & 58 deletions lib/codemirror.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions mode/apl/apl.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/asterisk/asterisk.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/*
* =====================================================================================
*
Expand Down
3 changes: 3 additions & 0 deletions mode/clike/clike.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/clojure/clojure.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* Author: Hans Engel
* Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
Expand Down
3 changes: 3 additions & 0 deletions mode/cobol/cobol.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* Author: Gautam Mehta
* Branched from CodeMirror's Scheme mode
Expand Down
3 changes: 3 additions & 0 deletions mode/coffeescript/coffeescript.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* Link to the project's GitHub page:
* https://github.com/pickhardt/coffeescript-codemirror-mode
Expand Down
3 changes: 3 additions & 0 deletions mode/commonlisp/commonlisp.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
27 changes: 13 additions & 14 deletions mode/css/css.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down Expand Up @@ -54,7 +57,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^[^-]+-/)) {
} else if (stream.match(/^\w+-/)) {
return ret("meta", "meta");
}
} else if (/[,+>*\/]/.test(ch)) {
Expand Down Expand Up @@ -164,7 +167,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
} else if (type == ":") {
return "pseudo";
} else if (allowNested && type == "(") {
return pushContext(state, stream, "params");
return pushContext(state, stream, "parens");
}
return state.context.type;
};
Expand Down Expand Up @@ -225,6 +228,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
states.parens = function(type, stream, state) {
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == ")") return popContext(state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "word") wordAsValue(stream);
return "parens";
};

Expand Down Expand Up @@ -300,13 +305,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return "interpolation";
};

states.params = function(type, stream, state) {
if (type == ")") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == "word") wordAsValue(stream);
return "params";
};

return {
startState: function(base) {
return {tokenize: null,
Expand All @@ -329,10 +327,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
indent: function(state, textAfter) {
var cx = state.context, ch = textAfter && textAfter.charAt(0);
var indent = cx.indent;
if (cx.type == "prop" && ch == "}") cx = cx.prev;
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
if (cx.prev &&
(ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
ch == ")" && (cx.type == "parens" || cx.type == "params" || cx.type == "media_parens") ||
ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
ch == "{" && (cx.type == "at" || cx.type == "media"))) {
indent = cx.indent - indentUnit;
cx = cx.prev;
Expand Down Expand Up @@ -422,7 +420,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"marker-offset", "marks", "marquee-direction", "marquee-loop",
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
"nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
"opacity", "order", "orphans", "outline",
"outline-color", "outline-offset", "outline-style", "outline-width",
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
Expand All @@ -433,8 +432,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"region-break-before", "region-break-inside", "region-fragment",
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
"speak", "speak-as", "speak-header",
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
"shape-outside", "size", "speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
Expand Down
3 changes: 3 additions & 0 deletions mode/css/less_test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
"use strict";

Expand Down
3 changes: 3 additions & 0 deletions mode/css/scss_test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
Expand Down
13 changes: 13 additions & 0 deletions mode/css/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "css");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down Expand Up @@ -119,4 +122,14 @@

MT("empty_url",
"[def @import] [tag url]() [tag screen];");

MT("parens",
"[qualifier .foo] {",
" [property background-image]: [variable fade]([atom #000], [number 20%]);",
" [property border-image]: [variable linear-gradient](",
" [atom to] [atom bottom],",
" [variable fade]([atom #000], [number 20%]) [number 0%],",
" [variable fade]([atom #000], [number 20%]) [number 100%]",
" );",
"}");
})();
146 changes: 146 additions & 0 deletions mode/cypher/cypher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// By the Neo4j Team and contributors.
// https://github.com/neo4j-contrib/CodeMirror

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var wordRegexp = function(words) {
return new RegExp("^(?:" + words.join("|") + ")$", "i");
};

CodeMirror.defineMode("cypher", function(config) {
var tokenBase = function(stream/*, state*/) {
var ch = stream.next(), curPunc = null;
if (ch === "\"" || ch === "'") {
stream.match(/.+?["']/);
return "string";
}
if (/[{}\(\),\.;\[\]]/.test(ch)) {
curPunc = ch;
return "node";
} else if (ch === "/" && stream.eat("/")) {
stream.skipToEnd();
return "comment";
} else if (operatorChars.test(ch)) {
stream.eatWhile(operatorChars);
return null;
} else {
stream.eatWhile(/[_\w\d]/);
if (stream.eat(":")) {
stream.eatWhile(/[\w\d_\-]/);
return "atom";
}
var word = stream.current();
if (funcs.test(word)) return "builtin";
if (preds.test(word)) return "def";
if (keywords.test(word)) return "keyword";
return "variable";
}
};
var pushContext = function(state, type, col) {
return state.context = {
prev: state.context,
indent: state.indent,
col: col,
type: type
};
};
var popContext = function(state) {
state.indent = state.context.indent;
return state.context = state.context.prev;
};
var indentUnit = config.indentUnit;
var curPunc;
var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "false", "foreach", "from", "headers", "in", "index", "is", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
var operatorChars = /[*+\-<>=&|~%^]/;

return {
startState: function(/*base*/) {
return {
tokenize: tokenBase,
context: null,
indent: 0,
col: 0
};
},
token: function(stream, state) {
if (stream.sol()) {
if (state.context && (state.context.align == null)) {
state.context.align = false;
}
state.indent = stream.indentation();
}
if (stream.eatSpace()) {
return null;
}
var style = state.tokenize(stream, state);
if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
state.context.align = true;
}
if (curPunc === "(") {
pushContext(state, ")", stream.column());
} else if (curPunc === "[") {
pushContext(state, "]", stream.column());
} else if (curPunc === "{") {
pushContext(state, "}", stream.column());
} else if (/[\]\}\)]/.test(curPunc)) {
while (state.context && state.context.type === "pattern") {
popContext(state);
}
if (state.context && curPunc === state.context.type) {
popContext(state);
}
} else if (curPunc === "." && state.context && state.context.type === "pattern") {
popContext(state);
} else if (/atom|string|variable/.test(style) && state.context) {
if (/[\}\]]/.test(state.context.type)) {
pushContext(state, "pattern", stream.column());
} else if (state.context.type === "pattern" && !state.context.align) {
state.context.align = true;
state.context.col = stream.column();
}
}
return style;
},
indent: function(state, textAfter) {
var firstChar = textAfter && textAfter.charAt(0);
var context = state.context;
if (/[\]\}]/.test(firstChar)) {
while (context && context.type === "pattern") {
context = context.prev;
}
}
var closing = context && firstChar === context.type;
if (!context) return 0;
if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
if (context.align) return context.col + (closing ? 0 : 1);
return context.indent + (closing ? 0 : indentUnit);
}
};
});

CodeMirror.modeExtensions["cypher"] = {
autoFormatLineBreaks: function(text) {
var i, lines, reProcessedPortion;
var lines = text.split("\n");
var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
for (var i = 0; i < lines.length; i++)
lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
return lines.join("\n");
}
};

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

});
63 changes: 63 additions & 0 deletions mode/cypher/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!doctype html>

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

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

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

<article>
<h2>Cypher Mode for CodeMirror</h2>
<form>
<textarea id="code" name="code">// Cypher Mode for CodeMirror, using the neo theme
MATCH (joe { name: 'Joe' })-[:knows*2..2]-(friend_of_friend)
WHERE NOT (joe)-[:knows]-(friend_of_friend)
RETURN friend_of_friend.name, COUNT(*)
ORDER BY COUNT(*) DESC , friend_of_friend.name
</textarea>
</form>
<p><strong>MIME types defined:</strong>
<code><a href="?mime=application/x-cypher-query">application/x-cypher-query</a></code>
</p>
<script>
window.onload = function() {
var mime = 'application/x-cypher-query';
// get mime type
if (window.location.href.indexOf('mime=') > -1) {
mime = window.location.href.substr(window.location.href.indexOf('mime=') + 5);
}
window.editor = CodeMirror.fromTextArea(document.getElementById('code'), {
mode: mime,
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets : true,
autofocus: true,
theme: 'neo'
});
};
</script>

</article>
3 changes: 3 additions & 0 deletions mode/d/d.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/diff/diff.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/django/django.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
Expand Down
3 changes: 3 additions & 0 deletions mode/dtd/dtd.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/*
DTD mode
Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
Expand Down
15 changes: 15 additions & 0 deletions mode/dylan/dylan.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

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

CodeMirror.defineMode("dylan", function(_config) {
// Words
var words = {
Expand Down Expand Up @@ -282,3 +295,5 @@ CodeMirror.defineMode("dylan", function(_config) {
});

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

});
3 changes: 3 additions & 0 deletions mode/ecl/ecl.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/eiffel/eiffel.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/erlang/erlang.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/*jshint unused:true, eqnull:true, curly:true, bitwise:true */
/*jshint undef:true, latedef:true, trailing:true */
/*global CodeMirror:true */
Expand Down
3 changes: 3 additions & 0 deletions mode/fortran/fortran.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/gas/gas.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
10 changes: 9 additions & 1 deletion mode/gfm/gfm.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay"));
Expand Down Expand Up @@ -30,6 +33,8 @@ CodeMirror.defineMode("gfm", function(config, modeConfig) {
};
},
token: function(stream, state) {
state.combineTokens = null;

// Hack to prevent formatting override inside code blocks (block and inline)
if (state.codeBlock) {
if (stream.match(/^```/)) {
Expand Down Expand Up @@ -77,19 +82,22 @@ CodeMirror.defineMode("gfm", function(config, modeConfig) {
// User/Project@SHA
// User@SHA
// SHA
state.combineTokens = true;
return "link";
} else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
// User/Project#Num
// User#Num
// #Num
state.combineTokens = true;
return "link";
}
}
if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i) &&
if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i) &&
stream.string.slice(stream.start - 2, stream.start) != "](") {
// URLs
// Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
// And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
state.combineTokens = true;
return "link";
}
stream.next();
Expand Down
24 changes: 24 additions & 0 deletions mode/gfm/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({tabSize: 4}, "gfm");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down Expand Up @@ -73,6 +76,9 @@
MT("SHA",
"foo [link be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] bar");

MT("SHAEmphasis",
"[em *foo ][em&link be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2][em *]");

MT("shortSHA",
"foo [link be6a8cc] bar");

Expand All @@ -88,21 +94,36 @@
MT("userSHA",
"foo [link bar@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] hello");

MT("userSHAEmphasis",
"[em *foo ][em&link bar@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2][em *]");

MT("userProjectSHA",
"foo [link bar/hello@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] world");

MT("userProjectSHAEmphasis",
"[em *foo ][em&link bar/hello@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2][em *]");

MT("num",
"foo [link #1] bar");

MT("numEmphasis",
"[em *foo ][em&link #1][em *]");

MT("badNum",
"foo #1bar hello");

MT("userNum",
"foo [link bar#1] hello");

MT("userNumEmphasis",
"[em *foo ][em&link bar#1][em *]");

MT("userProjectNum",
"foo [link bar/hello#1] world");

MT("userProjectNumEmphasis",
"[em *foo ][em&link bar/hello#1][em *]");

MT("vanillaLink",
"foo [link http://www.example.com/] bar");

Expand All @@ -112,6 +133,9 @@
MT("vanillaLinkExtension",
"foo [link http://www.example.com/index.html] bar");

MT("vanillaLinkEmphasis",
"foo [em *][em&link http://www.example.com/index.html][em *] bar");

MT("notALink",
"[comment ```css]",
"[tag foo] {[property color]:[keyword black];}",
Expand Down
3 changes: 3 additions & 0 deletions mode/gherkin/gherkin.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/*
Gherkin mode - http://www.cukes.info/
Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
Expand Down
3 changes: 3 additions & 0 deletions mode/go/go.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/groovy/groovy.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/haml/haml.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
Expand Down
3 changes: 3 additions & 0 deletions mode/haml/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "haml");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down
3 changes: 3 additions & 0 deletions mode/haskell/haskell.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
6 changes: 5 additions & 1 deletion mode/haxe/haxe.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down Expand Up @@ -505,7 +508,8 @@ CodeMirror.defineMode("hxml", function () {

stream.next();
return null;
}
},
lineComment: "#"
};
});

Expand Down
3 changes: 3 additions & 0 deletions mode/htmlembedded/htmlembedded.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"));
Expand Down
3 changes: 3 additions & 0 deletions mode/htmlmixed/htmlmixed.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
Expand Down
3 changes: 3 additions & 0 deletions mode/http/http.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
1 change: 1 addition & 0 deletions mode/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ <h2>Language modes</h2>
<li><a href="coffeescript/index.html">CoffeeScript</a></li>
<li><a href="commonlisp/index.html">Common Lisp</a></li>
<li><a href="css/index.html">CSS</a></li>
<li><a href="cypher/index.html">Cypher</a></li>
<li><a href="python/index.html">Cython</a></li>
<li><a href="d/index.html">D</a></li>
<li><a href="django/index.html">Django</a> (templating language)</li>
Expand Down
8 changes: 6 additions & 2 deletions mode/jade/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../xml/xml.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="jade.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
Expand All @@ -25,7 +29,7 @@
<article>
<h2>Jade Templating Mode</h2>
<form><textarea id="code" name="code">
doctype 5
doctype html
html
head
title= "Jade Templating CodeMirror Mode Example"
Expand Down Expand Up @@ -61,6 +65,6 @@ <h2>Jade Templating Mode</h2>
});
</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> Created by Forbes Lindesay. Managed as part of a Brackets extension at <a href="https://github.com/ForbesLindesay/jade-brackets">https://github.com/ForbesLindesay/jade-brackets</a>.</p>
<p><strong>MIME type defined:</strong> <code>text/x-jade</code>.</p>
</article>
650 changes: 569 additions & 81 deletions mode/jade/jade.js

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions mode/javascript/javascript.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// TODO actually recognize syntax of TypeScript constructs

(function(mod) {
Expand Down Expand Up @@ -645,6 +648,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
};
});

CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/);

CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
Expand Down
3 changes: 3 additions & 0 deletions mode/javascript/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down
3 changes: 3 additions & 0 deletions mode/jinja2/jinja2.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/julia/julia.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
34 changes: 17 additions & 17 deletions mode/livescript/livescript.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* Link to the project's GitHub page:
* https://github.com/duralog/CodeMirror
Expand All @@ -11,18 +14,17 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
"use strict";

(function() {
CodeMirror.defineMode('livescript', function(){
var tokenBase, external;
tokenBase = function(stream, state){
var next_rule, nr, i$, len$, r, m;
if (next_rule = state.next || 'start') {
var tokenBase = function(stream, state) {
var next_rule = state.next || "start";
if (next_rule) {
state.next = state.next;
if (Array.isArray(nr = Rules[next_rule])) {
for (i$ = 0, len$ = nr.length; i$ < len$; ++i$) {
r = nr[i$];
var nr = Rules[next_rule];
if (nr.splice) {
for (var i$ = 0; i$ < nr.length; ++i$) {
var r = nr[i$], m;
if (r.regex && (m = stream.match(r.regex))) {
state.next = r.next || state.next;
return r.token;
Expand All @@ -44,16 +46,16 @@
stream.next();
return 'error';
};
external = {
var external = {
startState: function(){
return {
next: 'start',
lastToken: null
};
},
token: function(stream, state){
var style;
style = tokenBase(stream, state);
while (stream.pos == stream.start)
var style = tokenBase(stream, state);
state.lastToken = {
style: style,
indent: stream.indentation(),
Expand All @@ -62,8 +64,7 @@
return style.replace(/\./g, ' ');
},
indent: function(state){
var indentation;
indentation = state.lastToken.indent;
var indentation = state.lastToken.indent;
if (state.lastToken.content.match(indenter)) {
indentation += 2;
}
Expand Down Expand Up @@ -262,7 +263,7 @@
};
for (var idx in Rules) {
var r = Rules[idx];
if (Array.isArray(r)) {
if (r.splice) {
for (var i = 0, len = r.length; i < len; ++i) {
var rr = r[i];
if (typeof rr.regex === 'string') {
Expand All @@ -273,8 +274,7 @@
Rules[idx].regex = new RegExp('^' + r.regex);
}
}
})();

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

});
266 changes: 0 additions & 266 deletions mode/livescript/livescript.ls

This file was deleted.

3 changes: 3 additions & 0 deletions mode/lua/lua.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// LUA mode. Ported to CodeMirror 2 from Franciszek Wawrzak's
// CodeMirror 1 mode.
// highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting
Expand Down
8 changes: 5 additions & 3 deletions mode/markdown/markdown.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror", require("../xml/xml")));
Expand Down Expand Up @@ -209,7 +212,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {

function htmlBlock(stream, state) {
var style = htmlMode.token(stream, state.htmlState);
if ((htmlFound && !state.htmlState.tagName && !state.htmlState.context) ||
if ((htmlFound && state.htmlState.tagStart === null && !state.htmlState.context) ||
(state.md_inside && stream.current().indexOf(">") > -1)) {
state.f = inlineNormal;
state.block = blockNormal;
Expand Down Expand Up @@ -709,8 +712,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {

if (forceBlankLine) {
state.prevLineHasContent = false;
blankLine(state);
return this.token(stream, state);
return blankLine(state);
} else {
state.prevLineHasContent = state.thisLineHasContent;
state.thisLineHasContent = true;
Expand Down
30 changes: 30 additions & 0 deletions mode/markdown/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({tabSize: 4}, "markdown");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down Expand Up @@ -89,6 +92,14 @@
" [comment hello]",
" [comment world]");

// Code blocks should end even after extra indented lines
MT("codeBlocksWithTrailingIndentedLine",
" [comment foo]",
" [comment bar]",
" [comment baz]",
" ",
"hello");

// Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value)
MT("codeBlocksUsing1Tab",
"\t[comment foo]");
Expand Down Expand Up @@ -721,4 +732,23 @@
"[comment ```]",
"foo",
"[comment ```]");

// Tests that require XML mode

MT("xmlMode",
"[tag&bracket <][tag div][tag&bracket >]",
"*foo*",
"[tag&bracket <][tag http://github.com][tag&bracket />]",
"[tag&bracket </][tag div][tag&bracket >]",
"[link <http://github.com/>]");

MT("xmlModeWithMarkdownInside",
"[tag&bracket <][tag div] [attribute markdown]=[string 1][tag&bracket >]",
"[em *foo*]",
"[link <http://github.com/>]",
"[tag </div>]",
"[link <http://github.com/>]",
"[tag&bracket <][tag div][tag&bracket >]",
"[tag&bracket </][tag div][tag&bracket >]");

})();
4 changes: 4 additions & 0 deletions mode/meta.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"));
Expand All @@ -20,6 +23,7 @@ CodeMirror.modeInfo = [
{name: 'Clojure', mime: 'text/x-clojure', mode: 'clojure'},
{name: 'CoffeeScript', mime: 'text/x-coffeescript', mode: 'coffeescript'},
{name: 'Common Lisp', mime: 'text/x-common-lisp', mode: 'commonlisp'},
{name: 'Cypher', mime: 'application/x-cypher-query', mode: 'cypher'},
{name: 'CSS', mime: 'text/css', mode: 'css'},
{name: 'D', mime: 'text/x-d', mode: 'd'},
{name: 'diff', mime: 'text/x-diff', mode: 'diff'},
Expand Down
3 changes: 3 additions & 0 deletions mode/mirc/mirc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

//mIRC mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara

(function(mod) {
Expand Down
3 changes: 3 additions & 0 deletions mode/mllike/mllike.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/nginx/nginx.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/ntriples/ntriples.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**********************************************************
* This script provides syntax highlighting support for
* the Ntriples format.
Expand Down
3 changes: 3 additions & 0 deletions mode/octave/octave.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/pascal/pascal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
Loading