14 changes: 14 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Alex Piggott
Aliaksei Chapyzhenka
Allen Sarkisyan
Amin Shali
amshali@google.com
Amsul
amuntean
Amy
Expand Down Expand Up @@ -63,6 +64,8 @@ as3boyan
AtomicPages LLC
Atul Bhouraskar
Aurelian Oancea
Barret Rennie
Basarat Ali Syed
Bastian Müller
belhaj
Bem Jones-Bey
Expand All @@ -86,6 +89,7 @@ Brett Zamir
Brian Grinstead
Brian Sletten
Bruce Mitchener
Caitlin Potter
Calin Barbat
Chandra Sekhar Pydi
Charles Skelton
Expand Down Expand Up @@ -144,6 +148,7 @@ duralog
eborden
edsharp
ekhaled
Elisée
Enam Mijbah Noor
Eric Allam
eustas
Expand Down Expand Up @@ -196,6 +201,7 @@ Ian Wehrman
Ian Wetherbee
Ice White
ICHIKAWA, Yuji
idleberg
ilvalle
Ingo Richter
Irakli Gozalishvili
Expand Down Expand Up @@ -230,6 +236,7 @@ Jeremy Parmenter
Jochen Berger
Johan Ask
John Connor
John Engler
John Lees-Miller
John Snelson
John Van Der Loo
Expand Down Expand Up @@ -296,12 +303,15 @@ Marek Rudnicki
Marijn Haverbeke
Mário Gonçalves
Mario Pietsch
Mark Anderson
Mark Lentczner
Marko Bonaci
Markus Bordihn
Martin Balek
Martín Gaitán
Martin Hasoň
Martin Hunt
Martin Laine
Martin Zagora
Mason Malone
Mateusz Paprocki
Expand All @@ -327,6 +337,7 @@ melpon
Metatheos
Micah Dubinko
Michael
Michael Goderbauer
Michael Grey
Michael Kaminsky
Michael Lehenbauer
Expand Down Expand Up @@ -386,6 +397,7 @@ Pavel Feldman
Pavel Strashkin
Paweł Bartkiewicz
peteguhl
peter
Peter Flynn
peterkroon
Peter Kroon
Expand Down Expand Up @@ -420,6 +432,7 @@ Sascha Peilicke
satamas
satchmorun
sathyamoorthi
S. Chris Colbert
SCLINIC\jdecker
Scott Aikin
Scott Goodhew
Expand Down Expand Up @@ -449,6 +462,7 @@ stoskov
Sungho Kim
sverweij
Taha Jahangir
Tako Schotanus
Takuji Shimokawa
Tarmil
tel
Expand Down
27 changes: 20 additions & 7 deletions addon/comment/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,28 @@
}

CodeMirror.commands.toggleComment = function(cm) {
var minLine = Infinity, ranges = cm.listSelections(), mode = null;
cm.toggleComment();
};

CodeMirror.defineExtension("toggleComment", function(options) {
if (!options) options = noOptions;
var cm = this;
var minLine = Infinity, ranges = this.listSelections(), mode = null;
for (var i = ranges.length - 1; i >= 0; i--) {
var from = ranges[i].from(), to = ranges[i].to();
if (from.line >= minLine) continue;
if (to.line >= minLine) to = Pos(minLine, 0);
minLine = from.line;
if (mode == null) {
if (cm.uncomment(from, to)) mode = "un";
else { cm.lineComment(from, to); mode = "line"; }
if (cm.uncomment(from, to, options)) mode = "un";
else { cm.lineComment(from, to, options); mode = "line"; }
} else if (mode == "un") {
cm.uncomment(from, to);
cm.uncomment(from, to, options);
} else {
cm.lineComment(from, to);
cm.lineComment(from, to, options);
}
}
};
});

CodeMirror.defineExtension("lineComment", function(from, to, options) {
if (!options) options = noOptions;
Expand All @@ -57,7 +63,14 @@

self.operation(function() {
if (options.indent) {
var baseString = firstLine.slice(0, firstNonWS(firstLine));
var baseString = null;
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i);
var whitespace = line.slice(0, firstNonWS(line));
if (baseString == null || baseString.length > whitespace.length) {
baseString = whitespace;
}
}
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i), cut = baseString.length;
if (!blankLines && !nonWS.test(line)) continue;
Expand Down
100 changes: 77 additions & 23 deletions addon/hint/show-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@
};

CodeMirror.defineExtension("showHint", function(options) {
// We want a single cursor position.
if (this.listSelections().length > 1 || this.somethingSelected()) return;
options = parseOptions(this, this.getCursor("start"), options);
var selections = this.listSelections()
if (selections.length > 1) return;
// By default, don't allow completion when something is selected.
// A hint function can have a `supportsSelection` property to
// indicate that it can handle selections.
if (this.somethingSelected()) {
if (!options.hint.supportsSelection) return;
// Don't try with cross-line selections
for (var i = 0; i < selections.length; i++)
if (selections[i].head.line != selections[i].anchor.line) return;
}

if (this.state.completionActive) this.state.completionActive.close();
var completion = this.state.completionActive = new Completion(this, options);
Expand All @@ -38,12 +48,12 @@

function Completion(cm, options) {
this.cm = cm;
this.options = this.buildOptions(options);
this.options = options;
this.widget = null;
this.debounce = 0;
this.tick = 0;
this.startPos = this.cm.getCursor();
this.startLen = this.cm.getLine(this.startPos.line).length;
this.startPos = this.cm.getCursor("start");
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;

var self = this;
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
Expand Down Expand Up @@ -124,20 +134,21 @@
CodeMirror.signal(data, "shown");
}
}
},

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;
}
};

function parseOptions(cm, pos, options) {
var editor = 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];
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
return out;
}

function getText(completion) {
if (typeof completion == "string") return completion;
else return completion.text;
Expand Down Expand Up @@ -336,18 +347,61 @@
}
};

CodeMirror.registerHelper("hint", "auto", function(cm, options) {
var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
function applicableHelpers(cm, helpers) {
if (!cm.somethingSelected()) return helpers
var result = []
for (var i = 0; i < helpers.length; i++)
if (helpers[i].supportsSelection) result.push(helpers[i])
return result
}

function resolveAutoHints(cm, pos) {
var helpers = cm.getHelpers(pos, "hint"), words
if (helpers.length) {
for (var i = 0; i < helpers.length; i++) {
var cur = helpers[i](cm, options);
if (cur && cur.list.length) return cur;
var async = false, resolved
for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true
if (async) {
resolved = function(cm, callback, options) {
var app = applicableHelpers(cm, helpers)
function run(i, result) {
if (i == app.length) return callback(null)
var helper = app[i]
if (helper.async) {
helper(cm, function(result) {
if (result) callback(result)
else run(i + 1)
}, options)
} else {
var result = helper(cm, options)
if (result) callback(result)
else run(i + 1)
}
}
run(0)
}
resolved.async = true
} else {
resolved = function(cm, options) {
var app = applicableHelpers(cm, helpers)
for (var i = 0; i < app.length; i++) {
var cur = app[i](cm, options)
if (cur && cur.list.length) return cur
}
}
}
resolved.supportsSelection = true
return resolved
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
if (words) return CodeMirror.hint.fromList(cm, {words: words});
return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
} else if (CodeMirror.hint.anyword) {
return CodeMirror.hint.anyword(cm, options);
return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
} else {
return function() {}
}
}

CodeMirror.registerHelper("hint", "auto", {
resolve: resolveAutoHints
});

CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
Expand Down
9 changes: 3 additions & 6 deletions addon/merge/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("diff_match_patch"));
mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "diff_match_patch"], mod);
else // Plain browser env
Expand Down Expand Up @@ -471,13 +471,10 @@
if (left) left.init(leftPane, origLeft, options);
if (right) right.init(rightPane, origRight, options);

if (options.collapseIdentical) {
updating = true;
if (options.collapseIdentical)
this.editor().operation(function() {
collapseIdenticalStretches(self, options.collapseIdentical);
});
updating = false;
}
if (options.connect == "align") {
this.aligners = [];
alignChunks(this.left || this.right, true);
Expand Down Expand Up @@ -640,7 +637,7 @@
mark.clear();
cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
}
widget.addEventListener("click", clear);
CodeMirror.on(widget, "click", clear);
return {mark: mark, clear: clear};
}

Expand Down
6 changes: 3 additions & 3 deletions addon/mode/multiplex.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
if (!other.parseDelimiters) stream.match(other.open);
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
return other.delimStyle;
return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
} else if (found != -1 && found < cutOff) {
cutOff = found;
}
Expand All @@ -70,7 +70,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
if (found == stream.pos && !curInner.parseDelimiters) {
stream.match(curInner.close);
state.innerActive = state.inner = null;
return curInner.delimStyle;
return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
}
if (found > -1) stream.string = oldContent.slice(0, found);
var innerToken = curInner.mode.token(stream, state.inner);
Expand All @@ -80,7 +80,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
state.innerActive = state.inner = null;

if (curInner.innerStyle) {
if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
else innerToken = curInner.innerStyle;
}

Expand Down
2 changes: 1 addition & 1 deletion addon/mode/multiplex_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@

MT(
"stexInsideMarkdown",
"[strong **Equation:**] [delim $][inner&tag \\pi][delim $]");
"[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]");
})();
15 changes: 9 additions & 6 deletions addon/wrap/hardwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
for (var at = column; at > 0; --at)
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
if (at == 0) at = column;
var endOfText = at;
if (killTrailingSpace)
while (text.charAt(endOfText - 1) == " ") --endOfText;
return {from: endOfText, to: at};
for (var first = true;; first = false) {
var endOfText = at;
if (killTrailingSpace)
while (text.charAt(endOfText - 1) == " ") --endOfText;
if (endOfText == 0 && first) at = column;
else return {from: endOfText, to: at};
}
}

function wrapRange(cm, from, to, options) {
Expand Down Expand Up @@ -86,7 +88,8 @@
if (changes.length) cm.operation(function() {
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
cm.replaceRange(change.text, change.from, change.to);
if (change.text || CodeMirror.cmpPos(change.from, change.to))
cm.replaceRange(change.text, change.from, change.to);
}
});
return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
Expand Down
7 changes: 5 additions & 2 deletions demo/hardwrap.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ <h2>Hard-wrapping Demo</h2>
"Ctrl-Q": function(cm) { cm.wrapParagraph(cm.getCursor(), options); }
}
});
var wait, options = {column: 60};
var wait, options = {column: 60}, changing = false;
editor.on("change", function(cm, change) {
if (changing) return;
clearTimeout(wait);
wait = setTimeout(function() {
console.log(cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options));
changing = true;
cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options);
changing = false;
}, 200);
});
</script>
Expand Down
Loading