codemirror-rails 5.2 → 5.3

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +34 -27
  4. data/vendor/assets/javascripts/codemirror/addons/display/rulers.js +1 -2
  5. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +1 -0
  6. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +14 -23
  7. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +12 -3
  8. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +6 -6
  9. data/vendor/assets/javascripts/codemirror/addons/search/search.js +1 -1
  10. data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +2 -2
  11. data/vendor/assets/javascripts/codemirror/addons/tern/worker.js +1 -1
  12. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +64 -67
  13. data/vendor/assets/javascripts/codemirror/modes/apl.js +1 -2
  14. data/vendor/assets/javascripts/codemirror/modes/asn.1.js +204 -0
  15. data/vendor/assets/javascripts/codemirror/modes/asterisk.js +2 -4
  16. data/vendor/assets/javascripts/codemirror/modes/clike.js +98 -36
  17. data/vendor/assets/javascripts/codemirror/modes/css.js +1 -16
  18. data/vendor/assets/javascripts/codemirror/modes/cypher.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/modes/dylan.js +18 -26
  20. data/vendor/assets/javascripts/codemirror/modes/ecl.js +1 -2
  21. data/vendor/assets/javascripts/codemirror/modes/eiffel.js +0 -2
  22. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +2 -2
  23. data/vendor/assets/javascripts/codemirror/modes/julia.js +0 -2
  24. data/vendor/assets/javascripts/codemirror/modes/livescript.js +2 -2
  25. data/vendor/assets/javascripts/codemirror/modes/mathematica.js +175 -0
  26. data/vendor/assets/javascripts/codemirror/modes/php.js +1 -0
  27. data/vendor/assets/javascripts/codemirror/modes/pig.js +15 -25
  28. data/vendor/assets/javascripts/codemirror/modes/sql.js +2 -2
  29. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +36 -47
  30. data/vendor/assets/javascripts/codemirror/modes/tiki.js +8 -19
  31. data/vendor/assets/javascripts/codemirror/modes/ttcn-cfg.js +214 -0
  32. data/vendor/assets/javascripts/codemirror/modes/ttcn.js +283 -0
  33. data/vendor/assets/javascripts/codemirror/modes/xquery.js +30 -40
  34. data/vendor/assets/stylesheets/codemirror/addons/dialog/dialog.css +2 -2
  35. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +1 -0
  36. data/vendor/assets/stylesheets/codemirror/themes/ttcn.css +66 -0
  37. metadata +8 -7
  38. data/vendor/assets/javascripts/codemirror/addons/mode/multiplex_test.js +0 -33
  39. data/vendor/assets/javascripts/codemirror/modes/less_test.js +0 -54
  40. data/vendor/assets/javascripts/codemirror/modes/scss_test.js +0 -110
  41. data/vendor/assets/javascripts/codemirror/modes/test.js +0 -67
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 050b051a53f2101672d02e5b5a5b0e8882e01efa
4
- data.tar.gz: 0a4451cf450a3dd4bd78c7269d779dfdda8fd7dd
3
+ metadata.gz: c6ddde433ae7b37ee0173fe1a42d41cd91f3744d
4
+ data.tar.gz: b69c9951146b7b058e70a132e59ea6572d16c853
5
5
  SHA512:
6
- metadata.gz: 00407212b29c41420da933d548ab4d703276f80a539a5593ac6ca21127f5837a7fd0fbf21af9414dd1bf275bbf96fa0de3c83be7834d7118767f6f29de00da45
7
- data.tar.gz: 49f03cf54ac054fd36d13e8e038956647eeb0120db8c3186a5036575d185e8ca71d2c1e9556bdcf675c95e2dffefb016772dfb5c59664cdad12caed2af2df4bb
6
+ metadata.gz: cbd3e9ba7e1b89305aaa9f361cf5f7859b9a46c0297974d5211ffd357eb5dc0d5b0453eb0715bb46e3f786dd02d871ea5b9712eda1886b27e20585c79c86ac9d
7
+ data.tar.gz: b232672158c10203601d827f7a3251b5c717f66ba0ce6e08b1e07537bf20854e42fd4a07c025bc5ddf84137544c4d2371fa4a89afbfc04d5720a3bd883cc017f
@@ -1,6 +1,6 @@
1
1
  module Codemirror
2
2
  module Rails
3
- VERSION = '5.2'
4
- CODEMIRROR_VERSION = '5.2'
3
+ VERSION = '5.3'
4
+ CODEMIRROR_VERSION = '5.3'
5
5
  end
6
6
  end
@@ -728,12 +728,9 @@
728
728
  }
729
729
 
730
730
  function postUpdateDisplay(cm, update) {
731
- var force = update.force, viewport = update.viewport;
731
+ var viewport = update.viewport;
732
732
  for (var first = true;; first = false) {
733
- if (first && cm.options.lineWrapping && update.oldDisplayWidth != displayWidth(cm)) {
734
- force = true;
735
- } else {
736
- force = false;
733
+ if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
737
734
  // Clip forced viewport to actual scrollable area.
738
735
  if (viewport && viewport.top != null)
739
736
  viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
@@ -1108,32 +1105,40 @@
1108
1105
  origin: origin || (cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
1109
1106
  makeChange(cm.doc, changeEvent);
1110
1107
  signalLater(cm, "inputRead", cm, changeEvent);
1111
- // When an 'electric' character is inserted, immediately trigger a reindent
1112
- if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
1113
- cm.options.smartIndent && range.head.ch < 100 &&
1114
- (!i || sel.ranges[i - 1].head.line != range.head.line)) {
1115
- var mode = cm.getModeAt(range.head);
1116
- var end = changeEnd(changeEvent);
1117
- var indented = false;
1118
- if (mode.electricChars) {
1119
- for (var j = 0; j < mode.electricChars.length; j++)
1120
- if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
1121
- indented = indentLine(cm, end.line, "smart");
1122
- break;
1123
- }
1124
- } else if (mode.electricInput) {
1125
- if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
1126
- indented = indentLine(cm, end.line, "smart");
1127
- }
1128
- if (indented) signalLater(cm, "electricInput", cm, end.line);
1129
- }
1130
1108
  }
1109
+ if (inserted && !cm.state.pasteIncoming)
1110
+ triggerElectric(cm, inserted);
1111
+
1131
1112
  ensureCursorVisible(cm);
1132
1113
  cm.curOp.updateInput = updateInput;
1133
1114
  cm.curOp.typing = true;
1134
1115
  cm.state.pasteIncoming = cm.state.cutIncoming = false;
1135
1116
  }
1136
1117
 
1118
+ function triggerElectric(cm, inserted) {
1119
+ // When an 'electric' character is inserted, immediately trigger a reindent
1120
+ if (!cm.options.electricChars || !cm.options.smartIndent) return;
1121
+ var sel = cm.doc.sel;
1122
+
1123
+ for (var i = sel.ranges.length - 1; i >= 0; i--) {
1124
+ var range = sel.ranges[i];
1125
+ if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue;
1126
+ var mode = cm.getModeAt(range.head);
1127
+ var indented = false;
1128
+ if (mode.electricChars) {
1129
+ for (var j = 0; j < mode.electricChars.length; j++)
1130
+ if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
1131
+ indented = indentLine(cm, range.head.line, "smart");
1132
+ break;
1133
+ }
1134
+ } else if (mode.electricInput) {
1135
+ if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
1136
+ indented = indentLine(cm, range.head.line, "smart");
1137
+ }
1138
+ if (indented) signalLater(cm, "electricInput", cm, range.head.line);
1139
+ }
1140
+ }
1141
+
1137
1142
  function copyableRanges(cm) {
1138
1143
  var text = [], ranges = [];
1139
1144
  for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
@@ -1836,7 +1841,7 @@
1836
1841
  var partPos = getBidiPartAt(order, pos.ch);
1837
1842
  side = partPos % 2 ? "right" : "left";
1838
1843
  }
1839
- var result = nodeAndOffsetInLineMap(info.map, pos.ch, "left");
1844
+ var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
1840
1845
  result.offset = result.collapse == "right" ? result.end : result.start;
1841
1846
  return result;
1842
1847
  }
@@ -5053,6 +5058,8 @@
5053
5058
  return commands[cmd](this);
5054
5059
  },
5055
5060
 
5061
+ triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
5062
+
5056
5063
  findPosH: function(from, amount, unit, visually) {
5057
5064
  var dir = 1;
5058
5065
  if (amount < 0) { dir = -1; amount = -amount; }
@@ -5720,7 +5727,7 @@
5720
5727
  for (var i = 0; i < keys.length; i++) {
5721
5728
  var val, name;
5722
5729
  if (i == keys.length - 1) {
5723
- name = keyname;
5730
+ name = keys.join(" ");
5724
5731
  val = value;
5725
5732
  } else {
5726
5733
  name = keys.slice(0, i + 1).join(" ");
@@ -8732,7 +8739,7 @@
8732
8739
 
8733
8740
  // THE END
8734
8741
 
8735
- CodeMirror.version = "5.2.0";
8742
+ CodeMirror.version = "5.3.0";
8736
8743
 
8737
8744
  return CodeMirror;
8738
8745
  });
@@ -38,7 +38,7 @@
38
38
  for (var i = 0; i < val.length; i++) {
39
39
  var elt = document.createElement("div");
40
40
  elt.className = "CodeMirror-ruler";
41
- var col, cls = null, conf = val[i];
41
+ var col, conf = val[i];
42
42
  if (typeof conf == "number") {
43
43
  col = conf;
44
44
  } else {
@@ -47,7 +47,6 @@
47
47
  if (conf.color) elt.style.borderColor = conf.color;
48
48
  if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle;
49
49
  if (conf.width) elt.style.borderLeftWidth = conf.width;
50
- cls = val[i].className;
51
50
  }
52
51
  elt.style.left = (left + col * cw) + "px";
53
52
  elt.style.top = "-50px";
@@ -147,6 +147,7 @@
147
147
  cm.replaceSelections(sels, "around");
148
148
  } else if (type == "both") {
149
149
  cm.replaceSelection(left + right, null);
150
+ cm.triggerElectric(left + right);
150
151
  cm.execCommand("goCharLeft");
151
152
  } else if (type == "addFour") {
152
153
  cm.replaceSelection(left + left + left + left, "before");
@@ -33,7 +33,7 @@
33
33
  if (!completion.options.hint) return;
34
34
 
35
35
  CodeMirror.signal(this, "startCompletion", this);
36
- completion.update();
36
+ completion.update(true);
37
37
  });
38
38
 
39
39
  function Completion(cm, options) {
@@ -61,6 +61,7 @@
61
61
  this.tick = null;
62
62
  this.cm.off("cursorActivity", this.activityFunc);
63
63
 
64
+ if (this.widget && this.data) CodeMirror.signal(this.data, "close");
64
65
  if (this.widget) this.widget.close();
65
66
  CodeMirror.signal(this.cm, "endCompletion", this.cm);
66
67
  },
@@ -78,15 +79,6 @@
78
79
  this.close();
79
80
  },
80
81
 
81
- showHints: function(data) {
82
- if (!data || !data.list.length || !this.active()) return this.close();
83
-
84
- if (this.options.completeSingle && data.list.length == 1)
85
- this.pick(data, 0);
86
- else
87
- this.showWidget(data);
88
- },
89
-
90
82
  cursorActivity: function() {
91
83
  if (this.debounce) {
92
84
  cancelAnimationFrame(this.debounce);
@@ -105,35 +97,34 @@
105
97
  }
106
98
  },
107
99
 
108
- update: function() {
100
+ update: function(first) {
109
101
  if (this.tick == null) return;
110
102
  if (this.data) CodeMirror.signal(this.data, "update");
111
103
  if (!this.options.hint.async) {
112
- this.finishUpdate(this.options.hint(this.cm, this.options), myTick);
104
+ this.finishUpdate(this.options.hint(this.cm, this.options), first);
113
105
  } else {
114
106
  var myTick = ++this.tick, self = this;
115
107
  this.options.hint(this.cm, function(data) {
116
- if (self.tick == myTick) self.finishUpdate(data);
108
+ if (self.tick == myTick) self.finishUpdate(data, first);
117
109
  }, this.options);
118
110
  }
119
111
  },
120
112
 
121
- finishUpdate: function(data) {
113
+ finishUpdate: function(data, first) {
122
114
  this.data = data;
123
- var picked = this.widget && this.widget.picked;
115
+
116
+ var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
124
117
  if (this.widget) this.widget.close();
125
118
  if (data && data.list.length) {
126
- if (picked && data.list.length == 1) this.pick(data, 0);
127
- else this.widget = new Widget(this, data);
119
+ if (picked && data.list.length == 1) {
120
+ this.pick(data, 0);
121
+ } else {
122
+ this.widget = new Widget(this, data);
123
+ CodeMirror.signal(data, "shown");
124
+ }
128
125
  }
129
126
  },
130
127
 
131
- showWidget: function(data) {
132
- this.data = data;
133
- this.widget = new Widget(this, data);
134
- CodeMirror.signal(data, "shown");
135
- },
136
-
137
128
  buildOptions: function(options) {
138
129
  var editor = this.cm.options.hintOptions;
139
130
  var out = {};
@@ -112,9 +112,14 @@
112
112
  string = nameParts.pop();
113
113
  var table = nameParts.join(".");
114
114
 
115
+ var alias = false;
116
+ var aliasTable = table;
115
117
  // Check if table is available. If not, find table by Alias
116
- if (!getItem(tables, table))
118
+ if (!getItem(tables, table)) {
119
+ var oldTable = table;
117
120
  table = findTableByAlias(table, editor);
121
+ if (table !== oldTable) alias = true;
122
+ }
118
123
 
119
124
  var columns = getItem(tables, table);
120
125
  if (columns && columns.columns)
@@ -123,7 +128,9 @@
123
128
  if (columns) {
124
129
  addMatches(result, string, columns, function(w) {
125
130
  if (typeof w == "string") {
126
- w = table + "." + w;
131
+ var tableInsert = table;
132
+ if (alias == true) tableInsert = aliasTable;
133
+ w = tableInsert + "." + w;
127
134
  } else {
128
135
  w = shallowClone(w);
129
136
  w.text = table + "." + w.text;
@@ -205,6 +212,7 @@
205
212
  CodeMirror.registerHelper("hint", "sql", function(editor, options) {
206
213
  tables = (options && options.tables) || {};
207
214
  var defaultTableName = options && options.defaultTable;
215
+ var disableKeywords = options && options.disableKeywords;
208
216
  defaultTable = defaultTableName && getItem(tables, defaultTableName);
209
217
  keywords = keywords || getKeywords(editor);
210
218
 
@@ -237,7 +245,8 @@
237
245
  } else {
238
246
  addMatches(result, search, tables, function(w) {return w;});
239
247
  addMatches(result, search, defaultTable, function(w) {return w;});
240
- addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
248
+ if (!disableKeywords)
249
+ addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
241
250
  }
242
251
 
243
252
  return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
@@ -63,11 +63,9 @@
63
63
  this.onMouseOver = function(e) { onMouseOver(cm, e); };
64
64
  }
65
65
 
66
- function parseOptions(cm, options) {
66
+ function parseOptions(_cm, options) {
67
67
  if (options instanceof Function) return {getAnnotations: options};
68
68
  if (!options || options === true) options = {};
69
- if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
70
- if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
71
69
  return options;
72
70
  }
73
71
 
@@ -120,10 +118,12 @@
120
118
  function startLinting(cm) {
121
119
  var state = cm.state.lint, options = state.options;
122
120
  var passOptions = options.options || options; // Support deprecated passing of `options` property in options
123
- if (options.async || options.getAnnotations.async)
124
- options.getAnnotations(cm.getValue(), updateLinting, passOptions, cm);
121
+ var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
122
+ if (!getAnnotations) return;
123
+ if (options.async || getAnnotations.async)
124
+ getAnnotations(cm.getValue(), updateLinting, passOptions, cm);
125
125
  else
126
- updateLinting(cm, options.getAnnotations(cm.getValue(), passOptions, cm));
126
+ updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm));
127
127
  }
128
128
 
129
129
  function updateLinting(cm, annotationsNotSorted) {
@@ -118,7 +118,7 @@
118
118
  var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
119
119
  function replace(cm, all) {
120
120
  if (cm.getOption("readOnly")) return;
121
- var query = cm.getSelection() || getSearchState().lastQuery;
121
+ var query = cm.getSelection() || getSearchState(cm).lastQuery;
122
122
  dialog(cm, replaceQueryDialog, "Replace:", query, function(query) {
123
123
  if (!query) return;
124
124
  query = parseQuery(query);
@@ -177,9 +177,9 @@
177
177
  });
178
178
 
179
179
  CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
180
- var ranges = [], next;
180
+ var ranges = [];
181
181
  var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
182
- while (next = cur.findNext()) {
182
+ while (cur.findNext()) {
183
183
  if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
184
184
  ranges.push({anchor: cur.from(), head: cur.to()});
185
185
  }
@@ -39,6 +39,6 @@ function startServer(defs, plugins, scripts) {
39
39
  });
40
40
  }
41
41
 
42
- var console = {
42
+ this.console = {
43
43
  log: function(v) { postMessage({type: "debug", message: v}); }
44
44
  };
@@ -3,42 +3,16 @@
3
3
 
4
4
  /**
5
5
  * Supported keybindings:
6
+ * Too many to list. Refer to defaultKeyMap below.
6
7
  *
7
- * Motion:
8
- * h, j, k, l
9
- * gj, gk
10
- * e, E, w, W, b, B, ge, gE
11
- * f<character>, F<character>, t<character>, T<character>
12
- * $, ^, 0, -, +, _
13
- * gg, G
14
- * %
15
- * '<character>, `<character>
16
- *
17
- * Operator:
18
- * d, y, c
19
- * dd, yy, cc
20
- * g~, g~g~
21
- * >, <, >>, <<
22
- *
23
- * Operator-Motion:
24
- * x, X, D, Y, C, ~
25
- *
26
- * Action:
27
- * a, i, s, A, I, S, o, O
28
- * zz, z., z<CR>, zt, zb, z-
29
- * J
30
- * u, Ctrl-r
31
- * m<character>
32
- * r<character>
33
- *
34
- * Modes:
35
- * ESC - leave insert mode, visual mode, and clear input state.
36
- * Ctrl-[, Ctrl-c - same as ESC.
8
+ * Supported Ex commands:
9
+ * Refer to defaultExCommandMap below.
37
10
  *
38
11
  * Registers: unnamed, -, a-z, A-Z, 0-9
39
12
  * (Does not respect the special case for number registers when delete
40
13
  * operator is made with these commands: %, (, ), , /, ?, n, N, {, } )
41
14
  * TODO: Implement the remaining registers.
15
+ *
42
16
  * Marks: a-z, A-Z, and 0-9
43
17
  * TODO: Implement the remaining special marks. They have more complex
44
18
  * behavior.
@@ -57,6 +31,7 @@
57
31
  * 6. Motion, operator, and action implementations
58
32
  * 7. Helper functions for the key handler, motions, operators, and actions
59
33
  * 8. Set up Vim to work as a keymap for CodeMirror.
34
+ * 9. Ex command implementations.
60
35
  */
61
36
 
62
37
  (function(mod) {
@@ -227,6 +202,34 @@
227
202
  { keys: ':', type: 'ex' }
228
203
  ];
229
204
 
205
+ /**
206
+ * Ex commands
207
+ * Care must be taken when adding to the default Ex command map. For any
208
+ * pair of commands that have a shared prefix, at least one of their
209
+ * shortNames must not match the prefix of the other command.
210
+ */
211
+ var defaultExCommandMap = [
212
+ { name: 'colorscheme', shortName: 'colo' },
213
+ { name: 'map' },
214
+ { name: 'imap', shortName: 'im' },
215
+ { name: 'nmap', shortName: 'nm' },
216
+ { name: 'vmap', shortName: 'vm' },
217
+ { name: 'unmap' },
218
+ { name: 'write', shortName: 'w' },
219
+ { name: 'undo', shortName: 'u' },
220
+ { name: 'redo', shortName: 'red' },
221
+ { name: 'set', shortName: 'se' },
222
+ { name: 'set', shortName: 'se' },
223
+ { name: 'setlocal', shortName: 'setl' },
224
+ { name: 'setglobal', shortName: 'setg' },
225
+ { name: 'sort', shortName: 'sor' },
226
+ { name: 'substitute', shortName: 's', possiblyAsync: true },
227
+ { name: 'nohlsearch', shortName: 'noh' },
228
+ { name: 'delmarks', shortName: 'delm' },
229
+ { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
230
+ { name: 'global', shortName: 'g' }
231
+ ];
232
+
230
233
  var Pos = CodeMirror.Pos;
231
234
 
232
235
  var Vim = function() {
@@ -463,7 +466,7 @@
463
466
  }
464
467
  // The 'filetype' option proxies to the CodeMirror 'mode' option.
465
468
  if (name === undefined) {
466
- var mode = cm.getMode().name;
469
+ var mode = cm.getOption('mode');
467
470
  return mode == 'null' ? '' : mode;
468
471
  } else {
469
472
  var mode = name == '' ? 'null' : name;
@@ -689,7 +692,9 @@
689
692
  getOption: getOption,
690
693
  defineOption: defineOption,
691
694
  defineEx: function(name, prefix, func){
692
- if (name.indexOf(prefix) !== 0) {
695
+ if (!prefix) {
696
+ prefix = name;
697
+ } else if (name.indexOf(prefix) !== 0) {
693
698
  throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered');
694
699
  }
695
700
  exCommands[name]=func;
@@ -3635,13 +3640,17 @@
3635
3640
  // Translates the replace part of a search and replace from ex (vim) syntax into
3636
3641
  // javascript form. Similar to translateRegex, but additionally fixes back references
3637
3642
  // (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'.
3643
+ var charUnescapes = {'\\n': '\n', '\\r': '\r', '\\t': '\t'};
3638
3644
  function translateRegexReplace(str) {
3639
3645
  var escapeNextChar = false;
3640
3646
  var out = [];
3641
3647
  for (var i = -1; i < str.length; i++) {
3642
3648
  var c = str.charAt(i) || '';
3643
3649
  var n = str.charAt(i+1) || '';
3644
- if (escapeNextChar) {
3650
+ if (charUnescapes[c + n]) {
3651
+ out.push(charUnescapes[c+n]);
3652
+ i++;
3653
+ } else if (escapeNextChar) {
3645
3654
  // At any point in the loop, escapeNextChar is true if the previous
3646
3655
  // character was a '\' and was not escaped.
3647
3656
  out.push(c);
@@ -3669,6 +3678,7 @@
3669
3678
  }
3670
3679
 
3671
3680
  // Unescape \ and / in the replace part, for PCRE mode.
3681
+ var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'};
3672
3682
  function unescapeRegexReplace(str) {
3673
3683
  var stream = new CodeMirror.StringStream(str);
3674
3684
  var output = [];
@@ -3677,13 +3687,15 @@
3677
3687
  while (stream.peek() && stream.peek() != '\\') {
3678
3688
  output.push(stream.next());
3679
3689
  }
3680
- if (stream.match('\\/', true)) {
3681
- // \/ => /
3682
- output.push('/');
3683
- } else if (stream.match('\\\\', true)) {
3684
- // \\ => \
3685
- output.push('\\');
3686
- } else {
3690
+ var matched = false;
3691
+ for (var matcher in unescapes) {
3692
+ if (stream.match(matcher, true)) {
3693
+ matched = true;
3694
+ output.push(unescapes[matcher]);
3695
+ break;
3696
+ }
3697
+ }
3698
+ if (!matched) {
3687
3699
  // Don't change anything
3688
3700
  output.push(stream.next());
3689
3701
  }
@@ -3913,31 +3925,6 @@
3913
3925
  return {top: from.line, bottom: to.line};
3914
3926
  }
3915
3927
 
3916
- // Ex command handling
3917
- // Care must be taken when adding to the default Ex command map. For any
3918
- // pair of commands that have a shared prefix, at least one of their
3919
- // shortNames must not match the prefix of the other command.
3920
- var defaultExCommandMap = [
3921
- { name: 'colorscheme', shortName: 'colo' },
3922
- { name: 'map' },
3923
- { name: 'imap', shortName: 'im' },
3924
- { name: 'nmap', shortName: 'nm' },
3925
- { name: 'vmap', shortName: 'vm' },
3926
- { name: 'unmap' },
3927
- { name: 'write', shortName: 'w' },
3928
- { name: 'undo', shortName: 'u' },
3929
- { name: 'redo', shortName: 'red' },
3930
- { name: 'set', shortName: 'se' },
3931
- { name: 'set', shortName: 'se' },
3932
- { name: 'setlocal', shortName: 'setl' },
3933
- { name: 'setglobal', shortName: 'setg' },
3934
- { name: 'sort', shortName: 'sor' },
3935
- { name: 'substitute', shortName: 's', possiblyAsync: true },
3936
- { name: 'nohlsearch', shortName: 'noh' },
3937
- { name: 'delmarks', shortName: 'delm' },
3938
- { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
3939
- { name: 'global', shortName: 'g' }
3940
- ];
3941
3928
  var ExCommandDispatcher = function() {
3942
3929
  this.buildCommandMap_();
3943
3930
  };
@@ -4483,6 +4470,9 @@
4483
4470
  var query = state.getQuery();
4484
4471
  var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;
4485
4472
  var lineEnd = params.lineEnd || lineStart;
4473
+ if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) {
4474
+ lineEnd = Infinity;
4475
+ }
4486
4476
  if (count) {
4487
4477
  lineStart = lineEnd;
4488
4478
  lineEnd = lineStart + count - 1;
@@ -4601,10 +4591,9 @@
4601
4591
  searchCursor.replace(newText);
4602
4592
  }
4603
4593
  function next() {
4604
- var found;
4605
4594
  // The below only loops to skip over multiple occurrences on the same
4606
4595
  // line when 'global' is not true.
4607
- while(found = searchCursor.findNext() &&
4596
+ while(searchCursor.findNext() &&
4608
4597
  isInRange(searchCursor.from(), lineStart, lineEnd)) {
4609
4598
  if (!global && lastPos && searchCursor.from().line == lastPos.line) {
4610
4599
  continue;
@@ -4779,6 +4768,14 @@
4779
4768
 
4780
4769
  function executeMacroRegister(cm, vim, macroModeState, registerName) {
4781
4770
  var register = vimGlobalState.registerController.getRegister(registerName);
4771
+ if (registerName == ':') {
4772
+ // Read-only register containing last Ex command.
4773
+ if (register.keyBuffer[0]) {
4774
+ exCommandDispatcher.processCommand(cm, register.keyBuffer[0]);
4775
+ }
4776
+ macroModeState.isPlaying = false;
4777
+ return;
4778
+ }
4782
4779
  var keyBuffer = register.keyBuffer;
4783
4780
  var imc = 0;
4784
4781
  macroModeState.isPlaying = true;