From 01b8a8860c29a4d5e3aace33250159d2ccf64d7f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 21 Aug 2014 23:03:46 +0200 Subject: [PATCH 01/34] Bump version number post-4.5.0 --- bower.json | 2 +- doc/manual.html | 2 +- lib/codemirror.js | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index 9cf2abecfe..534021cc1e 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"4.5.0", + "version":"4.5.1", "main": ["lib/codemirror.js", "lib/codemirror.css"], "ignore": [ "**/.*", diff --git a/doc/manual.html b/doc/manual.html index a511d9bc5b..a81e7d2791 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -63,7 +63,7 @@

User manual and reference guide - version 4.5.0 + version 4.5.1

CodeMirror is a code-editor component that can be embedded in diff --git a/lib/codemirror.js b/lib/codemirror.js index 61e8c41eb3..34eaeebe18 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -7825,7 +7825,7 @@ // THE END - CodeMirror.version = "4.5.0"; + CodeMirror.version = "4.5.1"; return CodeMirror; }); diff --git a/package.json b/package.json index 47f05587aa..34a1ecb52a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"4.5.0", + "version":"4.5.1", "main": "lib/codemirror.js", "description": "In-browser code editing made bearable", "licenses": [{"type": "MIT", From b62d6b0e84c879326cff987ea5fe08e69e9fe818 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 23 Aug 2014 22:05:18 +0200 Subject: [PATCH 02/34] Bound retry count in measureCharInner hack for wrapping characters --- lib/codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 34eaeebe18..c5c0443601 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -1646,7 +1646,7 @@ var rect; if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. - for (;;) { + for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start; while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end; if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) { From b3134823f85e3d87193614110554d6670d4cf094 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 23 Aug 2014 22:07:06 +0200 Subject: [PATCH 03/34] Work around odd safari behavior in bad bidi rect feature detection Issue #2780 --- lib/codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index c5c0443601..2c3b17df67 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -7462,7 +7462,7 @@ if (badBidiRects != null) return badBidiRects; var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); var r0 = range(txt, 0, 1).getBoundingClientRect(); - if (r0.left == r0.right) return false; + if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) var r1 = range(txt, 1, 2).getBoundingClientRect(); return badBidiRects = (r1.right - r0.right < 3); } From 76db4c110b6f20a190958aeb4e341fd91a964b13 Mon Sep 17 00:00:00 2001 From: Nick Small Date: Thu, 21 Aug 2014 18:12:00 -0400 Subject: [PATCH 04/34] [dialog addon] Document openDialog options and openNotification function --- addon/dialog/dialog.js | 2 ++ doc/manual.html | 45 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/addon/dialog/dialog.js b/addon/dialog/dialog.js index 946040cb91..56aaf3e4e1 100644 --- a/addon/dialog/dialog.js +++ b/addon/dialog/dialog.js @@ -145,5 +145,7 @@ }); if (duration) doneTimer = setTimeout(close, options.duration); + + return close; }); }); diff --git a/doc/manual.html b/doc/manual.html index a81e7d2791..6069fa6aea 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -2053,14 +2053,43 @@

Static properties

dialog/dialog.js
Provides a very simple way to query users for text input. - Adds an openDialog method to - CodeMirror instances, which can be called with an HTML fragment - or a detached DOM node that provides the prompt (should include - an input tag), and a callback function that is called - when text has been entered. Also adds - an openNotification function that - simply shows an HTML fragment as a notification. Depends - on addon/dialog/dialog.css.
+ Adds the openDialog(template, callback, options) → + closeFunction method to CodeMirror instances, + which can be called with an HTML fragment or a detached DOM + node that provides the prompt (should include an input + or button tag), and a callback function that is called + when the user presses enter. It returns a function closeFunction + which, if called, will close the dialog immediately. + openDialog takes the following options: +
+
closeOnEnter:
+
If true, the dialog will be closed when the user presses + enter in the input. Defaults to true.
+
onKeyDown:
+
An event handler of the signature (event, value, closeFunction) + that will be called whenever keydown fires in the + dialog's input. If your callback returns true, + the dialog will not do any further processing of the event.
+
onKeyUp:
+
Same as onKeyDown but for the + keyup event.
+
onInput:
+
Same as onKeyDown but for the + input event.
+
onClose:
+
A callback of the signature (dialogInstance) + that will be called after the dialog has been closed and + removed from the DOM. No return value.
+
+ +

Also adds an openNotification(template, options) → + closeFunction function that simply shows an HTML + fragment as a notification at the top of the editor. It takes a + single option: duration, the amount of time after + which the notification will be automatically closed. If + duration is zero, the dialog will not be closed automatically.

+ +

Depends on addon/dialog/dialog.css.

search/searchcursor.js
Adds the getSearchCursor(query, start, caseFold) → From 5e0692ffd181a1aa935e637ce918cc796fa45039 Mon Sep 17 00:00:00 2001 From: Nick Small Date: Thu, 21 Aug 2014 18:20:22 -0400 Subject: [PATCH 05/34] [dialog addon] Fix default openNotification duration --- addon/dialog/dialog.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addon/dialog/dialog.js b/addon/dialog/dialog.js index 56aaf3e4e1..35a6103c2d 100644 --- a/addon/dialog/dialog.js +++ b/addon/dialog/dialog.js @@ -129,8 +129,8 @@ CodeMirror.defineExtension("openNotification", function(template, options) { closeNotification(this, close); var dialog = dialogDiv(this, template, options && options.bottom); - var duration = options && (options.duration === undefined ? 5000 : options.duration); var closed = false, doneTimer; + var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; function close() { if (closed) return; @@ -143,8 +143,9 @@ CodeMirror.e_preventDefault(e); close(); }); + if (duration) - doneTimer = setTimeout(close, options.duration); + doneTimer = setTimeout(close, duration); return close; }); From bcb3737540279128a2e42194f9b76f4237e36549 Mon Sep 17 00:00:00 2001 From: lochel Date: Fri, 15 Aug 2014 13:38:35 +0200 Subject: [PATCH 06/34] [modelica mode] Add --- doc/compress.html | 1 + mode/index.html | 1 + mode/meta.js | 1 + mode/modelica/index.html | 67 +++++++++++++ mode/modelica/modelica.js | 245 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 315 insertions(+) create mode 100644 mode/modelica/index.html create mode 100644 mode/modelica/modelica.js diff --git a/doc/compress.html b/doc/compress.html index 46c102af47..e4178a2d80 100644 --- a/doc/compress.html +++ b/doc/compress.html @@ -131,6 +131,7 @@ + diff --git a/mode/index.html b/mode/index.html index 1c106ae8e0..e3339ad085 100644 --- a/mode/index.html +++ b/mode/index.html @@ -71,6 +71,7 @@
  • Lua
  • Markdown (GitHub-flavour)
  • mIRC
  • +
  • Modelica
  • Nginx
  • NTriples
  • OCaml
  • diff --git a/mode/meta.js b/mode/meta.js index e3c32b6f6c..d8ddd474c5 100644 --- a/mode/meta.js +++ b/mode/meta.js @@ -62,6 +62,7 @@ CodeMirror.modeInfo = [ {name: "Lua", mime: "text/x-lua", mode: "lua"}, {name: "Markdown (GitHub-flavour)", mime: "text/x-markdown", mode: "markdown"}, {name: "mIRC", mime: "text/mirc", mode: "mirc"}, + {name: "Modelica", mime: "text/x-modelica", mode: "modelica"}, {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx"}, {name: "NTriples", mime: "text/n-triples", mode: "ntriples"}, {name: "OCaml", mime: "text/x-ocaml", mode: "mllike"}, diff --git a/mode/modelica/index.html b/mode/modelica/index.html new file mode 100644 index 0000000000..eb4f08c57d --- /dev/null +++ b/mode/modelica/index.html @@ -0,0 +1,67 @@ + + +CodeMirror: Modelica mode + + + + + + + + + + + + +
    +

    Modelica mode

    + +
    + + + +

    Simple mode that tries to handle Modelica as well as it can.

    + +

    MIME types defined: text/x-modelica + (Modlica code).

    +
    diff --git a/mode/modelica/modelica.js b/mode/modelica/modelica.js new file mode 100644 index 0000000000..77ec7a3c18 --- /dev/null +++ b/mode/modelica/modelica.js @@ -0,0 +1,245 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Modelica support for CodeMirror, copyright (c) by Lennart Ochel + +(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("modelica", function(config, parserConfig) { + + var indentUnit = config.indentUnit; + var keywords = parserConfig.keywords || {}; + var builtin = parserConfig.builtin || {}; + var atoms = parserConfig.atoms || {}; + + var isSingleOperatorChar = /[;=\(:\),{}.*<>+\-\/^\[\]]/; + var isDoubleOperatorChar = /(:=|<=|>=|==|<>|\.\+|\.\-|\.\*|\.\/|\.\^)/; + var isDigit = /[0-9]/; + var isNonDigit = /[_a-zA-Z]/; + + function tokenLineComment(stream, state) { + stream.skipToEnd(); + state.tokenize = null; + return "comment"; + } + + function tokenBlockComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (maybeEnd && ch == "/") { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function tokenString(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == '"' && !escaped) { + state.tokenize = null; + state.sol = false; + break; + } + escaped = !escaped && ch == "\\"; + } + + return "string"; + } + + function tokenIdent(stream, state) { + stream.eatWhile(isDigit); + while (stream.eat(isDigit) || stream.eat(isNonDigit)) { } + + + var cur = stream.current(); + + if(state.sol && (cur == "package" || cur == "model" || cur == "when" || cur == "connector")) state.level++; + else if(state.sol && cur == "end" && state.level > 0) state.level--; + + state.tokenize = null; + state.sol = false; + + if (keywords.propertyIsEnumerable(cur)) return "keyword"; + else if (builtin.propertyIsEnumerable(cur)) return "builtin"; + else if (atoms.propertyIsEnumerable(cur)) return "atom"; + else return "variable"; + } + + function tokenQIdent(stream, state) { + while (stream.eat(/[^']/)) { } + + state.tokenize = null; + state.sol = false; + + if(stream.eat("'")) + return "variable"; + else + return "error"; + } + + function tokenUnsignedNuber(stream, state) { + stream.eatWhile(isDigit); + if (stream.eat('.')) { + stream.eatWhile(isDigit); + } + if (stream.eat('e') || stream.eat('E')) { + if (!stream.eat('-')) + stream.eat('+'); + stream.eatWhile(isDigit); + } + + state.tokenize = null; + state.sol = false; + return "number"; + } + + // Interface + return { + startState: function() { + return { + tokenize: null, + level: 0, + sol: true + }; + }, + + token: function(stream, state) { + if(state.tokenize != null) { + return state.tokenize(stream, state); + } + + if(stream.sol()) { + state.sol = true; + } + + // WHITESPACE + if(stream.eatSpace()) { + state.tokenize = null; + return null; + } + + var ch = stream.next(); + + // LINECOMMENT + if(ch == '/' && stream.eat('/')) { + state.tokenize = tokenLineComment; + } + // BLOCKCOMMENT + else if(ch == '/' && stream.eat('*')) { + state.tokenize = tokenBlockComment; + } + // TWO SYMBOL TOKENS + else if(isDoubleOperatorChar.test(ch+stream.peek())) { + stream.next(); + state.tokenize = null; + return "operator"; + } + // SINGLE SYMBOL TOKENS + else if(isSingleOperatorChar.test(ch)) { + state.tokenize = null; + return "operator"; + } + // IDENT + else if(isNonDigit.test(ch)) { + state.tokenize = tokenIdent; + } + // Q-IDENT + else if(ch == "'" && stream.peek() && stream.peek() != "'") { + state.tokenize = tokenQIdent; + } + // STRING + else if(ch == '"') { + state.tokenize = tokenString; + } + // UNSIGNED_NUBER + else if(isDigit.test(ch)) { + state.tokenize = tokenUnsignedNuber; + } + // ERROR + else { + state.tokenize = null; + return "error"; + } + + return state.tokenize(stream, state); + }, + + indent: function(state, textAfter) { + if (state.tokenize != null) return CodeMirror.Pass; + + var level = state.level; + if(/(algorithm)/.test(textAfter)) level--; + if(/(equation)/.test(textAfter)) level--; + if(/(initial algorithm)/.test(textAfter)) level--; + if(/(initial equation)/.test(textAfter)) level--; + if(/(end)/.test(textAfter)) level--; + + if(level > 0) + return indentUnit*level; + else + return 0; + }, + + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//" + }; + }); + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i=0; i Date: Wed, 27 Aug 2014 00:39:53 -0700 Subject: [PATCH 07/34] [python mode] Make 'in' a keyword --- mode/python/python.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mode/python/python.js b/mode/python/python.js index 45dd63ba48..4e1f296ae1 100644 --- a/mode/python/python.js +++ b/mode/python/python.js @@ -15,12 +15,12 @@ return new RegExp("^((" + words.join(")|(") + "))\\b"); } - var wordOperators = wordRegexp(["and", "or", "not", "is", "in"]); + var wordOperators = wordRegexp(["and", "or", "not", "is"]); var commonKeywords = ["as", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", "finally", "for", "from", "global", "if", "import", "lambda", "pass", "raise", "return", - "try", "while", "with", "yield"]; + "try", "while", "with", "yield", "in"]; var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr", "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod", "enumerate", "eval", "filter", "float", "format", "frozenset", From 43379968f6a62b89e2b350acd9174971e3e50706 Mon Sep 17 00:00:00 2001 From: Hiroyuki Makino Date: Thu, 28 Aug 2014 23:03:04 +0900 Subject: [PATCH 08/34] [release notes] Fix section structure --- doc/releases.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/releases.html b/doc/releases.html index 4b6d384b9e..f88a0373a6 100644 --- a/doc/releases.html +++ b/doc/releases.html @@ -25,9 +25,9 @@

    Release notes and version history

    -
    +
    -

    Version 4.x

    +

    Version 4.x

    21-08-2014: Version 4.5:

    @@ -114,7 +114,11 @@

    Version 4.x

  • Full list of patches.
  • -

    Version 3.x

    +
    + +
    + +

    Version 3.x

    22-04-2014: Version 3.24:

    From 3d8c1e506fd80feeb28a873a6dc6d1087d82327a Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 1 Sep 2014 13:32:06 +0200 Subject: [PATCH 09/34] Export findWordAt Closes #2790 --- doc/manual.html | 4 ++++ lib/codemirror.js | 42 +++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/doc/manual.html b/doc/manual.html index 6069fa6aea..02f3a59aaf 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -1312,6 +1312,10 @@

    Cursor and selection methods

    be "line" or "page". The other arguments and the returned value have the same interpretation as they have in findPosH.
    + +
    cm.findWordAt(pos: {line, ch}) → {anchor: {line, ch}, head: {line, ch}}
    +
    Returns the start and end of the 'word' (the stretch of + letters, whitespace, or punctuation) at the given position.

    Configuration methods

    diff --git a/lib/codemirror.js b/lib/codemirror.js index 2c3b17df67..4270b98a45 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -2528,7 +2528,7 @@ var pos = posFromMouse(cm, e); if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; e_preventDefault(e); - var word = findWordAt(cm, pos); + var word = cm.findWordAt(pos); extendSelection(cm.doc, word.anchor, word.head); })); else @@ -2807,7 +2807,7 @@ start = posFromMouse(cm, e, true, true); ourIndex = -1; } else if (type == "double") { - var word = findWordAt(cm, start); + var word = cm.findWordAt(start); if (cm.display.shift || doc.extend) ourRange = extendRange(doc, ourRange, word.anchor, word.head); else @@ -2861,7 +2861,7 @@ var anchor = oldRange.anchor, head = pos; if (type != "single") { if (type == "double") - var range = findWordAt(cm, pos); + var range = cm.findWordAt(pos); else var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); if (cmp(range.anchor, anchor) > 0) { @@ -3999,24 +3999,6 @@ return target; } - // Find the word at the given position (as returned by coordsChar). - function findWordAt(cm, pos) { - var doc = cm.doc, line = getLine(doc, pos.line).text; - var start = pos.ch, end = pos.ch; - if (line) { - var helper = cm.getHelper(pos, "wordChars"); - if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; - var startChar = line.charAt(start); - var check = isWordChar(startChar, helper) - ? function(ch) { return isWordChar(ch, helper); } - : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} - : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; - while (start > 0 && check(line.charAt(start - 1))) --start; - while (end < line.length && check(line.charAt(end))) ++end; - } - return new Range(Pos(pos.line, start), Pos(pos.line, end)); - } - // EDITOR METHODS // The publicly visible API. Note that methodOp(f) means @@ -4358,6 +4340,24 @@ doc.sel.ranges[i].goalColumn = goals[i]; }), + // Find the word at the given position (as returned by coordsChar). + findWordAt: function(pos) { + var doc = this.doc, line = getLine(doc, pos.line).text; + var start = pos.ch, end = pos.ch; + if (line) { + var helper = this.getHelper(pos, "wordChars"); + if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; + var startChar = line.charAt(start); + var check = isWordChar(startChar, helper) + ? function(ch) { return isWordChar(ch, helper); } + : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} + : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; + while (start > 0 && check(line.charAt(start - 1))) --start; + while (end < line.length && check(line.charAt(end))) ++end; + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)); + }, + toggleOverwrite: function(value) { if (value != null && value == this.state.overwrite) return; if (this.state.overwrite = !this.state.overwrite) From 9b87ca9ca4f8c81f84ff755e921ddaf3aa7373fc Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 1 Sep 2014 13:34:35 +0200 Subject: [PATCH 10/34] [merge addon] Add diff_match_patch as explicit dependency Closes #2783 --- addon/merge/merge.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addon/merge/merge.js b/addon/merge/merge.js index d9b277664b..da3ea47ccf 100644 --- a/addon/merge/merge.js +++ b/addon/merge/merge.js @@ -1,17 +1,17 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: http://codemirror.net/LICENSE +// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL + (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); + mod(require("../../lib/codemirror"), require("diff_match_patch")); else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); + define(["../../lib/codemirror", "diff_match_patch"], mod); else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { + mod(CodeMirror, diff_match_patch); +})(function(CodeMirror, diff_match_patch) { "use strict"; - // declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL - var Pos = CodeMirror.Pos; var svgNS = "http://www.w3.org/2000/svg"; From 59b7b9082be50d51e9b5589e6957668c5d3cb35a Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 1 Sep 2014 13:44:22 +0200 Subject: [PATCH 11/34] Add Hebrew code range to nonASCIISingleCaseWordChar regexp Fixes detection of Hebrew letters as word characters Closes #2789 --- lib/codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 4270b98a45..f06b99bd72 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -7295,7 +7295,7 @@ return function(){return f.apply(null, args);}; } - var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var nonASCIISingleCaseWordChar = /[\u00df\u0590-\u05f4\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; var isWordCharBasic = CodeMirror.isWordChar = function(ch) { return /\w/.test(ch) || ch > "\x80" && (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); From 623eb7badb58f5d7bc9bbd836f86f046180e2a1c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 1 Sep 2014 17:59:23 +0200 Subject: [PATCH 12/34] Force scroll update from swapDoc Issue #2714 --- lib/codemirror.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index f06b99bd72..c865bc560b 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -2090,11 +2090,11 @@ display.wheelStartX = display.wheelStartY = null; // Propagate the scroll position to the actual DOM scroller - if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) { + if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top; } - if (op.scrollLeft != null && display.scroller.scrollLeft != op.scrollLeft) { + if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left; alignHorizontally(cm); @@ -4444,6 +4444,7 @@ clearCaches(this); resetInput(this); this.scrollTo(doc.scrollLeft, doc.scrollTop); + this.curOp.forceScroll = true; signalLater(this, "swapDoc", this, old); return old; }), From 376f3ec90d05272459bf0b79d4ff9005a284705e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 1 Sep 2014 18:04:52 +0200 Subject: [PATCH 13/34] [sass mode] Make sure indentCount is initialized propertly Issue #2786 --- mode/sass/sass.js | 1 + 1 file changed, 1 insertion(+) diff --git a/mode/sass/sass.js b/mode/sass/sass.js index 68df323e18..b792a02aa3 100644 --- a/mode/sass/sass.js +++ b/mode/sass/sass.js @@ -303,6 +303,7 @@ CodeMirror.defineMode("sass", function(config) { return { tokenizer: tokenBase, scopes: [{offset: 0, type: "sass"}], + indentCount: 0, definedVars: [], definedMixins: [] }; From cb5416f1229e2c8555784cb089916a5953c07b1b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 3 Sep 2014 08:36:11 +0200 Subject: [PATCH 14/34] [markdown mode] Fix handling of escaped characters Issue #2792 --- mode/markdown/markdown.js | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/mode/markdown/markdown.js b/mode/markdown/markdown.js index 81ed24e8d3..90a9282f85 100644 --- a/mode/markdown/markdown.js +++ b/mode/markdown/markdown.js @@ -360,15 +360,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { var ch = stream.next(); - if (state.escape) { - state.escape = false; - return getType(state); - } - if (ch === '\\') { - if (modeCfg.highlightFormatting) state.formatting = "escape"; - state.escape = true; - return getType(state); + stream.next(); + if (modeCfg.highlightFormatting) return getType(state) + " escape"; } // Matches link titles present on next line @@ -650,7 +644,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { inline: inlineNormal, text: handleText, - escape: false, formatting: false, linkText: false, linkHref: false, @@ -683,7 +676,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { inline: s.inline, text: s.text, - escape: false, formatting: false, linkTitle: s.linkTitle, em: s.em, @@ -718,9 +710,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { state.thisLineHasContent = true; } - // Reset state.escape - state.escape = false; - // Reset state.taskList state.taskList = false; From 31319ee225a60dcc750ba01a40e70bdedaaaafc7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 3 Sep 2014 08:42:11 +0200 Subject: [PATCH 15/34] [markdown mode] Make test pass --- mode/markdown/markdown.js | 5 ++++- mode/markdown/test.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mode/markdown/markdown.js b/mode/markdown/markdown.js index 90a9282f85..1bad78d65e 100644 --- a/mode/markdown/markdown.js +++ b/mode/markdown/markdown.js @@ -362,7 +362,10 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { if (ch === '\\') { stream.next(); - if (modeCfg.highlightFormatting) return getType(state) + " escape"; + if (modeCfg.highlightFormatting) { + var type = getType(state); + return type ? type + " formatting-escape" : "formatting-escape"; + } } // Matches link titles present on next line diff --git a/mode/markdown/test.js b/mode/markdown/test.js index 77a3b659c0..96ca1aefc7 100644 --- a/mode/markdown/test.js +++ b/mode/markdown/test.js @@ -54,7 +54,7 @@ "[link&formatting&formatting-link <][link user@example.com][link&formatting&formatting-link >]"); FT("formatting_escape", - "[formatting&formatting-escape \\]*"); + "[formatting-escape \\*]"); MT("plainText", "foo"); From f593e03a09a156f1a7824757beaa001369f11422 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 3 Sep 2014 22:23:25 +0200 Subject: [PATCH 16/34] Set a min height on the lines element to prevent collapsing of wrapper Issue #2765 --- lib/codemirror.css | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/codemirror.css b/lib/codemirror.css index c0897771aa..1ab8acb296 100644 --- a/lib/codemirror.css +++ b/lib/codemirror.css @@ -213,6 +213,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} .CodeMirror-lines { cursor: text; + min-height: 1px; /* prevents collapsing before first draw */ } .CodeMirror pre { /* Reset some styles that the rest of the page might have set */ From 17c992e979daf3a3aa75926d38144e3c9d4dc064 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 4 Sep 2014 08:44:24 +0200 Subject: [PATCH 17/34] Only apply IE<11 zooming compensation for client rects when getting rect from a range It does not happen when measuring a node Issue #2665 --- lib/codemirror.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index c865bc560b..151ee91a66 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -1665,6 +1665,7 @@ start = start - 1; collapse = "right"; } + if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); } else { // If it is a widget, simply get the box for the whole widget. if (start > 0) collapse = bias = "right"; var rects; @@ -1681,8 +1682,6 @@ rect = nullRect; } - if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); - var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; var mid = (rtop + rbot) / 2; var heights = prepared.view.measure.heights; From 616339b47245b3a044057afa460a3768ffa0369c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 8 Sep 2014 12:52:49 +0200 Subject: [PATCH 18/34] [closetag addon] Work better with htmlmixed mode It now closes script and style tags when the slash is typed Closes #2797 --- addon/edit/closetag.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/addon/edit/closetag.js b/addon/edit/closetag.js index 69ea4446be..a0bec7dd43 100644 --- a/addon/edit/closetag.js +++ b/addon/edit/closetag.js @@ -102,11 +102,25 @@ var pos = ranges[i].head, tok = cm.getTokenAt(pos); var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; if (tok.type == "string" || tok.string.charAt(0) != "<" || - tok.start != pos.ch - 1 || inner.mode.name != "xml" || - !state.context || !state.context.tagName || - closingTagExists(cm, state.context.tagName, pos, state)) + tok.start != pos.ch - 1) return CodeMirror.Pass; - replacements[i] = "/" + state.context.tagName + ">"; + // Kludge to get around the fact that we are not in XML mode + // when completing in JS/CSS snippet in htmlmixed mode. Does not + // work for other XML embedded languages (there is no general + // way to go from a mixed mode to its current XML state). + if (inner.mode.name != "xml") { + if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript") + replacements[i] = "/script>"; + else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css") + replacements[i] = "/style>"; + else + return CodeMirror.Pass; + } else { + if (!state.context || !state.context.tagName || + closingTagExists(cm, state.context.tagName, pos, state)) + return CodeMirror.Pass; + replacements[i] = "/" + state.context.tagName + ">"; + } } cm.replaceSelections(replacements); ranges = cm.listSelections(); From 7817708c3165f1ca376bdc7181df6d036cb90ad8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 8 Sep 2014 13:03:54 +0200 Subject: [PATCH 19/34] [javascript mode] Fix parsing of argument-less fat arrow functions Closes #2794 --- mode/javascript/javascript.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mode/javascript/javascript.js b/mode/javascript/javascript.js index 46616bc021..2e24d3a55b 100644 --- a/mode/javascript/javascript.js +++ b/mode/javascript/javascript.js @@ -391,7 +391,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function maybeoperatorNoComma(type, value, noComma) { var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; var expr = noComma == false ? expression : expressionNoComma; - if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); + if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); if (type == "operator") { if (/\+\+|--/.test(value)) return cont(me); if (value == "?") return cont(expression, expect(":"), expr); @@ -417,13 +417,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } function arrowBody(type) { findFatArrow(cx.stream, cx.state); - if (type == "{") return pass(statement); - return pass(expression); + return pass(type == "{" ? statement : expression); } function arrowBodyNoComma(type) { findFatArrow(cx.stream, cx.state); - if (type == "{") return pass(statement); - return pass(expressionNoComma); + return pass(type == "{" ? statement : expressionNoComma); } function maybelabel(type) { if (type == ":") return cont(poplex, statement); From 0a91c1427a2771a94731384f3537c78468be44f8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 8 Sep 2014 13:22:02 +0200 Subject: [PATCH 20/34] [smalltalk mode] Use \s instead of space in regexps that denote whitespace Closes #2796 --- mode/smalltalk/smalltalk.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mode/smalltalk/smalltalk.js b/mode/smalltalk/smalltalk.js index 50f41cc615..bb510ba2e1 100644 --- a/mode/smalltalk/smalltalk.js +++ b/mode/smalltalk/smalltalk.js @@ -53,7 +53,7 @@ CodeMirror.defineMode('smalltalk', function(config) { stream.next(); token = nextSymbol(stream, new Context(nextSymbol, context)); } else { - if (stream.eatWhile(/[^ .{}\[\]()]/)) + if (stream.eatWhile(/[^\s.{}\[\]()]/)) token.name = 'string-2'; else token.name = 'meta'; @@ -61,7 +61,7 @@ CodeMirror.defineMode('smalltalk', function(config) { } else if (aChar === '$') { if (stream.next() === '<') { - stream.eatWhile(/[^ >]/); + stream.eatWhile(/[^\s>]/); stream.next(); } token.name = 'string-2'; From 1adaa01dbf7fb030b61731314dd245d9dbf8014e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 9 Sep 2014 16:22:11 +0200 Subject: [PATCH 21/34] Add a requireJS demo --- addon/hint/html-hint.js | 4 ++-- demo/requirejs.html | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 demo/requirejs.html diff --git a/addon/hint/html-hint.js b/addon/hint/html-hint.js index addd9b7bc0..992218f288 100755 --- a/addon/hint/html-hint.js +++ b/addon/hint/html-hint.js @@ -3,9 +3,9 @@ (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); + mod(require("../../lib/codemirror", "./xml-hint")); else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); + define(["../../lib/codemirror", "./xml-hint"], mod); else // Plain browser env mod(CodeMirror); })(function(CodeMirror) { diff --git a/demo/requirejs.html b/demo/requirejs.html new file mode 100644 index 0000000000..6399f8d769 --- /dev/null +++ b/demo/requirejs.html @@ -0,0 +1,52 @@ + + + + CodeMirror: HTML completion demo + + + + + + + + + + + + +
    +

    RequireJS module loading demo

    + +

    This demo does the same thing as + the HTML5 completion demo, but + loads its dependencies + with Require.js, rather than + explicitly. Press ctrl-space to activate + completion.

    + +
    + + +
    + From c012f411ee01c9802d046c2d76dc3b4b0001d67b Mon Sep 17 00:00:00 2001 From: Marcel Gerber Date: Tue, 9 Sep 2014 12:23:51 +0200 Subject: [PATCH 22/34] Improve isWordChar() for Arabic language --- lib/codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 151ee91a66..ea2caaff62 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -7295,7 +7295,7 @@ return function(){return f.apply(null, args);}; } - var nonASCIISingleCaseWordChar = /[\u00df\u0590-\u05f4\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var nonASCIISingleCaseWordChar = /[\u00df\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; var isWordCharBasic = CodeMirror.isWordChar = function(ch) { return /\w/.test(ch) || ch > "\x80" && (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); From 8fac50ac265de832e08d428faffb36d464cb5bda Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 15 Sep 2014 11:32:38 +0200 Subject: [PATCH 23/34] Fix handling of electricChars in multi-line edits Closes #2804 --- lib/codemirror.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index ea2caaff62..246492a9fb 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -2456,16 +2456,16 @@ cm.options.smartIndent && range.head.ch < 100 && (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) { var mode = cm.getModeAt(range.head); + var end = changeEnd(changeEvent); if (mode.electricChars) { for (var j = 0; j < mode.electricChars.length; j++) if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { - indentLine(cm, range.head.line, "smart"); + indentLine(cm, end.line, "smart"); break; } } else if (mode.electricInput) { - var end = changeEnd(changeEvent); if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch))) - indentLine(cm, range.head.line, "smart"); + indentLine(cm, end.line, "smart"); } } } From c2ee5a6ec55f4542adc9838b467861019a3cad9b Mon Sep 17 00:00:00 2001 From: Marko Bonaci Date: Fri, 12 Sep 2014 19:14:38 +0200 Subject: [PATCH 24/34] Make parentheses visible while under `matchingbracket` rule Code: Brackets now become black when they are highlighted as "matching". JSON: key names are now in "white" (json was a bit saturated with orange - keys and string values). Cleanup: removed some unnecessary rules. Default face color normalized to #ffffec (was #ffffe9). --- theme/mbo.css | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/theme/mbo.css b/theme/mbo.css index 6cb2b18d9b..0ad6360b50 100644 --- a/theme/mbo.css +++ b/theme/mbo.css @@ -1,6 +1,10 @@ -/* Based on mbonaci's Brackets mbo theme */ +/****************************************************************/ +/* Based on mbonaci's Brackets mbo theme */ +/* https://github.com/mbonaci/global/blob/master/Mbo.tmTheme */ +/* Create your own: http://tmtheme-editor.herokuapp.com */ +/****************************************************************/ -.cm-s-mbo.CodeMirror {background: #2c2c2c; color: #ffffe9;} +.cm-s-mbo.CodeMirror {background: #2c2c2c; color: #ffffec;} .cm-s-mbo div.CodeMirror-selected {background: #716C62 !important;} .cm-s-mbo .CodeMirror-gutters {background: #4e4e4e; border-right: 0px;} .cm-s-mbo .CodeMirror-guttermarker { color: white; } @@ -15,6 +19,7 @@ .cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute {color: #9ddfe9;} .cm-s-mbo span.cm-keyword {color: #ffb928;} .cm-s-mbo span.cm-string {color: #ffcf6c;} +.cm-s-mbo span.cm-string.cm-property {color: #ffffec;} .cm-s-mbo span.cm-variable {color: #ffffec;} .cm-s-mbo span.cm-variable-2 {color: #00a8c6;} @@ -23,17 +28,8 @@ .cm-s-mbo span.cm-tag {color: #9ddfe9;} .cm-s-mbo span.cm-link {color: #f54b07;} .cm-s-mbo span.cm-error {border-bottom: #636363; color: #ffffec;} +.cm-s-mbo span.cm-qualifier {color: #ffffec;} .cm-s-mbo .CodeMirror-activeline-background {background: #494b41 !important;} -.cm-s-mbo .CodeMirror-matchingbracket { - text-decoration: underline; - color: #f5e107 !important; - } - -.cm-s-mbo .CodeMirror-matchingtag { background: rgba(255, 255, 255, .37); } - -.cm-s-mbo span.cm-searching { - background-color: none; - background: none; - box-shadow: 0 0 0 1px #ffffec; -} +.cm-s-mbo .CodeMirror-matchingbracket {color: #222 !important;} +.cm-s-mbo .CodeMirror-matchingtag {background: rgba(255, 255, 255, .37);} From fcacef102486908b4331c8db9dc084daff7562bd Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 15 Sep 2014 15:29:33 +0200 Subject: [PATCH 25/34] [show-hint addon] Give active hint color more precedence To make it easy for client code to color completions without clashing with the selected styling. --- addon/hint/show-hint.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/hint/show-hint.css b/addon/hint/show-hint.css index 8a4ff052e3..924e638f7f 100644 --- a/addon/hint/show-hint.css +++ b/addon/hint/show-hint.css @@ -32,7 +32,7 @@ cursor: pointer; } -.CodeMirror-hint-active { +li.CodeMirror-hint-active { background: #08f; color: white; } From 640fbb28abf7dc4014c8c5ee6efe9309c091a98a Mon Sep 17 00:00:00 2001 From: snasa Date: Mon, 15 Sep 2014 22:30:25 -0700 Subject: [PATCH 26/34] Update shell.js --- mode/shell/shell.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mode/shell/shell.js b/mode/shell/shell.js index 77be75b97d..8e31f6f30b 100644 --- a/mode/shell/shell.js +++ b/mode/shell/shell.js @@ -128,7 +128,8 @@ CodeMirror.defineMode('shell', function() { startState: function() {return {tokens:[]};}, token: function(stream, state) { return tokenize(stream, state); - } + }, + lineComment: '#' }; }); From f09b6c5ec7bf2d7a7b2ee1ac8cc5c53b27f76f62 Mon Sep 17 00:00:00 2001 From: Daniele Di Sarli Date: Mon, 1 Sep 2014 21:53:17 +0200 Subject: [PATCH 27/34] Added wordsOnly option. Updated documentation. --- addon/search/match-highlighter.js | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/addon/search/match-highlighter.js b/addon/search/match-highlighter.js index 14dd4d4184..e9a22721f7 100644 --- a/addon/search/match-highlighter.js +++ b/addon/search/match-highlighter.js @@ -8,12 +8,15 @@ // document. // // The option can be set to true to simply enable it, or to a -// {minChars, style, showToken} object to explicitly configure it. -// minChars is the minimum amount of characters that should be +// {minChars, style, wordsOnly, showToken, delay} object to explicitly +// configure it. minChars is the minimum amount of characters that should be // selected for the behavior to occur, and style is the token style to // apply to the matches. This will be prefixed by "cm-" to create an -// actual CSS class name. showToken, when enabled, will cause the -// current token to be highlighted when nothing is selected. +// actual CSS class name. If wordsOnly is enabled, the matches will be +// highlighted only if the selected text is a word. showToken, when enabled, +// will cause the current token to be highlighted when nothing is selected. +// delay is used to specify how much time to wait, in milliseconds, before +// highlighting the matches. (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -28,6 +31,7 @@ var DEFAULT_MIN_CHARS = 2; var DEFAULT_TOKEN_STYLE = "matchhighlight"; var DEFAULT_DELAY = 100; + var DEFAULT_WORDS_ONLY = false; function State(options) { if (typeof options == "object") { @@ -35,10 +39,12 @@ this.style = options.style; this.showToken = options.showToken; this.delay = options.delay; + this.wordsOnly = options.wordsOnly; } if (this.style == null) this.style = DEFAULT_TOKEN_STYLE; if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS; if (this.delay == null) this.delay = DEFAULT_DELAY; + if (this.wordsOnly == null) this.wordsOnly = DEFAULT_WORDS_ONLY; this.overlay = this.timeout = null; } @@ -81,12 +87,30 @@ } var from = cm.getCursor("from"), to = cm.getCursor("to"); if (from.line != to.line) return; + if (state.wordsOnly && !isWord(cm, from, to)) 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)); }); } + function isWord(cm, from, to) { + var str = cm.getRange(from, to); + if (str.match(/^\w+$/) !== null) { + if (from.ch > 0) { + var pos = {line: from.line, ch: from.ch - 1}; + var chr = cm.getRange(pos, from); + if (chr.match(/\W/) === null) return false; + } + if (to.ch < cm.getLine(from.line).length) { + var pos = {line: to.line, ch: to.ch + 1}; + var chr = cm.getRange(to, pos); + if (chr.match(/\W/) === null) return false; + } + return true; + } else return false; + } + function boundariesAround(stream, re) { return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); From cf15c70108b65fda224510177c9ac18e6727f9c0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 18 Sep 2014 14:59:08 +0200 Subject: [PATCH 28/34] Add example of using markselection to style background to demo --- demo/markselection.html | 15 +++++++++++---- lib/codemirror.css | 9 ++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/demo/markselection.html b/demo/markselection.html index 93e38ec833..a182217fd5 100644 --- a/demo/markselection.html +++ b/demo/markselection.html @@ -12,6 +12,7 @@ .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror-selected { background-color: blue !important; } .CodeMirror-selectedtext { color: white; } + .styled-background { background-color: #ff7; }