codemirror-rails 2.24 → 2.32

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 (90) hide show
  1. data/.gitignore +1 -0
  2. data/Rakefile +19 -0
  3. data/codemirror-rails.gemspec +6 -1
  4. data/lib/codemirror/rails/version.rb +2 -2
  5. data/test/dummy/README.rdoc +261 -0
  6. data/test/dummy/Rakefile +7 -0
  7. data/test/dummy/app/assets/javascripts/application.js +15 -0
  8. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  9. data/test/dummy/app/controllers/application_controller.rb +3 -0
  10. data/test/dummy/app/helpers/application_helper.rb +2 -0
  11. data/test/dummy/app/mailers/.gitkeep +0 -0
  12. data/test/dummy/app/models/.gitkeep +0 -0
  13. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  14. data/test/dummy/config.ru +4 -0
  15. data/test/dummy/config/application.rb +56 -0
  16. data/test/dummy/config/boot.rb +10 -0
  17. data/test/dummy/config/environment.rb +5 -0
  18. data/test/dummy/config/environments/development.rb +37 -0
  19. data/test/dummy/config/environments/production.rb +67 -0
  20. data/test/dummy/config/environments/test.rb +37 -0
  21. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  22. data/test/dummy/config/initializers/inflections.rb +15 -0
  23. data/test/dummy/config/initializers/mime_types.rb +5 -0
  24. data/test/dummy/config/initializers/secret_token.rb +7 -0
  25. data/test/dummy/config/initializers/session_store.rb +8 -0
  26. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  27. data/test/dummy/config/locales/en.yml +5 -0
  28. data/test/dummy/config/routes.rb +58 -0
  29. data/test/dummy/lib/assets/.gitkeep +0 -0
  30. data/test/dummy/log/.gitkeep +0 -0
  31. data/test/dummy/public/404.html +26 -0
  32. data/test/dummy/public/422.html +26 -0
  33. data/test/dummy/public/500.html +25 -0
  34. data/test/dummy/public/favicon.ico +0 -0
  35. data/test/dummy/script/rails +6 -0
  36. data/test/integration/codemirror_rails_integration_test.rb +13 -0
  37. data/test/test_helper.rb +13 -0
  38. data/vendor/assets/javascripts/codemirror.js +381 -197
  39. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +1 -1
  40. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +649 -94
  41. data/vendor/assets/javascripts/codemirror/modes/clike.js +53 -7
  42. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +12 -7
  43. data/vendor/assets/javascripts/codemirror/modes/diff.js +24 -5
  44. data/vendor/assets/javascripts/codemirror/modes/ecl.js +2 -2
  45. data/vendor/assets/javascripts/codemirror/modes/erlang.js +463 -0
  46. data/vendor/assets/javascripts/codemirror/modes/gfm.js +38 -2
  47. data/vendor/assets/javascripts/codemirror/modes/go.js +1 -1
  48. data/vendor/assets/javascripts/codemirror/modes/groovy.js +1 -1
  49. data/vendor/assets/javascripts/codemirror/modes/haxe.js +432 -0
  50. data/vendor/assets/javascripts/codemirror/modes/javascript.js +1 -1
  51. data/vendor/assets/javascripts/codemirror/modes/less.js +93 -93
  52. data/vendor/assets/javascripts/codemirror/modes/markdown.js +29 -6
  53. data/vendor/assets/javascripts/codemirror/modes/mysql.js +6 -8
  54. data/vendor/assets/javascripts/codemirror/modes/ocaml.js +114 -0
  55. data/vendor/assets/javascripts/codemirror/modes/pascal.js +1 -1
  56. data/vendor/assets/javascripts/codemirror/modes/pig.js +2 -2
  57. data/vendor/assets/javascripts/codemirror/modes/plsql.js +2 -2
  58. data/vendor/assets/javascripts/codemirror/modes/python.js +13 -16
  59. data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -8
  60. data/vendor/assets/javascripts/codemirror/modes/scheme.js +74 -46
  61. data/vendor/assets/javascripts/codemirror/modes/shell.js +22 -7
  62. data/vendor/assets/javascripts/codemirror/modes/stex.js +7 -5
  63. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +14 -14
  64. data/vendor/assets/javascripts/codemirror/modes/vb.js +260 -0
  65. data/vendor/assets/javascripts/codemirror/modes/verilog.js +1 -1
  66. data/vendor/assets/javascripts/codemirror/modes/xml.js +2 -1
  67. data/vendor/assets/javascripts/codemirror/modes/xquery.js +3 -3
  68. data/vendor/assets/javascripts/codemirror/utils/closetag.js +24 -34
  69. data/vendor/assets/javascripts/codemirror/utils/dialog.js +5 -1
  70. data/vendor/assets/javascripts/codemirror/utils/foldcode.js +10 -5
  71. data/vendor/assets/javascripts/codemirror/utils/formatting.js +8 -3
  72. data/vendor/assets/javascripts/codemirror/utils/loadmode.js +2 -1
  73. data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +1 -1
  74. data/vendor/assets/javascripts/codemirror/utils/multiplex.js +81 -0
  75. data/vendor/assets/javascripts/codemirror/utils/overlay.js +2 -1
  76. data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +123 -0
  77. data/vendor/assets/javascripts/codemirror/utils/search.js +16 -12
  78. data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +1 -1
  79. data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +4 -0
  80. data/vendor/assets/javascripts/codemirror/utils/xml-hint.js +137 -0
  81. data/vendor/assets/stylesheets/codemirror.css +59 -4
  82. data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +14 -21
  83. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -2
  84. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +21 -0
  85. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +2 -3
  86. data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
  87. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +27 -0
  88. data/vendor/assets/stylesheets/codemirror/utils/dialog.css +4 -0
  89. metadata +98 -5
  90. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.css +0 -5
@@ -18,7 +18,7 @@
18
18
  "Alt-Y": function(cm) {cm.replaceSelection(popFromRing());},
19
19
  "Ctrl-/": "undo", "Shift-Ctrl--": "undo", "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
20
20
  "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
21
- "Ctrl-Z": "undo", "Cmd-Z": "undo",
21
+ "Ctrl-Z": "undo", "Cmd-Z": "undo", "Alt-/": "autocomplete",
22
22
  fallthrough: ["basic", "emacsy"]
23
23
  };
24
24
 
@@ -1,21 +1,96 @@
1
+ // Supported keybindings:
2
+ //
3
+ // Cursor movement:
4
+ // h, j, k, l
5
+ // e, E, w, W, b, B
6
+ // Ctrl-f, Ctrl-b
7
+ // Ctrl-n, Ctrl-p
8
+ // $, ^, 0
9
+ // G
10
+ // ge, gE
11
+ // gg
12
+ // f<char>, F<char>, t<char>, T<char>
13
+ // Ctrl-o, Ctrl-i TODO (FIXME - Ctrl-O wont work in Chrome)
14
+ // /, ?, n, N TODO (does not work)
15
+ // #, * TODO
16
+ //
17
+ // Entering insert mode:
18
+ // i, I, a, A, o, O
19
+ // s
20
+ // ce, cb (without support for number of actions like c3e - TODO)
21
+ // cc
22
+ // S, C TODO
23
+ // cf<char>, cF<char>, ct<char>, cT<char>
24
+ //
25
+ // Deleting text:
26
+ // x, X
27
+ // J
28
+ // dd, D
29
+ // de, db (without support for number of actions like d3e - TODO)
30
+ // df<char>, dF<char>, dt<char>, dT<char>
31
+ //
32
+ // Yanking and pasting:
33
+ // yy, Y
34
+ // p, P
35
+ // p'<char> TODO - test
36
+ // y'<char> TODO - test
37
+ // m<char> TODO - test
38
+ //
39
+ // Changing text in place:
40
+ // ~
41
+ // r<char>
42
+ //
43
+ // Visual mode:
44
+ // v, V TODO
45
+ //
46
+ // Misc:
47
+ // . TODO
48
+ //
49
+
1
50
  (function() {
2
51
  var count = "";
3
52
  var sdir = "f";
4
53
  var buf = "";
5
54
  var yank = 0;
6
55
  var mark = [];
56
+ var reptTimes = 0;
7
57
  function emptyBuffer() { buf = ""; }
8
- function pushInBuffer(str) { buf += str; };
9
- function pushCountDigit(digit) { return function(cm) {count += digit;} }
10
- function popCount() { var i = parseInt(count); count = ""; return i || 1; }
58
+ function pushInBuffer(str) { buf += str; }
59
+ function pushCountDigit(digit) { return function(cm) {count += digit;}; }
60
+ function popCount() { var i = parseInt(count, 10); count = ""; return i || 1; }
61
+ function iterTimes(func) {
62
+ for (var i = 0, c = popCount(); i < c; ++i) func(i, i == c - 1);
63
+ }
11
64
  function countTimes(func) {
12
65
  if (typeof func == "string") func = CodeMirror.commands[func];
13
- return function(cm) { for (var i = 0, c = popCount(); i < c; ++i) func(cm); }
66
+ return function(cm) { iterTimes(function () { func(cm); }); };
14
67
  }
15
68
 
16
69
  function iterObj(o, f) {
17
70
  for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]);
18
71
  }
72
+ function iterList(l, f) {
73
+ for (var i in l) f(l[i]);
74
+ }
75
+ function toLetter(ch) {
76
+ // T -> t, Shift-T -> T, '*' -> *, "Space" -> " "
77
+ if (ch.slice(0, 6) == "Shift-") {
78
+ return ch.slice(0, 1);
79
+ } else {
80
+ if (ch == "Space") return " ";
81
+ if (ch.length == 3 && ch[0] == "'" && ch[2] == "'") return ch[1];
82
+ return ch.toLowerCase();
83
+ }
84
+ }
85
+ var SPECIAL_SYMBOLS = "~`!@#$%^&*()_-+=[{}]\\|/?.,<>:;\"\'1234567890";
86
+ function toCombo(ch) {
87
+ // t -> T, T -> Shift-T, * -> '*', " " -> "Space"
88
+ if (ch == " ") return "Space";
89
+ var specialIdx = SPECIAL_SYMBOLS.indexOf(ch);
90
+ if (specialIdx != -1) return "'" + ch + "'";
91
+ if (ch.toLowerCase() == ch) return ch.toUpperCase();
92
+ return "Shift-" + ch.toUpperCase();
93
+ }
19
94
 
20
95
  var word = [/\w/, /[^\w\s]/], bigWord = [/\S/];
21
96
  function findWord(line, pos, dir, regexps) {
@@ -37,42 +112,62 @@
37
112
  }
38
113
  return {from: Math.min(start, end), to: Math.max(start, end)};
39
114
  }
40
- function moveToWord(cm, regexps, dir, where) {
41
- var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line), word;
42
- while (true) {
43
- word = findWord(line, ch, dir, regexps);
44
- ch = word[where == "end" ? "to" : "from"];
45
- if (ch == cur.ch && word.from != word.to) ch = word[dir < 0 ? "from" : "to"];
46
- else break;
115
+ function moveToWord(cm, regexps, dir, times, where) {
116
+ var cur = cm.getCursor();
117
+
118
+ for (var i = 0; i < times; i++) {
119
+ var line = cm.getLine(cur.line), startCh = cur.ch, word;
120
+ while (true) {
121
+ // If we're at start/end of line, start on prev/next respectivly
122
+ if (cur.ch == line.length && dir > 0) {
123
+ cur.line++;
124
+ cur.ch = 0;
125
+ line = cm.getLine(cur.line);
126
+ } else if (cur.ch == 0 && dir < 0) {
127
+ cur.line--;
128
+ cur.ch = line.length;
129
+ line = cm.getLine(cur.line);
130
+ }
131
+ if (!line) break;
132
+
133
+ // On to the actual searching
134
+ word = findWord(line, cur.ch, dir, regexps);
135
+ cur.ch = word[where == "end" ? "to" : "from"];
136
+ if (startCh == cur.ch && word.from != word.to) cur.ch = word[dir < 0 ? "from" : "to"];
137
+ else break;
138
+ }
47
139
  }
48
- cm.setCursor(cur.line, word[where == "end" ? "to" : "from"], true);
140
+ return cur;
49
141
  }
50
142
  function joinLineNext(cm) {
51
143
  var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line);
52
- CodeMirror.commands.goLineEnd(cm);
144
+ CodeMirror.commands.goLineEnd(cm);
53
145
  if (cur.line != cm.lineCount()) {
54
146
  CodeMirror.commands.goLineEnd(cm);
55
147
  cm.replaceSelection(" ", "end");
56
148
  CodeMirror.commands.delCharRight(cm);
57
- }
58
- }
59
- function editCursor(mode) {
60
- if (mode == "vim-insert") {
61
- // put in your cursor css changing code
62
- } else if (mode == "vim") {
63
- // put in your cursor css changing code
64
149
  }
65
150
  }
66
- function delTillMark(cm, cHar) {
67
- var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
151
+ function delTillMark(cm, cHar) {
152
+ var i = mark[cHar];
153
+ if (i === undefined) {
154
+ // console.log("Mark not set"); // TODO - show in status bar
155
+ return;
156
+ }
157
+ var l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
68
158
  cm.setCursor(start);
69
159
  for (var c = start; c <= end; c++) {
70
- pushInBuffer("\n"+cm.getLine(start));
160
+ pushInBuffer("\n"+cm.getLine(start));
71
161
  cm.removeLine(start);
72
162
  }
73
163
  }
74
- function yankTillMark(cm, cHar) {
75
- var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
164
+ function yankTillMark(cm, cHar) {
165
+ var i = mark[cHar];
166
+ if (i === undefined) {
167
+ // console.log("Mark not set"); // TODO - show in status bar
168
+ return;
169
+ }
170
+ var l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
76
171
  for (var c = start; c <= end; c++) {
77
172
  pushInBuffer("\n"+cm.getLine(c));
78
173
  }
@@ -84,25 +179,104 @@
84
179
  cm.setCursor(cur.line, firstNonWS == -1 ? line.length : firstNonWS, true);
85
180
  }
86
181
 
182
+ function charIdxInLine(cm, cHar, motion_options) {
183
+ // Search for cHar in line.
184
+ // motion_options: {forward, inclusive}
185
+ // If inclusive = true, include it too.
186
+ // If forward = true, search forward, else search backwards.
187
+ // If char is not found on this line, do nothing
188
+ var cur = cm.getCursor(), line = cm.getLine(cur.line), idx;
189
+ var ch = toLetter(cHar), mo = motion_options;
190
+ if (mo.forward) {
191
+ idx = line.indexOf(ch, cur.ch + 1);
192
+ if (idx != -1 && mo.inclusive) idx += 1;
193
+ } else {
194
+ idx = line.lastIndexOf(ch, cur.ch);
195
+ if (idx != -1 && !mo.inclusive) idx += 1;
196
+ }
197
+ return idx;
198
+ }
199
+
200
+ function moveTillChar(cm, cHar, motion_options) {
201
+ // Move to cHar in line, as found by charIdxInLine.
202
+ var idx = charIdxInLine(cm, cHar, motion_options), cur = cm.getCursor();
203
+ if (idx != -1) cm.setCursor({line: cur.line, ch: idx});
204
+ }
205
+
206
+ function delTillChar(cm, cHar, motion_options) {
207
+ // delete text in this line, untill cHar is met,
208
+ // as found by charIdxInLine.
209
+ // If char is not found on this line, do nothing
210
+ var idx = charIdxInLine(cm, cHar, motion_options);
211
+ var cur = cm.getCursor();
212
+ if (idx !== -1) {
213
+ if (motion_options.forward) {
214
+ cm.replaceRange("", {line: cur.line, ch: cur.ch}, {line: cur.line, ch: idx});
215
+ } else {
216
+ cm.replaceRange("", {line: cur.line, ch: idx}, {line: cur.line, ch: cur.ch});
217
+ }
218
+ }
219
+ }
220
+
221
+ function enterInsertMode(cm) {
222
+ // enter insert mode: switch mode and cursor
223
+ popCount();
224
+ cm.setOption("keyMap", "vim-insert");
225
+ }
226
+
227
+ function dialog(cm, text, shortText, f) {
228
+ if (cm.openDialog) cm.openDialog(text, f);
229
+ else f(prompt(shortText, ""));
230
+ }
231
+ function showAlert(cm, text) {
232
+ if (cm.openDialog) cm.openDialog(CodeMirror.htmlEscape(text) + " <button type=button>OK</button>");
233
+ else alert(text);
234
+ }
235
+
236
+ // main keymap
87
237
  var map = CodeMirror.keyMap.vim = {
88
- "0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);},
89
238
  // Pipe (|); TODO: should be *screen* chars, so need a util function to turn tabs into spaces?
90
- "'|'": function(cm) {cm.setCursor(cm.getCursor().line, popCount() - 1, true);},
91
- "'^'": function(cm) {popCount(); goLineStartText(cm);},
92
- "A": function(cm) {popCount(); cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
93
- "Shift-A": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
94
- "I": function(cm) {popCount(); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
95
- "Shift-I": function(cm) {popCount(); goLineStartText(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
96
- "O": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); CodeMirror.commands.newlineAndIndent(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
97
- "Shift-O": function(cm) {popCount(); CodeMirror.commands.goLineStart(cm); cm.replaceSelection("\n", "start"); cm.indentLine(cm.getCursor().line); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
98
- "G": function(cm) {cm.setOption("keyMap", "vim-prefix-g");},
99
- "D": function(cm) {cm.setOption("keyMap", "vim-prefix-d"); emptyBuffer();},
239
+ "'|'": function(cm) {
240
+ cm.setCursor(cm.getCursor().line, popCount() - 1, true);
241
+ },
242
+ "A": function(cm) {
243
+ cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true);
244
+ enterInsertMode(cm);
245
+ },
246
+ "Shift-A": function(cm) { CodeMirror.commands.goLineEnd(cm); enterInsertMode(cm);},
247
+ "I": function(cm) { enterInsertMode(cm);},
248
+ "Shift-I": function(cm) { goLineStartText(cm); enterInsertMode(cm);},
249
+ "O": function(cm) {
250
+ CodeMirror.commands.goLineEnd(cm);
251
+ CodeMirror.commands.newlineAndIndent(cm);
252
+ enterInsertMode(cm);
253
+ },
254
+ "Shift-O": function(cm) {
255
+ CodeMirror.commands.goLineStart(cm);
256
+ cm.replaceSelection("\n", "start");
257
+ cm.indentLine(cm.getCursor().line);
258
+ enterInsertMode(cm);
259
+ },
260
+ "G": function(cm) { cm.setOption("keyMap", "vim-prefix-g");},
100
261
  "Shift-D": function(cm) {
262
+ // commented out verions works, but I left original, cause maybe
263
+ // I don't know vim enouth to see what it does
264
+ /* var cur = cm.getCursor();
265
+ var f = {line: cur.line, ch: cur.ch}, t = {line: cur.line};
266
+ pushInBuffer(cm.getRange(f, t));
267
+ */
101
268
  emptyBuffer();
102
269
  mark["Shift-D"] = cm.getCursor(false).line;
103
270
  cm.setCursor(cm.getCursor(true).line);
104
271
  delTillMark(cm,"Shift-D"); mark = [];
105
272
  },
273
+
274
+ "S": function (cm) {
275
+ countTimes(function (_cm) {
276
+ CodeMirror.commands.delCharRight(_cm);
277
+ })(cm);
278
+ enterInsertMode(cm);
279
+ },
106
280
  "M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
107
281
  "Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
108
282
  "Shift-Y": function(cm) {
@@ -111,7 +285,7 @@
111
285
  cm.setCursor(cm.getCursor(true).line);
112
286
  yankTillMark(cm,"Shift-D"); mark = [];
113
287
  },
114
- "/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f"},
288
+ "/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f";},
115
289
  "'?'": function(cm) {
116
290
  var f = CodeMirror.commands.find;
117
291
  if (f) { f(cm); CodeMirror.commands.findPrev(cm); sdir = "r"; }
@@ -124,107 +298,488 @@
124
298
  var fn = CodeMirror.commands.findNext;
125
299
  if (fn) sdir != "r" ? CodeMirror.commands.findPrev(cm) : fn.findNext(cm);
126
300
  },
127
- "Shift-G": function(cm) {count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count)-1); popCount(); CodeMirror.commands.goLineStart(cm);},
128
- nofallthrough: true
301
+ "Shift-G": function(cm) {
302
+ count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count, 10)-1);
303
+ popCount();
304
+ CodeMirror.commands.goLineStart(cm);
305
+ },
306
+ "':'": function(cm) {
307
+ var exModeDialog = ': <input type="text" style="width: 90%"/>';
308
+ dialog(cm, exModeDialog, ':', function(command) {
309
+ if (command.match(/^\d+$/)) {
310
+ cm.setCursor(command - 1, cm.getCursor().ch);
311
+ } else {
312
+ showAlert(cm, "Bad command: " + command);
313
+ }
314
+ });
315
+ },
316
+ nofallthrough: true, style: "fat-cursor"
129
317
  };
130
- // Add bindings for number keys
131
- for (var i = 1; i < 10; ++i) map[i] = pushCountDigit(i);
318
+
319
+ // standard mode switching
320
+ iterList(["d", "t", "T", "f", "F", "c", "r"],
321
+ function (ch) {
322
+ CodeMirror.keyMap.vim[toCombo(ch)] = function (cm) {
323
+ cm.setOption("keyMap", "vim-prefix-" + ch);
324
+ emptyBuffer();
325
+ };
326
+ });
327
+
328
+ function addCountBindings(keyMap) {
329
+ // Add bindings for number keys
330
+ keyMap["0"] = function(cm) {
331
+ count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);
332
+ };
333
+ for (var i = 1; i < 10; ++i) keyMap[i] = pushCountDigit(i);
334
+ }
335
+ addCountBindings(CodeMirror.keyMap.vim);
336
+
337
+ // main num keymap
132
338
  // Add bindings that are influenced by number keys
133
339
  iterObj({
134
- "H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown",
135
- "K": "goLineUp", "Left": "goColumnLeft", "Right": "goColumnRight",
340
+ "Left": "goColumnLeft", "Right": "goColumnRight",
136
341
  "Down": "goLineDown", "Up": "goLineUp", "Backspace": "goCharLeft",
137
342
  "Space": "goCharRight",
138
- "B": function(cm) {moveToWord(cm, word, -1, "end");},
139
- "E": function(cm) {moveToWord(cm, word, 1, "end");},
140
- "W": function(cm) {moveToWord(cm, word, 1, "start");},
141
- "Shift-B": function(cm) {moveToWord(cm, bigWord, -1, "end");},
142
- "Shift-E": function(cm) {moveToWord(cm, bigWord, 1, "end");},
143
- "Shift-W": function(cm) {moveToWord(cm, bigWord, 1, "start");},
144
- "X": function(cm) {CodeMirror.commands.delCharRight(cm)},
343
+ "X": function(cm) {CodeMirror.commands.delCharRight(cm);},
145
344
  "P": function(cm) {
146
345
  var cur = cm.getCursor().line;
147
346
  if (buf!= "") {
148
- CodeMirror.commands.goLineEnd(cm);
347
+ if (buf[0] == "\n") CodeMirror.commands.goLineEnd(cm);
348
+ cm.replaceRange(buf, cm.getCursor());
349
+ }
350
+ },
351
+ "Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm);},
352
+ "Shift-J": function(cm) {joinLineNext(cm);},
353
+ "Shift-P": function(cm) {
354
+ var cur = cm.getCursor().line;
355
+ if (buf!= "") {
356
+ CodeMirror.commands.goLineUp(cm);
357
+ CodeMirror.commands.goLineEnd(cm);
149
358
  cm.replaceSelection(buf, "end");
150
359
  }
151
360
  cm.setCursor(cur+1);
152
361
  },
153
- "Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm)},
154
- "Shift-J": function(cm) {joinLineNext(cm)},
155
362
  "'~'": function(cm) {
156
363
  var cur = cm.getCursor(), cHar = cm.getRange({line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
157
364
  cHar = cHar != cHar.toLowerCase() ? cHar.toLowerCase() : cHar.toUpperCase();
158
365
  cm.replaceRange(cHar, {line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
159
366
  cm.setCursor(cur.line, cur.ch+1);
160
367
  },
161
- "Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm)},
162
- "Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm)},
368
+ "Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm);},
369
+ "Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm);},
163
370
  "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
164
- "U": "undo", "Ctrl-R": "redo", "'$'": "goLineEnd"
165
- }, function(key, cmd) { map[key] = countTimes(cmd); });
371
+ "U": "undo", "Ctrl-R": "redo"
372
+ }, function(key, cmd) { map[key] = countTimes(cmd); });
373
+
374
+ // empty key maps
375
+ iterList([
376
+ "vim-prefix-d'",
377
+ "vim-prefix-y'",
378
+ "vim-prefix-df",
379
+ "vim-prefix-dF",
380
+ "vim-prefix-dt",
381
+ "vim-prefix-dT",
382
+ "vim-prefix-c",
383
+ "vim-prefix-cf",
384
+ "vim-prefix-cF",
385
+ "vim-prefix-ct",
386
+ "vim-prefix-cT",
387
+ "vim-prefix-",
388
+ "vim-prefix-f",
389
+ "vim-prefix-F",
390
+ "vim-prefix-t",
391
+ "vim-prefix-T",
392
+ "vim-prefix-r",
393
+ "vim-prefix-m"
394
+ ],
395
+ function (prefix) {
396
+ CodeMirror.keyMap[prefix] = {
397
+ auto: "vim",
398
+ nofallthrough: true,
399
+ style: "fat-cursor"
400
+ };
401
+ });
166
402
 
167
403
  CodeMirror.keyMap["vim-prefix-g"] = {
168
- "E": countTimes(function(cm) { moveToWord(cm, word, -1, "start");}),
169
- "Shift-E": countTimes(function(cm) { moveToWord(cm, bigWord, -1, "start");}),
170
- auto: "vim",
171
- nofallthrough: true
404
+ "E": countTimes(function(cm) { cm.setCursor(moveToWord(cm, word, -1, 1, "start"));}),
405
+ "Shift-E": countTimes(function(cm) { cm.setCursor(moveToWord(cm, bigWord, -1, 1, "start"));}),
406
+ "G": function (cm) { cm.setCursor({line: 0, ch: cm.getCursor().ch});},
407
+ auto: "vim", nofallthrough: true, style: "fat-cursor"
172
408
  };
173
409
 
174
- CodeMirror.keyMap["vim-prefix-m"] = {
175
- auto: "vim",
176
- nofallthrough: true
177
- };
178
-
179
410
  CodeMirror.keyMap["vim-prefix-d"] = {
180
- "D": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line)); cm.removeLine(cm.getCursor().line); }),
181
- "'": function(cm) {cm.setOption("keyMap", "vim-prefix-d'"); emptyBuffer();},
182
- auto: "vim",
183
- nofallthrough: true
411
+ "D": countTimes(function(cm) {
412
+ pushInBuffer("\n"+cm.getLine(cm.getCursor().line));
413
+ cm.removeLine(cm.getCursor().line);
414
+ cm.setOption("keyMap", "vim");
415
+ }),
416
+ "'": function(cm) {
417
+ cm.setOption("keyMap", "vim-prefix-d'");
418
+ emptyBuffer();
419
+ },
420
+ "B": function(cm) {
421
+ var cur = cm.getCursor();
422
+ var line = cm.getLine(cur.line);
423
+ var index = line.lastIndexOf(" ", cur.ch);
424
+
425
+ pushInBuffer(line.substring(index, cur.ch));
426
+ cm.replaceRange("", {line: cur.line, ch: index}, cur);
427
+ cm.setOption("keyMap", "vim");
428
+ },
429
+ nofallthrough: true, style: "fat-cursor"
184
430
  };
431
+ // FIXME - does not work for bindings like "d3e"
432
+ addCountBindings(CodeMirror.keyMap["vim-prefix-d"]);
185
433
 
186
- CodeMirror.keyMap["vim-prefix-d'"] = {
187
- auto: "vim",
188
- nofallthrough: true
434
+ CodeMirror.keyMap["vim-prefix-c"] = {
435
+ "B": function (cm) {
436
+ countTimes("delWordLeft")(cm);
437
+ enterInsertMode(cm);
438
+ },
439
+ "C": function (cm) {
440
+ iterTimes(function (i, last) {
441
+ CodeMirror.commands.deleteLine(cm);
442
+ if (i) {
443
+ CodeMirror.commands.delCharRight(cm);
444
+ if (last) CodeMirror.commands.deleteLine(cm);
445
+ }
446
+ });
447
+ enterInsertMode(cm);
448
+ },
449
+ nofallthrough: true, style: "fat-cursor"
189
450
  };
190
451
 
191
- CodeMirror.keyMap["vim-prefix-y'"] = {
192
- auto: "vim",
193
- nofallthrough: true
452
+ iterList(["vim-prefix-d", "vim-prefix-c", "vim-prefix-"], function (prefix) {
453
+ iterList(["f", "F", "T", "t"],
454
+ function (ch) {
455
+ CodeMirror.keyMap[prefix][toCombo(ch)] = function (cm) {
456
+ cm.setOption("keyMap", prefix + ch);
457
+ emptyBuffer();
458
+ };
459
+ });
460
+ });
461
+
462
+ var MOTION_OPTIONS = {
463
+ "t": {inclusive: false, forward: true},
464
+ "f": {inclusive: true, forward: true},
465
+ "T": {inclusive: false, forward: false},
466
+ "F": {inclusive: true, forward: false}
194
467
  };
195
468
 
196
- // iterate through uppercase alphabet char codes
197
- for (var i = 65; i < 65 + 26; i++) {
198
- // apply for `letter` and 'Shift-' + `letter`
199
- for (var m = String.fromCharCode(i); m.length < 8; m = "Shift-" + m) {
200
- CodeMirror.keyMap["vim-prefix-m"][m] = function(cm) {
201
- mark[m] = cm.getCursor().line;
469
+ function setupPrefixBindingForKey(m) {
470
+ CodeMirror.keyMap["vim-prefix-m"][m] = function(cm) {
471
+ mark[m] = cm.getCursor().line;
472
+ };
473
+ CodeMirror.keyMap["vim-prefix-d'"][m] = function(cm) {
474
+ delTillMark(cm,m);
475
+ };
476
+ CodeMirror.keyMap["vim-prefix-y'"][m] = function(cm) {
477
+ yankTillMark(cm,m);
478
+ };
479
+ CodeMirror.keyMap["vim-prefix-r"][m] = function (cm) {
480
+ var cur = cm.getCursor();
481
+ cm.replaceRange(toLetter(m),
482
+ {line: cur.line, ch: cur.ch},
483
+ {line: cur.line, ch: cur.ch + 1});
484
+ CodeMirror.commands.goColumnLeft(cm);
485
+ };
486
+ // all commands, related to motions till char in line
487
+ iterObj(MOTION_OPTIONS, function (ch, options) {
488
+ CodeMirror.keyMap["vim-prefix-" + ch][m] = function(cm) {
489
+ moveTillChar(cm, m, options);
202
490
  };
203
- CodeMirror.keyMap["vim-prefix-d'"][m] = function(cm) {
204
- delTillMark(cm,m);
491
+ CodeMirror.keyMap["vim-prefix-d" + ch][m] = function(cm) {
492
+ delTillChar(cm, m, options);
205
493
  };
206
- CodeMirror.keyMap["vim-prefix-y'"][m] = function(cm) {
207
- yankTillMark(cm,m);
494
+ CodeMirror.keyMap["vim-prefix-c" + ch][m] = function(cm) {
495
+ delTillChar(cm, m, options);
496
+ enterInsertMode(cm);
208
497
  };
209
- }
498
+ });
210
499
  }
500
+ for (var i = 65; i < 65 + 26; i++) { // uppercase alphabet char codes
501
+ var ch = String.fromCharCode(i);
502
+ setupPrefixBindingForKey(toCombo(ch));
503
+ setupPrefixBindingForKey(toCombo(ch.toLowerCase()));
504
+ }
505
+ iterList(SPECIAL_SYMBOLS, function (ch) {
506
+ setupPrefixBindingForKey(toCombo(ch));
507
+ });
508
+ setupPrefixBindingForKey("Space");
211
509
 
212
510
  CodeMirror.keyMap["vim-prefix-y"] = {
213
511
  "Y": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line+yank)); yank++; }),
214
512
  "'": function(cm) {cm.setOption("keyMap", "vim-prefix-y'"); emptyBuffer();},
215
- auto: "vim",
216
- nofallthrough: true
513
+ nofallthrough: true, style: "fat-cursor"
217
514
  };
218
515
 
219
516
  CodeMirror.keyMap["vim-insert"] = {
220
517
  // TODO: override navigation keys so that Esc will cancel automatic indentation from o, O, i_<CR>
221
518
  "Esc": function(cm) {
222
- cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
519
+ cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
223
520
  cm.setOption("keyMap", "vim");
224
- editCursor("vim");
225
- },
226
- "Ctrl-N": function(cm) {/* Code to bring up autocomplete hint */},
227
- "Ctrl-P": function(cm) {/* Code to bring up autocomplete hint */},
521
+ },
522
+ "Ctrl-N": "autocomplete",
523
+ "Ctrl-P": "autocomplete",
228
524
  fallthrough: ["default"]
229
525
  };
526
+
527
+ function findMatchedSymbol(cm, cur, symb) {
528
+ var line = cur.line;
529
+ var symb = symb ? symb : cm.getLine(line)[cur.ch];
530
+
531
+ // Are we at the opening or closing char
532
+ var forwards = ['(', '[', '{'].indexOf(symb) != -1;
533
+
534
+ var reverseSymb = (function(sym) {
535
+ switch (sym) {
536
+ case '(' : return ')';
537
+ case '[' : return ']';
538
+ case '{' : return '}';
539
+ case ')' : return '(';
540
+ case ']' : return '[';
541
+ case '}' : return '{';
542
+ default : return null;
543
+ }
544
+ })(symb);
545
+
546
+ // Couldn't find a matching symbol, abort
547
+ if (reverseSymb == null) return cur;
548
+
549
+ // Tracking our imbalance in open/closing symbols. An opening symbol wii be
550
+ // the first thing we pick up if moving forward, this isn't true moving backwards
551
+ var disBal = forwards ? 0 : 1;
552
+
553
+ while (true) {
554
+ if (line == cur.line) {
555
+ // First pass, do some special stuff
556
+ var currLine = forwards ? cm.getLine(line).substr(cur.ch).split('') : cm.getLine(line).substr(0,cur.ch).split('').reverse();
557
+ } else {
558
+ var currLine = forwards ? cm.getLine(line).split('') : cm.getLine(line).split('').reverse();
559
+ }
560
+
561
+ for (var index = 0; index < currLine.length; index++) {
562
+ if (currLine[index] == symb) disBal++;
563
+ else if (currLine[index] == reverseSymb) disBal--;
564
+
565
+ if (disBal == 0) {
566
+ if (forwards && cur.line == line) return {line: line, ch: index + cur.ch};
567
+ else if (forwards) return {line: line, ch: index};
568
+ else return {line: line, ch: currLine.length - index - 1 };
569
+ }
570
+ }
571
+
572
+ if (forwards) line++;
573
+ else line--;
574
+ }
575
+ }
576
+
577
+ function selectCompanionObject(cm, revSymb, inclusive) {
578
+ var cur = cm.getCursor();
579
+
580
+ var end = findMatchedSymbol(cm, cur, revSymb);
581
+ var start = findMatchedSymbol(cm, end);
582
+ start.ch += inclusive ? 1 : 0;
583
+ end.ch += inclusive ? 0 : 1;
584
+
585
+ return {start: start, end: end};
586
+ }
587
+
588
+ // These are our motion commands to be used for navigation and selection with
589
+ // certian other commands. All should return a cursor object.
590
+ var motionList = ['B', 'E', 'J', 'K', 'H', 'L', 'W', 'Shift-W', "'^'", "'$'", "'%'", 'Esc'];
591
+
592
+ motions = {
593
+ 'B': function(cm, times) { return moveToWord(cm, word, -1, times); },
594
+ 'Shift-B': function(cm, times) { return moveToWord(cm, bigWord, -1, times); },
595
+ 'E': function(cm, times) { return moveToWord(cm, word, 1, times, 'end'); },
596
+ 'Shift-E': function(cm, times) { return moveToWord(cm, bigWord, 1, times, 'end'); },
597
+ 'J': function(cm, times) {
598
+ var cur = cm.getCursor();
599
+ return {line: cur.line+times, ch : cur.ch};
600
+ },
601
+
602
+ 'K': function(cm, times) {
603
+ var cur = cm.getCursor();
604
+ return {line: cur.line-times, ch: cur.ch};
605
+ },
606
+
607
+ 'H': function(cm, times) {
608
+ var cur = cm.getCursor();
609
+ return {line: cur.line, ch: cur.ch-times};
610
+ },
611
+
612
+ 'L': function(cm, times) {
613
+ var cur = cm.getCursor();
614
+ return {line: cur.line, ch: cur.ch+times};
615
+ },
616
+ 'W': function(cm, times) { return moveToWord(cm, word, 1, times); },
617
+ 'Shift-W': function(cm, times) { return moveToWord(cm, bigWord, 1, times); },
618
+ "'^'": function(cm, times) {
619
+ var cur = cm.getCursor();
620
+ var line = cm.getLine(cur.line).split('');
621
+
622
+ // Empty line :o
623
+ if (line.length == 0) return cur;
624
+
625
+ for (var index = 0; index < line.length; index++) {
626
+ if (line[index].match(/[^\s]/)) return {line: cur.line, ch: index};
627
+ }
628
+ },
629
+ "'$'": function(cm) {
630
+ var cur = cm.getCursor();
631
+ var line = cm.getLine(cur.line);
632
+ return {line: cur.line, ch: line.length};
633
+ },
634
+ "'%'": function(cm) { return findMatchedSymbol(cm, cm.getCursor()); },
635
+ "Esc" : function(cm) {
636
+ cm.setOption('vim');
637
+ reptTimes = 0;
638
+
639
+ return cm.getCursor();
640
+ }
641
+ };
642
+
643
+ // Map our movement actions each operator and non-operational movement
644
+ motionList.forEach(function(key, index, array) {
645
+ CodeMirror.keyMap['vim-prefix-d'][key] = function(cm) {
646
+ // Get our selected range
647
+ var start = cm.getCursor();
648
+ var end = motions[key](cm, reptTimes ? reptTimes : 1);
649
+
650
+ // Set swap var if range is of negative length
651
+ if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true;
652
+
653
+ // Take action, switching start and end if swap var is set
654
+ pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
655
+ cm.replaceRange("", swap ? end : start, swap ? start : end);
656
+
657
+ // And clean up
658
+ reptTimes = 0;
659
+ cm.setOption("keyMap", "vim");
660
+ };
661
+
662
+ CodeMirror.keyMap['vim-prefix-c'][key] = function(cm) {
663
+ var start = cm.getCursor();
664
+ var end = motions[key](cm, reptTimes ? reptTimes : 1);
665
+
666
+ if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true;
667
+ pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
668
+ cm.replaceRange("", swap ? end : start, swap ? start : end);
669
+
670
+ reptTimes = 0;
671
+ cm.setOption('keyMap', 'vim-insert');
672
+ };
673
+
674
+ CodeMirror.keyMap['vim-prefix-y'][key] = function(cm) {
675
+ var start = cm.getCursor();
676
+ var end = motions[key](cm, reptTimes ? reptTimes : 1);
677
+
678
+ if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true;
679
+ pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
680
+
681
+ reptTimes = 0;
682
+ cm.setOption("keyMap", "vim");
683
+ };
684
+
685
+ CodeMirror.keyMap['vim'][key] = function(cm) {
686
+ var cur = motions[key](cm, reptTimes ? reptTimes : 1);
687
+ cm.setCursor(cur.line, cur.ch);
688
+
689
+ reptTimes = 0;
690
+ };
691
+ });
692
+
693
+ var nums = [1,2,3,4,5,6,7,8,9];
694
+ nums.forEach(function(key, index, array) {
695
+ CodeMirror.keyMap['vim'][key] = function (cm) {
696
+ reptTimes = (reptTimes * 10) + key;
697
+ };
698
+ CodeMirror.keyMap['vim-prefix-d'][key] = function (cm) {
699
+ reptTimes = (reptTimes * 10) + key;
700
+ };
701
+ CodeMirror.keyMap['vim-prefix-y'][key] = function (cm) {
702
+ reptTimes = (reptTimes * 10) + key;
703
+ };
704
+ CodeMirror.keyMap['vim-prefix-c'][key] = function (cm) {
705
+ reptTimes = (reptTimes * 10) + key;
706
+ };
707
+ });
708
+
709
+ // Create our keymaps for each operator and make xa and xi where x is an operator
710
+ // change to the corrosponding keymap
711
+ var operators = ['d', 'y', 'c'];
712
+ operators.forEach(function(key, index, array) {
713
+ CodeMirror.keyMap['vim-prefix-'+key+'a'] = {
714
+ auto: 'vim', nofallthrough: true, style: "fat-cursor"
715
+ };
716
+ CodeMirror.keyMap['vim-prefix-'+key+'i'] = {
717
+ auto: 'vim', nofallthrough: true, style: "fat-cursor"
718
+ };
719
+
720
+ CodeMirror.keyMap['vim-prefix-'+key]['A'] = function(cm) {
721
+ reptTimes = 0;
722
+ cm.setOption('keyMap', 'vim-prefix-' + key + 'a');
723
+ };
724
+
725
+ CodeMirror.keyMap['vim-prefix-'+key]['I'] = function(cm) {
726
+ reptTimes = 0;
727
+ cm.setOption('keyMap', 'vim-prefix-' + key + 'i');
728
+ };
729
+ });
730
+
731
+ function regexLastIndexOf(string, pattern, startIndex) {
732
+ for (var i = startIndex == null ? string.length : startIndex; i >= 0; --i)
733
+ if (pattern.test(string.charAt(i))) return i;
734
+ return -1;
735
+ }
736
+
737
+ // Create our text object functions. They work similar to motions but they
738
+ // return a start cursor as well
739
+ var textObjectList = ['W', 'Shift-[', 'Shift-9', '['];
740
+ var textObjects = {
741
+ 'W': function(cm, inclusive) {
742
+ var cur = cm.getCursor();
743
+ var line = cm.getLine(cur.line);
744
+
745
+ var line_to_char = new String(line.substring(0, cur.ch));
746
+ var start = regexLastIndexOf(line_to_char, /[^a-zA-Z0-9]/) + 1;
747
+ var end = motions["E"](cm, 1) ;
748
+
749
+ end.ch += inclusive ? 1 : 0 ;
750
+ return {start: {line: cur.line, ch: start}, end: end };
751
+ },
752
+ 'Shift-[': function(cm, inclusive) { return selectCompanionObject(cm, '}', inclusive); },
753
+ 'Shift-9': function(cm, inclusive) { return selectCompanionObject(cm, ')', inclusive); },
754
+ '[': function(cm, inclusive) { return selectCompanionObject(cm, ']', inclusive); }
755
+ };
756
+
757
+ // One function to handle all operation upon text objects. Kinda funky but it works
758
+ // better than rewriting this code six times
759
+ function textObjectManipulation(cm, object, remove, insert, inclusive) {
760
+ // Object is the text object, delete object if remove is true, enter insert
761
+ // mode if insert is true, inclusive is the difference between a and i
762
+ var tmp = textObjects[object](cm, inclusive);
763
+ var start = tmp.start;
764
+ var end = tmp.end;
765
+
766
+ if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true ;
767
+
768
+ pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
769
+ if (remove) cm.replaceRange("", swap ? end : start, swap ? start : end);
770
+ if (insert) cm.setOption('keyMap', 'vim-insert');
771
+ }
772
+
773
+ // And finally build the keymaps up from the text objects
774
+ for (var i = 0; i < textObjectList.length; ++i) {
775
+ var object = textObjectList[i];
776
+ (function(object) {
777
+ CodeMirror.keyMap['vim-prefix-di'][object] = function(cm) { textObjectManipulation(cm, object, true, false, false); };
778
+ CodeMirror.keyMap['vim-prefix-da'][object] = function(cm) { textObjectManipulation(cm, object, true, false, true); };
779
+ CodeMirror.keyMap['vim-prefix-yi'][object] = function(cm) { textObjectManipulation(cm, object, false, false, false); };
780
+ CodeMirror.keyMap['vim-prefix-ya'][object] = function(cm) { textObjectManipulation(cm, object, false, false, true); };
781
+ CodeMirror.keyMap['vim-prefix-ci'][object] = function(cm) { textObjectManipulation(cm, object, true, true, false); };
782
+ CodeMirror.keyMap['vim-prefix-ca'][object] = function(cm) { textObjectManipulation(cm, object, true, true, true); };
783
+ })(object)
784
+ }
230
785
  })();