You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
6.4 KiB

5 months ago
  1. (function() {
  2. "use strict";
  3. var Pos = CodeMirror.Pos;
  4. namespace = "emacs_";
  5. var eventCache = {};
  6. function fakeEvent(keyName) {
  7. var event = eventCache[key];
  8. if (event) return event;
  9. var ctrl, shift, alt;
  10. var key = keyName.replace(/\w+-/g, function(type) {
  11. if (type == "Ctrl-") ctrl = true;
  12. else if (type == "Alt-") alt = true;
  13. else if (type == "Shift-") shift = true;
  14. return "";
  15. });
  16. var code;
  17. for (var c in CodeMirror.keyNames)
  18. if (CodeMirror.keyNames[c] == key) { code = c; break; }
  19. if (code == null) throw new Error("Unknown key: " + key);
  20. return eventCache[keyName] = {
  21. type: "keydown", keyCode: code, ctrlKey: ctrl, shiftKey: shift, altKey: alt,
  22. preventDefault: function(){}, stopPropagation: function(){}
  23. };
  24. }
  25. function sim(name, start /*, actions... */) {
  26. var keys = Array.prototype.slice.call(arguments, 2);
  27. testCM(name, function(cm) {
  28. for (var i = 0; i < keys.length; ++i) {
  29. var cur = keys[i];
  30. if (cur instanceof Pos) cm.setCursor(cur);
  31. else if (cur.call) cur(cm);
  32. else cm.triggerOnKeyDown(fakeEvent(cur));
  33. }
  34. }, {keyMap: "emacs", value: start, mode: "javascript"});
  35. }
  36. function dialog(answer) { return function(cm) { cm.openDialog = function(_, cb) { cb(answer); }; }; }
  37. function at(line, ch, sticky) { return function(cm) { eqCursorPos(cm.getCursor(), Pos(line, ch, sticky)); }; }
  38. function txt(str) { return function(cm) { eq(cm.getValue(), str); }; }
  39. sim("motionHSimple", "abc", "Ctrl-F", "Ctrl-F", "Ctrl-B", at(0, 1, "after"));
  40. sim("motionHMulti", "abcde",
  41. "Ctrl-4", "Ctrl-F", at(0, 4, "before"), "Ctrl--", "Ctrl-2", "Ctrl-F", at(0, 2, "after"),
  42. "Ctrl-5", "Ctrl-B", at(0, 0, "after"));
  43. sim("motionHWord", "abc. def ghi",
  44. "Alt-F", at(0, 3, "before"), "Alt-F", at(0, 8, "before"),
  45. "Ctrl-B", "Alt-B", at(0, 5, "after"), "Alt-B", at(0, 0, "after"));
  46. sim("motionHWordMulti", "abc. def ghi ",
  47. "Ctrl-3", "Alt-F", at(0, 12, "before"), "Ctrl-2", "Alt-B", at(0, 5, "after"),
  48. "Ctrl--", "Alt-B", at(0, 8, "before"));
  49. sim("motionVSimple", "a\nb\nc\n", "Ctrl-N", "Ctrl-N", "Ctrl-P", at(1, 0, "after"));
  50. sim("motionVMulti", "a\nb\nc\nd\ne\n",
  51. "Ctrl-2", "Ctrl-N", at(2, 0, "after"), "Ctrl-F", "Ctrl--", "Ctrl-N", at(1, 1, "before"),
  52. "Ctrl--", "Ctrl-3", "Ctrl-P", at(4, 1, "before"));
  53. sim("killYank", "abc\ndef\nghi",
  54. "Ctrl-F", "Ctrl-Space", "Ctrl-N", "Ctrl-N", "Ctrl-W", "Ctrl-E", "Ctrl-Y",
  55. txt("ahibc\ndef\ng"));
  56. sim("killRing", "abcdef",
  57. "Ctrl-Space", "Ctrl-F", "Ctrl-W", "Ctrl-Space", "Ctrl-F", "Ctrl-W",
  58. "Ctrl-Y", "Alt-Y",
  59. txt("acdef"));
  60. sim("copyYank", "abcd",
  61. "Ctrl-Space", "Ctrl-E", "Alt-W", "Ctrl-Y",
  62. txt("abcdabcd"));
  63. sim("killLineSimple", "foo\nbar", "Ctrl-F", "Ctrl-K", txt("f\nbar"));
  64. sim("killLineEmptyLine", "foo\n \nbar", "Ctrl-N", "Ctrl-K", txt("foo\nbar"));
  65. sim("killLineMulti", "foo\nbar\nbaz",
  66. "Ctrl-F", "Ctrl-F", "Ctrl-K", "Ctrl-K", "Ctrl-K", "Ctrl-A", "Ctrl-Y",
  67. txt("o\nbarfo\nbaz"));
  68. sim("moveByParagraph", "abc\ndef\n\n\nhij\nklm\n\n",
  69. "Ctrl-F", "Ctrl-Down", at(2, 0), "Ctrl-Down", at(6, 0),
  70. "Ctrl-N", "Ctrl-Up", at(3, 0), "Ctrl-Up", at(0, 0),
  71. Pos(1, 2), "Ctrl-Down", at(2, 0), Pos(4, 2), "Ctrl-Up", at(3, 0));
  72. sim("moveByParagraphMulti", "abc\n\ndef\n\nhij\n\nklm",
  73. "Ctrl-U", "2", "Ctrl-Down", at(3, 0),
  74. "Shift-Alt-.", "Ctrl-3", "Ctrl-Up", at(1, 0));
  75. sim("moveBySentence", "sentence one! sentence\ntwo\n\nparagraph two",
  76. "Alt-E", at(0, 13), "Alt-E", at(1, 3), "Ctrl-F", "Alt-A", at(0, 13));
  77. sim("moveByExpr", "function foo(a, b) {}",
  78. "Ctrl-Alt-F", at(0, 8), "Ctrl-Alt-F", at(0, 12), "Ctrl-Alt-F", at(0, 18),
  79. "Ctrl-Alt-B", at(0, 12), "Ctrl-Alt-B", at(0, 9));
  80. sim("moveByExprMulti", "foo bar baz bug",
  81. "Ctrl-2", "Ctrl-Alt-F", at(0, 7),
  82. "Ctrl--", "Ctrl-Alt-F", at(0, 4),
  83. "Ctrl--", "Ctrl-2", "Ctrl-Alt-B", at(0, 11));
  84. sim("delExpr", "var x = [\n a,\n b\n c\n];",
  85. Pos(0, 8), "Ctrl-Alt-K", txt("var x = ;"), "Ctrl-/",
  86. Pos(4, 1), "Ctrl-Alt-Backspace", txt("var x = ;"));
  87. sim("delExprMulti", "foo bar baz",
  88. "Ctrl-2", "Ctrl-Alt-K", txt(" baz"),
  89. "Ctrl-/", "Ctrl-E", "Ctrl-2", "Ctrl-Alt-Backspace", txt("foo "));
  90. sim("justOneSpace", "hi bye ",
  91. Pos(0, 4), "Alt-Space", txt("hi bye "),
  92. Pos(0, 4), "Alt-Space", txt("hi b ye "),
  93. "Ctrl-A", "Alt-Space", "Ctrl-E", "Alt-Space", txt(" hi b ye "));
  94. sim("openLine", "foo bar", "Alt-F", "Ctrl-O", txt("foo\n bar"))
  95. sim("transposeChar", "abcd\ne",
  96. "Ctrl-F", "Ctrl-T", "Ctrl-T", txt("bcad\ne"), at(0, 3),
  97. "Ctrl-F", "Ctrl-T", "Ctrl-T", "Ctrl-T", txt("bcda\ne"), at(0, 4),
  98. "Ctrl-F", "Ctrl-T", txt("bcde\na"), at(1, 1));
  99. sim("manipWordCase", "foo BAR bAZ",
  100. "Alt-C", "Alt-L", "Alt-U", txt("Foo bar BAZ"),
  101. "Ctrl-A", "Alt-U", "Alt-L", "Alt-C", txt("FOO bar Baz"));
  102. sim("manipWordCaseMulti", "foo Bar bAz",
  103. "Ctrl-2", "Alt-U", txt("FOO BAR bAz"),
  104. "Ctrl-A", "Ctrl-3", "Alt-C", txt("Foo Bar Baz"));
  105. sim("upExpr", "foo {\n bar[];\n baz(blah);\n}",
  106. Pos(2, 7), "Ctrl-Alt-U", at(2, 5), "Ctrl-Alt-U", at(0, 4));
  107. sim("transposeExpr", "do foo[bar] dah",
  108. Pos(0, 6), "Ctrl-Alt-T", txt("do [bar]foo dah"));
  109. sim("clearMark", "abcde", Pos(0, 2), "Ctrl-Space", "Ctrl-F", "Ctrl-F",
  110. "Ctrl-G", "Ctrl-W", txt("abcde"));
  111. sim("delRegion", "abcde", "Ctrl-Space", "Ctrl-F", "Ctrl-F", "Delete", txt("cde"));
  112. sim("backspaceRegion", "abcde", "Ctrl-Space", "Ctrl-F", "Ctrl-F", "Backspace", txt("cde"));
  113. sim("backspaceDoesntAddToRing", "foobar", "Ctrl-F", "Ctrl-F", "Ctrl-F", "Ctrl-K", "Backspace", "Backspace", "Ctrl-Y", txt("fbar"));
  114. sim("gotoLine", "0\n1\n2\n3", dialog("3"), "Alt-G", "G", at(2, 0));
  115. sim("gotoInvalidLineFloat", "0\n1\n2\n3", dialog("2.2"), "Alt-G", "G", at(0, 0));
  116. testCM("gotoDialogTemplate", function(cm) {
  117. cm.openDialog = function(template, cb) {
  118. var input = template.querySelector("input");
  119. eq(template.textContent, "Goto line: ");
  120. eq(input.tagName, "INPUT");
  121. };
  122. cm.triggerOnKeyDown(fakeEvent("Alt-G"));
  123. cm.triggerOnKeyDown(fakeEvent("G"));
  124. }, {value: "", keyMap: "emacs"});
  125. testCM("save", function(cm) {
  126. var saved = false;
  127. CodeMirror.commands.save = function(cm) { saved = cm.getValue(); };
  128. cm.triggerOnKeyDown(fakeEvent("Ctrl-X"));
  129. cm.triggerOnKeyDown(fakeEvent("Ctrl-S"));
  130. is(saved, "hi");
  131. }, {value: "hi", keyMap: "emacs"});
  132. })();