Showing with 1,946 additions and 1,213 deletions.
  1. +3 −0 AUTHORS
  2. +1 −1 README.md
  3. +3 −1 addon/dialog/dialog.js
  4. +144 −121 addon/edit/closebrackets.js
  5. +4 −2 addon/fold/foldgutter.js
  6. +4 −0 addon/hint/css-hint.js
  7. +13 −8 addon/hint/sql-hint.js
  8. +2 −0 addon/lint/lint.js
  9. +40 −0 addon/merge/merge.js
  10. +8 −2 addon/scroll/simplescrollbars.js
  11. +1 −1 addon/tern/tern.js
  12. +1 −1 bower.json
  13. +4 −1 doc/compress.html
  14. +20 −6 doc/manual.html
  15. +26 −6 doc/releases.html
  16. +1 −1 index.html
  17. +13 −0 keymap/sublime.js
  18. +43 −54 keymap/vim.js
  19. +11 −8 lib/codemirror.css
  20. +104 −64 lib/codemirror.js
  21. +73 −0 mode/asciiarmor/asciiarmor.js
  22. +46 −0 mode/asciiarmor/index.html
  23. +2 −1 mode/clike/clike.js
  24. +1 −0 mode/clojure/clojure.js
  25. +97 −0 mode/cmake/cmake.js
  26. +129 −0 mode/cmake/index.html
  27. +1 −0 mode/commonlisp/commonlisp.js
  28. +1 −0 mode/css/css.js
  29. +1 −1 mode/css/less.html
  30. +1 −1 mode/css/scss.html
  31. +1 −0 mode/groovy/groovy.js
  32. +18 −76 mode/htmlembedded/htmlembedded.js
  33. +1 −0 mode/htmlembedded/index.html
  34. +3 −2 mode/index.html
  35. +5 −0 mode/javascript/javascript.js
  36. +1 −0 mode/kotlin/kotlin.js
  37. +4 −2 mode/meta.js
  38. +1 −1 mode/mllike/mllike.js
  39. +1 −1 mode/properties/properties.js
  40. +1 −0 mode/python/python.js
  41. +1 −1 mode/sass/sass.js
  42. +1 −0 mode/scheme/scheme.js
  43. +39 −37 mode/smarty/index.html
  44. +100 −107 mode/smarty/smarty.js
  45. +0 −114 mode/smartymixed/index.html
  46. +0 −197 mode/smartymixed/smartymixed.js
  47. +5 −3 mode/stylus/index.html
  48. +651 −332 mode/stylus/stylus.js
  49. +146 −0 mode/troff/index.html
  50. +82 −0 mode/troff/troff.js
  51. +6 −5 mode/vb/vb.js
  52. +53 −53 mode/verilog/verilog.js
  53. +1 −1 package.json
  54. +7 −0 test/test.js
  55. +19 −0 test/vim_test.js
  56. +1 −1 theme/mdn-like.css
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Christian Petrov
Christopher Brown
ciaranj
CodeAnimal
coderaiser
ComFreek
Curtis Gagliardi
dagsta
Expand Down Expand Up @@ -230,6 +231,7 @@ jwallers@gmail.com
kaniga
Ken Newman
Ken Rockot
Kevin Earls
Kevin Sawicki
Kevin Ushey
Klaus Silveira
Expand Down Expand Up @@ -351,6 +353,7 @@ Randall Mason
Randy Burden
Randy Edmunds
Rasmus Erik Voel Jensen
ray ratchup
Ray Ratchup
Richard van der Meer
Richard Z.H. Wang
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# CodeMirror
[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](https://marijnhaverbeke.nl/fund/)
[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?again)](https://marijnhaverbeke.nl/fund/)

CodeMirror is a JavaScript component that provides a code editor in
the browser. When a mode is available for the language you are coding
Expand Down
4 changes: 3 additions & 1 deletion addon/dialog/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
if (inp) {
if (options.value) {
inp.value = options.value;
inp.select();
if (options.selectValueOnOpen !== false) {
inp.select();
}
}

if (options.onInput)
Expand Down
265 changes: 144 additions & 121 deletions addon/edit/closebrackets.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,157 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var DEFAULT_BRACKETS = "()[]{}''\"\"";
var DEFAULT_TRIPLES = "'\"";
var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
var SPACE_CHAR_REGEX = /\s/;
var defaults = {
pairs: "()[]{}''\"\"",
triples: "",
explode: "[]{}"
};

var Pos = CodeMirror.Pos;

CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
if (old != CodeMirror.Init && old)
cm.removeKeyMap("autoCloseBrackets");
if (!val) return;
var pairs = DEFAULT_BRACKETS, triples = DEFAULT_TRIPLES, explode = DEFAULT_EXPLODE_ON_ENTER;
if (typeof val == "string") pairs = val;
else if (typeof val == "object") {
if (val.pairs != null) pairs = val.pairs;
if (val.triples != null) triples = val.triples;
if (val.explode != null) explode = val.explode;
if (old && old != CodeMirror.Init) {
cm.removeKeyMap(keyMap);
cm.state.closeBrackets = null;
}
if (val) {
cm.state.closeBrackets = val;
cm.addKeyMap(keyMap);
}
var map = buildKeymap(pairs, triples);
if (explode) map.Enter = buildExplodeHandler(explode);
cm.addKeyMap(map);
});

function getOption(conf, name) {
if (name == "pairs" && typeof conf == "string") return conf;
if (typeof conf == "object" && conf[name] != null) return conf[name];
return defaults[name];
}

var bind = defaults.pairs + "`";
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
for (var i = 0; i < bind.length; i++)
keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));

function handler(ch) {
return function(cm) { return handleChar(cm, ch); };
}

function getConfig(cm) {
var deflt = cm.state.closeBrackets;
if (!deflt) return null;
var mode = cm.getModeAt(cm.getCursor());
return mode.closeBrackets || deflt;
}

function handleBackspace(cm) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;

var pairs = getOption(conf, "pairs");
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
}
}

function handleEnter(cm) {
var conf = getConfig(cm);
var explode = conf && getOption(conf, "explode");
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;

var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
}

function handleChar(cm, ch) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;

var pairs = getOption(conf, "pairs");
var pos = pairs.indexOf(ch);
if (pos == -1) return CodeMirror.Pass;
var triples = getOption(conf, "triples");

var identical = pairs.charAt(pos + 1) == ch;
var ranges = cm.listSelections();
var opening = pos % 2 == 0;

var type, next;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (opening && !range.empty()) {
curType = "surround";
} else if ((identical || !opening) && next == ch) {
if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
curType = "skipThree";
else
curType = "skip";
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
curType = "addFour";
} else if (identical) {
if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
else return CodeMirror.Pass;
} else if (opening && (cm.getLine(cur.line).length == cur.ch ||
isClosingBracket(next, pairs) ||
/\s/.test(next))) {
curType = "both";
} else {
return CodeMirror.Pass;
}
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}

var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
}

function isClosingBracket(ch, pairs) {
var pos = pairs.lastIndexOf(ch);
return pos > -1 && pos % 2 == 1;
}

function charsAround(cm, pos) {
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
Pos(pos.line, pos.ch + 1));
Expand All @@ -53,109 +181,4 @@
stream.start = stream.pos;
}
}

function buildKeymap(pairs, triples) {
var map = {
name : "autoCloseBrackets",
Backspace: function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
}
}
};
var closingBrackets = "";
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
closingBrackets += right;
map["'" + left + "'"] = function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), type, next;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (!range.empty()) {
curType = "surround";
} else if (left == right && next == right) {
if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left)
curType = "skipThree";
else
curType = "skip";
} else if (left == right && cur.ch > 1 && triples.indexOf(left) >= 0 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left &&
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != left)) {
curType = "addFour";
} else if (left == '"' || left == "'") {
if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, left)) curType = "both";
else return CodeMirror.Pass;
} else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next)) {
curType = "both";
} else {
return CodeMirror.Pass;
}
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}

cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
};
if (left != right) map["'" + right + "'"] = function(cm) {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (!range.empty() ||
cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right)
return CodeMirror.Pass;
}
cm.execCommand("goCharRight");
};
})(pairs.charAt(i), pairs.charAt(i + 1));
return map;
}

function buildExplodeHandler(pairs) {
return function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
};
}
});
6 changes: 4 additions & 2 deletions addon/fold/foldgutter.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
function isFolded(cm, line) {
var marks = cm.findMarksAt(Pos(line));
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold && marks[i].find().from.line == line) return true;
if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
}

function marker(spec) {
Expand Down Expand Up @@ -98,7 +98,9 @@
if (!state) return;
var opts = state.options;
if (gutter != opts.gutter) return;
cm.foldCode(Pos(line, 0), opts.rangeFinder);
var folded = isFolded(cm, line);
if (folded) folded.clear();
else cm.foldCode(Pos(line, 0), opts.rangeFinder);
}

function onChange(cm) {
Expand Down
4 changes: 4 additions & 0 deletions addon/hint/css-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
if (inner.mode.name != "css") return;

if (token.type == "keyword" && "!important".indexOf(token.string) == 0)
return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)};

var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
if (/[^\w$_-]/.test(word)) {
word = ""; start = end = cur.ch;
Expand Down
Loading