michael@0: (function() { michael@0: "use strict"; michael@0: michael@0: var Pos = CodeMirror.Pos; michael@0: namespace = "emacs_"; michael@0: michael@0: var eventCache = {}; michael@0: function fakeEvent(keyName) { michael@0: var event = eventCache[key]; michael@0: if (event) return event; michael@0: michael@0: var ctrl, shift, alt; michael@0: var key = keyName.replace(/\w+-/g, function(type) { michael@0: if (type == "Ctrl-") ctrl = true; michael@0: else if (type == "Alt-") alt = true; michael@0: else if (type == "Shift-") shift = true; michael@0: return ""; michael@0: }); michael@0: var code; michael@0: for (var c in CodeMirror.keyNames) michael@0: if (CodeMirror.keyNames[c] == key) { code = c; break; } michael@0: if (c == null) throw new Error("Unknown key: " + key); michael@0: michael@0: return eventCache[keyName] = { michael@0: type: "keydown", keyCode: code, ctrlKey: ctrl, shiftKey: shift, altKey: alt, michael@0: preventDefault: function(){}, stopPropagation: function(){} michael@0: }; michael@0: } michael@0: michael@0: function sim(name, start /*, actions... */) { michael@0: var keys = Array.prototype.slice.call(arguments, 2); michael@0: testCM(name, function(cm) { michael@0: for (var i = 0; i < keys.length; ++i) { michael@0: var cur = keys[i]; michael@0: if (cur instanceof Pos) cm.setCursor(cur); michael@0: else if (cur.call) cur(cm); michael@0: else cm.triggerOnKeyDown(fakeEvent(cur)); michael@0: } michael@0: }, {keyMap: "emacs", value: start, mode: "javascript"}); michael@0: } michael@0: michael@0: function at(line, ch) { return function(cm) { eqPos(cm.getCursor(), Pos(line, ch)); }; } michael@0: function txt(str) { return function(cm) { eq(cm.getValue(), str); }; } michael@0: michael@0: sim("motionHSimple", "abc", "Ctrl-F", "Ctrl-F", "Ctrl-B", at(0, 1)); michael@0: sim("motionHMulti", "abcde", michael@0: "Ctrl-4", "Ctrl-F", at(0, 4), "Ctrl--", "Ctrl-2", "Ctrl-F", at(0, 2), michael@0: "Ctrl-5", "Ctrl-B", at(0, 0)); michael@0: michael@0: sim("motionHWord", "abc. def ghi", michael@0: "Alt-F", at(0, 3), "Alt-F", at(0, 8), michael@0: "Ctrl-B", "Alt-B", at(0, 5), "Alt-B", at(0, 0)); michael@0: sim("motionHWordMulti", "abc. def ghi ", michael@0: "Ctrl-3", "Alt-F", at(0, 12), "Ctrl-2", "Alt-B", at(0, 5), michael@0: "Ctrl--", "Alt-B", at(0, 8)); michael@0: michael@0: sim("motionVSimple", "a\nb\nc\n", "Ctrl-N", "Ctrl-N", "Ctrl-P", at(1, 0)); michael@0: sim("motionVMulti", "a\nb\nc\nd\ne\n", michael@0: "Ctrl-2", "Ctrl-N", at(2, 0), "Ctrl-F", "Ctrl--", "Ctrl-N", at(1, 1), michael@0: "Ctrl--", "Ctrl-3", "Ctrl-P", at(4, 1)); michael@0: michael@0: sim("killYank", "abc\ndef\nghi", michael@0: "Ctrl-F", "Ctrl-Space", "Ctrl-N", "Ctrl-N", "Ctrl-W", "Ctrl-E", "Ctrl-Y", michael@0: txt("ahibc\ndef\ng")); michael@0: sim("killRing", "abcdef", michael@0: "Ctrl-Space", "Ctrl-F", "Ctrl-W", "Ctrl-Space", "Ctrl-F", "Ctrl-W", michael@0: "Ctrl-Y", "Alt-Y", michael@0: txt("acdef")); michael@0: sim("copyYank", "abcd", michael@0: "Ctrl-Space", "Ctrl-E", "Alt-W", "Ctrl-Y", michael@0: txt("abcdabcd")); michael@0: michael@0: sim("killLineSimple", "foo\nbar", "Ctrl-F", "Ctrl-K", txt("f\nbar")); michael@0: sim("killLineEmptyLine", "foo\n \nbar", "Ctrl-N", "Ctrl-K", txt("foo\nbar")); michael@0: sim("killLineMulti", "foo\nbar\nbaz", michael@0: "Ctrl-F", "Ctrl-F", "Ctrl-K", "Ctrl-K", "Ctrl-K", "Ctrl-A", "Ctrl-Y", michael@0: txt("o\nbarfo\nbaz")); michael@0: michael@0: sim("moveByParagraph", "abc\ndef\n\n\nhij\nklm\n\n", michael@0: "Ctrl-F", "Ctrl-Down", at(2, 0), "Ctrl-Down", at(6, 0), michael@0: "Ctrl-N", "Ctrl-Up", at(3, 0), "Ctrl-Up", at(0, 0), michael@0: Pos(1, 2), "Ctrl-Down", at(2, 0), Pos(4, 2), "Ctrl-Up", at(3, 0)); michael@0: sim("moveByParagraphMulti", "abc\n\ndef\n\nhij\n\nklm", michael@0: "Ctrl-U", "2", "Ctrl-Down", at(3, 0), michael@0: "Shift-Alt-.", "Ctrl-3", "Ctrl-Up", at(1, 0)); michael@0: michael@0: sim("moveBySentence", "sentence one! sentence\ntwo\n\nparagraph two", michael@0: "Alt-E", at(0, 13), "Alt-E", at(1, 3), "Ctrl-F", "Alt-A", at(0, 13)); michael@0: michael@0: sim("moveByExpr", "function foo(a, b) {}", michael@0: "Ctrl-Alt-F", at(0, 8), "Ctrl-Alt-F", at(0, 12), "Ctrl-Alt-F", at(0, 18), michael@0: "Ctrl-Alt-B", at(0, 12), "Ctrl-Alt-B", at(0, 9)); michael@0: sim("moveByExprMulti", "foo bar baz bug", michael@0: "Ctrl-2", "Ctrl-Alt-F", at(0, 7), michael@0: "Ctrl--", "Ctrl-Alt-F", at(0, 4), michael@0: "Ctrl--", "Ctrl-2", "Ctrl-Alt-B", at(0, 11)); michael@0: sim("delExpr", "var x = [\n a,\n b\n c\n];", michael@0: Pos(0, 8), "Ctrl-Alt-K", txt("var x = ;"), "Ctrl-/", michael@0: Pos(4, 1), "Ctrl-Alt-Backspace", txt("var x = ;")); michael@0: sim("delExprMulti", "foo bar baz", michael@0: "Ctrl-2", "Ctrl-Alt-K", txt(" baz"), michael@0: "Ctrl-/", "Ctrl-E", "Ctrl-2", "Ctrl-Alt-Backspace", txt("foo ")); michael@0: michael@0: sim("justOneSpace", "hi bye ", michael@0: Pos(0, 4), "Alt-Space", txt("hi bye "), michael@0: Pos(0, 4), "Alt-Space", txt("hi b ye "), michael@0: "Ctrl-A", "Alt-Space", "Ctrl-E", "Alt-Space", txt(" hi b ye ")); michael@0: michael@0: sim("openLine", "foo bar", "Alt-F", "Ctrl-O", txt("foo\n bar")) michael@0: michael@0: sim("transposeChar", "abcd\n\ne", michael@0: "Ctrl-F", "Ctrl-T", "Ctrl-T", txt("bcad\n\ne"), at(0, 3), michael@0: "Ctrl-F", "Ctrl-T", "Ctrl-T", "Ctrl-T", txt("bcda\n\ne"), at(0, 4), michael@0: "Ctrl-F", "Ctrl-T", txt("bcd\na\ne"), at(1, 1)); michael@0: michael@0: sim("manipWordCase", "foo BAR bAZ", michael@0: "Alt-C", "Alt-L", "Alt-U", txt("Foo bar BAZ"), michael@0: "Ctrl-A", "Alt-U", "Alt-L", "Alt-C", txt("FOO bar Baz")); michael@0: sim("manipWordCaseMulti", "foo Bar bAz", michael@0: "Ctrl-2", "Alt-U", txt("FOO BAR bAz"), michael@0: "Ctrl-A", "Ctrl-3", "Alt-C", txt("Foo Bar Baz")); michael@0: michael@0: sim("upExpr", "foo {\n bar[];\n baz(blah);\n}", michael@0: Pos(2, 7), "Ctrl-Alt-U", at(2, 5), "Ctrl-Alt-U", at(0, 4)); michael@0: sim("transposeExpr", "do foo[bar] dah", michael@0: Pos(0, 6), "Ctrl-Alt-T", txt("do [bar]foo dah")); michael@0: michael@0: sim("clearMark", "abcde", Pos(0, 2), "Ctrl-Space", "Ctrl-F", "Ctrl-F", michael@0: "Ctrl-G", "Ctrl-W", txt("abcde")); michael@0: michael@0: testCM("save", function(cm) { michael@0: var saved = false; michael@0: CodeMirror.commands.save = function(cm) { saved = cm.getValue(); }; michael@0: cm.triggerOnKeyDown(fakeEvent("Ctrl-X")); michael@0: cm.triggerOnKeyDown(fakeEvent("Ctrl-S")); michael@0: is(saved, "hi"); michael@0: }, {value: "hi", keyMap: "emacs"}); michael@0: })();