codemirror-rails 3.20 → 3.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +240 -135
- data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +6 -2
- data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +1 -0
- data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +5 -3
- data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +10 -6
- data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +2 -0
- data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/fold/comment-fold.js +3 -1
- data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +13 -2
- data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +2 -2
- data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +6 -0
- data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +3 -5
- data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +29 -33
- data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/hint/pig-hint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +1 -5
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +58 -9
- data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +58 -17
- data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +5 -5
- data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +6 -1
- data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +5 -3
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +26 -11
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +22 -11
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +22 -9
- data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +48 -24
- data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +15 -9
- data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +3 -3
- data/vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js +21 -9
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +12 -1
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +110 -28
- data/vendor/assets/javascripts/codemirror/modes/clike.js +28 -9
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +3 -4
- data/vendor/assets/javascripts/codemirror/modes/css.js +341 -297
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +302 -179
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +10 -5
- data/vendor/assets/javascripts/codemirror/modes/gherkin.js +45 -50
- data/vendor/assets/javascripts/codemirror/modes/haml.js +0 -4
- data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -3
- data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +0 -2
- data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +0 -2
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +43 -30
- data/vendor/assets/javascripts/codemirror/modes/jinja2.js +13 -3
- data/vendor/assets/javascripts/codemirror/modes/less.js +7 -6
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +231 -45
- data/vendor/assets/javascripts/codemirror/modes/{ocaml.js → mllike.js} +88 -13
- data/vendor/assets/javascripts/codemirror/modes/pegjs.js +5 -9
- data/vendor/assets/javascripts/codemirror/modes/php.js +6 -7
- data/vendor/assets/javascripts/codemirror/modes/python.js +6 -0
- data/vendor/assets/javascripts/codemirror/modes/r.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +4 -2
- data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +0 -2
- data/vendor/assets/javascripts/codemirror/modes/sql.js +5 -4
- data/vendor/assets/javascripts/codemirror/modes/xml.js +87 -100
- data/vendor/assets/stylesheets/codemirror/themes/mbo.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/midnight.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/pastel-on-dark.css +49 -0
- data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +1 -1
- metadata +3 -2
@@ -3,6 +3,10 @@
|
|
3
3
|
|
4
4
|
var tables;
|
5
5
|
var keywords;
|
6
|
+
var CONS = {
|
7
|
+
QUERY_DIV: ";",
|
8
|
+
ALIAS_KEYWORD: "AS"
|
9
|
+
};
|
6
10
|
|
7
11
|
function getKeywords(editor) {
|
8
12
|
var mode = editor.doc.modeOption;
|
@@ -34,11 +38,10 @@
|
|
34
38
|
var string = token.string.substr(1);
|
35
39
|
var prevCur = CodeMirror.Pos(cur.line, token.start);
|
36
40
|
var table = editor.getTokenAt(prevCur).string;
|
37
|
-
|
38
|
-
if(!columns) {
|
41
|
+
if( !tables.hasOwnProperty( table ) ){
|
39
42
|
table = findTableByAlias(table, editor);
|
40
43
|
}
|
41
|
-
columns = tables[table];
|
44
|
+
var columns = tables[table];
|
42
45
|
if(!columns) {
|
43
46
|
return;
|
44
47
|
}
|
@@ -46,32 +49,72 @@
|
|
46
49
|
function(w) {return "." + w;});
|
47
50
|
}
|
48
51
|
|
49
|
-
function eachWord(
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
function eachWord(lineText, f) {
|
53
|
+
if( !lineText ){return;}
|
54
|
+
var excepted = /[,;]/g;
|
55
|
+
var words = lineText.split( " " );
|
56
|
+
for( var i = 0; i < words.length; i++ ){
|
57
|
+
f( words[i]?words[i].replace( excepted, '' ) : '' );
|
53
58
|
}
|
54
59
|
}
|
55
60
|
|
56
|
-
|
61
|
+
function convertCurToNumber( cur ){
|
62
|
+
// max characters of a line is 999,999.
|
63
|
+
return cur.line + cur.ch / Math.pow( 10, 6 );
|
64
|
+
}
|
65
|
+
|
66
|
+
function convertNumberToCur( num ){
|
67
|
+
return CodeMirror.Pos(Math.floor( num ), +num.toString().split( '.' ).pop());
|
68
|
+
}
|
69
|
+
|
57
70
|
function findTableByAlias(alias, editor) {
|
71
|
+
var doc = editor.doc;
|
72
|
+
var fullQuery = doc.getValue();
|
58
73
|
var aliasUpperCase = alias.toUpperCase();
|
59
74
|
var previousWord = "";
|
60
75
|
var table = "";
|
76
|
+
var separator = [];
|
77
|
+
var validRange = {
|
78
|
+
start: CodeMirror.Pos( 0, 0 ),
|
79
|
+
end: CodeMirror.Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).length )
|
80
|
+
};
|
61
81
|
|
62
|
-
|
63
|
-
|
82
|
+
//add separator
|
83
|
+
var indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV );
|
84
|
+
while( indexOfSeparator != -1 ){
|
85
|
+
separator.push( doc.posFromIndex(indexOfSeparator));
|
86
|
+
indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV, indexOfSeparator+1);
|
87
|
+
}
|
88
|
+
separator.unshift( CodeMirror.Pos( 0, 0 ) );
|
89
|
+
separator.push( CodeMirror.Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).text.length ) );
|
90
|
+
|
91
|
+
//find valieRange
|
92
|
+
var prevItem = 0;
|
93
|
+
var current = convertCurToNumber( editor.getCursor() );
|
94
|
+
for( var i=0; i< separator.length; i++){
|
95
|
+
var _v = convertCurToNumber( separator[i] );
|
96
|
+
if( current > prevItem && current <= _v ){
|
97
|
+
validRange = { start: convertNumberToCur( prevItem ), end: convertNumberToCur( _v ) };
|
98
|
+
break;
|
99
|
+
}
|
100
|
+
prevItem = _v;
|
101
|
+
}
|
102
|
+
|
103
|
+
var query = doc.getRange(validRange.start, validRange.end, false);
|
104
|
+
|
105
|
+
for(var i=0; i < query.length; i++){
|
106
|
+
var lineText = query[i];
|
107
|
+
eachWord( lineText, function( word ){
|
64
108
|
var wordUpperCase = word.toUpperCase();
|
65
|
-
if(wordUpperCase === aliasUpperCase) {
|
66
|
-
if(tables.hasOwnProperty(previousWord)) {
|
109
|
+
if( wordUpperCase === aliasUpperCase && tables.hasOwnProperty( previousWord ) ){
|
67
110
|
table = previousWord;
|
68
|
-
}
|
69
111
|
}
|
70
|
-
if(wordUpperCase !==
|
112
|
+
if( wordUpperCase !== CONS.ALIAS_KEYWORD ){
|
71
113
|
previousWord = word;
|
72
114
|
}
|
73
115
|
});
|
74
|
-
|
116
|
+
if( table ){ break; }
|
117
|
+
}
|
75
118
|
return table;
|
76
119
|
}
|
77
120
|
|
@@ -80,9 +123,7 @@
|
|
80
123
|
keywords = keywords || getKeywords(editor);
|
81
124
|
var cur = editor.getCursor();
|
82
125
|
var token = editor.getTokenAt(cur);
|
83
|
-
|
84
126
|
var result = [];
|
85
|
-
|
86
127
|
var search = token.string.trim();
|
87
128
|
|
88
129
|
addMatches(result, search, keywords,
|
@@ -20,13 +20,13 @@
|
|
20
20
|
var cx = inner.state.context, curTag = cx && tags[cx.tagName];
|
21
21
|
var childList = cx ? curTag && curTag.children : tags["!top"];
|
22
22
|
if (childList) {
|
23
|
-
for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].
|
23
|
+
for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
|
24
24
|
result.push("<" + childList[i]);
|
25
25
|
} else {
|
26
|
-
for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.
|
26
|
+
for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
|
27
27
|
result.push("<" + name);
|
28
28
|
}
|
29
|
-
if (cx && (!prefix || ("/" + cx.tagName).
|
29
|
+
if (cx && (!prefix || ("/" + cx.tagName).lastIndexOf(prefix, 0) == 0))
|
30
30
|
result.push("</" + cx.tagName + ">");
|
31
31
|
} else {
|
32
32
|
// Attribute completion
|
@@ -46,14 +46,14 @@
|
|
46
46
|
}
|
47
47
|
replaceToken = true;
|
48
48
|
}
|
49
|
-
for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].
|
49
|
+
for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0)
|
50
50
|
result.push(quote + atValues[i] + quote);
|
51
51
|
} else { // An attribute name
|
52
52
|
if (token.type == "attribute") {
|
53
53
|
prefix = token.string;
|
54
54
|
replaceToken = true;
|
55
55
|
}
|
56
|
-
for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.
|
56
|
+
for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0))
|
57
57
|
result.push(attr);
|
58
58
|
}
|
59
59
|
}
|
@@ -112,7 +112,7 @@
|
|
112
112
|
if (options.async)
|
113
113
|
options.getAnnotations(cm, updateLinting, options);
|
114
114
|
else
|
115
|
-
updateLinting(cm, options.getAnnotations(cm.getValue(), options));
|
115
|
+
updateLinting(cm, options.getAnnotations(cm.getValue(), options.options));
|
116
116
|
}
|
117
117
|
|
118
118
|
function updateLinting(cm, annotationsNotSorted) {
|
@@ -29,7 +29,7 @@
|
|
29
29
|
this.edit = this.mv.edit;
|
30
30
|
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: true}, copyObj(options)));
|
31
31
|
|
32
|
-
this.diff = getDiff(orig, options.value);
|
32
|
+
this.diff = getDiff(asString(orig), asString(options.value));
|
33
33
|
this.diffOutOfDate = false;
|
34
34
|
|
35
35
|
this.showDifferences = options.showDifferences !== false;
|
@@ -352,6 +352,11 @@
|
|
352
352
|
}
|
353
353
|
};
|
354
354
|
|
355
|
+
function asString(obj) {
|
356
|
+
if (typeof obj == "string") return obj;
|
357
|
+
else return obj.getValue();
|
358
|
+
}
|
359
|
+
|
355
360
|
// Operations on diffs
|
356
361
|
|
357
362
|
var dmp = new diff_match_patch();
|
@@ -47,7 +47,11 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
|
47
47
|
return outerToken;
|
48
48
|
} else {
|
49
49
|
var curInner = state.innerActive, oldContent = stream.string;
|
50
|
-
|
50
|
+
if (!curInner.close && stream.sol()) {
|
51
|
+
state.innerActive = state.inner = null;
|
52
|
+
return this.token(stream, state);
|
53
|
+
}
|
54
|
+
var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1;
|
51
55
|
if (found == stream.pos) {
|
52
56
|
stream.match(curInner.close);
|
53
57
|
state.innerActive = state.inner = null;
|
@@ -56,8 +60,6 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
|
56
60
|
if (found > -1) stream.string = oldContent.slice(0, found);
|
57
61
|
var innerToken = curInner.mode.token(stream, state.inner);
|
58
62
|
if (found > -1) stream.string = oldContent;
|
59
|
-
var cur = stream.current(), found = cur.indexOf(curInner.close);
|
60
|
-
if (found > -1) stream.backUp(cur.length - found);
|
61
63
|
|
62
64
|
if (curInner.innerStyle) {
|
63
65
|
if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
|
@@ -10,6 +10,7 @@ function splitLines(string){ return string.split(/\r?\n|\r/); };
|
|
10
10
|
function StringStream(string) {
|
11
11
|
this.pos = this.start = 0;
|
12
12
|
this.string = string;
|
13
|
+
this.lineStart = 0;
|
13
14
|
}
|
14
15
|
StringStream.prototype = {
|
15
16
|
eol: function() {return this.pos >= this.string.length;},
|
@@ -41,7 +42,7 @@ StringStream.prototype = {
|
|
41
42
|
if (found > -1) {this.pos = found; return true;}
|
42
43
|
},
|
43
44
|
backUp: function(n) {this.pos -= n;},
|
44
|
-
column: function() {return this.start;},
|
45
|
+
column: function() {return this.start - this.lineStart;},
|
45
46
|
indentation: function() {return 0;},
|
46
47
|
match: function(pattern, consume, caseInsensitive) {
|
47
48
|
if (typeof pattern == "string") {
|
@@ -58,7 +59,12 @@ StringStream.prototype = {
|
|
58
59
|
return match;
|
59
60
|
}
|
60
61
|
},
|
61
|
-
current: function(){return this.string.slice(this.start, this.pos);}
|
62
|
+
current: function(){return this.string.slice(this.start, this.pos);},
|
63
|
+
hideFirstChars: function(n, inner) {
|
64
|
+
this.lineStart += n;
|
65
|
+
try { return inner(); }
|
66
|
+
finally { this.lineStart -= n; }
|
67
|
+
}
|
62
68
|
};
|
63
69
|
CodeMirror.StringStream = StringStream;
|
64
70
|
|
@@ -69,17 +75,26 @@ CodeMirror.startState = function (mode, a1, a2) {
|
|
69
75
|
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
|
70
76
|
CodeMirror.defineMode = function (name, mode) { modes[name] = mode; };
|
71
77
|
CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
|
72
|
-
CodeMirror.
|
73
|
-
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
78
|
+
CodeMirror.resolveMode = function(spec) {
|
79
|
+
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
|
74
80
|
spec = mimeModes[spec];
|
75
|
-
if (typeof spec == "string")
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
81
|
+
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
|
82
|
+
spec = mimeModes[spec.name];
|
83
|
+
}
|
84
|
+
if (typeof spec == "string") return {name: spec};
|
85
|
+
else return spec || {name: "null"};
|
86
|
+
};
|
87
|
+
CodeMirror.getMode = function (options, spec) {
|
88
|
+
spec = CodeMirror.resolveMode(spec);
|
89
|
+
var mfactory = modes[spec.name];
|
80
90
|
if (!mfactory) throw new Error("Unknown mode: " + spec);
|
81
|
-
return mfactory(options,
|
91
|
+
return mfactory(options, spec);
|
82
92
|
};
|
93
|
+
CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
|
94
|
+
CodeMirror.defineMode("null", function() {
|
95
|
+
return {token: function(stream) {stream.skipToEnd();}};
|
96
|
+
});
|
97
|
+
CodeMirror.defineMIME("text/plain", "null");
|
83
98
|
|
84
99
|
CodeMirror.runMode = function (string, modespec, callback, options) {
|
85
100
|
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
|
@@ -122,7 +137,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
|
|
122
137
|
};
|
123
138
|
}
|
124
139
|
|
125
|
-
var lines = splitLines(string), state = CodeMirror.startState(mode);
|
140
|
+
var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
|
126
141
|
for (var i = 0, e = lines.length; i < e; ++i) {
|
127
142
|
if (i) callback("\n");
|
128
143
|
var stream = new CodeMirror.StringStream(lines[i]);
|
@@ -43,7 +43,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
|
|
43
43
|
};
|
44
44
|
}
|
45
45
|
|
46
|
-
var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
|
46
|
+
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
|
47
47
|
for (var i = 0, e = lines.length; i < e; ++i) {
|
48
48
|
if (i) callback("\n");
|
49
49
|
var stream = new CodeMirror.StringStream(lines[i]);
|
@@ -5,6 +5,7 @@ function splitLines(string){ return string.split(/\r?\n|\r/); };
|
|
5
5
|
function StringStream(string) {
|
6
6
|
this.pos = this.start = 0;
|
7
7
|
this.string = string;
|
8
|
+
this.lineStart = 0;
|
8
9
|
}
|
9
10
|
StringStream.prototype = {
|
10
11
|
eol: function() {return this.pos >= this.string.length;},
|
@@ -36,7 +37,7 @@ StringStream.prototype = {
|
|
36
37
|
if (found > -1) {this.pos = found; return true;}
|
37
38
|
},
|
38
39
|
backUp: function(n) {this.pos -= n;},
|
39
|
-
column: function() {return this.start;},
|
40
|
+
column: function() {return this.start - this.lineStart;},
|
40
41
|
indentation: function() {return 0;},
|
41
42
|
match: function(pattern, consume, caseInsensitive) {
|
42
43
|
if (typeof pattern == "string") {
|
@@ -53,7 +54,12 @@ StringStream.prototype = {
|
|
53
54
|
return match;
|
54
55
|
}
|
55
56
|
},
|
56
|
-
current: function(){return this.string.slice(this.start, this.pos);}
|
57
|
+
current: function(){return this.string.slice(this.start, this.pos);},
|
58
|
+
hideFirstChars: function(n, inner) {
|
59
|
+
this.lineStart += n;
|
60
|
+
try { return inner(); }
|
61
|
+
finally { this.lineStart -= n; }
|
62
|
+
}
|
57
63
|
};
|
58
64
|
exports.StringStream = StringStream;
|
59
65
|
|
@@ -76,21 +82,26 @@ exports.defineMode("null", function() {
|
|
76
82
|
});
|
77
83
|
exports.defineMIME("text/plain", "null");
|
78
84
|
|
79
|
-
exports.
|
80
|
-
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
85
|
+
exports.resolveMode = function(spec) {
|
86
|
+
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
|
81
87
|
spec = mimeModes[spec];
|
82
|
-
if (typeof spec == "string")
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
|
89
|
+
spec = mimeModes[spec.name];
|
90
|
+
}
|
91
|
+
if (typeof spec == "string") return {name: spec};
|
92
|
+
else return spec || {name: "null"};
|
93
|
+
};
|
94
|
+
exports.getMode = function(options, spec) {
|
95
|
+
spec = exports.resolveMode(mimeModes[spec]);
|
96
|
+
var mfactory = modes[spec.name];
|
87
97
|
if (!mfactory) throw new Error("Unknown mode: " + spec);
|
88
|
-
return mfactory(options,
|
98
|
+
return mfactory(options, spec);
|
89
99
|
};
|
100
|
+
exports.registerHelper = exports.registerGlobalHelper = Math.min;
|
90
101
|
|
91
102
|
exports.runMode = function(string, modespec, callback) {
|
92
103
|
var mode = exports.getMode({indentUnit: 2}, modespec);
|
93
|
-
var lines = splitLines(string), state = exports.startState(mode);
|
104
|
+
var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
|
94
105
|
for (var i = 0, e = lines.length; i < e; ++i) {
|
95
106
|
if (i) callback("\n");
|
96
107
|
var stream = new exports.StringStream(lines[i]);
|
@@ -7,7 +7,15 @@
|
|
7
7
|
// Ctrl-G.
|
8
8
|
|
9
9
|
(function() {
|
10
|
-
function searchOverlay(query) {
|
10
|
+
function searchOverlay(query, caseInsensitive) {
|
11
|
+
var startChar;
|
12
|
+
if (typeof query == "string") {
|
13
|
+
startChar = query.charAt(0);
|
14
|
+
query = new RegExp("^" + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),
|
15
|
+
caseInsensitive ? "i" : "");
|
16
|
+
} else {
|
17
|
+
query = new RegExp("^(?:" + query.source + ")", query.ignoreCase ? "i" : "");
|
18
|
+
}
|
11
19
|
if (typeof query == "string") return {token: function(stream) {
|
12
20
|
if (stream.match(query)) return "searching";
|
13
21
|
stream.next();
|
@@ -17,6 +25,8 @@
|
|
17
25
|
if (stream.match(query)) return "searching";
|
18
26
|
while (!stream.eol()) {
|
19
27
|
stream.next();
|
28
|
+
if (startChar)
|
29
|
+
stream.skipTo(startChar) || stream.skipToEnd();
|
20
30
|
if (stream.match(query, false)) break;
|
21
31
|
}
|
22
32
|
}};
|
@@ -29,13 +39,16 @@
|
|
29
39
|
function getSearchState(cm) {
|
30
40
|
return cm.state.search || (cm.state.search = new SearchState());
|
31
41
|
}
|
42
|
+
function queryCaseInsensitive(query) {
|
43
|
+
return typeof query == "string" && query == query.toLowerCase();
|
44
|
+
}
|
32
45
|
function getSearchCursor(cm, query, pos) {
|
33
46
|
// Heuristic: if the query string is all lowercase, do a case insensitive search.
|
34
|
-
return cm.getSearchCursor(query, pos,
|
47
|
+
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
|
35
48
|
}
|
36
|
-
function dialog(cm, text, shortText, f) {
|
37
|
-
if (cm.openDialog) cm.openDialog(text, f);
|
38
|
-
else f(prompt(shortText,
|
49
|
+
function dialog(cm, text, shortText, deflt, f) {
|
50
|
+
if (cm.openDialog) cm.openDialog(text, f, {value: deflt});
|
51
|
+
else f(prompt(shortText, deflt));
|
39
52
|
}
|
40
53
|
function confirmDialog(cm, text, shortText, fs) {
|
41
54
|
if (cm.openConfirm) cm.openConfirm(text, fs);
|
@@ -50,11 +63,11 @@
|
|
50
63
|
function doSearch(cm, rev) {
|
51
64
|
var state = getSearchState(cm);
|
52
65
|
if (state.query) return findNext(cm, rev);
|
53
|
-
dialog(cm, queryDialog, "Search for:", function(query) {
|
66
|
+
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
|
54
67
|
cm.operation(function() {
|
55
68
|
if (!query || state.query) return;
|
56
69
|
state.query = parseQuery(query);
|
57
|
-
cm.removeOverlay(state.overlay);
|
70
|
+
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
|
58
71
|
state.overlay = searchOverlay(state.query);
|
59
72
|
cm.addOverlay(state.overlay);
|
60
73
|
state.posFrom = state.posTo = cm.getCursor();
|
@@ -85,10 +98,10 @@
|
|
85
98
|
var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
|
86
99
|
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
|
87
100
|
function replace(cm, all) {
|
88
|
-
dialog(cm, replaceQueryDialog, "Replace:", function(query) {
|
101
|
+
dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) {
|
89
102
|
if (!query) return;
|
90
103
|
query = parseQuery(query);
|
91
|
-
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
|
104
|
+
dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
|
92
105
|
if (all) {
|
93
106
|
cm.operation(function() {
|
94
107
|
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
|
@@ -47,6 +47,7 @@
|
|
47
47
|
match: match};
|
48
48
|
};
|
49
49
|
} else { // String query
|
50
|
+
var origQuery = query;
|
50
51
|
if (caseFold) query = query.toLowerCase();
|
51
52
|
var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
|
52
53
|
var target = query.split("\n");
|
@@ -58,33 +59,45 @@
|
|
58
59
|
this.matches = function() {};
|
59
60
|
} else {
|
60
61
|
this.matches = function(reverse, pos) {
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
if (reverse) {
|
63
|
+
var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);
|
64
|
+
var match = line.lastIndexOf(query);
|
65
|
+
if (match > -1) {
|
66
|
+
match = adjustPos(orig, line, match);
|
67
|
+
return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
|
68
|
+
}
|
69
|
+
} else {
|
70
|
+
var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);
|
71
|
+
var match = line.indexOf(query);
|
72
|
+
if (match > -1) {
|
73
|
+
match = adjustPos(orig, line, match) + pos.ch;
|
74
|
+
return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
|
75
|
+
}
|
76
|
+
}
|
66
77
|
};
|
67
78
|
}
|
68
79
|
} else {
|
80
|
+
var origTarget = origQuery.split("\n");
|
69
81
|
this.matches = function(reverse, pos) {
|
70
|
-
var
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
line =
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
var last = target.length - 1;
|
83
|
+
if (reverse) {
|
84
|
+
if (pos.line - (target.length - 1) < doc.firstLine()) return;
|
85
|
+
if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;
|
86
|
+
var to = Pos(pos.line, origTarget[last].length);
|
87
|
+
for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)
|
88
|
+
if (target[i] != fold(doc.getLine(ln))) return;
|
89
|
+
var line = doc.getLine(ln), cut = line.length - origTarget[0].length;
|
90
|
+
if (fold(line.slice(cut)) != target[0]) return;
|
91
|
+
return {from: Pos(ln, cut), to: to};
|
92
|
+
} else {
|
93
|
+
if (pos.line + (target.length - 1) > doc.lastLine()) return;
|
94
|
+
var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;
|
95
|
+
if (fold(line.slice(cut)) != target[0]) return;
|
96
|
+
var from = Pos(pos.line, cut);
|
97
|
+
for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
|
98
|
+
if (target[i] != fold(doc.getLine(ln))) return;
|
99
|
+
if (doc.getLine(ln).slice(0, origTarget[last].length) != target[last]) return;
|
100
|
+
return {from: from, to: Pos(ln, origTarget[last].length)};
|
88
101
|
}
|
89
102
|
};
|
90
103
|
}
|
@@ -106,7 +119,6 @@
|
|
106
119
|
|
107
120
|
for (;;) {
|
108
121
|
if (this.pos = this.matches(reverse, pos)) {
|
109
|
-
if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); }
|
110
122
|
this.atOccurrence = true;
|
111
123
|
return this.pos.match || true;
|
112
124
|
}
|
@@ -134,6 +146,18 @@
|
|
134
146
|
}
|
135
147
|
};
|
136
148
|
|
149
|
+
// Maps a position in a case-folded line back to a position in the original line
|
150
|
+
// (compensating for codepoints increasing in number during folding)
|
151
|
+
function adjustPos(orig, folded, pos) {
|
152
|
+
if (orig.length == folded.length) return pos;
|
153
|
+
for (var pos1 = Math.min(pos, orig.length);;) {
|
154
|
+
var len1 = orig.slice(0, pos1).toLowerCase().length;
|
155
|
+
if (len1 < pos) ++pos1;
|
156
|
+
else if (len1 > pos) --pos1;
|
157
|
+
else return pos1;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
137
161
|
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
|
138
162
|
return new SearchCursor(this.doc, query, pos, caseFold);
|
139
163
|
});
|