|
11 | 11 | for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]); |
12 | 12 | } |
13 | 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 | + |
14 | 45 | var map = CodeMirror.keyMap.vim = { |
15 | 46 | "0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);}, |
16 | 47 | "I": function(cm) {popCount(); cm.setOption("keyMap", "vim-insert");}, |
| 48 | + "G": function(cm) {cm.setOption("keyMap", "vim-prefix-g");}, |
17 | 49 | catchall: function(cm) {/*ignore*/} |
18 | 50 | }; |
19 | 51 | // Add bindings for number keys |
|
22 | 54 | iterObj({"H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown", "K": "goLineUp", |
23 | 55 | "Left": "goColumnLeft", "Right": "goColumnRight", "Down": "goLineDown", "Up": "goLineUp", |
24 | 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");}, |
25 | 63 | "U": "undo", "Ctrl-R": "redo", "Shift-4": "goLineEnd"}, |
26 | 64 | function(key, cmd) { map[key] = countTimes(cmd); }); |
27 | 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 | + |
28 | 72 | CodeMirror.keyMap["vim-insert"] = { |
29 | 73 | "Esc": function(cm) {cm.setOption("keyMap", "vim");}, |
30 | 74 | fallthrough: ["default"] |
|
0 commit comments