codemirror-rails 2.3 → 2.21

Sign up to get free protection for your applications and to get access to all the features.
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
- })();