From 0e04fff0ea80fa5cbe96b8354db38bd334aea83a Mon Sep 17 00:00:00 2001 From: Ananya Sen Date: Mon, 16 Jul 2012 16:04:05 -0700 Subject: upgrade to codemirror 2.3 Signed-off-by: Ananya Sen Conflicts: js/code-editor/codemirror-ninja/theme/lesser-dark-ninja.css Signed-off-by: Ananya Sen --- imports/codemirror/lib/util/closetag.js | 28 ------ imports/codemirror/lib/util/foldcode.js | 36 ++++--- imports/codemirror/lib/util/formatting.js | 9 +- imports/codemirror/lib/util/loadmode.js | 51 ++++++++++ imports/codemirror/lib/util/match-highlighter.js | 2 +- imports/codemirror/lib/util/multiplex.js | 72 +++++++++++++ imports/codemirror/lib/util/overlay.js | 5 +- imports/codemirror/lib/util/pig-hint.js | 123 +++++++++++++++++++++++ imports/codemirror/lib/util/search.js | 32 +++--- imports/codemirror/lib/util/searchcursor.js | 2 +- 10 files changed, 298 insertions(+), 62 deletions(-) create mode 100644 imports/codemirror/lib/util/loadmode.js create mode 100644 imports/codemirror/lib/util/multiplex.js create mode 100644 imports/codemirror/lib/util/pig-hint.js (limited to 'imports/codemirror/lib/util') diff --git a/imports/codemirror/lib/util/closetag.js b/imports/codemirror/lib/util/closetag.js index 44c2b435..20a43b9d 100644 --- a/imports/codemirror/lib/util/closetag.js +++ b/imports/codemirror/lib/util/closetag.js @@ -10,7 +10,6 @@ * following CodeMirror modes and will ignore all others: * - htmlmixed * - xml - * - xmlpure * * See demos/closetag.html for a usage example. * @@ -104,33 +103,6 @@ } } - } else if (mode == 'xmlpure') { - - var pos = cm.getCursor(); - var tok = cm.getTokenAt(pos); - var tagName = tok.state.context.tagName; - - if (ch == '>') { - // tagName=foo, string=foo - // tagName=foo, string=/ # ignore - // tagName=foo, string=/foo # ignore - if (tok.string == tagName) { - cm.replaceSelection('>'); // parity w/html modes - pos = {line: pos.line, ch: pos.ch + 1}; - cm.setCursor(pos); - - insertEndTag(cm, indent, pos, tagName); - return; - } - - } else if (ch == '/') { - // // released under the MIT license (../../LICENSE) like the rest of CodeMirror -CodeMirror.tagRangeFinder = function(cm, line) { +CodeMirror.tagRangeFinder = function(cm, line, hideEnd) { var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; - var nameChar = nameStartChar + "\-\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; + var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*"); var lineText = cm.getLine(line); @@ -36,8 +36,10 @@ CodeMirror.tagRangeFinder = function(cm, line) { var slash = lt.lastIndexOf("/", gt); if (-1 != slash && slash < gt) { var str = lineText.substr(slash, gt - slash + 1); - if (!str.match( /\/\s*\>/ )) // yep, that's the end of empty tag - return l+1; + if (!str.match( /\/\s*\>/ )) { // yep, that's the end of empty tag + if (hideEnd === true) l++; + return l; + } } } l++; @@ -95,8 +97,10 @@ CodeMirror.tagRangeFinder = function(cm, line) { depth--; else depth++; - if (!depth) - return l+1; + if (!depth) { + if (hideEnd === true) l++; + return l; + } } } l++; @@ -105,11 +109,16 @@ CodeMirror.tagRangeFinder = function(cm, line) { } }; -CodeMirror.braceRangeFinder = function(cm, line) { - var lineText = cm.getLine(line); - var startChar = lineText.lastIndexOf("{"); - if (startChar < 0 || lineText.lastIndexOf("}") > startChar) return; - var tokenType = cm.getTokenAt({line: line, ch: startChar}).className; +CodeMirror.braceRangeFinder = function(cm, line, hideEnd) { + var lineText = cm.getLine(line), at = lineText.length, startChar, tokenType; + for (;;) { + var found = lineText.lastIndexOf("{", at); + if (found < 0) break; + tokenType = cm.getTokenAt({line: line, ch: found}).className; + if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; } + at = found - 1; + } + if (startChar == null || lineText.lastIndexOf("}") > startChar) return; var count = 1, lastLine = cm.lineCount(), end; outer: for (var i = line + 1; i < lastLine; ++i) { var text = cm.getLine(i), pos = 0; @@ -127,6 +136,7 @@ CodeMirror.braceRangeFinder = function(cm, line) { } } if (end == null || end == line + 1) return; + if (hideEnd === true) end++; return end; }; @@ -144,7 +154,7 @@ CodeMirror.indentRangeFinder = function(cm, line) { return last + 1; }; -CodeMirror.newFoldFunction = function(rangeFinder, markText) { +CodeMirror.newFoldFunction = function(rangeFinder, markText, hideEnd) { var folded = []; if (markText == null) markText = '
%N%'; @@ -169,7 +179,7 @@ CodeMirror.newFoldFunction = function(rangeFinder, markText) { folded.splice(known.pos, 1); expand(cm, known.region); } else { - var end = rangeFinder(cm, line); + var end = rangeFinder(cm, line, hideEnd); if (end == null) return; var hidden = []; for (var i = line + 1; i < end; ++i) { diff --git a/imports/codemirror/lib/util/formatting.js b/imports/codemirror/lib/util/formatting.js index e1891191..3a1a9873 100644 --- a/imports/codemirror/lib/util/formatting.js +++ b/imports/codemirror/lib/util/formatting.js @@ -84,7 +84,8 @@ CodeMirror.modeExtensions["css"] = { commentStart: "/*", commentEnd: "*/", wordWrapChars: [";", "\\{", "\\}"], - autoFormatLineBreaks: function (text) { + autoFormatLineBreaks: function (text, startPos, endPos) { + text = text.substring(startPos, endPos); return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2"); } }; @@ -125,7 +126,8 @@ CodeMirror.modeExtensions["javascript"] = { return nonBreakableBlocks; }, - autoFormatLineBreaks: function (text) { + autoFormatLineBreaks: function (text, startPos, endPos) { + text = text.substring(startPos, endPos); var curPos = 0; var reLinesSplitter = new RegExp("(;|\\{|\\})([^\r\n])", "g"); var nonBreakableBlocks = this.getNonBreakableBlocks(text); @@ -158,7 +160,8 @@ CodeMirror.modeExtensions["xml"] = { commentEnd: "-->", wordWrapChars: [">"], - autoFormatLineBreaks: function (text) { + autoFormatLineBreaks: function (text, startPos, endPos) { + text = text.substring(startPos, endPos); var lines = text.split("\n"); var reProcessedPortion = new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)"); var reOpenBrackets = new RegExp("<", "g"); diff --git a/imports/codemirror/lib/util/loadmode.js b/imports/codemirror/lib/util/loadmode.js new file mode 100644 index 00000000..48d5a7ab --- /dev/null +++ b/imports/codemirror/lib/util/loadmode.js @@ -0,0 +1,51 @@ +(function() { + if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js"; + + var loading = {}; + function splitCallback(cont, n) { + var countDown = n; + return function() { if (--countDown == 0) cont(); } + } + function ensureDeps(mode, cont) { + var deps = CodeMirror.modes[mode].dependencies; + if (!deps) return cont(); + var missing = []; + for (var i = 0; i < deps.length; ++i) { + if (!CodeMirror.modes.hasOwnProperty(deps[i])) + missing.push(deps[i]); + } + if (!missing.length) return cont(); + var split = splitCallback(cont, missing.length); + for (var i = 0; i < missing.length; ++i) + CodeMirror.requireMode(missing[i], split); + } + + CodeMirror.requireMode = function(mode, cont) { + if (typeof mode != "string") mode = mode.name; + if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); + if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); + + var script = document.createElement("script"); + script.src = CodeMirror.modeURL.replace(/%N/g, mode); + var others = document.getElementsByTagName("script")[0]; + others.parentNode.insertBefore(script, others); + var list = loading[mode] = [cont]; + var count = 0, poll = setInterval(function() { + if (++count > 100) return clearInterval(poll); + if (CodeMirror.modes.hasOwnProperty(mode)) { + clearInterval(poll); + loading[mode] = null; + ensureDeps(mode, function() { + for (var i = 0; i < list.length; ++i) list[i](); + }); + } + }, 200); + }; + + CodeMirror.autoLoadMode = function(instance, mode) { + if (!CodeMirror.modes.hasOwnProperty(mode)) + CodeMirror.requireMode(mode, function() { + instance.setOption("mode", instance.getOption("mode")); + }); + }; +}()); diff --git a/imports/codemirror/lib/util/match-highlighter.js b/imports/codemirror/lib/util/match-highlighter.js index b70cc4cf..59098ff8 100644 --- a/imports/codemirror/lib/util/match-highlighter.js +++ b/imports/codemirror/lib/util/match-highlighter.js @@ -23,7 +23,7 @@ function markDocument(cm, className, minChars) { clearMarks(cm); minChars = (typeof minChars !== 'undefined' ? minChars : DEFAULT_MIN_CHARS); - if (cm.somethingSelected() && cm.getSelection().length >= minChars) { + if (cm.somethingSelected() && cm.getSelection().replace(/^\s+|\s+$/g, "").length >= minChars) { var state = getMatchHighlightState(cm); var query = cm.getSelection(); cm.operation(function() { diff --git a/imports/codemirror/lib/util/multiplex.js b/imports/codemirror/lib/util/multiplex.js new file mode 100644 index 00000000..822ee62a --- /dev/null +++ b/imports/codemirror/lib/util/multiplex.js @@ -0,0 +1,72 @@ +CodeMirror.multiplexingMode = function(outer /*, others */) { + // Others should be {open, close, mode [, delimStyle]} objects + var others = Array.prototype.slice.call(arguments, 1); + var n_others = others.length; + + return { + startState: function() { + return { + outer: CodeMirror.startState(outer), + innerActive: null, + inner: null + }; + }, + + copyState: function(state) { + return { + outer: CodeMirror.copyState(outer, state.outer), + innerActive: state.innerActive, + inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) + }; + }, + + token: function(stream, state) { + if (!state.innerActive) { + for (var i = 0; i < n_others; ++i) { + var other = others[i]; + if (stream.match(other.open)) { + state.innerActive = other; + state.inner = CodeMirror.startState(other.mode); + return other.delimStyle; + } + } + var outerToken = outer.token(stream, state.outer); + var cur = stream.current(); + for (var i = 0; i < n_others; ++i) { + var other = others[i], found = cur.indexOf(other.open); + if (found > -1) { + stream.backUp(cur.length - found); + cur = cur.slice(0, found); + } + } + return outerToken; + } else { + var curInner = state.innerActive; + if (stream.match(curInner.close)) { + state.innerActive = state.inner = null; + return curInner.delimStyle; + } + var innerToken = curInner.mode.token(stream, state.inner); + var cur = stream.current(), found = cur.indexOf(curInner.close); + if (found > -1) stream.backUp(cur.length - found); + return innerToken; + } + }, + + indent: function(state, textAfter) { + var mode = state.innerActive || outer; + if (!mode.indent) return CodeMirror.Pass; + return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); + }, + + compareStates: function(a, b) { + if (a.innerActive != b.innerActive) return false; + var mode = a.innerActive || outer; + if (!mode.compareStates) return CodeMirror.Pass; + return mode.compareStates(a.innerActive ? a.inner : a.outer, + b.innerActive ? b.inner : b.outer); + }, + + electricChars: outer.electricChars + }; +}; diff --git a/imports/codemirror/lib/util/overlay.js b/imports/codemirror/lib/util/overlay.js index c4cdf9fc..1d5df6c6 100644 --- a/imports/codemirror/lib/util/overlay.js +++ b/imports/codemirror/lib/util/overlay.js @@ -6,7 +6,8 @@ // overlay wins, unless the combine argument was true, in which case // the styles are combined. -CodeMirror.overlayParser = function(base, overlay, combine) { +// overlayParser is the old, deprecated name +CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, combine) { return { startState: function() { return { @@ -43,7 +44,7 @@ CodeMirror.overlayParser = function(base, overlay, combine) { else return state.overlayCur; }, - indent: function(state, textAfter) { + indent: base.indent && function(state, textAfter) { return base.indent(state.base, textAfter); }, electricChars: base.electricChars diff --git a/imports/codemirror/lib/util/pig-hint.js b/imports/codemirror/lib/util/pig-hint.js new file mode 100644 index 00000000..233b72bf --- /dev/null +++ b/imports/codemirror/lib/util/pig-hint.js @@ -0,0 +1,123 @@ +(function () { + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, keywords, getToken) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; + // If it's not a 'word-style' token, ignore the token. + + if (!/^[\w$_]*$/.test(token.string)) { + token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, + className: token.string == ":" ? "pig-type" : null}; + } + + if (!context) var context = []; + context.push(tprop); + + completionList = getCompletions(token, context); + completionList = completionList.sort(); + //prevent autocomplete for last word, instead show dropdown with one word + if(completionList.length == 1) { + completionList.push(" "); + } + + return {list: completionList, + from: {line: cur.line, ch: token.start}, + to: {line: cur.line, ch: token.end}}; + } + + CodeMirror.pigHint = function(editor) { + return scriptHint(editor, pigKeywordsU, function (e, cur) {return e.getTokenAt(cur);}); + } + + function toTitleCase(str) { + return str.replace(/(?:^|\s)\w/g, function(match) { + return match.toUpperCase(); + }); + } + + var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP " + + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL " + + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE " + + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE " + + "NEQ MATCHES TRUE FALSE"; + var pigKeywordsU = pigKeywords.split(" "); + var pigKeywordsL = pigKeywords.toLowerCase().split(" "); + + var pigTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP"; + var pigTypesU = pigTypes.split(" "); + var pigTypesL = pigTypes.toLowerCase().split(" "); + + var pigBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL " + + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS " + + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG " + + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN " + + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER " + + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS " + + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA " + + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE " + + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG " + + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER"; + var pigBuiltinsU = pigBuiltins.split(" ").join("() ").split(" "); + var pigBuiltinsL = pigBuiltins.toLowerCase().split(" ").join("() ").split(" "); + var pigBuiltinsC = ("BagSize BinStorage Bloom BuildBloom ConstantSize CubeDimensions DoubleAbs " + + "DoubleAvg DoubleBase DoubleMax DoubleMin DoubleRound DoubleSum FloatAbs FloatAvg FloatMax " + + "FloatMin FloatRound FloatSum GenericInvoker IntAbs IntAvg IntMax IntMin IntSum " + + "InvokeForDouble InvokeForFloat InvokeForInt InvokeForLong InvokeForString Invoker " + + "IsEmpty JsonLoader JsonMetadata JsonStorage LongAbs LongAvg LongMax LongMin LongSum MapSize " + + "MonitoredUDF Nondeterministic OutputSchema PigStorage PigStreaming StringConcat StringMax " + + "StringMin StringSize TextLoader TupleSize Utf8StorageConverter").split(" ").join("() ").split(" "); + + function getCompletions(token, context) { + var found = [], start = token.string; + function maybeAdd(str) { + if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str); + } + + function gatherCompletions(obj) { + if(obj == ":") { + forEach(pigTypesL, maybeAdd); + } + else { + forEach(pigBuiltinsU, maybeAdd); + forEach(pigBuiltinsL, maybeAdd); + forEach(pigBuiltinsC, maybeAdd); + forEach(pigTypesU, maybeAdd); + forEach(pigTypesL, maybeAdd); + forEach(pigKeywordsU, maybeAdd); + forEach(pigKeywordsL, maybeAdd); + } + } + + if (context) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + + if (obj.className == "pig-word") + base = obj.string; + else if(obj.className == "pig-type") + base = ":" + obj.string; + + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } + return found; + } +})(); diff --git a/imports/codemirror/lib/util/search.js b/imports/codemirror/lib/util/search.js index 63ebca9b..c5a2bccf 100644 --- a/imports/codemirror/lib/util/search.js +++ b/imports/codemirror/lib/util/search.js @@ -14,6 +14,10 @@ function getSearchState(cm) { return cm._searchState || (cm._searchState = new SearchState()); } + function getSearchCursor(cm, query, pos) { + // Heuristic: if the query string is all lowercase, do a case insensitive search. + return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase()); + } function dialog(cm, text, shortText, f) { if (cm.openDialog) cm.openDialog(text, f); else f(prompt(shortText, "")); @@ -23,11 +27,11 @@ else if (confirm(shortText)) fs[0](); } function parseQuery(query) { - var isRE = query.match(/^\/(.*)\/$/); - return isRE ? new RegExp(isRE[1]) : query; + var isRE = query.match(/^\/(.*)\/([a-z]*)$/); + return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query; } var queryDialog = - 'Search: (Use /re/ syntax for regexp search)'; + 'Search: (Use /re/ syntax for regexp search)'; function doSearch(cm, rev) { var state = getSearchState(cm); if (state.query) return findNext(cm, rev); @@ -36,7 +40,7 @@ if (!query || state.query) return; state.query = parseQuery(query); if (cm.lineCount() < 2000) { // This is too expensive on big documents. - for (var cursor = cm.getSearchCursor(query); cursor.findNext();) + for (var cursor = getSearchCursor(cm, query); cursor.findNext();) state.marked.push(cm.markText(cursor.from(), cursor.to(), "CodeMirror-searching")); } state.posFrom = state.posTo = cm.getCursor(); @@ -46,9 +50,9 @@ } function findNext(cm, rev) {cm.operation(function() { var state = getSearchState(cm); - var cursor = cm.getSearchCursor(state.query, rev ? state.posFrom : state.posTo); + var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); if (!cursor.find(rev)) { - cursor = cm.getSearchCursor(state.query, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0}); + cursor = getSearchCursor(cm, state.query, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0}); if (!cursor.find(rev)) return; } cm.setSelection(cursor.from(), cursor.to()); @@ -63,8 +67,8 @@ })} var replaceQueryDialog = - 'Replace: (Use /re/ syntax for regexp search)'; - var replacementQueryDialog = 'With: '; + 'Replace: (Use /re/ syntax for regexp search)'; + var replacementQueryDialog = 'With: '; var doReplaceConfirm = "Replace? "; function replace(cm, all) { dialog(cm, replaceQueryDialog, "Replace:", function(query) { @@ -72,23 +76,23 @@ query = parseQuery(query); dialog(cm, replacementQueryDialog, "Replace with:", function(text) { if (all) { - cm.operation(function() { - for (var cursor = cm.getSearchCursor(query); cursor.findNext();) { + cm.compoundChange(function() { cm.operation(function() { + for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { if (typeof query != "string") { var match = cm.getRange(cursor.from(), cursor.to()).match(query); cursor.replace(text.replace(/\$(\d)/, function(w, i) {return match[i];})); } else cursor.replace(text); } - }); + })}); } else { clearSearch(cm); - var cursor = cm.getSearchCursor(query, cm.getCursor()); + var cursor = getSearchCursor(cm, query, cm.getCursor()); function advance() { var start = cursor.from(), match; if (!(match = cursor.findNext())) { - cursor = cm.getSearchCursor(query); + cursor = getSearchCursor(cm, query); if (!(match = cursor.findNext()) || - (cursor.from().line == start.line && cursor.from().ch == start.ch)) return; + (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; } cm.setSelection(cursor.from(), cursor.to()); confirmDialog(cm, doReplaceConfirm, "Replace?", diff --git a/imports/codemirror/lib/util/searchcursor.js b/imports/codemirror/lib/util/searchcursor.js index 3b77829f..ec3f73c3 100644 --- a/imports/codemirror/lib/util/searchcursor.js +++ b/imports/codemirror/lib/util/searchcursor.js @@ -1,7 +1,7 @@ (function(){ function SearchCursor(cm, query, pos, caseFold) { this.atOccurrence = false; this.cm = cm; - if (caseFold == null) caseFold = typeof query == "string" && query == query.toLowerCase(); + if (caseFold == null && typeof query == "string") caseFold = false; pos = pos ? cm.clipPos(pos) : {line: 0, ch: 0}; this.pos = {from: pos, to: pos}; -- cgit v1.2.3