codemirror-rails 3.20 → 3.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
});
|