diff options
Diffstat (limited to 'imports/codemirror/keymap')
-rwxr-xr-x | imports/codemirror/keymap/emacs.js | 29 | ||||
-rwxr-xr-x | imports/codemirror/keymap/vim.js | 76 |
2 files changed, 105 insertions, 0 deletions
diff --git a/imports/codemirror/keymap/emacs.js b/imports/codemirror/keymap/emacs.js new file mode 100755 index 00000000..8fd3564e --- /dev/null +++ b/imports/codemirror/keymap/emacs.js | |||
@@ -0,0 +1,29 @@ | |||
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", | ||
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", catchall: function(cm) {/*ignore*/} | ||
28 | }; | ||
29 | })(); | ||
diff --git a/imports/codemirror/keymap/vim.js b/imports/codemirror/keymap/vim.js new file mode 100755 index 00000000..e03e0128 --- /dev/null +++ b/imports/codemirror/keymap/vim.js | |||
@@ -0,0 +1,76 @@ | |||
1 | (function() { | ||
2 | var count = ""; | ||
3 | function pushCountDigit(digit) { return function(cm) {count += digit;} } | ||
4 | function popCount() { var i = parseInt(count); count = ""; return i || 1; } | ||
5 | function countTimes(func) { | ||
6 | if (typeof func == "string") func = CodeMirror.commands[func]; | ||
7 | return function(cm) { for (var i = 0, c = popCount(); i < c; ++i) func(cm); } | ||
8 | } | ||
9 | |||
10 | function iterObj(o, f) { | ||
11 | for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]); | ||
12 | } | ||
13 | |||
14 | var word = [/\w/, /[^\w\s]/], bigWord = [/\S/]; | ||
15 | function findWord(line, pos, dir, regexps) { | ||
16 | var stop = 0, next = -1; | ||
17 | if (dir > 0) { stop = line.length; next = 0; } | ||
18 | var start = stop, end = stop; | ||
19 | // Find bounds of next one. | ||
20 | outer: for (; pos != stop; pos += dir) { | ||
21 | for (var i = 0; i < regexps.length; ++i) { | ||
22 | if (regexps[i].test(line.charAt(pos + next))) { | ||
23 | start = pos; | ||
24 | for (; pos != stop; pos += dir) { | ||
25 | if (!regexps[i].test(line.charAt(pos + next))) break; | ||
26 | } | ||
27 | end = pos; | ||
28 | break outer; | ||
29 | } | ||
30 | } | ||
31 | } | ||
32 | return {from: Math.min(start, end), to: Math.max(start, end)}; | ||
33 | } | ||
34 | function moveToWord(cm, regexps, dir, where) { | ||
35 | var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line), word; | ||
36 | while (true) { | ||
37 | word = findWord(line, ch, dir, regexps); | ||
38 | ch = word[where == "end" ? "to" : "from"]; | ||
39 | if (ch == cur.ch && word.from != word.to) ch = word[dir < 0 ? "from" : "to"]; | ||
40 | else break; | ||
41 | } | ||
42 | cm.setCursor(cur.line, word[where == "end" ? "to" : "from"], true); | ||
43 | } | ||
44 | |||
45 | var map = CodeMirror.keyMap.vim = { | ||
46 | "0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);}, | ||
47 | "I": function(cm) {popCount(); cm.setOption("keyMap", "vim-insert");}, | ||
48 | "G": function(cm) {cm.setOption("keyMap", "vim-prefix-g");}, | ||
49 | catchall: function(cm) {/*ignore*/} | ||
50 | }; | ||
51 | // Add bindings for number keys | ||
52 | for (var i = 1; i < 10; ++i) map[i] = pushCountDigit(i); | ||
53 | // Add bindings that are influenced by number keys | ||
54 | iterObj({"H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown", "K": "goLineUp", | ||
55 | "Left": "goColumnLeft", "Right": "goColumnRight", "Down": "goLineDown", "Up": "goLineUp", | ||
56 | "Backspace": "goCharLeft", "Space": "goCharRight", | ||
57 | "B": function(cm) {moveToWord(cm, word, -1, "end");}, | ||
58 | "E": function(cm) {moveToWord(cm, word, 1, "end");}, | ||
59 | "W": function(cm) {moveToWord(cm, word, 1, "start");}, | ||
60 | "Shift-B": function(cm) {moveToWord(cm, bigWord, -1, "end");}, | ||
61 | "Shift-E": function(cm) {moveToWord(cm, bigWord, 1, "end");}, | ||
62 | "Shift-W": function(cm) {moveToWord(cm, bigWord, 1, "start");}, | ||
63 | "U": "undo", "Ctrl-R": "redo", "Shift-4": "goLineEnd"}, | ||
64 | function(key, cmd) { map[key] = countTimes(cmd); }); | ||
65 | |||
66 | CodeMirror.keyMap["vim-prefix-g"] = { | ||
67 | "E": countTimes(function(cm) { moveToWord(cm, word, -1, "start");}), | ||
68 | "Shift-E": countTimes(function(cm) { moveToWord(cm, bigWord, -1, "start");}), | ||
69 | auto: "vim", catchall: function(cm) {/*ignore*/} | ||
70 | }; | ||
71 | |||
72 | CodeMirror.keyMap["vim-insert"] = { | ||
73 | "Esc": function(cm) {cm.setOption("keyMap", "vim");}, | ||
74 | fallthrough: ["default"] | ||
75 | }; | ||
76 | })(); | ||