codemirror-rails 3.20 → 3.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +240 -135
  4. data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +6 -2
  5. data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +1 -1
  6. data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +1 -0
  7. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +5 -3
  8. data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +10 -6
  9. data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +2 -0
  10. data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +1 -1
  11. data/vendor/assets/javascripts/codemirror/addons/fold/comment-fold.js +3 -1
  12. data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +13 -2
  13. data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +1 -1
  14. data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +2 -2
  15. data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +6 -0
  16. data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +3 -5
  17. data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +29 -33
  18. data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/addons/hint/pig-hint.js +1 -1
  20. data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +1 -5
  21. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +58 -9
  22. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +58 -17
  23. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +5 -5
  24. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +1 -1
  25. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +6 -1
  26. data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +5 -3
  27. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +26 -11
  28. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -1
  29. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +22 -11
  30. data/vendor/assets/javascripts/codemirror/addons/search/search.js +22 -9
  31. data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +48 -24
  32. data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +15 -9
  33. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +3 -3
  34. data/vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js +21 -9
  35. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +12 -1
  36. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +110 -28
  37. data/vendor/assets/javascripts/codemirror/modes/clike.js +28 -9
  38. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +3 -4
  39. data/vendor/assets/javascripts/codemirror/modes/css.js +341 -297
  40. data/vendor/assets/javascripts/codemirror/modes/erlang.js +302 -179
  41. data/vendor/assets/javascripts/codemirror/modes/gfm.js +10 -5
  42. data/vendor/assets/javascripts/codemirror/modes/gherkin.js +45 -50
  43. data/vendor/assets/javascripts/codemirror/modes/haml.js +0 -4
  44. data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -3
  45. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +0 -2
  46. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +0 -2
  47. data/vendor/assets/javascripts/codemirror/modes/javascript.js +43 -30
  48. data/vendor/assets/javascripts/codemirror/modes/jinja2.js +13 -3
  49. data/vendor/assets/javascripts/codemirror/modes/less.js +7 -6
  50. data/vendor/assets/javascripts/codemirror/modes/markdown.js +231 -45
  51. data/vendor/assets/javascripts/codemirror/modes/{ocaml.js → mllike.js} +88 -13
  52. data/vendor/assets/javascripts/codemirror/modes/pegjs.js +5 -9
  53. data/vendor/assets/javascripts/codemirror/modes/php.js +6 -7
  54. data/vendor/assets/javascripts/codemirror/modes/python.js +6 -0
  55. data/vendor/assets/javascripts/codemirror/modes/r.js +5 -1
  56. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
  57. data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -1
  58. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +4 -2
  59. data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +0 -2
  60. data/vendor/assets/javascripts/codemirror/modes/sql.js +5 -4
  61. data/vendor/assets/javascripts/codemirror/modes/xml.js +87 -100
  62. data/vendor/assets/stylesheets/codemirror/themes/mbo.css +1 -1
  63. data/vendor/assets/stylesheets/codemirror/themes/midnight.css +1 -1
  64. data/vendor/assets/stylesheets/codemirror/themes/pastel-on-dark.css +49 -0
  65. data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +1 -1
  66. 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
- var columns = tables[table];
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(line, f) {
50
- var words = line.text.split(" ");
51
- for(var i = 0; i < words.length; i++) {
52
- f(words[i]);
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
- // Tries to find possible table name from alias.
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
- editor.eachLine(function(line) {
63
- eachWord(line, function(word) {
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 !== "AS") {
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].indexOf(prefix) == 0)
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.indexOf(prefix) == 0))
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).indexOf(prefix) == 0))
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].indexOf(prefix) == 0)
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.indexOf(prefix) == 0))
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
- var found = indexOf(oldContent, curInner.close, stream.pos);
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.getMode = function (options, spec) {
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
- var mname = spec, config = {};
77
- else if (spec != null)
78
- var mname = spec.name, config = spec;
79
- var mfactory = modes[mname];
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, config || {});
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.getMode = function(options, spec) {
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
- var mname = spec, config = {};
84
- else if (spec != null)
85
- var mname = spec.name, config = spec;
86
- var mfactory = modes[mname];
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, config || {});
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, typeof query == "string" && query == query.toLowerCase());
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
- var line = fold(doc.getLine(pos.line)), len = query.length, match;
62
- if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1)
63
- : (match = line.indexOf(query, pos.ch)) != -1)
64
- return {from: Pos(pos.line, match),
65
- to: Pos(pos.line, match + len)};
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 ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln));
71
- var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
72
- if (reverse ? offsetA > pos.ch || offsetA != match.length
73
- : offsetA < pos.ch || offsetA != line.length - match.length)
74
- return;
75
- for (;;) {
76
- if (reverse ? !ln : ln == doc.lineCount() - 1) return;
77
- line = fold(doc.getLine(ln += reverse ? -1 : 1));
78
- match = target[reverse ? --idx : ++idx];
79
- if (idx > 0 && idx < target.length - 1) {
80
- if (line != match) return;
81
- else continue;
82
- }
83
- var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length);
84
- if (reverse ? offsetB != line.length - match.length : offsetB != match.length)
85
- return;
86
- var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB);
87
- return {from: reverse ? end : start, to: reverse ? start : end};
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
  });