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
@@ -12,10 +12,10 @@
12
12
  CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
13
13
  var prev = old && old != CodeMirror.Init;
14
14
  if (val && !prev) {
15
- updateActiveLine(cm);
16
- cm.on("cursorActivity", updateActiveLine);
15
+ updateActiveLine(cm, cm.getCursor().line);
16
+ cm.on("beforeSelectionChange", selectionChange);
17
17
  } else if (!val && prev) {
18
- cm.off("cursorActivity", updateActiveLine);
18
+ cm.off("beforeSelectionChange", selectionChange);
19
19
  clearActiveLine(cm);
20
20
  delete cm.state.activeLine;
21
21
  }
@@ -28,12 +28,18 @@
28
28
  }
29
29
  }
30
30
 
31
- function updateActiveLine(cm) {
32
- var line = cm.getLineHandleVisualStart(cm.getCursor().line);
31
+ function updateActiveLine(cm, selectedLine) {
32
+ var line = cm.getLineHandleVisualStart(selectedLine);
33
33
  if (cm.state.activeLine == line) return;
34
- clearActiveLine(cm);
35
- cm.addLineClass(line, "wrap", WRAP_CLASS);
36
- cm.addLineClass(line, "background", BACK_CLASS);
37
- cm.state.activeLine = line;
34
+ cm.operation(function() {
35
+ clearActiveLine(cm);
36
+ cm.addLineClass(line, "wrap", WRAP_CLASS);
37
+ cm.addLineClass(line, "background", BACK_CLASS);
38
+ cm.state.activeLine = line;
39
+ });
40
+ }
41
+
42
+ function selectionChange(cm, sel) {
43
+ updateActiveLine(cm, sel.head.line);
38
44
  }
39
45
  })();
@@ -251,7 +251,7 @@
251
251
  var lex = inner.state.lexical;
252
252
  if (lex.info != "call") return;
253
253
 
254
- var ch, pos = lex.pos || 0, tabSize = cm.getOption("tabSize");
254
+ var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize");
255
255
  for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) {
256
256
  var str = cm.getLine(line), extra = 0;
257
257
  for (var pos = 0;;) {
@@ -268,7 +268,7 @@
268
268
  var start = Pos(line, ch);
269
269
  var cache = ts.cachedArgHints;
270
270
  if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0)
271
- return showArgHints(ts, cm, pos);
271
+ return showArgHints(ts, cm, argPos);
272
272
 
273
273
  ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
274
274
  if (error || !data.type || !(/^fn\(/).test(data.type)) return;
@@ -279,7 +279,7 @@
279
279
  guess: data.guess,
280
280
  doc: cm.getDoc()
281
281
  };
282
- showArgHints(ts, cm, pos);
282
+ showArgHints(ts, cm, argPos);
283
283
  });
284
284
  }
285
285
 
@@ -36,31 +36,40 @@
36
36
  var killTrailing = options.killTrailingSpace !== false;
37
37
  var changes = [], curLine = "", curNo = from.line;
38
38
  var lines = cm.getRange(from, to, false);
39
+ if (!lines.length) return null;
40
+ var leadingSpace = lines[0].match(/^[ \t]*/)[0];
41
+
39
42
  for (var i = 0; i < lines.length; ++i) {
40
43
  var text = lines[i], oldLen = curLine.length, spaceInserted = 0;
41
44
  if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) {
42
45
  curLine += " ";
43
46
  spaceInserted = 1;
44
47
  }
48
+ var spaceTrimmed = "";
49
+ if (i) {
50
+ spaceTrimmed = text.match(/^\s*/)[0];
51
+ text = text.slice(spaceTrimmed.length);
52
+ }
45
53
  curLine += text;
46
54
  if (i) {
47
- var firstBreak = curLine.length > column && findBreakPoint(curLine, column, wrapOn, killTrailing);
55
+ var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed &&
56
+ findBreakPoint(curLine, column, wrapOn, killTrailing);
48
57
  // If this isn't broken, or is broken at a different point, remove old break
49
58
  if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) {
50
- changes.push({text: spaceInserted ? " " : "",
59
+ changes.push({text: [spaceInserted ? " " : ""],
51
60
  from: Pos(curNo, oldLen),
52
- to: Pos(curNo + 1, 0)});
61
+ to: Pos(curNo + 1, spaceTrimmed.length)});
53
62
  } else {
54
- curLine = text;
63
+ curLine = leadingSpace + text;
55
64
  ++curNo;
56
65
  }
57
66
  }
58
67
  while (curLine.length > column) {
59
68
  var bp = findBreakPoint(curLine, column, wrapOn, killTrailing);
60
- changes.push({text: "\n",
69
+ changes.push({text: ["", leadingSpace],
61
70
  from: Pos(curNo, bp.from),
62
71
  to: Pos(curNo, bp.to)});
63
- curLine = curLine.slice(bp.to);
72
+ curLine = leadingSpace + curLine.slice(bp.to);
64
73
  ++curNo;
65
74
  }
66
75
  }
@@ -70,17 +79,18 @@
70
79
  cm.replaceRange(change.text, change.from, change.to);
71
80
  }
72
81
  });
82
+ return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
73
83
  }
74
84
 
75
85
  CodeMirror.defineExtension("wrapParagraph", function(pos, options) {
76
86
  options = options || {};
77
87
  if (!pos) pos = this.getCursor();
78
88
  var para = findParagraph(this, pos, options);
79
- wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options);
89
+ return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options);
80
90
  });
81
91
 
82
92
  CodeMirror.defineExtension("wrapRange", function(from, to, options) {
83
- wrapRange(this, from, to, options || {});
93
+ return wrapRange(this, from, to, options || {});
84
94
  });
85
95
 
86
96
  CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) {
@@ -91,9 +101,11 @@
91
101
  paras.push(para);
92
102
  line = para.to;
93
103
  }
104
+ var madeChange = false;
94
105
  if (paras.length) cm.operation(function() {
95
106
  for (var i = paras.length - 1; i >= 0; --i)
96
- wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options);
107
+ madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options);
97
108
  });
109
+ return madeChange;
98
110
  });
99
111
  })();
@@ -201,6 +201,11 @@
201
201
  cm.on("change", function() { cm.setExtending(false); });
202
202
  }
203
203
 
204
+ function clearMark(cm) {
205
+ cm.setExtending(false);
206
+ cm.setCursor(cm.getCursor());
207
+ }
208
+
204
209
  function getInput(cm, msg, f) {
205
210
  if (cm.openDialog)
206
211
  cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true});
@@ -234,6 +239,11 @@
234
239
  }
235
240
  }
236
241
 
242
+ function quit(cm) {
243
+ cm.execCommand("clearSearch");
244
+ clearMark(cm);
245
+ }
246
+
237
247
  // Actual keymap
238
248
 
239
249
  var keyMap = CodeMirror.keyMap.emacs = {
@@ -249,6 +259,7 @@
249
259
  }),
250
260
  "Alt-W": function(cm) {
251
261
  addToRing(cm.getSelection());
262
+ clearMark(cm);
252
263
  },
253
264
  "Ctrl-Y": function(cm) {
254
265
  var start = cm.getCursor();
@@ -334,7 +345,7 @@
334
345
  "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
335
346
  "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
336
347
  "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
337
- "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
348
+ "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
338
349
  "Alt-/": "autocomplete",
339
350
  "Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto",
340
351
 
@@ -84,6 +84,7 @@
84
84
  { keys: ['<End>'], type: 'keyToKey', toKeys: ['$'] },
85
85
  { keys: ['<PageUp>'], type: 'keyToKey', toKeys: ['<C-b>'] },
86
86
  { keys: ['<PageDown>'], type: 'keyToKey', toKeys: ['<C-f>'] },
87
+ { keys: ['<CR>'], type: 'keyToKey', toKeys: ['j', '^'], context: 'normal' },
87
88
  // Motions
88
89
  { keys: ['H'], type: 'motion',
89
90
  motion: 'moveToTopLine',
@@ -247,6 +248,12 @@
247
248
  actionArgs: { forward: true }},
248
249
  { keys: ['<C-o>'], type: 'action', action: 'jumpListWalk',
249
250
  actionArgs: { forward: false }},
251
+ { keys: ['<C-e>'], type: 'action',
252
+ action: 'scroll',
253
+ actionArgs: { forward: true, linewise: true }},
254
+ { keys: ['<C-y>'], type: 'action',
255
+ action: 'scroll',
256
+ actionArgs: { forward: false, linewise: true }},
250
257
  { keys: ['a'], type: 'action', action: 'enterInsertMode', isEdit: true,
251
258
  actionArgs: { insertAt: 'charAfter' }},
252
259
  { keys: ['A'], type: 'action', action: 'enterInsertMode', isEdit: true,
@@ -324,12 +331,16 @@
324
331
  CodeMirror.defineOption('vimMode', false, function(cm, val) {
325
332
  if (val) {
326
333
  cm.setOption('keyMap', 'vim');
334
+ cm.setOption('disableInput', true);
327
335
  CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
328
336
  cm.on('beforeSelectionChange', beforeSelectionChange);
329
337
  maybeInitVimState(cm);
338
+ CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm));
330
339
  } else if (cm.state.vim) {
331
340
  cm.setOption('keyMap', 'default');
341
+ cm.setOption('disableInput', false);
332
342
  cm.off('beforeSelectionChange', beforeSelectionChange);
343
+ CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));
333
344
  cm.state.vim = null;
334
345
  }
335
346
  });
@@ -342,6 +353,18 @@
342
353
  head.ch--;
343
354
  }
344
355
  }
356
+ function getOnPasteFn(cm) {
357
+ var vim = cm.state.vim;
358
+ if (!vim.onPasteFn) {
359
+ vim.onPasteFn = function() {
360
+ if (!vim.insertMode) {
361
+ cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));
362
+ actions.enterInsertMode(cm, {}, vim);
363
+ }
364
+ };
365
+ }
366
+ return vim.onPasteFn;
367
+ }
345
368
 
346
369
  var numberRegex = /[\d]/;
347
370
  var wordRegexp = [(/\w/), (/[^\w\s]/)], bigWordRegexp = [(/\S/)];
@@ -549,9 +572,9 @@
549
572
  maybeInitVimState_: maybeInitVimState,
550
573
 
551
574
  InsertModeKey: InsertModeKey,
552
- map: function(lhs, rhs) {
575
+ map: function(lhs, rhs, ctx) {
553
576
  // Add user defined key bindings.
554
- exCommandDispatcher.map(lhs, rhs);
577
+ exCommandDispatcher.map(lhs, rhs, ctx);
555
578
  },
556
579
  defineEx: function(name, prefix, func){
557
580
  if (name.indexOf(prefix) !== 0) {
@@ -833,11 +856,17 @@
833
856
  } else {
834
857
  // Find the best match in the list of matchedCommands.
835
858
  var context = vim.visualMode ? 'visual' : 'normal';
836
- var bestMatch = matchedCommands[0]; // Default to first in the list.
859
+ var bestMatch; // Default to first in the list.
837
860
  for (var i = 0; i < matchedCommands.length; i++) {
838
- if (matchedCommands[i].context == context) {
839
- bestMatch = matchedCommands[i];
861
+ var current = matchedCommands[i];
862
+ if (current.context == context) {
863
+ bestMatch = current;
840
864
  break;
865
+ } else if (!bestMatch && !current.context) {
866
+ // Only set an imperfect match to best match if no best match is
867
+ // set and the imperfect match is not restricted to another
868
+ // context.
869
+ bestMatch = current;
841
870
  }
842
871
  }
843
872
  return getFullyMatchedCommandOrNull(bestMatch);
@@ -1636,6 +1665,43 @@
1636
1665
  markPos = markPos ? markPos : cm.getCursor();
1637
1666
  cm.setCursor(markPos);
1638
1667
  },
1668
+ scroll: function(cm, actionArgs, vim) {
1669
+ if (vim.visualMode) {
1670
+ return;
1671
+ }
1672
+ var repeat = actionArgs.repeat || 1;
1673
+ var lineHeight = cm.defaultTextHeight();
1674
+ var top = cm.getScrollInfo().top;
1675
+ var delta = lineHeight * repeat;
1676
+ var newPos = actionArgs.forward ? top + delta : top - delta;
1677
+ var cursor = cm.getCursor();
1678
+ var cursorCoords = cm.charCoords(cursor, 'local');
1679
+ if (actionArgs.forward) {
1680
+ if (newPos > cursorCoords.top) {
1681
+ cursor.line += (newPos - cursorCoords.top) / lineHeight;
1682
+ cursor.line = Math.ceil(cursor.line);
1683
+ cm.setCursor(cursor);
1684
+ cursorCoords = cm.charCoords(cursor, 'local');
1685
+ cm.scrollTo(null, cursorCoords.top);
1686
+ } else {
1687
+ // Cursor stays within bounds. Just reposition the scroll window.
1688
+ cm.scrollTo(null, newPos);
1689
+ }
1690
+ } else {
1691
+ var newBottom = newPos + cm.getScrollInfo().clientHeight;
1692
+ if (newBottom < cursorCoords.bottom) {
1693
+ cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight;
1694
+ cursor.line = Math.floor(cursor.line);
1695
+ cm.setCursor(cursor);
1696
+ cursorCoords = cm.charCoords(cursor, 'local');
1697
+ cm.scrollTo(
1698
+ null, cursorCoords.bottom - cm.getScrollInfo().clientHeight);
1699
+ } else {
1700
+ // Cursor stays within bounds. Just reposition the scroll window.
1701
+ cm.scrollTo(null, newPos);
1702
+ }
1703
+ }
1704
+ },
1639
1705
  scrollToCursor: function(cm, actionArgs) {
1640
1706
  var lineNum = cm.getCursor().line;
1641
1707
  var charCoords = cm.charCoords({line: lineNum, ch: 0}, 'local');
@@ -1691,6 +1757,7 @@
1691
1757
  cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm));
1692
1758
  }
1693
1759
  cm.setOption('keyMap', 'vim-insert');
1760
+ cm.setOption('disableInput', false);
1694
1761
  if (actionArgs && actionArgs.replace) {
1695
1762
  // Handle Replace-mode as a special case of insert mode.
1696
1763
  cm.toggleOverwrite(true);
@@ -2896,14 +2963,16 @@
2896
2963
  // pair of commands that have a shared prefix, at least one of their
2897
2964
  // shortNames must not match the prefix of the other command.
2898
2965
  var defaultExCommandMap = [
2899
- { name: 'map', type: 'builtIn' },
2900
- { name: 'write', shortName: 'w', type: 'builtIn' },
2901
- { name: 'undo', shortName: 'u', type: 'builtIn' },
2902
- { name: 'redo', shortName: 'red', type: 'builtIn' },
2903
- { name: 'sort', shortName: 'sor', type: 'builtIn'},
2904
- { name: 'substitute', shortName: 's', type: 'builtIn'},
2905
- { name: 'nohlsearch', shortName: 'noh', type: 'builtIn'},
2906
- { name: 'delmarks', shortName: 'delm', type: 'builtin'}
2966
+ { name: 'map' },
2967
+ { name: 'nmap', shortName: 'nm' },
2968
+ { name: 'vmap', shortName: 'vm' },
2969
+ { name: 'write', shortName: 'w' },
2970
+ { name: 'undo', shortName: 'u' },
2971
+ { name: 'redo', shortName: 'red' },
2972
+ { name: 'sort', shortName: 'sor' },
2973
+ { name: 'substitute', shortName: 's' },
2974
+ { name: 'nohlsearch', shortName: 'noh' },
2975
+ { name: 'delmarks', shortName: 'delm' }
2907
2976
  ];
2908
2977
  Vim.ExCommandDispatcher = function() {
2909
2978
  this.buildCommandMap_();
@@ -2955,6 +3024,7 @@
2955
3024
  exCommands[commandName](cm, params);
2956
3025
  } catch(e) {
2957
3026
  showConfirm(cm, e);
3027
+ throw e;
2958
3028
  }
2959
3029
  },
2960
3030
  parseInput_: function(cm, inputStream, result) {
@@ -3037,8 +3107,9 @@
3037
3107
  this.commandMap_[key] = command;
3038
3108
  }
3039
3109
  },
3040
- map: function(lhs, rhs) {
3110
+ map: function(lhs, rhs, ctx) {
3041
3111
  if (lhs != ':' && lhs.charAt(0) == ':') {
3112
+ if (ctx) { throw Error('Mode not supported for ex mappings'); }
3042
3113
  var commandName = lhs.substring(1);
3043
3114
  if (rhs != ':' && rhs.charAt(0) == ':') {
3044
3115
  // Ex to Ex mapping
@@ -3058,17 +3129,21 @@
3058
3129
  } else {
3059
3130
  if (rhs != ':' && rhs.charAt(0) == ':') {
3060
3131
  // Key to Ex mapping.
3061
- defaultKeymap.unshift({
3132
+ var mapping = {
3062
3133
  keys: parseKeyString(lhs),
3063
3134
  type: 'keyToEx',
3064
- exArgs: { input: rhs.substring(1) }});
3135
+ exArgs: { input: rhs.substring(1) }};
3136
+ if (ctx) { mapping.context = ctx; }
3137
+ defaultKeymap.unshift(mapping);
3065
3138
  } else {
3066
3139
  // Key to key mapping
3067
- defaultKeymap.unshift({
3140
+ var mapping = {
3068
3141
  keys: parseKeyString(lhs),
3069
3142
  type: 'keyToKey',
3070
3143
  toKeys: parseKeyString(rhs)
3071
- });
3144
+ };
3145
+ if (ctx) { mapping.context = ctx; }
3146
+ defaultKeymap.unshift(mapping);
3072
3147
  }
3073
3148
  }
3074
3149
  }
@@ -3090,7 +3165,7 @@
3090
3165
  }
3091
3166
 
3092
3167
  var exCommands = {
3093
- map: function(cm, params) {
3168
+ map: function(cm, params, ctx) {
3094
3169
  var mapArgs = params.args;
3095
3170
  if (!mapArgs || mapArgs.length < 2) {
3096
3171
  if (cm) {
@@ -3098,8 +3173,10 @@
3098
3173
  }
3099
3174
  return;
3100
3175
  }
3101
- exCommandDispatcher.map(mapArgs[0], mapArgs[1], cm);
3176
+ exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx);
3102
3177
  },
3178
+ nmap: function(cm, params) { this.map(cm, params, 'normal'); },
3179
+ vmap: function(cm, params) { this.map(cm, params, 'visual'); },
3103
3180
  move: function(cm, params) {
3104
3181
  commandDispatcher.processCommand(cm, cm.state.vim, {
3105
3182
  type: 'motion',
@@ -3115,7 +3192,7 @@
3115
3192
  var args = new CodeMirror.StringStream(params.argString);
3116
3193
  if (args.eat('!')) { reverse = true; }
3117
3194
  if (args.eol()) { return; }
3118
- if (!args.eatSpace()) { throw new Error('invalid arguments ' + args.match(/.*/)[0]); }
3195
+ if (!args.eatSpace()) { return 'Invalid arguments'; }
3119
3196
  var opts = args.match(/[a-z]+/);
3120
3197
  if (opts) {
3121
3198
  opts = opts[0];
@@ -3124,13 +3201,17 @@
3124
3201
  var decimal = opts.indexOf('d') != -1 && 1;
3125
3202
  var hex = opts.indexOf('x') != -1 && 1;
3126
3203
  var octal = opts.indexOf('o') != -1 && 1;
3127
- if (decimal + hex + octal > 1) { throw new Error('invalid arguments'); }
3204
+ if (decimal + hex + octal > 1) { return 'Invalid arguments'; }
3128
3205
  number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';
3129
3206
  }
3130
- if (args.eatSpace() && args.match(/\/.*\//)) { throw new Error('patterns not supported'); }
3207
+ if (args.eatSpace() && args.match(/\/.*\//)) { 'patterns not supported'; }
3131
3208
  }
3132
3209
  }
3133
- parseArgs();
3210
+ var err = parseArgs();
3211
+ if (err) {
3212
+ showConfirm(cm, err + ': ' + params.argString);
3213
+ return;
3214
+ }
3134
3215
  var lineStart = params.line || cm.firstLine();
3135
3216
  var lineEnd = params.lineEnd || params.line || cm.lastLine();
3136
3217
  if (lineStart == lineEnd) { return; }
@@ -3251,13 +3332,13 @@
3251
3332
  clearSearchHighlight(cm);
3252
3333
  },
3253
3334
  delmarks: function(cm, params) {
3254
- if (!params.argString || !params.argString.trim()) {
3335
+ if (!params.argString || !trim(params.argString)) {
3255
3336
  showConfirm(cm, 'Argument required');
3256
3337
  return;
3257
3338
  }
3258
3339
 
3259
3340
  var state = cm.state.vim;
3260
- var stream = new CodeMirror.StringStream(params.argString.trim());
3341
+ var stream = new CodeMirror.StringStream(trim(params.argString));
3261
3342
  while (!stream.eol()) {
3262
3343
  stream.eatSpace();
3263
3344
 
@@ -3394,7 +3475,8 @@
3394
3475
  // Actually do replace.
3395
3476
  next();
3396
3477
  if (done) {
3397
- throw new Error('No matches for ' + query.source);
3478
+ showConfirm(cm, 'No matches for ' + query.source);
3479
+ return;
3398
3480
  }
3399
3481
  if (!confirm) {
3400
3482
  replaceAll();
@@ -3445,7 +3527,6 @@
3445
3527
 
3446
3528
  var cmToVimKeymap = {
3447
3529
  'nofallthrough': true,
3448
- 'disableInput': true,
3449
3530
  'style': 'fat-cursor'
3450
3531
  };
3451
3532
  function bindKeys(keys, modifier) {
@@ -3492,6 +3573,7 @@
3492
3573
  cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
3493
3574
  vim.insertMode = false;
3494
3575
  cm.setOption('keyMap', 'vim');
3576
+ cm.setOption('disableInput', true);
3495
3577
  cm.toggleOverwrite(false); // exit replace mode if we were in it.
3496
3578
  CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
3497
3579
  }