codemirror-rails 2.3 → 2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. data/README.md +0 -16
  2. data/codemirror-rails.gemspec +1 -1
  3. data/lib/codemirror/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/codemirror.js +323 -687
  5. data/vendor/assets/javascripts/codemirror/modes/clike.js +3 -40
  6. data/vendor/assets/javascripts/codemirror/modes/clojure.js +14 -14
  7. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +0 -6
  8. data/vendor/assets/javascripts/codemirror/modes/css.js +1 -1
  9. data/vendor/assets/javascripts/codemirror/modes/diff.js +5 -24
  10. data/vendor/assets/javascripts/codemirror/modes/gfm.js +4 -40
  11. data/vendor/assets/javascripts/codemirror/modes/go.js +22 -20
  12. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +1 -1
  13. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +2 -4
  14. data/vendor/assets/javascripts/codemirror/modes/javascript.js +7 -8
  15. data/vendor/assets/javascripts/codemirror/modes/less.js +54 -100
  16. data/vendor/assets/javascripts/codemirror/modes/markdown.js +49 -52
  17. data/vendor/assets/javascripts/codemirror/modes/pascal.js +46 -2
  18. data/vendor/assets/javascripts/codemirror/modes/perl.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/modes/php.js +25 -54
  20. data/vendor/assets/javascripts/codemirror/modes/python.js +16 -14
  21. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
  22. data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -1
  23. data/vendor/assets/javascripts/codemirror/modes/ruby.js +9 -4
  24. data/vendor/assets/javascripts/codemirror/modes/scheme.js +46 -74
  25. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +16 -16
  26. data/vendor/assets/javascripts/codemirror/modes/stex.js +6 -21
  27. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +45 -55
  28. data/vendor/assets/javascripts/codemirror/modes/xml.js +14 -79
  29. data/vendor/assets/javascripts/codemirror/{utils/overlay.js → overlay.js} +2 -3
  30. data/vendor/assets/javascripts/codemirror/runmode.js +27 -0
  31. data/vendor/assets/stylesheets/codemirror.css +2 -63
  32. data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +21 -14
  33. data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +1 -1
  34. data/vendor/assets/stylesheets/codemirror/themes/elegant.css +2 -2
  35. data/vendor/assets/stylesheets/codemirror/themes/neat.css +3 -3
  36. data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
  37. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +2 -2
  38. metadata +6 -39
  39. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +0 -29
  40. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +0 -766
  41. data/vendor/assets/javascripts/codemirror/modes/ecl.js +0 -203
  42. data/vendor/assets/javascripts/codemirror/modes/erlang.js +0 -251
  43. data/vendor/assets/javascripts/codemirror/modes/pig.js +0 -172
  44. data/vendor/assets/javascripts/codemirror/modes/properties.js +0 -63
  45. data/vendor/assets/javascripts/codemirror/modes/shell.js +0 -103
  46. data/vendor/assets/javascripts/codemirror/modes/smarty.js +0 -148
  47. data/vendor/assets/javascripts/codemirror/modes/tiki.js +0 -316
  48. data/vendor/assets/javascripts/codemirror/modes/vbscript.js +0 -26
  49. data/vendor/assets/javascripts/codemirror/modes/xquery.js +0 -448
  50. data/vendor/assets/javascripts/codemirror/utils/closetag.js +0 -146
  51. data/vendor/assets/javascripts/codemirror/utils/dialog.js +0 -63
  52. data/vendor/assets/javascripts/codemirror/utils/foldcode.js +0 -196
  53. data/vendor/assets/javascripts/codemirror/utils/formatting.js +0 -297
  54. data/vendor/assets/javascripts/codemirror/utils/javascript-hint.js +0 -134
  55. data/vendor/assets/javascripts/codemirror/utils/loadmode.js +0 -51
  56. data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +0 -44
  57. data/vendor/assets/javascripts/codemirror/utils/multiplex.js +0 -72
  58. data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +0 -123
  59. data/vendor/assets/javascripts/codemirror/utils/runmode.js +0 -49
  60. data/vendor/assets/javascripts/codemirror/utils/search.js +0 -118
  61. data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +0 -117
  62. data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +0 -72
  63. data/vendor/assets/stylesheets/codemirror/modes/tiki.css +0 -26
  64. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +0 -81
  65. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +0 -25
  66. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +0 -21
  67. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +0 -44
  68. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +0 -27
  69. data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +0 -46
  70. data/vendor/assets/stylesheets/codemirror/utils/dialog.css +0 -23
  71. data/vendor/assets/stylesheets/codemirror/utils/simple-hint.css +0 -16
@@ -1,29 +0,0 @@
1
- // TODO number prefixes
2
- (function() {
3
- // Really primitive kill-ring implementation.
4
- var killRing = [];
5
- function addToRing(str) {
6
- killRing.push(str);
7
- if (killRing.length > 50) killRing.shift();
8
- }
9
- function getFromRing() { return killRing[killRing.length - 1] || ""; }
10
- function popFromRing() { if (killRing.length > 1) killRing.pop(); return getFromRing(); }
11
-
12
- CodeMirror.keyMap.emacs = {
13
- "Ctrl-X": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-X");},
14
- "Ctrl-W": function(cm) {addToRing(cm.getSelection()); cm.replaceSelection("");},
15
- "Ctrl-Alt-W": function(cm) {addToRing(cm.getSelection()); cm.replaceSelection("");},
16
- "Alt-W": function(cm) {addToRing(cm.getSelection());},
17
- "Ctrl-Y": function(cm) {cm.replaceSelection(getFromRing());},
18
- "Alt-Y": function(cm) {cm.replaceSelection(popFromRing());},
19
- "Ctrl-/": "undo", "Shift-Ctrl--": "undo", "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
20
- "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
21
- "Ctrl-Z": "undo", "Cmd-Z": "undo", "Alt-/": "autocomplete",
22
- fallthrough: ["basic", "emacsy"]
23
- };
24
-
25
- CodeMirror.keyMap["emacs-Ctrl-X"] = {
26
- "Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": "undo", "K": "close",
27
- auto: "emacs", nofallthrough: true
28
- };
29
- })();
@@ -1,766 +0,0 @@
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
-
50
- (function() {
51
- var count = "";
52
- var sdir = "f";
53
- var buf = "";
54
- var yank = 0;
55
- var mark = [];
56
- var reptTimes = 0;
57
- function emptyBuffer() { buf = ""; }
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
- }
64
- function countTimes(func) {
65
- if (typeof func == "string") func = CodeMirror.commands[func];
66
- return function(cm) { iterTimes(function () { func(cm); }); };
67
- }
68
-
69
- function iterObj(o, f) {
70
- for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]);
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
- }
94
-
95
- var word = [/\w/, /[^\w\s]/], bigWord = [/\S/];
96
- function findWord(line, pos, dir, regexps) {
97
- var stop = 0, next = -1;
98
- if (dir > 0) { stop = line.length; next = 0; }
99
- var start = stop, end = stop;
100
- // Find bounds of next one.
101
- outer: for (; pos != stop; pos += dir) {
102
- for (var i = 0; i < regexps.length; ++i) {
103
- if (regexps[i].test(line.charAt(pos + next))) {
104
- start = pos;
105
- for (; pos != stop; pos += dir) {
106
- if (!regexps[i].test(line.charAt(pos + next))) break;
107
- }
108
- end = pos;
109
- break outer;
110
- }
111
- }
112
- }
113
- return {from: Math.min(start, end), to: Math.max(start, end)};
114
- }
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
- }
139
- }
140
- return cur;
141
- }
142
- function joinLineNext(cm) {
143
- var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line);
144
- CodeMirror.commands.goLineEnd(cm);
145
- if (cur.line != cm.lineCount()) {
146
- CodeMirror.commands.goLineEnd(cm);
147
- cm.replaceSelection(" ", "end");
148
- CodeMirror.commands.delCharRight(cm);
149
- }
150
- }
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;
158
- cm.setCursor(start);
159
- for (var c = start; c <= end; c++) {
160
- pushInBuffer("\n"+cm.getLine(start));
161
- cm.removeLine(start);
162
- }
163
- }
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;
171
- for (var c = start; c <= end; c++) {
172
- pushInBuffer("\n"+cm.getLine(c));
173
- }
174
- cm.setCursor(start);
175
- }
176
- function goLineStartText(cm) {
177
- // Go to the start of the line where the text begins, or the end for whitespace-only lines
178
- var cur = cm.getCursor(), firstNonWS = cm.getLine(cur.line).search(/\S/);
179
- cm.setCursor(cur.line, firstNonWS == -1 ? line.length : firstNonWS, true);
180
- }
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
- // main keymap
228
- var map = CodeMirror.keyMap.vim = {
229
- // Pipe (|); TODO: should be *screen* chars, so need a util function to turn tabs into spaces?
230
- "'|'": function(cm) {
231
- cm.setCursor(cm.getCursor().line, popCount() - 1, true);
232
- },
233
- "A": function(cm) {
234
- cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true);
235
- enterInsertMode(cm);
236
- },
237
- "Shift-A": function(cm) { CodeMirror.commands.goLineEnd(cm); enterInsertMode(cm);},
238
- "I": function(cm) { enterInsertMode(cm);},
239
- "Shift-I": function(cm) { goLineStartText(cm); enterInsertMode(cm);},
240
- "O": function(cm) {
241
- CodeMirror.commands.goLineEnd(cm);
242
- CodeMirror.commands.newlineAndIndent(cm);
243
- enterInsertMode(cm);
244
- },
245
- "Shift-O": function(cm) {
246
- CodeMirror.commands.goLineStart(cm);
247
- cm.replaceSelection("\n", "start");
248
- cm.indentLine(cm.getCursor().line);
249
- enterInsertMode(cm);
250
- },
251
- "G": function(cm) { cm.setOption("keyMap", "vim-prefix-g");},
252
- "Shift-D": function(cm) {
253
- // commented out verions works, but I left original, cause maybe
254
- // I don't know vim enouth to see what it does
255
- /* var cur = cm.getCursor();
256
- var f = {line: cur.line, ch: cur.ch}, t = {line: cur.line};
257
- pushInBuffer(cm.getRange(f, t));
258
- */
259
- emptyBuffer();
260
- mark["Shift-D"] = cm.getCursor(false).line;
261
- cm.setCursor(cm.getCursor(true).line);
262
- delTillMark(cm,"Shift-D"); mark = [];
263
- },
264
-
265
- "S": function (cm) {
266
- countTimes(function (_cm) {
267
- CodeMirror.commands.delCharRight(_cm);
268
- })(cm);
269
- enterInsertMode(cm);
270
- },
271
- "M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
272
- "Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
273
- "Shift-Y": function(cm) {
274
- emptyBuffer();
275
- mark["Shift-D"] = cm.getCursor(false).line;
276
- cm.setCursor(cm.getCursor(true).line);
277
- yankTillMark(cm,"Shift-D"); mark = [];
278
- },
279
- "/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f";},
280
- "'?'": function(cm) {
281
- var f = CodeMirror.commands.find;
282
- if (f) { f(cm); CodeMirror.commands.findPrev(cm); sdir = "r"; }
283
- },
284
- "N": function(cm) {
285
- var fn = CodeMirror.commands.findNext;
286
- if (fn) sdir != "r" ? fn(cm) : CodeMirror.commands.findPrev(cm);
287
- },
288
- "Shift-N": function(cm) {
289
- var fn = CodeMirror.commands.findNext;
290
- if (fn) sdir != "r" ? CodeMirror.commands.findPrev(cm) : fn.findNext(cm);
291
- },
292
- "Shift-G": function(cm) {
293
- count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count, 10)-1);
294
- popCount();
295
- CodeMirror.commands.goLineStart(cm);
296
- },
297
- nofallthrough: true, style: "fat-cursor"
298
- };
299
-
300
- // standard mode switching
301
- iterList(["d", "t", "T", "f", "F", "c", "r"],
302
- function (ch) {
303
- CodeMirror.keyMap.vim[toCombo(ch)] = function (cm) {
304
- cm.setOption("keyMap", "vim-prefix-" + ch);
305
- emptyBuffer();
306
- };
307
- });
308
-
309
- function addCountBindings(keyMap) {
310
- // Add bindings for number keys
311
- keyMap["0"] = function(cm) {
312
- count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);
313
- };
314
- for (var i = 1; i < 10; ++i) keyMap[i] = pushCountDigit(i);
315
- }
316
- addCountBindings(CodeMirror.keyMap.vim);
317
-
318
- // main num keymap
319
- // Add bindings that are influenced by number keys
320
- iterObj({
321
- "Left": "goColumnLeft", "Right": "goColumnRight",
322
- "Down": "goLineDown", "Up": "goLineUp", "Backspace": "goCharLeft",
323
- "Space": "goCharRight",
324
- "X": function(cm) {CodeMirror.commands.delCharRight(cm);},
325
- "P": function(cm) {
326
- var cur = cm.getCursor().line;
327
- if (buf!= "") {
328
- if (buf[0] == "\n") CodeMirror.commands.goLineEnd(cm);
329
- cm.replaceRange(buf, cm.getCursor());
330
- }
331
- },
332
- "Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm);},
333
- "Shift-J": function(cm) {joinLineNext(cm);},
334
- "Shift-P": function(cm) {
335
- var cur = cm.getCursor().line;
336
- if (buf!= "") {
337
- CodeMirror.commands.goLineUp(cm);
338
- CodeMirror.commands.goLineEnd(cm);
339
- cm.replaceSelection(buf, "end");
340
- }
341
- cm.setCursor(cur+1);
342
- },
343
- "'~'": function(cm) {
344
- var cur = cm.getCursor(), cHar = cm.getRange({line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
345
- cHar = cHar != cHar.toLowerCase() ? cHar.toLowerCase() : cHar.toUpperCase();
346
- cm.replaceRange(cHar, {line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
347
- cm.setCursor(cur.line, cur.ch+1);
348
- },
349
- "Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm);},
350
- "Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm);},
351
- "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
352
- "U": "undo", "Ctrl-R": "redo"
353
- }, function(key, cmd) { map[key] = countTimes(cmd); });
354
-
355
- // empty key maps
356
- iterList([
357
- "vim-prefix-d'",
358
- "vim-prefix-y'",
359
- "vim-prefix-df",
360
- "vim-prefix-dF",
361
- "vim-prefix-dt",
362
- "vim-prefix-dT",
363
- "vim-prefix-c",
364
- "vim-prefix-cf",
365
- "vim-prefix-cF",
366
- "vim-prefix-ct",
367
- "vim-prefix-cT",
368
- "vim-prefix-",
369
- "vim-prefix-f",
370
- "vim-prefix-F",
371
- "vim-prefix-t",
372
- "vim-prefix-T",
373
- "vim-prefix-r",
374
- "vim-prefix-m"
375
- ],
376
- function (prefix) {
377
- CodeMirror.keyMap[prefix] = {
378
- auto: "vim",
379
- nofallthrough: true,
380
- style: "fat-cursor"
381
- };
382
- });
383
-
384
- CodeMirror.keyMap["vim-prefix-g"] = {
385
- "E": countTimes(function(cm) { cm.setCursor(moveToWord(cm, word, -1, 1, "start"));}),
386
- "Shift-E": countTimes(function(cm) { cm.setCursor(moveToWord(cm, bigWord, -1, 1, "start"));}),
387
- "G": function (cm) { cm.setCursor({line: 0, ch: cm.getCursor().ch});},
388
- auto: "vim", nofallthrough: true, style: "fat-cursor"
389
- };
390
-
391
- CodeMirror.keyMap["vim-prefix-d"] = {
392
- "D": countTimes(function(cm) {
393
- pushInBuffer("\n"+cm.getLine(cm.getCursor().line));
394
- cm.removeLine(cm.getCursor().line);
395
- cm.setOption("keyMap", "vim");
396
- }),
397
- "'": function(cm) {
398
- cm.setOption("keyMap", "vim-prefix-d'");
399
- emptyBuffer();
400
- },
401
- "B": function(cm) {
402
- var cur = cm.getCursor();
403
- var line = cm.getLine(cur.line);
404
- var index = line.lastIndexOf(" ", cur.ch);
405
-
406
- pushInBuffer(line.substring(index, cur.ch));
407
- cm.replaceRange("", {line: cur.line, ch: index}, cur);
408
- cm.setOption("keyMap", "vim");
409
- },
410
- nofallthrough: true, style: "fat-cursor"
411
- };
412
- // FIXME - does not work for bindings like "d3e"
413
- addCountBindings(CodeMirror.keyMap["vim-prefix-d"]);
414
-
415
- CodeMirror.keyMap["vim-prefix-c"] = {
416
- "B": function (cm) {
417
- countTimes("delWordLeft")(cm);
418
- enterInsertMode(cm);
419
- },
420
- "C": function (cm) {
421
- iterTimes(function (i, last) {
422
- CodeMirror.commands.deleteLine(cm);
423
- if (i) {
424
- CodeMirror.commands.delCharRight(cm);
425
- if (last) CodeMirror.commands.deleteLine(cm);
426
- }
427
- });
428
- enterInsertMode(cm);
429
- },
430
- nofallthrough: true, style: "fat-cursor"
431
- };
432
-
433
- iterList(["vim-prefix-d", "vim-prefix-c", "vim-prefix-"], function (prefix) {
434
- iterList(["f", "F", "T", "t"],
435
- function (ch) {
436
- CodeMirror.keyMap[prefix][toCombo(ch)] = function (cm) {
437
- cm.setOption("keyMap", prefix + ch);
438
- emptyBuffer();
439
- };
440
- });
441
- });
442
-
443
- var MOTION_OPTIONS = {
444
- "t": {inclusive: false, forward: true},
445
- "f": {inclusive: true, forward: true},
446
- "T": {inclusive: false, forward: false},
447
- "F": {inclusive: true, forward: false}
448
- };
449
-
450
- function setupPrefixBindingForKey(m) {
451
- CodeMirror.keyMap["vim-prefix-m"][m] = function(cm) {
452
- mark[m] = cm.getCursor().line;
453
- };
454
- CodeMirror.keyMap["vim-prefix-d'"][m] = function(cm) {
455
- delTillMark(cm,m);
456
- };
457
- CodeMirror.keyMap["vim-prefix-y'"][m] = function(cm) {
458
- yankTillMark(cm,m);
459
- };
460
- CodeMirror.keyMap["vim-prefix-r"][m] = function (cm) {
461
- var cur = cm.getCursor();
462
- cm.replaceRange(toLetter(m),
463
- {line: cur.line, ch: cur.ch},
464
- {line: cur.line, ch: cur.ch + 1});
465
- CodeMirror.commands.goColumnLeft(cm);
466
- };
467
- // all commands, related to motions till char in line
468
- iterObj(MOTION_OPTIONS, function (ch, options) {
469
- CodeMirror.keyMap["vim-prefix-" + ch][m] = function(cm) {
470
- moveTillChar(cm, m, options);
471
- };
472
- CodeMirror.keyMap["vim-prefix-d" + ch][m] = function(cm) {
473
- delTillChar(cm, m, options);
474
- };
475
- CodeMirror.keyMap["vim-prefix-c" + ch][m] = function(cm) {
476
- delTillChar(cm, m, options);
477
- enterInsertMode(cm);
478
- };
479
- });
480
- }
481
- for (var i = 65; i < 65 + 26; i++) { // uppercase alphabet char codes
482
- var ch = String.fromCharCode(i);
483
- setupPrefixBindingForKey(toCombo(ch));
484
- setupPrefixBindingForKey(toCombo(ch.toLowerCase()));
485
- }
486
- iterList(SPECIAL_SYMBOLS, function (ch) {
487
- setupPrefixBindingForKey(toCombo(ch));
488
- });
489
- setupPrefixBindingForKey("Space");
490
-
491
- CodeMirror.keyMap["vim-prefix-y"] = {
492
- "Y": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line+yank)); yank++; }),
493
- "'": function(cm) {cm.setOption("keyMap", "vim-prefix-y'"); emptyBuffer();},
494
- nofallthrough: true, style: "fat-cursor"
495
- };
496
-
497
- CodeMirror.keyMap["vim-insert"] = {
498
- // TODO: override navigation keys so that Esc will cancel automatic indentation from o, O, i_<CR>
499
- "Esc": function(cm) {
500
- cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
501
- cm.setOption("keyMap", "vim");
502
- },
503
- "Ctrl-N": "autocomplete",
504
- "Ctrl-P": "autocomplete",
505
- fallthrough: ["default"]
506
- };
507
-
508
- function findMatchedSymbol(cm, cur, symb) {
509
- var line = cur.line;
510
- var symb = symb ? symb : cm.getLine(line)[cur.ch];
511
-
512
- // Are we at the opening or closing char
513
- var forwards = ['(', '[', '{'].indexOf(symb) != -1;
514
-
515
- var reverseSymb = (function(sym) {
516
- switch (sym) {
517
- case '(' : return ')';
518
- case '[' : return ']';
519
- case '{' : return '}';
520
- case ')' : return '(';
521
- case ']' : return '[';
522
- case '}' : return '{';
523
- default : return null;
524
- }
525
- })(symb);
526
-
527
- // Couldn't find a matching symbol, abort
528
- if (reverseSymb == null) return cur;
529
-
530
- // Tracking our imbalance in open/closing symbols. An opening symbol wii be
531
- // the first thing we pick up if moving forward, this isn't true moving backwards
532
- var disBal = forwards ? 0 : 1;
533
-
534
- while (true) {
535
- if (line == cur.line) {
536
- // First pass, do some special stuff
537
- var currLine = forwards ? cm.getLine(line).substr(cur.ch).split('') : cm.getLine(line).substr(0,cur.ch).split('').reverse();
538
- } else {
539
- var currLine = forwards ? cm.getLine(line).split('') : cm.getLine(line).split('').reverse();
540
- }
541
-
542
- for (var index = 0; index < currLine.length; index++) {
543
- if (currLine[index] == symb) disBal++;
544
- else if (currLine[index] == reverseSymb) disBal--;
545
-
546
- if (disBal == 0) {
547
- if (forwards && cur.line == line) return {line: line, ch: index + cur.ch};
548
- else if (forwards) return {line: line, ch: index};
549
- else return {line: line, ch: currLine.length - index - 1 };
550
- }
551
- }
552
-
553
- if (forwards) line++;
554
- else line--;
555
- }
556
- }
557
-
558
- function selectCompanionObject(cm, revSymb, inclusive) {
559
- var cur = cm.getCursor();
560
-
561
- var end = findMatchedSymbol(cm, cur, revSymb);
562
- var start = findMatchedSymbol(cm, end);
563
- start.ch += inclusive ? 1 : 0;
564
- end.ch += inclusive ? 0 : 1;
565
-
566
- return {start: start, end: end};
567
- }
568
-
569
- // These are our motion commands to be used for navigation and selection with
570
- // certian other commands. All should return a cursor object.
571
- var motionList = ['B', 'E', 'J', 'K', 'H', 'L', 'W', 'Shift-W', "'^'", "'$'", "'%'", 'Esc'];
572
-
573
- motions = {
574
- 'B': function(cm, times) { return moveToWord(cm, word, -1, times); },
575
- 'Shift-B': function(cm, times) { return moveToWord(cm, bigWord, -1, times); },
576
- 'E': function(cm, times) { return moveToWord(cm, word, 1, times, 'end'); },
577
- 'Shift-E': function(cm, times) { return moveToWord(cm, bigWord, 1, times, 'end'); },
578
- 'J': function(cm, times) {
579
- var cur = cm.getCursor();
580
- return {line: cur.line+times, ch : cur.ch};
581
- },
582
-
583
- 'K': function(cm, times) {
584
- var cur = cm.getCursor();
585
- return {line: cur.line-times, ch: cur.ch};
586
- },
587
-
588
- 'H': function(cm, times) {
589
- var cur = cm.getCursor();
590
- return {line: cur.line, ch: cur.ch-times};
591
- },
592
-
593
- 'L': function(cm, times) {
594
- var cur = cm.getCursor();
595
- return {line: cur.line, ch: cur.ch+times};
596
- },
597
- 'W': function(cm, times) { return moveToWord(cm, word, 1, times); },
598
- 'Shift-W': function(cm, times) { return moveToWord(cm, bigWord, 1, times); },
599
- "'^'": function(cm, times) {
600
- var cur = cm.getCursor();
601
- var line = cm.getLine(cur.line).split('');
602
-
603
- // Empty line :o
604
- if (line.length == 0) return cur;
605
-
606
- for (var index = 0; index < line.length; index++) {
607
- if (line[index].match(/[^\s]/)) return {line: cur.line, ch: index};
608
- }
609
- },
610
- "'$'": function(cm) {
611
- var cur = cm.getCursor();
612
- var line = cm.getLine(cur.line);
613
- return {line: cur.line, ch: line.length};
614
- },
615
- "'%'": function(cm) { return findMatchedSymbol(cm, cm.getCursor()); },
616
- "Esc" : function(cm) {
617
- cm.setOption('vim');
618
- reptTimes = 0;
619
-
620
- return cm.getCursor();
621
- }
622
- };
623
-
624
- // Map our movement actions each operator and non-operational movement
625
- motionList.forEach(function(key, index, array) {
626
- CodeMirror.keyMap['vim-prefix-d'][key] = function(cm) {
627
- // Get our selected range
628
- var start = cm.getCursor();
629
- var end = motions[key](cm, reptTimes ? reptTimes : 1);
630
-
631
- // Set swap var if range is of negative length
632
- if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true;
633
-
634
- // Take action, switching start and end if swap var is set
635
- pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
636
- cm.replaceRange("", swap ? end : start, swap ? start : end);
637
-
638
- // And clean up
639
- reptTimes = 0;
640
- cm.setOption("keyMap", "vim");
641
- };
642
-
643
- CodeMirror.keyMap['vim-prefix-c'][key] = function(cm) {
644
- var start = cm.getCursor();
645
- var end = motions[key](cm, reptTimes ? reptTimes : 1);
646
-
647
- if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true;
648
- pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
649
- cm.replaceRange("", swap ? end : start, swap ? start : end);
650
-
651
- reptTimes = 0;
652
- cm.setOption('keyMap', 'vim-insert');
653
- };
654
-
655
- CodeMirror.keyMap['vim-prefix-y'][key] = function(cm) {
656
- var start = cm.getCursor();
657
- var end = motions[key](cm, reptTimes ? reptTimes : 1);
658
-
659
- if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true;
660
- pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
661
-
662
- reptTimes = 0;
663
- cm.setOption("keyMap", "vim");
664
- };
665
-
666
- CodeMirror.keyMap['vim'][key] = function(cm) {
667
- var cur = motions[key](cm, reptTimes ? reptTimes : 1);
668
- cm.setCursor(cur.line, cur.ch);
669
-
670
- reptTimes = 0;
671
- };
672
- });
673
-
674
- var nums = [1,2,3,4,5,6,7,8,9];
675
- nums.forEach(function(key, index, array) {
676
- CodeMirror.keyMap['vim'][key] = function (cm) {
677
- reptTimes = (reptTimes * 10) + key;
678
- };
679
- CodeMirror.keyMap['vim-prefix-d'][key] = function (cm) {
680
- reptTimes = (reptTimes * 10) + key;
681
- };
682
- CodeMirror.keyMap['vim-prefix-y'][key] = function (cm) {
683
- reptTimes = (reptTimes * 10) + key;
684
- };
685
- CodeMirror.keyMap['vim-prefix-c'][key] = function (cm) {
686
- reptTimes = (reptTimes * 10) + key;
687
- };
688
- });
689
-
690
- // Create our keymaps for each operator and make xa and xi where x is an operator
691
- // change to the corrosponding keymap
692
- var operators = ['d', 'y', 'c'];
693
- operators.forEach(function(key, index, array) {
694
- CodeMirror.keyMap['vim-prefix-'+key+'a'] = {
695
- auto: 'vim', nofallthrough: true, style: "fat-cursor"
696
- };
697
- CodeMirror.keyMap['vim-prefix-'+key+'i'] = {
698
- auto: 'vim', nofallthrough: true, style: "fat-cursor"
699
- };
700
-
701
- CodeMirror.keyMap['vim-prefix-'+key]['A'] = function(cm) {
702
- reptTimes = 0;
703
- cm.setOption('keyMap', 'vim-prefix-' + key + 'a');
704
- };
705
-
706
- CodeMirror.keyMap['vim-prefix-'+key]['I'] = function(cm) {
707
- reptTimes = 0;
708
- cm.setOption('keyMap', 'vim-prefix-' + key + 'i');
709
- };
710
- });
711
-
712
- function regexLastIndexOf(string, pattern, startIndex) {
713
- for (var i = startIndex == null ? string.length : startIndex; i >= 0; --i)
714
- if (pattern.test(string.charAt(i))) return i;
715
- return -1;
716
- }
717
-
718
- // Create our text object functions. They work similar to motions but they
719
- // return a start cursor as well
720
- var textObjectList = ['W', 'Shift-[', 'Shift-9', '['];
721
- var textObjects = {
722
- 'W': function(cm, inclusive) {
723
- var cur = cm.getCursor();
724
- var line = cm.getLine(cur.line);
725
-
726
- var line_to_char = new String(line.substring(0, cur.ch));
727
- var start = regexLastIndexOf(line_to_char, /[^a-zA-Z0-9]/) + 1;
728
- var end = motions["E"](cm, 1) ;
729
-
730
- end.ch += inclusive ? 1 : 0 ;
731
- return {start: {line: cur.line, ch: start}, end: end };
732
- },
733
- 'Shift-[': function(cm, inclusive) { return selectCompanionObject(cm, '}', inclusive); },
734
- 'Shift-9': function(cm, inclusive) { return selectCompanionObject(cm, ')', inclusive); },
735
- '[': function(cm, inclusive) { return selectCompanionObject(cm, ']', inclusive); }
736
- };
737
-
738
- // One function to handle all operation upon text objects. Kinda funky but it works
739
- // better than rewriting this code six times
740
- function textObjectManipulation(cm, object, remove, insert, inclusive) {
741
- // Object is the text object, delete object if remove is true, enter insert
742
- // mode if insert is true, inclusive is the difference between a and i
743
- var tmp = textObjects[object](cm, inclusive);
744
- var start = tmp.start;
745
- var end = tmp.end;
746
-
747
- if ((start.line > end.line) || (start.line == end.line && start.ch > end.ch)) var swap = true ;
748
-
749
- pushInBuffer(cm.getRange(swap ? end : start, swap ? start : end));
750
- if (remove) cm.replaceRange("", swap ? end : start, swap ? start : end);
751
- if (insert) cm.setOption('keyMap', 'vim-insert');
752
- }
753
-
754
- // And finally build the keymaps up from the text objects
755
- for (var i = 0; i < textObjectList.length; ++i) {
756
- var object = textObjectList[i];
757
- (function(object) {
758
- CodeMirror.keyMap['vim-prefix-di'][object] = function(cm) { textObjectManipulation(cm, object, true, false, false); };
759
- CodeMirror.keyMap['vim-prefix-da'][object] = function(cm) { textObjectManipulation(cm, object, true, false, true); };
760
- CodeMirror.keyMap['vim-prefix-yi'][object] = function(cm) { textObjectManipulation(cm, object, false, false, false); };
761
- CodeMirror.keyMap['vim-prefix-ya'][object] = function(cm) { textObjectManipulation(cm, object, false, false, true); };
762
- CodeMirror.keyMap['vim-prefix-ci'][object] = function(cm) { textObjectManipulation(cm, object, true, true, false); };
763
- CodeMirror.keyMap['vim-prefix-ca'][object] = function(cm) { textObjectManipulation(cm, object, true, true, true); };
764
- })(object)
765
- }
766
- })();