browser/devtools/sourceeditor/test/cm_vim_test.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 var code = '' +
michael@0 2 ' wOrd1 (#%\n' +
michael@0 3 ' word3] \n' +
michael@0 4 'aopop pop 0 1 2 3 4\n' +
michael@0 5 ' (a) [b] {c} \n' +
michael@0 6 'int getchar(void) {\n' +
michael@0 7 ' static char buf[BUFSIZ];\n' +
michael@0 8 ' static char *bufp = buf;\n' +
michael@0 9 ' if (n == 0) { /* buffer is empty */\n' +
michael@0 10 ' n = read(0, buf, sizeof buf);\n' +
michael@0 11 ' bufp = buf;\n' +
michael@0 12 ' }\n' +
michael@0 13 '\n' +
michael@0 14 ' return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\n' +
michael@0 15 ' \n' +
michael@0 16 '}\n';
michael@0 17
michael@0 18 var lines = (function() {
michael@0 19 lineText = code.split('\n');
michael@0 20 var ret = [];
michael@0 21 for (var i = 0; i < lineText.length; i++) {
michael@0 22 ret[i] = {
michael@0 23 line: i,
michael@0 24 length: lineText[i].length,
michael@0 25 lineText: lineText[i],
michael@0 26 textStart: /^\s*/.exec(lineText[i])[0].length
michael@0 27 };
michael@0 28 }
michael@0 29 return ret;
michael@0 30 })();
michael@0 31 var endOfDocument = makeCursor(lines.length - 1,
michael@0 32 lines[lines.length - 1].length);
michael@0 33 var wordLine = lines[0];
michael@0 34 var bigWordLine = lines[1];
michael@0 35 var charLine = lines[2];
michael@0 36 var bracesLine = lines[3];
michael@0 37 var seekBraceLine = lines[4];
michael@0 38
michael@0 39 var word1 = {
michael@0 40 start: { line: wordLine.line, ch: 1 },
michael@0 41 end: { line: wordLine.line, ch: 5 }
michael@0 42 };
michael@0 43 var word2 = {
michael@0 44 start: { line: wordLine.line, ch: word1.end.ch + 2 },
michael@0 45 end: { line: wordLine.line, ch: word1.end.ch + 4 }
michael@0 46 };
michael@0 47 var word3 = {
michael@0 48 start: { line: bigWordLine.line, ch: 1 },
michael@0 49 end: { line: bigWordLine.line, ch: 5 }
michael@0 50 };
michael@0 51 var bigWord1 = word1;
michael@0 52 var bigWord2 = word2;
michael@0 53 var bigWord3 = {
michael@0 54 start: { line: bigWordLine.line, ch: 1 },
michael@0 55 end: { line: bigWordLine.line, ch: 7 }
michael@0 56 };
michael@0 57 var bigWord4 = {
michael@0 58 start: { line: bigWordLine.line, ch: bigWord1.end.ch + 3 },
michael@0 59 end: { line: bigWordLine.line, ch: bigWord1.end.ch + 7 }
michael@0 60 };
michael@0 61
michael@0 62 var oChars = [ { line: charLine.line, ch: 1 },
michael@0 63 { line: charLine.line, ch: 3 },
michael@0 64 { line: charLine.line, ch: 7 } ];
michael@0 65 var pChars = [ { line: charLine.line, ch: 2 },
michael@0 66 { line: charLine.line, ch: 4 },
michael@0 67 { line: charLine.line, ch: 6 },
michael@0 68 { line: charLine.line, ch: 8 } ];
michael@0 69 var numChars = [ { line: charLine.line, ch: 10 },
michael@0 70 { line: charLine.line, ch: 12 },
michael@0 71 { line: charLine.line, ch: 14 },
michael@0 72 { line: charLine.line, ch: 16 },
michael@0 73 { line: charLine.line, ch: 18 }];
michael@0 74 var parens1 = {
michael@0 75 start: { line: bracesLine.line, ch: 1 },
michael@0 76 end: { line: bracesLine.line, ch: 3 }
michael@0 77 };
michael@0 78 var squares1 = {
michael@0 79 start: { line: bracesLine.line, ch: 5 },
michael@0 80 end: { line: bracesLine.line, ch: 7 }
michael@0 81 };
michael@0 82 var curlys1 = {
michael@0 83 start: { line: bracesLine.line, ch: 9 },
michael@0 84 end: { line: bracesLine.line, ch: 11 }
michael@0 85 };
michael@0 86 var seekOutside = {
michael@0 87 start: { line: seekBraceLine.line, ch: 1 },
michael@0 88 end: { line: seekBraceLine.line, ch: 16 }
michael@0 89 };
michael@0 90 var seekInside = {
michael@0 91 start: { line: seekBraceLine.line, ch: 14 },
michael@0 92 end: { line: seekBraceLine.line, ch: 11 }
michael@0 93 };
michael@0 94
michael@0 95 function copyCursor(cur) {
michael@0 96 return { ch: cur.ch, line: cur.line };
michael@0 97 }
michael@0 98
michael@0 99 function forEach(arr, func) {
michael@0 100 for (var i = 0; i < arr.length; i++) {
michael@0 101 func(arr[i]);
michael@0 102 }
michael@0 103 }
michael@0 104
michael@0 105 function testVim(name, run, opts, expectedFail) {
michael@0 106 var vimOpts = {
michael@0 107 lineNumbers: true,
michael@0 108 vimMode: true,
michael@0 109 showCursorWhenSelecting: true,
michael@0 110 value: code
michael@0 111 };
michael@0 112 for (var prop in opts) {
michael@0 113 if (opts.hasOwnProperty(prop)) {
michael@0 114 vimOpts[prop] = opts[prop];
michael@0 115 }
michael@0 116 }
michael@0 117 return test('vim_' + name, function() {
michael@0 118 var place = document.getElementById("testground");
michael@0 119 var cm = CodeMirror(place, vimOpts);
michael@0 120 var vim = CodeMirror.Vim.maybeInitVimState_(cm);
michael@0 121
michael@0 122 function doKeysFn(cm) {
michael@0 123 return function(args) {
michael@0 124 if (args instanceof Array) {
michael@0 125 arguments = args;
michael@0 126 }
michael@0 127 for (var i = 0; i < arguments.length; i++) {
michael@0 128 CodeMirror.Vim.handleKey(cm, arguments[i]);
michael@0 129 }
michael@0 130 }
michael@0 131 }
michael@0 132 function doInsertModeKeysFn(cm) {
michael@0 133 return function(args) {
michael@0 134 if (args instanceof Array) { arguments = args; }
michael@0 135 function executeHandler(handler) {
michael@0 136 if (typeof handler == 'string') {
michael@0 137 CodeMirror.commands[handler](cm);
michael@0 138 } else {
michael@0 139 handler(cm);
michael@0 140 }
michael@0 141 return true;
michael@0 142 }
michael@0 143 for (var i = 0; i < arguments.length; i++) {
michael@0 144 var key = arguments[i];
michael@0 145 // Find key in keymap and handle.
michael@0 146 var handled = CodeMirror.lookupKey(key, ['vim-insert'], executeHandler);
michael@0 147 // Record for insert mode.
michael@0 148 if (handled === true && cm.state.vim.insertMode && arguments[i] != 'Esc') {
michael@0 149 var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges;
michael@0 150 if (lastChange) {
michael@0 151 lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key));
michael@0 152 }
michael@0 153 }
michael@0 154 }
michael@0 155 }
michael@0 156 }
michael@0 157 function doExFn(cm) {
michael@0 158 return function(command) {
michael@0 159 cm.openDialog = helpers.fakeOpenDialog(command);
michael@0 160 helpers.doKeys(':');
michael@0 161 }
michael@0 162 }
michael@0 163 function assertCursorAtFn(cm) {
michael@0 164 return function(line, ch) {
michael@0 165 var pos;
michael@0 166 if (ch == null && typeof line.line == 'number') {
michael@0 167 pos = line;
michael@0 168 } else {
michael@0 169 pos = makeCursor(line, ch);
michael@0 170 }
michael@0 171 eqPos(pos, cm.getCursor());
michael@0 172 }
michael@0 173 }
michael@0 174 function fakeOpenDialog(result) {
michael@0 175 return function(text, callback) {
michael@0 176 return callback(result);
michael@0 177 }
michael@0 178 }
michael@0 179 function fakeOpenNotification(matcher) {
michael@0 180 return function(text) {
michael@0 181 matcher(text);
michael@0 182 }
michael@0 183 }
michael@0 184 var helpers = {
michael@0 185 doKeys: doKeysFn(cm),
michael@0 186 // Warning: Only emulates keymap events, not character insertions. Use
michael@0 187 // replaceRange to simulate character insertions.
michael@0 188 // Keys are in CodeMirror format, NOT vim format.
michael@0 189 doInsertModeKeys: doInsertModeKeysFn(cm),
michael@0 190 doEx: doExFn(cm),
michael@0 191 assertCursorAt: assertCursorAtFn(cm),
michael@0 192 fakeOpenDialog: fakeOpenDialog,
michael@0 193 fakeOpenNotification: fakeOpenNotification,
michael@0 194 getRegisterController: function() {
michael@0 195 return CodeMirror.Vim.getRegisterController();
michael@0 196 }
michael@0 197 }
michael@0 198 CodeMirror.Vim.resetVimGlobalState_();
michael@0 199 var successful = false;
michael@0 200 var savedOpenNotification = cm.openNotification;
michael@0 201 try {
michael@0 202 run(cm, vim, helpers);
michael@0 203 successful = true;
michael@0 204 } finally {
michael@0 205 cm.openNotification = savedOpenNotification;
michael@0 206 if (!successful || verbose) {
michael@0 207 place.style.visibility = "visible";
michael@0 208 } else {
michael@0 209 place.removeChild(cm.getWrapperElement());
michael@0 210 }
michael@0 211 }
michael@0 212 }, expectedFail);
michael@0 213 };
michael@0 214 testVim('qq@q', function(cm, vim, helpers) {
michael@0 215 cm.setCursor(0, 0);
michael@0 216 helpers.doKeys('q', 'q', 'l', 'l', 'q');
michael@0 217 helpers.assertCursorAt(0,2);
michael@0 218 helpers.doKeys('@', 'q');
michael@0 219 helpers.assertCursorAt(0,4);
michael@0 220 }, { value: ' '});
michael@0 221 testVim('@@', function(cm, vim, helpers) {
michael@0 222 cm.setCursor(0, 0);
michael@0 223 helpers.doKeys('q', 'q', 'l', 'l', 'q');
michael@0 224 helpers.assertCursorAt(0,2);
michael@0 225 helpers.doKeys('@', 'q');
michael@0 226 helpers.assertCursorAt(0,4);
michael@0 227 helpers.doKeys('@', '@');
michael@0 228 helpers.assertCursorAt(0,6);
michael@0 229 }, { value: ' '});
michael@0 230 var jumplistScene = ''+
michael@0 231 'word\n'+
michael@0 232 '(word)\n'+
michael@0 233 '{word\n'+
michael@0 234 'word.\n'+
michael@0 235 '\n'+
michael@0 236 'word search\n'+
michael@0 237 '}word\n'+
michael@0 238 'word\n'+
michael@0 239 'word\n';
michael@0 240 function testJumplist(name, keys, endPos, startPos, dialog) {
michael@0 241 endPos = makeCursor(endPos[0], endPos[1]);
michael@0 242 startPos = makeCursor(startPos[0], startPos[1]);
michael@0 243 testVim(name, function(cm, vim, helpers) {
michael@0 244 CodeMirror.Vim.resetVimGlobalState_();
michael@0 245 if(dialog)cm.openDialog = helpers.fakeOpenDialog('word');
michael@0 246 cm.setCursor(startPos);
michael@0 247 helpers.doKeys.apply(null, keys);
michael@0 248 helpers.assertCursorAt(endPos);
michael@0 249 }, {value: jumplistScene});
michael@0 250 };
michael@0 251 testJumplist('jumplist_H', ['H', '<C-o>'], [5,2], [5,2]);
michael@0 252 testJumplist('jumplist_M', ['M', '<C-o>'], [2,2], [2,2]);
michael@0 253 testJumplist('jumplist_L', ['L', '<C-o>'], [2,2], [2,2]);
michael@0 254 testJumplist('jumplist_[[', ['[', '[', '<C-o>'], [5,2], [5,2]);
michael@0 255 testJumplist('jumplist_]]', [']', ']', '<C-o>'], [2,2], [2,2]);
michael@0 256 testJumplist('jumplist_G', ['G', '<C-o>'], [5,2], [5,2]);
michael@0 257 testJumplist('jumplist_gg', ['g', 'g', '<C-o>'], [5,2], [5,2]);
michael@0 258 testJumplist('jumplist_%', ['%', '<C-o>'], [1,5], [1,5]);
michael@0 259 testJumplist('jumplist_{', ['{', '<C-o>'], [1,5], [1,5]);
michael@0 260 testJumplist('jumplist_}', ['}', '<C-o>'], [1,5], [1,5]);
michael@0 261 testJumplist('jumplist_\'', ['m', 'a', 'h', '\'', 'a', 'h', '<C-i>'], [1,5], [1,5]);
michael@0 262 testJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', '<C-i>'], [1,5], [1,5]);
michael@0 263 testJumplist('jumplist_*_cachedCursor', ['*', '<C-o>'], [1,3], [1,3]);
michael@0 264 testJumplist('jumplist_#_cachedCursor', ['#', '<C-o>'], [1,3], [1,3]);
michael@0 265 testJumplist('jumplist_n', ['#', 'n', '<C-o>'], [1,1], [2,3]);
michael@0 266 testJumplist('jumplist_N', ['#', 'N', '<C-o>'], [1,1], [2,3]);
michael@0 267 testJumplist('jumplist_repeat_<c-o>', ['*', '*', '*', '3', '<C-o>'], [2,3], [2,3]);
michael@0 268 testJumplist('jumplist_repeat_<c-i>', ['*', '*', '*', '3', '<C-o>', '2', '<C-i>'], [5,0], [2,3]);
michael@0 269 testJumplist('jumplist_repeated_motion', ['3', '*', '<C-o>'], [2,3], [2,3]);
michael@0 270 testJumplist('jumplist_/', ['/', '<C-o>'], [2,3], [2,3], 'dialog');
michael@0 271 testJumplist('jumplist_?', ['?', '<C-o>'], [2,3], [2,3], 'dialog');
michael@0 272 testJumplist('jumplist_skip_delted_mark<c-o>',
michael@0 273 ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-o>', '<C-o>'],
michael@0 274 [0,2], [0,2]);
michael@0 275 testJumplist('jumplist_skip_delted_mark<c-i>',
michael@0 276 ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-i>', '<C-i>'],
michael@0 277 [1,0], [0,2]);
michael@0 278
michael@0 279 /**
michael@0 280 * @param name Name of the test
michael@0 281 * @param keys An array of keys or a string with a single key to simulate.
michael@0 282 * @param endPos The expected end position of the cursor.
michael@0 283 * @param startPos The position the cursor should start at, defaults to 0, 0.
michael@0 284 */
michael@0 285 function testMotion(name, keys, endPos, startPos) {
michael@0 286 testVim(name, function(cm, vim, helpers) {
michael@0 287 if (!startPos) {
michael@0 288 startPos = { line: 0, ch: 0 };
michael@0 289 }
michael@0 290 cm.setCursor(startPos);
michael@0 291 helpers.doKeys(keys);
michael@0 292 helpers.assertCursorAt(endPos);
michael@0 293 });
michael@0 294 };
michael@0 295
michael@0 296 function makeCursor(line, ch) {
michael@0 297 return { line: line, ch: ch };
michael@0 298 };
michael@0 299
michael@0 300 function offsetCursor(cur, offsetLine, offsetCh) {
michael@0 301 return { line: cur.line + offsetLine, ch: cur.ch + offsetCh };
michael@0 302 };
michael@0 303
michael@0 304 // Motion tests
michael@0 305 testMotion('|', '|', makeCursor(0, 0), makeCursor(0,4));
michael@0 306 testMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4));
michael@0 307 testMotion('h', 'h', makeCursor(0, 0), word1.start);
michael@0 308 testMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end);
michael@0 309 testMotion('l', 'l', makeCursor(0, 1));
michael@0 310 testMotion('l_repeat', ['2', 'l'], makeCursor(0, 2));
michael@0 311 testMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end);
michael@0 312 testMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end);
michael@0 313 testMotion('j_repeat_clip', ['1000', 'j'], endOfDocument);
michael@0 314 testMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end);
michael@0 315 testMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4));
michael@0 316 testMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4));
michael@0 317 testMotion('w', 'w', word1.start);
michael@0 318 testMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2));
michael@0 319 testMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51));
michael@0 320 testMotion('w_repeat', ['2', 'w'], word2.start);
michael@0 321 testMotion('w_wrap', ['w'], word3.start, word2.start);
michael@0 322 testMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument);
michael@0 323 testMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0));
michael@0 324 testMotion('W', 'W', bigWord1.start);
michael@0 325 testMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start);
michael@0 326 testMotion('e', 'e', word1.end);
michael@0 327 testMotion('e_repeat', ['2', 'e'], word2.end);
michael@0 328 testMotion('e_wrap', 'e', word3.end, word2.end);
michael@0 329 testMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument);
michael@0 330 testMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0));
michael@0 331 testMotion('b', 'b', word3.start, word3.end);
michael@0 332 testMotion('b_repeat', ['2', 'b'], word2.start, word3.end);
michael@0 333 testMotion('b_wrap', 'b', word2.start, word3.start);
michael@0 334 testMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0));
michael@0 335 testMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument);
michael@0 336 testMotion('ge', ['g', 'e'], word2.end, word3.end);
michael@0 337 testMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start);
michael@0 338 testMotion('ge_wrap', ['g', 'e'], word2.end, word3.start);
michael@0 339 testMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0),
michael@0 340 makeCursor(0, 0));
michael@0 341 testMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument);
michael@0 342 testMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart),
michael@0 343 makeCursor(3, 1));
michael@0 344 testMotion('gg_repeat', ['3', 'g', 'g'],
michael@0 345 makeCursor(lines[2].line, lines[2].textStart));
michael@0 346 testMotion('G', 'G',
michael@0 347 makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart),
michael@0 348 makeCursor(3, 1));
michael@0 349 testMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line,
michael@0 350 lines[2].textStart));
michael@0 351 // TODO: Make the test code long enough to test Ctrl-F and Ctrl-B.
michael@0 352 testMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8));
michael@0 353 testMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8));
michael@0 354 testMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8));
michael@0 355 testMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4));
michael@0 356 testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8));
michael@0 357 testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1));
michael@0 358 testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1),
michael@0 359 makeCursor(0, 3));
michael@0 360 testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0));
michael@0 361 testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]);
michael@0 362 testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0));
michael@0 363 testMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1),
michael@0 364 makeCursor(charLine.line, 0));
michael@0 365 testMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1),
michael@0 366 pChars[0]);
michael@0 367 testMotion('F', ['F', 'p'], pChars[0], pChars[1]);
michael@0 368 testMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]);
michael@0 369 testMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]);
michael@0 370 testMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]);
michael@0 371 testMotion('%_parens', ['%'], parens1.end, parens1.start);
michael@0 372 testMotion('%_squares', ['%'], squares1.end, squares1.start);
michael@0 373 testMotion('%_braces', ['%'], curlys1.end, curlys1.start);
michael@0 374 testMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start);
michael@0 375 testMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start);
michael@0 376 testVim('%_seek_skip', function(cm, vim, helpers) {
michael@0 377 cm.setCursor(0,0);
michael@0 378 helpers.doKeys(['%']);
michael@0 379 helpers.assertCursorAt(0,9);
michael@0 380 }, {value:'01234"("()'});
michael@0 381 testVim('%_skip_string', function(cm, vim, helpers) {
michael@0 382 cm.setCursor(0,0);
michael@0 383 helpers.doKeys(['%']);
michael@0 384 helpers.assertCursorAt(0,4);
michael@0 385 cm.setCursor(0,2);
michael@0 386 helpers.doKeys(['%']);
michael@0 387 helpers.assertCursorAt(0,0);
michael@0 388 }, {value:'(")")'});
michael@0 389 (')')
michael@0 390 testVim('%_skip_comment', function(cm, vim, helpers) {
michael@0 391 cm.setCursor(0,0);
michael@0 392 helpers.doKeys(['%']);
michael@0 393 helpers.assertCursorAt(0,6);
michael@0 394 cm.setCursor(0,3);
michael@0 395 helpers.doKeys(['%']);
michael@0 396 helpers.assertCursorAt(0,0);
michael@0 397 }, {value:'(/*)*/)'});
michael@0 398 // Make sure that moving down after going to the end of a line always leaves you
michael@0 399 // at the end of a line, but preserves the offset in other cases
michael@0 400 testVim('Changing lines after Eol operation', function(cm, vim, helpers) {
michael@0 401 cm.setCursor(0,0);
michael@0 402 helpers.doKeys(['$']);
michael@0 403 helpers.doKeys(['j']);
michael@0 404 // After moving to Eol and then down, we should be at Eol of line 2
michael@0 405 helpers.assertCursorAt({ line: 1, ch: lines[1].length - 1 });
michael@0 406 helpers.doKeys(['j']);
michael@0 407 // After moving down, we should be at Eol of line 3
michael@0 408 helpers.assertCursorAt({ line: 2, ch: lines[2].length - 1 });
michael@0 409 helpers.doKeys(['h']);
michael@0 410 helpers.doKeys(['j']);
michael@0 411 // After moving back one space and then down, since line 4 is shorter than line 2, we should
michael@0 412 // be at Eol of line 2 - 1
michael@0 413 helpers.assertCursorAt({ line: 3, ch: lines[3].length - 1 });
michael@0 414 helpers.doKeys(['j']);
michael@0 415 helpers.doKeys(['j']);
michael@0 416 // After moving down again, since line 3 has enough characters, we should be back to the
michael@0 417 // same place we were at on line 1
michael@0 418 helpers.assertCursorAt({ line: 5, ch: lines[2].length - 2 });
michael@0 419 });
michael@0 420 //making sure gj and gk recover from clipping
michael@0 421 testVim('gj_gk_clipping', function(cm,vim,helpers){
michael@0 422 cm.setCursor(0, 1);
michael@0 423 helpers.doKeys('g','j','g','j');
michael@0 424 helpers.assertCursorAt(2, 1);
michael@0 425 helpers.doKeys('g','k','g','k');
michael@0 426 helpers.assertCursorAt(0, 1);
michael@0 427 },{value: 'line 1\n\nline 2'});
michael@0 428 //testing a mix of j/k and gj/gk
michael@0 429 testVim('j_k_and_gj_gk', function(cm,vim,helpers){
michael@0 430 cm.setSize(120);
michael@0 431 cm.setCursor(0, 0);
michael@0 432 //go to the last character on the first line
michael@0 433 helpers.doKeys('$');
michael@0 434 //move up/down on the column within the wrapped line
michael@0 435 //side-effect: cursor is not locked to eol anymore
michael@0 436 helpers.doKeys('g','k');
michael@0 437 var cur=cm.getCursor();
michael@0 438 eq(cur.line,0);
michael@0 439 is((cur.ch<176),'gk didn\'t move cursor back (1)');
michael@0 440 helpers.doKeys('g','j');
michael@0 441 helpers.assertCursorAt(0, 176);
michael@0 442 //should move to character 177 on line 2 (j/k preserve character index within line)
michael@0 443 helpers.doKeys('j');
michael@0 444 //due to different line wrapping, the cursor can be on a different screen-x now
michael@0 445 //gj and gk preserve screen-x on movement, much like moveV
michael@0 446 helpers.doKeys('3','g','k');
michael@0 447 cur=cm.getCursor();
michael@0 448 eq(cur.line,1);
michael@0 449 is((cur.ch<176),'gk didn\'t move cursor back (2)');
michael@0 450 helpers.doKeys('g','j','2','g','j');
michael@0 451 //should return to the same character-index
michael@0 452 helpers.doKeys('k');
michael@0 453 helpers.assertCursorAt(0, 176);
michael@0 454 },{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'});
michael@0 455 testVim('gj_gk', function(cm, vim, helpers) {
michael@0 456 if (phantom) return;
michael@0 457 cm.setSize(120);
michael@0 458 // Test top of document edge case.
michael@0 459 cm.setCursor(0, 4);
michael@0 460 helpers.doKeys('g', 'j');
michael@0 461 helpers.doKeys('10', 'g', 'k');
michael@0 462 helpers.assertCursorAt(0, 4);
michael@0 463
michael@0 464 // Test moving down preserves column position.
michael@0 465 helpers.doKeys('g', 'j');
michael@0 466 var pos1 = cm.getCursor();
michael@0 467 var expectedPos2 = { line: 0, ch: (pos1.ch - 4) * 2 + 4};
michael@0 468 helpers.doKeys('g', 'j');
michael@0 469 helpers.assertCursorAt(expectedPos2);
michael@0 470
michael@0 471 // Move to the last character
michael@0 472 cm.setCursor(0, 0);
michael@0 473 // Move left to reset HSPos
michael@0 474 helpers.doKeys('h');
michael@0 475 // Test bottom of document edge case.
michael@0 476 helpers.doKeys('100', 'g', 'j');
michael@0 477 var endingPos = cm.getCursor();
michael@0 478 is(endingPos != 0, 'gj should not be on wrapped line 0');
michael@0 479 var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
michael@0 480 var endingCharCoords = cm.charCoords(endingPos);
michael@0 481 is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');
michael@0 482 },{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentiallylongtotestmovementofgjandgkoverwrappedlines.' });
michael@0 483 testVim('}', function(cm, vim, helpers) {
michael@0 484 cm.setCursor(0, 0);
michael@0 485 helpers.doKeys('}');
michael@0 486 helpers.assertCursorAt(1, 0);
michael@0 487 cm.setCursor(0, 0);
michael@0 488 helpers.doKeys('2', '}');
michael@0 489 helpers.assertCursorAt(4, 0);
michael@0 490 cm.setCursor(0, 0);
michael@0 491 helpers.doKeys('6', '}');
michael@0 492 helpers.assertCursorAt(5, 0);
michael@0 493 }, { value: 'a\n\nb\nc\n\nd' });
michael@0 494 testVim('{', function(cm, vim, helpers) {
michael@0 495 cm.setCursor(5, 0);
michael@0 496 helpers.doKeys('{');
michael@0 497 helpers.assertCursorAt(4, 0);
michael@0 498 cm.setCursor(5, 0);
michael@0 499 helpers.doKeys('2', '{');
michael@0 500 helpers.assertCursorAt(1, 0);
michael@0 501 cm.setCursor(5, 0);
michael@0 502 helpers.doKeys('6', '{');
michael@0 503 helpers.assertCursorAt(0, 0);
michael@0 504 }, { value: 'a\n\nb\nc\n\nd' });
michael@0 505
michael@0 506 // Operator tests
michael@0 507 testVim('dl', function(cm, vim, helpers) {
michael@0 508 var curStart = makeCursor(0, 0);
michael@0 509 cm.setCursor(curStart);
michael@0 510 helpers.doKeys('d', 'l');
michael@0 511 eq('word1 ', cm.getValue());
michael@0 512 var register = helpers.getRegisterController().getRegister();
michael@0 513 eq(' ', register.toString());
michael@0 514 is(!register.linewise);
michael@0 515 eqPos(curStart, cm.getCursor());
michael@0 516 }, { value: ' word1 ' });
michael@0 517 testVim('dl_eol', function(cm, vim, helpers) {
michael@0 518 cm.setCursor(0, 6);
michael@0 519 helpers.doKeys('d', 'l');
michael@0 520 eq(' word1', cm.getValue());
michael@0 521 var register = helpers.getRegisterController().getRegister();
michael@0 522 eq(' ', register.toString());
michael@0 523 is(!register.linewise);
michael@0 524 helpers.assertCursorAt(0, 5);
michael@0 525 }, { value: ' word1 ' });
michael@0 526 testVim('dl_repeat', function(cm, vim, helpers) {
michael@0 527 var curStart = makeCursor(0, 0);
michael@0 528 cm.setCursor(curStart);
michael@0 529 helpers.doKeys('2', 'd', 'l');
michael@0 530 eq('ord1 ', cm.getValue());
michael@0 531 var register = helpers.getRegisterController().getRegister();
michael@0 532 eq(' w', register.toString());
michael@0 533 is(!register.linewise);
michael@0 534 eqPos(curStart, cm.getCursor());
michael@0 535 }, { value: ' word1 ' });
michael@0 536 testVim('dh', function(cm, vim, helpers) {
michael@0 537 var curStart = makeCursor(0, 3);
michael@0 538 cm.setCursor(curStart);
michael@0 539 helpers.doKeys('d', 'h');
michael@0 540 eq(' wrd1 ', cm.getValue());
michael@0 541 var register = helpers.getRegisterController().getRegister();
michael@0 542 eq('o', register.toString());
michael@0 543 is(!register.linewise);
michael@0 544 eqPos(offsetCursor(curStart, 0 , -1), cm.getCursor());
michael@0 545 }, { value: ' word1 ' });
michael@0 546 testVim('dj', function(cm, vim, helpers) {
michael@0 547 var curStart = makeCursor(0, 3);
michael@0 548 cm.setCursor(curStart);
michael@0 549 helpers.doKeys('d', 'j');
michael@0 550 eq(' word3', cm.getValue());
michael@0 551 var register = helpers.getRegisterController().getRegister();
michael@0 552 eq(' word1\nword2\n', register.toString());
michael@0 553 is(register.linewise);
michael@0 554 helpers.assertCursorAt(0, 1);
michael@0 555 }, { value: ' word1\nword2\n word3' });
michael@0 556 testVim('dj_end_of_document', function(cm, vim, helpers) {
michael@0 557 var curStart = makeCursor(0, 3);
michael@0 558 cm.setCursor(curStart);
michael@0 559 helpers.doKeys('d', 'j');
michael@0 560 eq(' word1 ', cm.getValue());
michael@0 561 var register = helpers.getRegisterController().getRegister();
michael@0 562 eq('', register.toString());
michael@0 563 is(!register.linewise);
michael@0 564 helpers.assertCursorAt(0, 3);
michael@0 565 }, { value: ' word1 ' });
michael@0 566 testVim('dk', function(cm, vim, helpers) {
michael@0 567 var curStart = makeCursor(1, 3);
michael@0 568 cm.setCursor(curStart);
michael@0 569 helpers.doKeys('d', 'k');
michael@0 570 eq(' word3', cm.getValue());
michael@0 571 var register = helpers.getRegisterController().getRegister();
michael@0 572 eq(' word1\nword2\n', register.toString());
michael@0 573 is(register.linewise);
michael@0 574 helpers.assertCursorAt(0, 1);
michael@0 575 }, { value: ' word1\nword2\n word3' });
michael@0 576 testVim('dk_start_of_document', function(cm, vim, helpers) {
michael@0 577 var curStart = makeCursor(0, 3);
michael@0 578 cm.setCursor(curStart);
michael@0 579 helpers.doKeys('d', 'k');
michael@0 580 eq(' word1 ', cm.getValue());
michael@0 581 var register = helpers.getRegisterController().getRegister();
michael@0 582 eq('', register.toString());
michael@0 583 is(!register.linewise);
michael@0 584 helpers.assertCursorAt(0, 3);
michael@0 585 }, { value: ' word1 ' });
michael@0 586 testVim('dw_space', function(cm, vim, helpers) {
michael@0 587 var curStart = makeCursor(0, 0);
michael@0 588 cm.setCursor(curStart);
michael@0 589 helpers.doKeys('d', 'w');
michael@0 590 eq('word1 ', cm.getValue());
michael@0 591 var register = helpers.getRegisterController().getRegister();
michael@0 592 eq(' ', register.toString());
michael@0 593 is(!register.linewise);
michael@0 594 eqPos(curStart, cm.getCursor());
michael@0 595 }, { value: ' word1 ' });
michael@0 596 testVim('dw_word', function(cm, vim, helpers) {
michael@0 597 var curStart = makeCursor(0, 1);
michael@0 598 cm.setCursor(curStart);
michael@0 599 helpers.doKeys('d', 'w');
michael@0 600 eq(' word2', cm.getValue());
michael@0 601 var register = helpers.getRegisterController().getRegister();
michael@0 602 eq('word1 ', register.toString());
michael@0 603 is(!register.linewise);
michael@0 604 eqPos(curStart, cm.getCursor());
michael@0 605 }, { value: ' word1 word2' });
michael@0 606 testVim('dw_only_word', function(cm, vim, helpers) {
michael@0 607 // Test that if there is only 1 word left, dw deletes till the end of the
michael@0 608 // line.
michael@0 609 cm.setCursor(0, 1);
michael@0 610 helpers.doKeys('d', 'w');
michael@0 611 eq(' ', cm.getValue());
michael@0 612 var register = helpers.getRegisterController().getRegister();
michael@0 613 eq('word1 ', register.toString());
michael@0 614 is(!register.linewise);
michael@0 615 helpers.assertCursorAt(0, 0);
michael@0 616 }, { value: ' word1 ' });
michael@0 617 testVim('dw_eol', function(cm, vim, helpers) {
michael@0 618 // Assert that dw does not delete the newline if last word to delete is at end
michael@0 619 // of line.
michael@0 620 cm.setCursor(0, 1);
michael@0 621 helpers.doKeys('d', 'w');
michael@0 622 eq(' \nword2', cm.getValue());
michael@0 623 var register = helpers.getRegisterController().getRegister();
michael@0 624 eq('word1', register.toString());
michael@0 625 is(!register.linewise);
michael@0 626 helpers.assertCursorAt(0, 0);
michael@0 627 }, { value: ' word1\nword2' });
michael@0 628 testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) {
michael@0 629 // Assert that dw does not delete the newline if last word to delete is at end
michael@0 630 // of line and it is followed by multiple newlines.
michael@0 631 cm.setCursor(0, 1);
michael@0 632 helpers.doKeys('d', 'w');
michael@0 633 eq(' \n\nword2', cm.getValue());
michael@0 634 var register = helpers.getRegisterController().getRegister();
michael@0 635 eq('word1', register.toString());
michael@0 636 is(!register.linewise);
michael@0 637 helpers.assertCursorAt(0, 0);
michael@0 638 }, { value: ' word1\n\nword2' });
michael@0 639 testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) {
michael@0 640 cm.setCursor(0, 0);
michael@0 641 helpers.doKeys('d', 'w');
michael@0 642 eq(' \nword', cm.getValue());
michael@0 643 }, { value: '\n \nword' });
michael@0 644 testVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) {
michael@0 645 cm.setCursor(0, 0);
michael@0 646 helpers.doKeys('d', 'w');
michael@0 647 eq('word', cm.getValue());
michael@0 648 }, { value: '\nword' });
michael@0 649 testVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) {
michael@0 650 cm.setCursor(0, 0);
michael@0 651 helpers.doKeys('d', 'w');
michael@0 652 eq('\n', cm.getValue());
michael@0 653 }, { value: '\n\n' });
michael@0 654 testVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) {
michael@0 655 cm.setCursor(0, 0);
michael@0 656 helpers.doKeys('d', 'w');
michael@0 657 eq('\n \n', cm.getValue());
michael@0 658 }, { value: ' \n \n' });
michael@0 659 testVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) {
michael@0 660 cm.setCursor(0, 0);
michael@0 661 helpers.doKeys('d', 'w');
michael@0 662 eq('\n\n', cm.getValue());
michael@0 663 }, { value: ' \n\n' });
michael@0 664 testVim('dw_word_whitespace_word', function(cm, vim, helpers) {
michael@0 665 cm.setCursor(0, 0);
michael@0 666 helpers.doKeys('d', 'w');
michael@0 667 eq('\n \nword2', cm.getValue());
michael@0 668 }, { value: 'word1\n \nword2'})
michael@0 669 testVim('dw_end_of_document', function(cm, vim, helpers) {
michael@0 670 cm.setCursor(1, 2);
michael@0 671 helpers.doKeys('d', 'w');
michael@0 672 eq('\nab', cm.getValue());
michael@0 673 }, { value: '\nabc' });
michael@0 674 testVim('dw_repeat', function(cm, vim, helpers) {
michael@0 675 // Assert that dw does delete newline if it should go to the next line, and
michael@0 676 // that repeat works properly.
michael@0 677 cm.setCursor(0, 1);
michael@0 678 helpers.doKeys('d', '2', 'w');
michael@0 679 eq(' ', cm.getValue());
michael@0 680 var register = helpers.getRegisterController().getRegister();
michael@0 681 eq('word1\nword2', register.toString());
michael@0 682 is(!register.linewise);
michael@0 683 helpers.assertCursorAt(0, 0);
michael@0 684 }, { value: ' word1\nword2' });
michael@0 685 testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) {
michael@0 686 cm.setCursor(0, 0);
michael@0 687 helpers.doKeys('d', 'e');
michael@0 688 eq('\n\n', cm.getValue());
michael@0 689 }, { value: 'word\n\n' });
michael@0 690 testVim('de_word_end_and_empty_lines', function(cm, vim, helpers) {
michael@0 691 cm.setCursor(0, 3);
michael@0 692 helpers.doKeys('d', 'e');
michael@0 693 eq('wor', cm.getValue());
michael@0 694 }, { value: 'word\n\n\n' });
michael@0 695 testVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) {
michael@0 696 cm.setCursor(0, 0);
michael@0 697 helpers.doKeys('d', 'e');
michael@0 698 eq('', cm.getValue());
michael@0 699 }, { value: ' \n\n\n' });
michael@0 700 testVim('de_end_of_document', function(cm, vim, helpers) {
michael@0 701 cm.setCursor(1, 2);
michael@0 702 helpers.doKeys('d', 'e');
michael@0 703 eq('\nab', cm.getValue());
michael@0 704 }, { value: '\nabc' });
michael@0 705 testVim('db_empty_lines', function(cm, vim, helpers) {
michael@0 706 cm.setCursor(2, 0);
michael@0 707 helpers.doKeys('d', 'b');
michael@0 708 eq('\n\n', cm.getValue());
michael@0 709 }, { value: '\n\n\n' });
michael@0 710 testVim('db_word_start_and_empty_lines', function(cm, vim, helpers) {
michael@0 711 cm.setCursor(2, 0);
michael@0 712 helpers.doKeys('d', 'b');
michael@0 713 eq('\nword', cm.getValue());
michael@0 714 }, { value: '\n\nword' });
michael@0 715 testVim('db_word_end_and_empty_lines', function(cm, vim, helpers) {
michael@0 716 cm.setCursor(2, 3);
michael@0 717 helpers.doKeys('d', 'b');
michael@0 718 eq('\n\nd', cm.getValue());
michael@0 719 }, { value: '\n\nword' });
michael@0 720 testVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) {
michael@0 721 cm.setCursor(2, 0);
michael@0 722 helpers.doKeys('d', 'b');
michael@0 723 eq('', cm.getValue());
michael@0 724 }, { value: '\n \n' });
michael@0 725 testVim('db_start_of_document', function(cm, vim, helpers) {
michael@0 726 cm.setCursor(0, 0);
michael@0 727 helpers.doKeys('d', 'b');
michael@0 728 eq('abc\n', cm.getValue());
michael@0 729 }, { value: 'abc\n' });
michael@0 730 testVim('dge_empty_lines', function(cm, vim, helpers) {
michael@0 731 cm.setCursor(1, 0);
michael@0 732 helpers.doKeys('d', 'g', 'e');
michael@0 733 // Note: In real VIM the result should be '', but it's not quite consistent,
michael@0 734 // since 2 newlines are deleted. But in the similar case of word\n\n, only
michael@0 735 // 1 newline is deleted. We'll diverge from VIM's behavior since it's much
michael@0 736 // easier this way.
michael@0 737 eq('\n', cm.getValue());
michael@0 738 }, { value: '\n\n' });
michael@0 739 testVim('dge_word_and_empty_lines', function(cm, vim, helpers) {
michael@0 740 cm.setCursor(1, 0);
michael@0 741 helpers.doKeys('d', 'g', 'e');
michael@0 742 eq('wor\n', cm.getValue());
michael@0 743 }, { value: 'word\n\n'});
michael@0 744 testVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) {
michael@0 745 cm.setCursor(2, 0);
michael@0 746 helpers.doKeys('d', 'g', 'e');
michael@0 747 eq('', cm.getValue());
michael@0 748 }, { value: '\n \n' });
michael@0 749 testVim('dge_start_of_document', function(cm, vim, helpers) {
michael@0 750 cm.setCursor(0, 0);
michael@0 751 helpers.doKeys('d', 'g', 'e');
michael@0 752 eq('bc\n', cm.getValue());
michael@0 753 }, { value: 'abc\n' });
michael@0 754 testVim('d_inclusive', function(cm, vim, helpers) {
michael@0 755 // Assert that when inclusive is set, the character the cursor is on gets
michael@0 756 // deleted too.
michael@0 757 var curStart = makeCursor(0, 1);
michael@0 758 cm.setCursor(curStart);
michael@0 759 helpers.doKeys('d', 'e');
michael@0 760 eq(' ', cm.getValue());
michael@0 761 var register = helpers.getRegisterController().getRegister();
michael@0 762 eq('word1', register.toString());
michael@0 763 is(!register.linewise);
michael@0 764 eqPos(curStart, cm.getCursor());
michael@0 765 }, { value: ' word1 ' });
michael@0 766 testVim('d_reverse', function(cm, vim, helpers) {
michael@0 767 // Test that deleting in reverse works.
michael@0 768 cm.setCursor(1, 0);
michael@0 769 helpers.doKeys('d', 'b');
michael@0 770 eq(' word2 ', cm.getValue());
michael@0 771 var register = helpers.getRegisterController().getRegister();
michael@0 772 eq('word1\n', register.toString());
michael@0 773 is(!register.linewise);
michael@0 774 helpers.assertCursorAt(0, 1);
michael@0 775 }, { value: ' word1\nword2 ' });
michael@0 776 testVim('dd', function(cm, vim, helpers) {
michael@0 777 cm.setCursor(0, 3);
michael@0 778 var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
michael@0 779 { line: 1, ch: 0 });
michael@0 780 var expectedLineCount = cm.lineCount() - 1;
michael@0 781 helpers.doKeys('d', 'd');
michael@0 782 eq(expectedLineCount, cm.lineCount());
michael@0 783 var register = helpers.getRegisterController().getRegister();
michael@0 784 eq(expectedBuffer, register.toString());
michael@0 785 is(register.linewise);
michael@0 786 helpers.assertCursorAt(0, lines[1].textStart);
michael@0 787 });
michael@0 788 testVim('dd_prefix_repeat', function(cm, vim, helpers) {
michael@0 789 cm.setCursor(0, 3);
michael@0 790 var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
michael@0 791 { line: 2, ch: 0 });
michael@0 792 var expectedLineCount = cm.lineCount() - 2;
michael@0 793 helpers.doKeys('2', 'd', 'd');
michael@0 794 eq(expectedLineCount, cm.lineCount());
michael@0 795 var register = helpers.getRegisterController().getRegister();
michael@0 796 eq(expectedBuffer, register.toString());
michael@0 797 is(register.linewise);
michael@0 798 helpers.assertCursorAt(0, lines[2].textStart);
michael@0 799 });
michael@0 800 testVim('dd_motion_repeat', function(cm, vim, helpers) {
michael@0 801 cm.setCursor(0, 3);
michael@0 802 var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
michael@0 803 { line: 2, ch: 0 });
michael@0 804 var expectedLineCount = cm.lineCount() - 2;
michael@0 805 helpers.doKeys('d', '2', 'd');
michael@0 806 eq(expectedLineCount, cm.lineCount());
michael@0 807 var register = helpers.getRegisterController().getRegister();
michael@0 808 eq(expectedBuffer, register.toString());
michael@0 809 is(register.linewise);
michael@0 810 helpers.assertCursorAt(0, lines[2].textStart);
michael@0 811 });
michael@0 812 testVim('dd_multiply_repeat', function(cm, vim, helpers) {
michael@0 813 cm.setCursor(0, 3);
michael@0 814 var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
michael@0 815 { line: 6, ch: 0 });
michael@0 816 var expectedLineCount = cm.lineCount() - 6;
michael@0 817 helpers.doKeys('2', 'd', '3', 'd');
michael@0 818 eq(expectedLineCount, cm.lineCount());
michael@0 819 var register = helpers.getRegisterController().getRegister();
michael@0 820 eq(expectedBuffer, register.toString());
michael@0 821 is(register.linewise);
michael@0 822 helpers.assertCursorAt(0, lines[6].textStart);
michael@0 823 });
michael@0 824 testVim('dd_lastline', function(cm, vim, helpers) {
michael@0 825 cm.setCursor(cm.lineCount(), 0);
michael@0 826 var expectedLineCount = cm.lineCount() - 1;
michael@0 827 helpers.doKeys('d', 'd');
michael@0 828 eq(expectedLineCount, cm.lineCount());
michael@0 829 helpers.assertCursorAt(cm.lineCount() - 1, 0);
michael@0 830 });
michael@0 831 // Yank commands should behave the exact same as d commands, expect that nothing
michael@0 832 // gets deleted.
michael@0 833 testVim('yw_repeat', function(cm, vim, helpers) {
michael@0 834 // Assert that yw does yank newline if it should go to the next line, and
michael@0 835 // that repeat works properly.
michael@0 836 var curStart = makeCursor(0, 1);
michael@0 837 cm.setCursor(curStart);
michael@0 838 helpers.doKeys('y', '2', 'w');
michael@0 839 eq(' word1\nword2', cm.getValue());
michael@0 840 var register = helpers.getRegisterController().getRegister();
michael@0 841 eq('word1\nword2', register.toString());
michael@0 842 is(!register.linewise);
michael@0 843 eqPos(curStart, cm.getCursor());
michael@0 844 }, { value: ' word1\nword2' });
michael@0 845 testVim('yy_multiply_repeat', function(cm, vim, helpers) {
michael@0 846 var curStart = makeCursor(0, 3);
michael@0 847 cm.setCursor(curStart);
michael@0 848 var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
michael@0 849 { line: 6, ch: 0 });
michael@0 850 var expectedLineCount = cm.lineCount();
michael@0 851 helpers.doKeys('2', 'y', '3', 'y');
michael@0 852 eq(expectedLineCount, cm.lineCount());
michael@0 853 var register = helpers.getRegisterController().getRegister();
michael@0 854 eq(expectedBuffer, register.toString());
michael@0 855 is(register.linewise);
michael@0 856 eqPos(curStart, cm.getCursor());
michael@0 857 });
michael@0 858 // Change commands behave like d commands except that it also enters insert
michael@0 859 // mode. In addition, when the change is linewise, an additional newline is
michael@0 860 // inserted so that insert mode starts on that line.
michael@0 861 testVim('cw', function(cm, vim, helpers) {
michael@0 862 cm.setCursor(0, 0);
michael@0 863 helpers.doKeys('c', '2', 'w');
michael@0 864 eq(' word3', cm.getValue());
michael@0 865 helpers.assertCursorAt(0, 0);
michael@0 866 }, { value: 'word1 word2 word3'});
michael@0 867 testVim('cw_repeat', function(cm, vim, helpers) {
michael@0 868 // Assert that cw does delete newline if it should go to the next line, and
michael@0 869 // that repeat works properly.
michael@0 870 var curStart = makeCursor(0, 1);
michael@0 871 cm.setCursor(curStart);
michael@0 872 helpers.doKeys('c', '2', 'w');
michael@0 873 eq(' ', cm.getValue());
michael@0 874 var register = helpers.getRegisterController().getRegister();
michael@0 875 eq('word1\nword2', register.toString());
michael@0 876 is(!register.linewise);
michael@0 877 eqPos(curStart, cm.getCursor());
michael@0 878 eq('vim-insert', cm.getOption('keyMap'));
michael@0 879 }, { value: ' word1\nword2' });
michael@0 880 testVim('cc_multiply_repeat', function(cm, vim, helpers) {
michael@0 881 cm.setCursor(0, 3);
michael@0 882 var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
michael@0 883 { line: 6, ch: 0 });
michael@0 884 var expectedLineCount = cm.lineCount() - 5;
michael@0 885 helpers.doKeys('2', 'c', '3', 'c');
michael@0 886 eq(expectedLineCount, cm.lineCount());
michael@0 887 var register = helpers.getRegisterController().getRegister();
michael@0 888 eq(expectedBuffer, register.toString());
michael@0 889 is(register.linewise);
michael@0 890 eq('vim-insert', cm.getOption('keyMap'));
michael@0 891 });
michael@0 892 testVim('cc_append', function(cm, vim, helpers) {
michael@0 893 var expectedLineCount = cm.lineCount();
michael@0 894 cm.setCursor(cm.lastLine(), 0);
michael@0 895 helpers.doKeys('c', 'c');
michael@0 896 eq(expectedLineCount, cm.lineCount());
michael@0 897 });
michael@0 898 // Swapcase commands edit in place and do not modify registers.
michael@0 899 testVim('g~w_repeat', function(cm, vim, helpers) {
michael@0 900 // Assert that dw does delete newline if it should go to the next line, and
michael@0 901 // that repeat works properly.
michael@0 902 var curStart = makeCursor(0, 1);
michael@0 903 cm.setCursor(curStart);
michael@0 904 helpers.doKeys('g', '~', '2', 'w');
michael@0 905 eq(' WORD1\nWORD2', cm.getValue());
michael@0 906 var register = helpers.getRegisterController().getRegister();
michael@0 907 eq('', register.toString());
michael@0 908 is(!register.linewise);
michael@0 909 eqPos(curStart, cm.getCursor());
michael@0 910 }, { value: ' word1\nword2' });
michael@0 911 testVim('g~g~', function(cm, vim, helpers) {
michael@0 912 var curStart = makeCursor(0, 3);
michael@0 913 cm.setCursor(curStart);
michael@0 914 var expectedLineCount = cm.lineCount();
michael@0 915 var expectedValue = cm.getValue().toUpperCase();
michael@0 916 helpers.doKeys('2', 'g', '~', '3', 'g', '~');
michael@0 917 eq(expectedValue, cm.getValue());
michael@0 918 var register = helpers.getRegisterController().getRegister();
michael@0 919 eq('', register.toString());
michael@0 920 is(!register.linewise);
michael@0 921 eqPos(curStart, cm.getCursor());
michael@0 922 }, { value: ' word1\nword2\nword3\nword4\nword5\nword6' });
michael@0 923 testVim('>{motion}', function(cm, vim, helpers) {
michael@0 924 cm.setCursor(1, 3);
michael@0 925 var expectedLineCount = cm.lineCount();
michael@0 926 var expectedValue = ' word1\n word2\nword3 ';
michael@0 927 helpers.doKeys('>', 'k');
michael@0 928 eq(expectedValue, cm.getValue());
michael@0 929 var register = helpers.getRegisterController().getRegister();
michael@0 930 eq('', register.toString());
michael@0 931 is(!register.linewise);
michael@0 932 helpers.assertCursorAt(0, 3);
michael@0 933 }, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
michael@0 934 testVim('>>', function(cm, vim, helpers) {
michael@0 935 cm.setCursor(0, 3);
michael@0 936 var expectedLineCount = cm.lineCount();
michael@0 937 var expectedValue = ' word1\n word2\nword3 ';
michael@0 938 helpers.doKeys('2', '>', '>');
michael@0 939 eq(expectedValue, cm.getValue());
michael@0 940 var register = helpers.getRegisterController().getRegister();
michael@0 941 eq('', register.toString());
michael@0 942 is(!register.linewise);
michael@0 943 helpers.assertCursorAt(0, 3);
michael@0 944 }, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
michael@0 945 testVim('<{motion}', function(cm, vim, helpers) {
michael@0 946 cm.setCursor(1, 3);
michael@0 947 var expectedLineCount = cm.lineCount();
michael@0 948 var expectedValue = ' word1\nword2\nword3 ';
michael@0 949 helpers.doKeys('<', 'k');
michael@0 950 eq(expectedValue, cm.getValue());
michael@0 951 var register = helpers.getRegisterController().getRegister();
michael@0 952 eq('', register.toString());
michael@0 953 is(!register.linewise);
michael@0 954 helpers.assertCursorAt(0, 1);
michael@0 955 }, { value: ' word1\n word2\nword3 ', indentUnit: 2 });
michael@0 956 testVim('<<', function(cm, vim, helpers) {
michael@0 957 cm.setCursor(0, 3);
michael@0 958 var expectedLineCount = cm.lineCount();
michael@0 959 var expectedValue = ' word1\nword2\nword3 ';
michael@0 960 helpers.doKeys('2', '<', '<');
michael@0 961 eq(expectedValue, cm.getValue());
michael@0 962 var register = helpers.getRegisterController().getRegister();
michael@0 963 eq('', register.toString());
michael@0 964 is(!register.linewise);
michael@0 965 helpers.assertCursorAt(0, 1);
michael@0 966 }, { value: ' word1\n word2\nword3 ', indentUnit: 2 });
michael@0 967
michael@0 968 // Edit tests
michael@0 969 function testEdit(name, before, pos, edit, after) {
michael@0 970 return testVim(name, function(cm, vim, helpers) {
michael@0 971 var ch = before.search(pos)
michael@0 972 var line = before.substring(0, ch).split('\n').length - 1;
michael@0 973 if (line) {
michael@0 974 ch = before.substring(0, ch).split('\n').pop().length;
michael@0 975 }
michael@0 976 cm.setCursor(line, ch);
michael@0 977 helpers.doKeys.apply(this, edit.split(''));
michael@0 978 eq(after, cm.getValue());
michael@0 979 }, {value: before});
michael@0 980 }
michael@0 981
michael@0 982 // These Delete tests effectively cover word-wise Change, Visual & Yank.
michael@0 983 // Tabs are used as differentiated whitespace to catch edge cases.
michael@0 984 // Normal word:
michael@0 985 testEdit('diw_mid_spc', 'foo \tbAr\t baz', /A/, 'diw', 'foo \t\t baz');
michael@0 986 testEdit('daw_mid_spc', 'foo \tbAr\t baz', /A/, 'daw', 'foo \tbaz');
michael@0 987 testEdit('diw_mid_punct', 'foo \tbAr.\t baz', /A/, 'diw', 'foo \t.\t baz');
michael@0 988 testEdit('daw_mid_punct', 'foo \tbAr.\t baz', /A/, 'daw', 'foo.\t baz');
michael@0 989 testEdit('diw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diw', 'foo \t,.\t baz');
michael@0 990 testEdit('daw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daw', 'foo \t,.\t baz');
michael@0 991 testEdit('diw_start_spc', 'bAr \tbaz', /A/, 'diw', ' \tbaz');
michael@0 992 testEdit('daw_start_spc', 'bAr \tbaz', /A/, 'daw', 'baz');
michael@0 993 testEdit('diw_start_punct', 'bAr. \tbaz', /A/, 'diw', '. \tbaz');
michael@0 994 testEdit('daw_start_punct', 'bAr. \tbaz', /A/, 'daw', '. \tbaz');
michael@0 995 testEdit('diw_end_spc', 'foo \tbAr', /A/, 'diw', 'foo \t');
michael@0 996 testEdit('daw_end_spc', 'foo \tbAr', /A/, 'daw', 'foo');
michael@0 997 testEdit('diw_end_punct', 'foo \tbAr.', /A/, 'diw', 'foo \t.');
michael@0 998 testEdit('daw_end_punct', 'foo \tbAr.', /A/, 'daw', 'foo.');
michael@0 999 // Big word:
michael@0 1000 testEdit('diW_mid_spc', 'foo \tbAr\t baz', /A/, 'diW', 'foo \t\t baz');
michael@0 1001 testEdit('daW_mid_spc', 'foo \tbAr\t baz', /A/, 'daW', 'foo \tbaz');
michael@0 1002 testEdit('diW_mid_punct', 'foo \tbAr.\t baz', /A/, 'diW', 'foo \t\t baz');
michael@0 1003 testEdit('daW_mid_punct', 'foo \tbAr.\t baz', /A/, 'daW', 'foo \tbaz');
michael@0 1004 testEdit('diW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diW', 'foo \t\t baz');
michael@0 1005 testEdit('daW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daW', 'foo \tbaz');
michael@0 1006 testEdit('diW_start_spc', 'bAr\t baz', /A/, 'diW', '\t baz');
michael@0 1007 testEdit('daW_start_spc', 'bAr\t baz', /A/, 'daW', 'baz');
michael@0 1008 testEdit('diW_start_punct', 'bAr.\t baz', /A/, 'diW', '\t baz');
michael@0 1009 testEdit('daW_start_punct', 'bAr.\t baz', /A/, 'daW', 'baz');
michael@0 1010 testEdit('diW_end_spc', 'foo \tbAr', /A/, 'diW', 'foo \t');
michael@0 1011 testEdit('daW_end_spc', 'foo \tbAr', /A/, 'daW', 'foo');
michael@0 1012 testEdit('diW_end_punct', 'foo \tbAr.', /A/, 'diW', 'foo \t');
michael@0 1013 testEdit('daW_end_punct', 'foo \tbAr.', /A/, 'daW', 'foo');
michael@0 1014 // Deleting text objects
michael@0 1015 // Open and close on same line
michael@0 1016 testEdit('di(_open_spc', 'foo (bAr) baz', /\(/, 'di(', 'foo () baz');
michael@0 1017 testEdit('di)_open_spc', 'foo (bAr) baz', /\(/, 'di)', 'foo () baz');
michael@0 1018 testEdit('da(_open_spc', 'foo (bAr) baz', /\(/, 'da(', 'foo baz');
michael@0 1019 testEdit('da)_open_spc', 'foo (bAr) baz', /\(/, 'da)', 'foo baz');
michael@0 1020
michael@0 1021 testEdit('di(_middle_spc', 'foo (bAr) baz', /A/, 'di(', 'foo () baz');
michael@0 1022 testEdit('di)_middle_spc', 'foo (bAr) baz', /A/, 'di)', 'foo () baz');
michael@0 1023 testEdit('da(_middle_spc', 'foo (bAr) baz', /A/, 'da(', 'foo baz');
michael@0 1024 testEdit('da)_middle_spc', 'foo (bAr) baz', /A/, 'da)', 'foo baz');
michael@0 1025
michael@0 1026 testEdit('di(_close_spc', 'foo (bAr) baz', /\)/, 'di(', 'foo () baz');
michael@0 1027 testEdit('di)_close_spc', 'foo (bAr) baz', /\)/, 'di)', 'foo () baz');
michael@0 1028 testEdit('da(_close_spc', 'foo (bAr) baz', /\)/, 'da(', 'foo baz');
michael@0 1029 testEdit('da)_close_spc', 'foo (bAr) baz', /\)/, 'da)', 'foo baz');
michael@0 1030
michael@0 1031 // Open and close on different lines, equally indented
michael@0 1032 testEdit('di{_middle_spc', 'a{\n\tbar\n}b', /r/, 'di{', 'a{}b');
michael@0 1033 testEdit('di}_middle_spc', 'a{\n\tbar\n}b', /r/, 'di}', 'a{}b');
michael@0 1034 testEdit('da{_middle_spc', 'a{\n\tbar\n}b', /r/, 'da{', 'ab');
michael@0 1035 testEdit('da}_middle_spc', 'a{\n\tbar\n}b', /r/, 'da}', 'ab');
michael@0 1036
michael@0 1037 // open and close on diff lines, open indented less than close
michael@0 1038 testEdit('di{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di{', 'a{}b');
michael@0 1039 testEdit('di}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di}', 'a{}b');
michael@0 1040 testEdit('da{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da{', 'ab');
michael@0 1041 testEdit('da}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da}', 'ab');
michael@0 1042
michael@0 1043 // open and close on diff lines, open indented more than close
michael@0 1044 testEdit('di[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di[', 'a\t[]b');
michael@0 1045 testEdit('di]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di]', 'a\t[]b');
michael@0 1046 testEdit('da[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da[', 'a\tb');
michael@0 1047 testEdit('da]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da]', 'a\tb');
michael@0 1048
michael@0 1049 // Operator-motion tests
michael@0 1050 testVim('D', function(cm, vim, helpers) {
michael@0 1051 cm.setCursor(0, 3);
michael@0 1052 helpers.doKeys('D');
michael@0 1053 eq(' wo\nword2\n word3', cm.getValue());
michael@0 1054 var register = helpers.getRegisterController().getRegister();
michael@0 1055 eq('rd1', register.toString());
michael@0 1056 is(!register.linewise);
michael@0 1057 helpers.assertCursorAt(0, 2);
michael@0 1058 }, { value: ' word1\nword2\n word3' });
michael@0 1059 testVim('C', function(cm, vim, helpers) {
michael@0 1060 var curStart = makeCursor(0, 3);
michael@0 1061 cm.setCursor(curStart);
michael@0 1062 helpers.doKeys('C');
michael@0 1063 eq(' wo\nword2\n word3', cm.getValue());
michael@0 1064 var register = helpers.getRegisterController().getRegister();
michael@0 1065 eq('rd1', register.toString());
michael@0 1066 is(!register.linewise);
michael@0 1067 eqPos(curStart, cm.getCursor());
michael@0 1068 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1069 }, { value: ' word1\nword2\n word3' });
michael@0 1070 testVim('Y', function(cm, vim, helpers) {
michael@0 1071 var curStart = makeCursor(0, 3);
michael@0 1072 cm.setCursor(curStart);
michael@0 1073 helpers.doKeys('Y');
michael@0 1074 eq(' word1\nword2\n word3', cm.getValue());
michael@0 1075 var register = helpers.getRegisterController().getRegister();
michael@0 1076 eq('rd1', register.toString());
michael@0 1077 is(!register.linewise);
michael@0 1078 helpers.assertCursorAt(0, 3);
michael@0 1079 }, { value: ' word1\nword2\n word3' });
michael@0 1080 testVim('~', function(cm, vim, helpers) {
michael@0 1081 helpers.doKeys('3', '~');
michael@0 1082 eq('ABCdefg', cm.getValue());
michael@0 1083 helpers.assertCursorAt(0, 3);
michael@0 1084 }, { value: 'abcdefg' });
michael@0 1085
michael@0 1086 // Action tests
michael@0 1087 testVim('ctrl-a', function(cm, vim, helpers) {
michael@0 1088 cm.setCursor(0, 0);
michael@0 1089 helpers.doKeys('<C-a>');
michael@0 1090 eq('-9', cm.getValue());
michael@0 1091 helpers.assertCursorAt(0, 1);
michael@0 1092 helpers.doKeys('2','<C-a>');
michael@0 1093 eq('-7', cm.getValue());
michael@0 1094 }, {value: '-10'});
michael@0 1095 testVim('ctrl-x', function(cm, vim, helpers) {
michael@0 1096 cm.setCursor(0, 0);
michael@0 1097 helpers.doKeys('<C-x>');
michael@0 1098 eq('-1', cm.getValue());
michael@0 1099 helpers.assertCursorAt(0, 1);
michael@0 1100 helpers.doKeys('2','<C-x>');
michael@0 1101 eq('-3', cm.getValue());
michael@0 1102 }, {value: '0'});
michael@0 1103 testVim('<C-x>/<C-a> search forward', function(cm, vim, helpers) {
michael@0 1104 forEach(['<C-x>', '<C-a>'], function(key) {
michael@0 1105 cm.setCursor(0, 0);
michael@0 1106 helpers.doKeys(key);
michael@0 1107 helpers.assertCursorAt(0, 5);
michael@0 1108 helpers.doKeys('l');
michael@0 1109 helpers.doKeys(key);
michael@0 1110 helpers.assertCursorAt(0, 10);
michael@0 1111 cm.setCursor(0, 11);
michael@0 1112 helpers.doKeys(key);
michael@0 1113 helpers.assertCursorAt(0, 11);
michael@0 1114 });
michael@0 1115 }, {value: '__jmp1 jmp2 jmp'});
michael@0 1116 testVim('a', function(cm, vim, helpers) {
michael@0 1117 cm.setCursor(0, 1);
michael@0 1118 helpers.doKeys('a');
michael@0 1119 helpers.assertCursorAt(0, 2);
michael@0 1120 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1121 });
michael@0 1122 testVim('a_eol', function(cm, vim, helpers) {
michael@0 1123 cm.setCursor(0, lines[0].length - 1);
michael@0 1124 helpers.doKeys('a');
michael@0 1125 helpers.assertCursorAt(0, lines[0].length);
michael@0 1126 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1127 });
michael@0 1128 testVim('i', function(cm, vim, helpers) {
michael@0 1129 cm.setCursor(0, 1);
michael@0 1130 helpers.doKeys('i');
michael@0 1131 helpers.assertCursorAt(0, 1);
michael@0 1132 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1133 });
michael@0 1134 testVim('i_repeat', function(cm, vim, helpers) {
michael@0 1135 helpers.doKeys('3', 'i');
michael@0 1136 cm.replaceRange('test', cm.getCursor());
michael@0 1137 helpers.doInsertModeKeys('Esc');
michael@0 1138 eq('testtesttest', cm.getValue());
michael@0 1139 helpers.assertCursorAt(0, 11);
michael@0 1140 }, { value: '' });
michael@0 1141 testVim('i_repeat_delete', function(cm, vim, helpers) {
michael@0 1142 cm.setCursor(0, 4);
michael@0 1143 helpers.doKeys('2', 'i');
michael@0 1144 cm.replaceRange('z', cm.getCursor());
michael@0 1145 helpers.doInsertModeKeys('Backspace', 'Backspace', 'Esc');
michael@0 1146 eq('abe', cm.getValue());
michael@0 1147 helpers.assertCursorAt(0, 1);
michael@0 1148 }, { value: 'abcde' });
michael@0 1149 testVim('A', function(cm, vim, helpers) {
michael@0 1150 helpers.doKeys('A');
michael@0 1151 helpers.assertCursorAt(0, lines[0].length);
michael@0 1152 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1153 });
michael@0 1154 testVim('I', function(cm, vim, helpers) {
michael@0 1155 cm.setCursor(0, 4);
michael@0 1156 helpers.doKeys('I');
michael@0 1157 helpers.assertCursorAt(0, lines[0].textStart);
michael@0 1158 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1159 });
michael@0 1160 testVim('I_repeat', function(cm, vim, helpers) {
michael@0 1161 cm.setCursor(0, 1);
michael@0 1162 helpers.doKeys('3', 'I');
michael@0 1163 cm.replaceRange('test', cm.getCursor());
michael@0 1164 helpers.doInsertModeKeys('Esc');
michael@0 1165 eq('testtesttestblah', cm.getValue());
michael@0 1166 helpers.assertCursorAt(0, 11);
michael@0 1167 }, { value: 'blah' });
michael@0 1168 testVim('o', function(cm, vim, helpers) {
michael@0 1169 cm.setCursor(0, 4);
michael@0 1170 helpers.doKeys('o');
michael@0 1171 eq('word1\n\nword2', cm.getValue());
michael@0 1172 helpers.assertCursorAt(1, 0);
michael@0 1173 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1174 }, { value: 'word1\nword2' });
michael@0 1175 testVim('o_repeat', function(cm, vim, helpers) {
michael@0 1176 cm.setCursor(0, 0);
michael@0 1177 helpers.doKeys('3', 'o');
michael@0 1178 cm.replaceRange('test', cm.getCursor());
michael@0 1179 helpers.doInsertModeKeys('Esc');
michael@0 1180 eq('\ntest\ntest\ntest', cm.getValue());
michael@0 1181 helpers.assertCursorAt(3, 3);
michael@0 1182 }, { value: '' });
michael@0 1183 testVim('O', function(cm, vim, helpers) {
michael@0 1184 cm.setCursor(0, 4);
michael@0 1185 helpers.doKeys('O');
michael@0 1186 eq('\nword1\nword2', cm.getValue());
michael@0 1187 helpers.assertCursorAt(0, 0);
michael@0 1188 eq('vim-insert', cm.getOption('keyMap'));
michael@0 1189 }, { value: 'word1\nword2' });
michael@0 1190 testVim('J', function(cm, vim, helpers) {
michael@0 1191 cm.setCursor(0, 4);
michael@0 1192 helpers.doKeys('J');
michael@0 1193 var expectedValue = 'word1 word2\nword3\n word4';
michael@0 1194 eq(expectedValue, cm.getValue());
michael@0 1195 helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1);
michael@0 1196 }, { value: 'word1 \n word2\nword3\n word4' });
michael@0 1197 testVim('J_repeat', function(cm, vim, helpers) {
michael@0 1198 cm.setCursor(0, 4);
michael@0 1199 helpers.doKeys('3', 'J');
michael@0 1200 var expectedValue = 'word1 word2 word3\n word4';
michael@0 1201 eq(expectedValue, cm.getValue());
michael@0 1202 helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1);
michael@0 1203 }, { value: 'word1 \n word2\nword3\n word4' });
michael@0 1204 testVim('p', function(cm, vim, helpers) {
michael@0 1205 cm.setCursor(0, 1);
michael@0 1206 helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
michael@0 1207 helpers.doKeys('p');
michael@0 1208 eq('__abc\ndef_', cm.getValue());
michael@0 1209 helpers.assertCursorAt(1, 2);
michael@0 1210 }, { value: '___' });
michael@0 1211 testVim('p_register', function(cm, vim, helpers) {
michael@0 1212 cm.setCursor(0, 1);
michael@0 1213 helpers.getRegisterController().getRegister('a').setText('abc\ndef', false);
michael@0 1214 helpers.doKeys('"', 'a', 'p');
michael@0 1215 eq('__abc\ndef_', cm.getValue());
michael@0 1216 helpers.assertCursorAt(1, 2);
michael@0 1217 }, { value: '___' });
michael@0 1218 testVim('p_wrong_register', function(cm, vim, helpers) {
michael@0 1219 cm.setCursor(0, 1);
michael@0 1220 helpers.getRegisterController().getRegister('a').setText('abc\ndef', false);
michael@0 1221 helpers.doKeys('p');
michael@0 1222 eq('___', cm.getValue());
michael@0 1223 helpers.assertCursorAt(0, 1);
michael@0 1224 }, { value: '___' });
michael@0 1225 testVim('p_line', function(cm, vim, helpers) {
michael@0 1226 cm.setCursor(0, 1);
michael@0 1227 helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true);
michael@0 1228 helpers.doKeys('2', 'p');
michael@0 1229 eq('___\n a\nd\n a\nd', cm.getValue());
michael@0 1230 helpers.assertCursorAt(1, 2);
michael@0 1231 }, { value: '___' });
michael@0 1232 testVim('p_lastline', function(cm, vim, helpers) {
michael@0 1233 cm.setCursor(0, 1);
michael@0 1234 helpers.getRegisterController().pushText('"', 'yank', ' a\nd', true);
michael@0 1235 helpers.doKeys('2', 'p');
michael@0 1236 eq('___\n a\nd\n a\nd', cm.getValue());
michael@0 1237 helpers.assertCursorAt(1, 2);
michael@0 1238 }, { value: '___' });
michael@0 1239 testVim('P', function(cm, vim, helpers) {
michael@0 1240 cm.setCursor(0, 1);
michael@0 1241 helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
michael@0 1242 helpers.doKeys('P');
michael@0 1243 eq('_abc\ndef__', cm.getValue());
michael@0 1244 helpers.assertCursorAt(1, 3);
michael@0 1245 }, { value: '___' });
michael@0 1246 testVim('P_line', function(cm, vim, helpers) {
michael@0 1247 cm.setCursor(0, 1);
michael@0 1248 helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true);
michael@0 1249 helpers.doKeys('2', 'P');
michael@0 1250 eq(' a\nd\n a\nd\n___', cm.getValue());
michael@0 1251 helpers.assertCursorAt(0, 2);
michael@0 1252 }, { value: '___' });
michael@0 1253 testVim('r', function(cm, vim, helpers) {
michael@0 1254 cm.setCursor(0, 1);
michael@0 1255 helpers.doKeys('3', 'r', 'u');
michael@0 1256 eq('wuuuet\nanother', cm.getValue(),'3r failed');
michael@0 1257 helpers.assertCursorAt(0, 3);
michael@0 1258 cm.setCursor(0, 4);
michael@0 1259 helpers.doKeys('v', 'j', 'h', 'r', '<Space>');
michael@0 1260 eq('wuuu \n her', cm.getValue(),'Replacing selection by space-characters failed');
michael@0 1261 }, { value: 'wordet\nanother' });
michael@0 1262 testVim('R', function(cm, vim, helpers) {
michael@0 1263 cm.setCursor(0, 1);
michael@0 1264 helpers.doKeys('R');
michael@0 1265 helpers.assertCursorAt(0, 1);
michael@0 1266 eq('vim-replace', cm.getOption('keyMap'));
michael@0 1267 is(cm.state.overwrite, 'Setting overwrite state failed');
michael@0 1268 });
michael@0 1269 testVim('mark', function(cm, vim, helpers) {
michael@0 1270 cm.setCursor(2, 2);
michael@0 1271 helpers.doKeys('m', 't');
michael@0 1272 cm.setCursor(0, 0);
michael@0 1273 helpers.doKeys('\'', 't');
michael@0 1274 helpers.assertCursorAt(2, 2);
michael@0 1275 cm.setCursor(0, 0);
michael@0 1276 helpers.doKeys('`', 't');
michael@0 1277 helpers.assertCursorAt(2, 2);
michael@0 1278 });
michael@0 1279 testVim('jumpToMark_next', function(cm, vim, helpers) {
michael@0 1280 cm.setCursor(2, 2);
michael@0 1281 helpers.doKeys('m', 't');
michael@0 1282 cm.setCursor(0, 0);
michael@0 1283 helpers.doKeys(']', '`');
michael@0 1284 helpers.assertCursorAt(2, 2);
michael@0 1285 cm.setCursor(0, 0);
michael@0 1286 helpers.doKeys(']', '\'');
michael@0 1287 helpers.assertCursorAt(2, 0);
michael@0 1288 });
michael@0 1289 testVim('jumpToMark_next_repeat', function(cm, vim, helpers) {
michael@0 1290 cm.setCursor(2, 2);
michael@0 1291 helpers.doKeys('m', 'a');
michael@0 1292 cm.setCursor(3, 2);
michael@0 1293 helpers.doKeys('m', 'b');
michael@0 1294 cm.setCursor(4, 2);
michael@0 1295 helpers.doKeys('m', 'c');
michael@0 1296 cm.setCursor(0, 0);
michael@0 1297 helpers.doKeys('2', ']', '`');
michael@0 1298 helpers.assertCursorAt(3, 2);
michael@0 1299 cm.setCursor(0, 0);
michael@0 1300 helpers.doKeys('2', ']', '\'');
michael@0 1301 helpers.assertCursorAt(3, 1);
michael@0 1302 });
michael@0 1303 testVim('jumpToMark_next_sameline', function(cm, vim, helpers) {
michael@0 1304 cm.setCursor(2, 0);
michael@0 1305 helpers.doKeys('m', 'a');
michael@0 1306 cm.setCursor(2, 4);
michael@0 1307 helpers.doKeys('m', 'b');
michael@0 1308 cm.setCursor(2, 2);
michael@0 1309 helpers.doKeys(']', '`');
michael@0 1310 helpers.assertCursorAt(2, 4);
michael@0 1311 });
michael@0 1312 testVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) {
michael@0 1313 cm.setCursor(2, 0);
michael@0 1314 helpers.doKeys('m', 'a');
michael@0 1315 cm.setCursor(4, 0);
michael@0 1316 helpers.doKeys(']', '`');
michael@0 1317 helpers.assertCursorAt(4, 0);
michael@0 1318 });
michael@0 1319 testVim('jumpToMark_next_nomark', function(cm, vim, helpers) {
michael@0 1320 cm.setCursor(2, 2);
michael@0 1321 helpers.doKeys(']', '`');
michael@0 1322 helpers.assertCursorAt(2, 2);
michael@0 1323 helpers.doKeys(']', '\'');
michael@0 1324 helpers.assertCursorAt(2, 0);
michael@0 1325 });
michael@0 1326 testVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) {
michael@0 1327 cm.setCursor(2, 2);
michael@0 1328 helpers.doKeys('m', 'a');
michael@0 1329 cm.setCursor(3, 4);
michael@0 1330 helpers.doKeys('m', 'b');
michael@0 1331 cm.setCursor(2, 1);
michael@0 1332 helpers.doKeys(']', '\'');
michael@0 1333 helpers.assertCursorAt(3, 1);
michael@0 1334 });
michael@0 1335 testVim('jumpToMark_next_action', function(cm, vim, helpers) {
michael@0 1336 cm.setCursor(2, 2);
michael@0 1337 helpers.doKeys('m', 't');
michael@0 1338 cm.setCursor(0, 0);
michael@0 1339 helpers.doKeys('d', ']', '`');
michael@0 1340 helpers.assertCursorAt(0, 0);
michael@0 1341 var actual = cm.getLine(0);
michael@0 1342 var expected = 'pop pop 0 1 2 3 4';
michael@0 1343 eq(actual, expected, "Deleting while jumping to the next mark failed.");
michael@0 1344 });
michael@0 1345 testVim('jumpToMark_next_line_action', function(cm, vim, helpers) {
michael@0 1346 cm.setCursor(2, 2);
michael@0 1347 helpers.doKeys('m', 't');
michael@0 1348 cm.setCursor(0, 0);
michael@0 1349 helpers.doKeys('d', ']', '\'');
michael@0 1350 helpers.assertCursorAt(0, 1);
michael@0 1351 var actual = cm.getLine(0);
michael@0 1352 var expected = ' (a) [b] {c} '
michael@0 1353 eq(actual, expected, "Deleting while jumping to the next mark line failed.");
michael@0 1354 });
michael@0 1355 testVim('jumpToMark_prev', function(cm, vim, helpers) {
michael@0 1356 cm.setCursor(2, 2);
michael@0 1357 helpers.doKeys('m', 't');
michael@0 1358 cm.setCursor(4, 0);
michael@0 1359 helpers.doKeys('[', '`');
michael@0 1360 helpers.assertCursorAt(2, 2);
michael@0 1361 cm.setCursor(4, 0);
michael@0 1362 helpers.doKeys('[', '\'');
michael@0 1363 helpers.assertCursorAt(2, 0);
michael@0 1364 });
michael@0 1365 testVim('jumpToMark_prev_repeat', function(cm, vim, helpers) {
michael@0 1366 cm.setCursor(2, 2);
michael@0 1367 helpers.doKeys('m', 'a');
michael@0 1368 cm.setCursor(3, 2);
michael@0 1369 helpers.doKeys('m', 'b');
michael@0 1370 cm.setCursor(4, 2);
michael@0 1371 helpers.doKeys('m', 'c');
michael@0 1372 cm.setCursor(5, 0);
michael@0 1373 helpers.doKeys('2', '[', '`');
michael@0 1374 helpers.assertCursorAt(3, 2);
michael@0 1375 cm.setCursor(5, 0);
michael@0 1376 helpers.doKeys('2', '[', '\'');
michael@0 1377 helpers.assertCursorAt(3, 1);
michael@0 1378 });
michael@0 1379 testVim('jumpToMark_prev_sameline', function(cm, vim, helpers) {
michael@0 1380 cm.setCursor(2, 0);
michael@0 1381 helpers.doKeys('m', 'a');
michael@0 1382 cm.setCursor(2, 4);
michael@0 1383 helpers.doKeys('m', 'b');
michael@0 1384 cm.setCursor(2, 2);
michael@0 1385 helpers.doKeys('[', '`');
michael@0 1386 helpers.assertCursorAt(2, 0);
michael@0 1387 });
michael@0 1388 testVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) {
michael@0 1389 cm.setCursor(4, 4);
michael@0 1390 helpers.doKeys('m', 'a');
michael@0 1391 cm.setCursor(2, 0);
michael@0 1392 helpers.doKeys('[', '`');
michael@0 1393 helpers.assertCursorAt(2, 0);
michael@0 1394 });
michael@0 1395 testVim('jumpToMark_prev_nomark', function(cm, vim, helpers) {
michael@0 1396 cm.setCursor(2, 2);
michael@0 1397 helpers.doKeys('[', '`');
michael@0 1398 helpers.assertCursorAt(2, 2);
michael@0 1399 helpers.doKeys('[', '\'');
michael@0 1400 helpers.assertCursorAt(2, 0);
michael@0 1401 });
michael@0 1402 testVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) {
michael@0 1403 cm.setCursor(2, 2);
michael@0 1404 helpers.doKeys('m', 'a');
michael@0 1405 cm.setCursor(3, 4);
michael@0 1406 helpers.doKeys('m', 'b');
michael@0 1407 cm.setCursor(3, 6);
michael@0 1408 helpers.doKeys('[', '\'');
michael@0 1409 helpers.assertCursorAt(2, 0);
michael@0 1410 });
michael@0 1411 testVim('delmark_single', function(cm, vim, helpers) {
michael@0 1412 cm.setCursor(1, 2);
michael@0 1413 helpers.doKeys('m', 't');
michael@0 1414 helpers.doEx('delmarks t');
michael@0 1415 cm.setCursor(0, 0);
michael@0 1416 helpers.doKeys('`', 't');
michael@0 1417 helpers.assertCursorAt(0, 0);
michael@0 1418 });
michael@0 1419 testVim('delmark_range', function(cm, vim, helpers) {
michael@0 1420 cm.setCursor(1, 2);
michael@0 1421 helpers.doKeys('m', 'a');
michael@0 1422 cm.setCursor(2, 2);
michael@0 1423 helpers.doKeys('m', 'b');
michael@0 1424 cm.setCursor(3, 2);
michael@0 1425 helpers.doKeys('m', 'c');
michael@0 1426 cm.setCursor(4, 2);
michael@0 1427 helpers.doKeys('m', 'd');
michael@0 1428 cm.setCursor(5, 2);
michael@0 1429 helpers.doKeys('m', 'e');
michael@0 1430 helpers.doEx('delmarks b-d');
michael@0 1431 cm.setCursor(0, 0);
michael@0 1432 helpers.doKeys('`', 'a');
michael@0 1433 helpers.assertCursorAt(1, 2);
michael@0 1434 helpers.doKeys('`', 'b');
michael@0 1435 helpers.assertCursorAt(1, 2);
michael@0 1436 helpers.doKeys('`', 'c');
michael@0 1437 helpers.assertCursorAt(1, 2);
michael@0 1438 helpers.doKeys('`', 'd');
michael@0 1439 helpers.assertCursorAt(1, 2);
michael@0 1440 helpers.doKeys('`', 'e');
michael@0 1441 helpers.assertCursorAt(5, 2);
michael@0 1442 });
michael@0 1443 testVim('delmark_multi', function(cm, vim, helpers) {
michael@0 1444 cm.setCursor(1, 2);
michael@0 1445 helpers.doKeys('m', 'a');
michael@0 1446 cm.setCursor(2, 2);
michael@0 1447 helpers.doKeys('m', 'b');
michael@0 1448 cm.setCursor(3, 2);
michael@0 1449 helpers.doKeys('m', 'c');
michael@0 1450 cm.setCursor(4, 2);
michael@0 1451 helpers.doKeys('m', 'd');
michael@0 1452 cm.setCursor(5, 2);
michael@0 1453 helpers.doKeys('m', 'e');
michael@0 1454 helpers.doEx('delmarks bcd');
michael@0 1455 cm.setCursor(0, 0);
michael@0 1456 helpers.doKeys('`', 'a');
michael@0 1457 helpers.assertCursorAt(1, 2);
michael@0 1458 helpers.doKeys('`', 'b');
michael@0 1459 helpers.assertCursorAt(1, 2);
michael@0 1460 helpers.doKeys('`', 'c');
michael@0 1461 helpers.assertCursorAt(1, 2);
michael@0 1462 helpers.doKeys('`', 'd');
michael@0 1463 helpers.assertCursorAt(1, 2);
michael@0 1464 helpers.doKeys('`', 'e');
michael@0 1465 helpers.assertCursorAt(5, 2);
michael@0 1466 });
michael@0 1467 testVim('delmark_multi_space', function(cm, vim, helpers) {
michael@0 1468 cm.setCursor(1, 2);
michael@0 1469 helpers.doKeys('m', 'a');
michael@0 1470 cm.setCursor(2, 2);
michael@0 1471 helpers.doKeys('m', 'b');
michael@0 1472 cm.setCursor(3, 2);
michael@0 1473 helpers.doKeys('m', 'c');
michael@0 1474 cm.setCursor(4, 2);
michael@0 1475 helpers.doKeys('m', 'd');
michael@0 1476 cm.setCursor(5, 2);
michael@0 1477 helpers.doKeys('m', 'e');
michael@0 1478 helpers.doEx('delmarks b c d');
michael@0 1479 cm.setCursor(0, 0);
michael@0 1480 helpers.doKeys('`', 'a');
michael@0 1481 helpers.assertCursorAt(1, 2);
michael@0 1482 helpers.doKeys('`', 'b');
michael@0 1483 helpers.assertCursorAt(1, 2);
michael@0 1484 helpers.doKeys('`', 'c');
michael@0 1485 helpers.assertCursorAt(1, 2);
michael@0 1486 helpers.doKeys('`', 'd');
michael@0 1487 helpers.assertCursorAt(1, 2);
michael@0 1488 helpers.doKeys('`', 'e');
michael@0 1489 helpers.assertCursorAt(5, 2);
michael@0 1490 });
michael@0 1491 testVim('delmark_all', function(cm, vim, helpers) {
michael@0 1492 cm.setCursor(1, 2);
michael@0 1493 helpers.doKeys('m', 'a');
michael@0 1494 cm.setCursor(2, 2);
michael@0 1495 helpers.doKeys('m', 'b');
michael@0 1496 cm.setCursor(3, 2);
michael@0 1497 helpers.doKeys('m', 'c');
michael@0 1498 cm.setCursor(4, 2);
michael@0 1499 helpers.doKeys('m', 'd');
michael@0 1500 cm.setCursor(5, 2);
michael@0 1501 helpers.doKeys('m', 'e');
michael@0 1502 helpers.doEx('delmarks a b-de');
michael@0 1503 cm.setCursor(0, 0);
michael@0 1504 helpers.doKeys('`', 'a');
michael@0 1505 helpers.assertCursorAt(0, 0);
michael@0 1506 helpers.doKeys('`', 'b');
michael@0 1507 helpers.assertCursorAt(0, 0);
michael@0 1508 helpers.doKeys('`', 'c');
michael@0 1509 helpers.assertCursorAt(0, 0);
michael@0 1510 helpers.doKeys('`', 'd');
michael@0 1511 helpers.assertCursorAt(0, 0);
michael@0 1512 helpers.doKeys('`', 'e');
michael@0 1513 helpers.assertCursorAt(0, 0);
michael@0 1514 });
michael@0 1515 testVim('visual', function(cm, vim, helpers) {
michael@0 1516 helpers.doKeys('l', 'v', 'l', 'l');
michael@0 1517 helpers.assertCursorAt(0, 3);
michael@0 1518 eqPos(makeCursor(0, 1), cm.getCursor('anchor'));
michael@0 1519 helpers.doKeys('d');
michael@0 1520 eq('15', cm.getValue());
michael@0 1521 }, { value: '12345' });
michael@0 1522 testVim('visual_line', function(cm, vim, helpers) {
michael@0 1523 helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd');
michael@0 1524 eq(' 4\n 5', cm.getValue());
michael@0 1525 }, { value: ' 1\n 2\n 3\n 4\n 5' });
michael@0 1526 testVim('visual_marks', function(cm, vim, helpers) {
michael@0 1527 helpers.doKeys('l', 'v', 'l', 'l', 'v');
michael@0 1528 // Test visual mode marks
michael@0 1529 cm.setCursor(0, 0);
michael@0 1530 helpers.doKeys('\'', '<');
michael@0 1531 helpers.assertCursorAt(0, 1);
michael@0 1532 helpers.doKeys('\'', '>');
michael@0 1533 helpers.assertCursorAt(0, 3);
michael@0 1534 });
michael@0 1535 testVim('visual_join', function(cm, vim, helpers) {
michael@0 1536 helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J');
michael@0 1537 eq(' 1 2 3\n 4\n 5', cm.getValue());
michael@0 1538 }, { value: ' 1\n 2\n 3\n 4\n 5' });
michael@0 1539 testVim('visual_blank', function(cm, vim, helpers) {
michael@0 1540 helpers.doKeys('v', 'k');
michael@0 1541 eq(vim.visualMode, true);
michael@0 1542 }, { value: '\n' });
michael@0 1543 testVim('reselect_visual', function(cm, vim, helpers) {
michael@0 1544 helpers.doKeys('l', 'v', 'l', 'l', 'y', 'g', 'v');
michael@0 1545 helpers.assertCursorAt(0, 3);
michael@0 1546 eqPos(makeCursor(0, 1), cm.getCursor('anchor'));
michael@0 1547 helpers.doKeys('d');
michael@0 1548 eq('15', cm.getValue());
michael@0 1549 }, { value: '12345' });
michael@0 1550 testVim('reselect_visual_line', function(cm, vim, helpers) {
michael@0 1551 helpers.doKeys('l', 'V', 'l', 'j', 'j', 'V', 'g', 'v', 'd');
michael@0 1552 eq(' 4\n 5', cm.getValue());
michael@0 1553 }, { value: ' 1\n 2\n 3\n 4\n 5' });
michael@0 1554 testVim('s_normal', function(cm, vim, helpers) {
michael@0 1555 cm.setCursor(0, 1);
michael@0 1556 helpers.doKeys('s');
michael@0 1557 helpers.doInsertModeKeys('Esc');
michael@0 1558 helpers.assertCursorAt(0, 0);
michael@0 1559 eq('ac', cm.getValue());
michael@0 1560 }, { value: 'abc'});
michael@0 1561 testVim('s_visual', function(cm, vim, helpers) {
michael@0 1562 cm.setCursor(0, 1);
michael@0 1563 helpers.doKeys('v', 's');
michael@0 1564 helpers.doInsertModeKeys('Esc');
michael@0 1565 helpers.assertCursorAt(0, 0);
michael@0 1566 eq('ac', cm.getValue());
michael@0 1567 }, { value: 'abc'});
michael@0 1568 testVim('o_visual', function(cm,vim,helpers) {
michael@0 1569 cm.setCursor(0,0);
michael@0 1570 helpers.doKeys('v','l','l','l','o');
michael@0 1571 helpers.assertCursorAt(0,0);
michael@0 1572 helpers.doKeys('v','v','j','j','j','o');
michael@0 1573 helpers.assertCursorAt(0,0);
michael@0 1574 helpers.doKeys('o');
michael@0 1575 helpers.doKeys('l','l')
michael@0 1576 helpers.assertCursorAt(3,2);
michael@0 1577 helpers.doKeys('d');
michael@0 1578 eq('p',cm.getValue());
michael@0 1579 }, { value: 'abcd\nefgh\nijkl\nmnop'});
michael@0 1580
michael@0 1581 testVim('S_normal', function(cm, vim, helpers) {
michael@0 1582 cm.setCursor(0, 1);
michael@0 1583 helpers.doKeys('j', 'S');
michael@0 1584 helpers.doInsertModeKeys('Esc');
michael@0 1585 helpers.assertCursorAt(1, 0);
michael@0 1586 eq('aa\n\ncc', cm.getValue());
michael@0 1587 }, { value: 'aa\nbb\ncc'});
michael@0 1588 testVim('S_visual', function(cm, vim, helpers) {
michael@0 1589 cm.setCursor(0, 1);
michael@0 1590 helpers.doKeys('v', 'j', 'S');
michael@0 1591 helpers.doInsertModeKeys('Esc');
michael@0 1592 helpers.assertCursorAt(0, 0);
michael@0 1593 eq('\ncc', cm.getValue());
michael@0 1594 }, { value: 'aa\nbb\ncc'});
michael@0 1595
michael@0 1596 testVim('/ and n/N', function(cm, vim, helpers) {
michael@0 1597 cm.openDialog = helpers.fakeOpenDialog('match');
michael@0 1598 helpers.doKeys('/');
michael@0 1599 helpers.assertCursorAt(0, 11);
michael@0 1600 helpers.doKeys('n');
michael@0 1601 helpers.assertCursorAt(1, 6);
michael@0 1602 helpers.doKeys('N');
michael@0 1603 helpers.assertCursorAt(0, 11);
michael@0 1604
michael@0 1605 cm.setCursor(0, 0);
michael@0 1606 helpers.doKeys('2', '/');
michael@0 1607 helpers.assertCursorAt(1, 6);
michael@0 1608 }, { value: 'match nope match \n nope Match' });
michael@0 1609 testVim('/_case', function(cm, vim, helpers) {
michael@0 1610 cm.openDialog = helpers.fakeOpenDialog('Match');
michael@0 1611 helpers.doKeys('/');
michael@0 1612 helpers.assertCursorAt(1, 6);
michael@0 1613 }, { value: 'match nope match \n nope Match' });
michael@0 1614 testVim('/_2_pcre', function(cm, vim, helpers) {
michael@0 1615 CodeMirror.Vim.setOption('pcre', true);
michael@0 1616 cm.openDialog = helpers.fakeOpenDialog('(word){2}');
michael@0 1617 helpers.doKeys('/');
michael@0 1618 helpers.assertCursorAt(1, 9);
michael@0 1619 helpers.doKeys('n');
michael@0 1620 helpers.assertCursorAt(2, 1);
michael@0 1621 }, { value: 'word\n another wordword\n wordwordword\n' });
michael@0 1622 testVim('/_2_nopcre', function(cm, vim, helpers) {
michael@0 1623 CodeMirror.Vim.setOption('pcre', false);
michael@0 1624 cm.openDialog = helpers.fakeOpenDialog('\\(word\\)\\{2}');
michael@0 1625 helpers.doKeys('/');
michael@0 1626 helpers.assertCursorAt(1, 9);
michael@0 1627 helpers.doKeys('n');
michael@0 1628 helpers.assertCursorAt(2, 1);
michael@0 1629 }, { value: 'word\n another wordword\n wordwordword\n' });
michael@0 1630 testVim('/_nongreedy', function(cm, vim, helpers) {
michael@0 1631 cm.openDialog = helpers.fakeOpenDialog('aa');
michael@0 1632 helpers.doKeys('/');
michael@0 1633 helpers.assertCursorAt(0, 4);
michael@0 1634 helpers.doKeys('n');
michael@0 1635 helpers.assertCursorAt(1, 3);
michael@0 1636 helpers.doKeys('n');
michael@0 1637 helpers.assertCursorAt(0, 0);
michael@0 1638 }, { value: 'aaa aa \n a aa'});
michael@0 1639 testVim('?_nongreedy', function(cm, vim, helpers) {
michael@0 1640 cm.openDialog = helpers.fakeOpenDialog('aa');
michael@0 1641 helpers.doKeys('?');
michael@0 1642 helpers.assertCursorAt(1, 3);
michael@0 1643 helpers.doKeys('n');
michael@0 1644 helpers.assertCursorAt(0, 4);
michael@0 1645 helpers.doKeys('n');
michael@0 1646 helpers.assertCursorAt(0, 0);
michael@0 1647 }, { value: 'aaa aa \n a aa'});
michael@0 1648 testVim('/_greedy', function(cm, vim, helpers) {
michael@0 1649 cm.openDialog = helpers.fakeOpenDialog('a+');
michael@0 1650 helpers.doKeys('/');
michael@0 1651 helpers.assertCursorAt(0, 4);
michael@0 1652 helpers.doKeys('n');
michael@0 1653 helpers.assertCursorAt(1, 1);
michael@0 1654 helpers.doKeys('n');
michael@0 1655 helpers.assertCursorAt(1, 3);
michael@0 1656 helpers.doKeys('n');
michael@0 1657 helpers.assertCursorAt(0, 0);
michael@0 1658 }, { value: 'aaa aa \n a aa'});
michael@0 1659 testVim('?_greedy', function(cm, vim, helpers) {
michael@0 1660 cm.openDialog = helpers.fakeOpenDialog('a+');
michael@0 1661 helpers.doKeys('?');
michael@0 1662 helpers.assertCursorAt(1, 3);
michael@0 1663 helpers.doKeys('n');
michael@0 1664 helpers.assertCursorAt(1, 1);
michael@0 1665 helpers.doKeys('n');
michael@0 1666 helpers.assertCursorAt(0, 4);
michael@0 1667 helpers.doKeys('n');
michael@0 1668 helpers.assertCursorAt(0, 0);
michael@0 1669 }, { value: 'aaa aa \n a aa'});
michael@0 1670 testVim('/_greedy_0_or_more', function(cm, vim, helpers) {
michael@0 1671 cm.openDialog = helpers.fakeOpenDialog('a*');
michael@0 1672 helpers.doKeys('/');
michael@0 1673 helpers.assertCursorAt(0, 3);
michael@0 1674 helpers.doKeys('n');
michael@0 1675 helpers.assertCursorAt(0, 4);
michael@0 1676 helpers.doKeys('n');
michael@0 1677 helpers.assertCursorAt(0, 5);
michael@0 1678 helpers.doKeys('n');
michael@0 1679 helpers.assertCursorAt(1, 0);
michael@0 1680 helpers.doKeys('n');
michael@0 1681 helpers.assertCursorAt(1, 1);
michael@0 1682 helpers.doKeys('n');
michael@0 1683 helpers.assertCursorAt(0, 0);
michael@0 1684 }, { value: 'aaa aa\n aa'});
michael@0 1685 testVim('?_greedy_0_or_more', function(cm, vim, helpers) {
michael@0 1686 cm.openDialog = helpers.fakeOpenDialog('a*');
michael@0 1687 helpers.doKeys('?');
michael@0 1688 helpers.assertCursorAt(1, 1);
michael@0 1689 helpers.doKeys('n');
michael@0 1690 helpers.assertCursorAt(1, 0);
michael@0 1691 helpers.doKeys('n');
michael@0 1692 helpers.assertCursorAt(0, 5);
michael@0 1693 helpers.doKeys('n');
michael@0 1694 helpers.assertCursorAt(0, 4);
michael@0 1695 helpers.doKeys('n');
michael@0 1696 helpers.assertCursorAt(0, 3);
michael@0 1697 helpers.doKeys('n');
michael@0 1698 helpers.assertCursorAt(0, 0);
michael@0 1699 }, { value: 'aaa aa\n aa'});
michael@0 1700 testVim('? and n/N', function(cm, vim, helpers) {
michael@0 1701 cm.openDialog = helpers.fakeOpenDialog('match');
michael@0 1702 helpers.doKeys('?');
michael@0 1703 helpers.assertCursorAt(1, 6);
michael@0 1704 helpers.doKeys('n');
michael@0 1705 helpers.assertCursorAt(0, 11);
michael@0 1706 helpers.doKeys('N');
michael@0 1707 helpers.assertCursorAt(1, 6);
michael@0 1708
michael@0 1709 cm.setCursor(0, 0);
michael@0 1710 helpers.doKeys('2', '?');
michael@0 1711 helpers.assertCursorAt(0, 11);
michael@0 1712 }, { value: 'match nope match \n nope Match' });
michael@0 1713 testVim('*', function(cm, vim, helpers) {
michael@0 1714 cm.setCursor(0, 9);
michael@0 1715 helpers.doKeys('*');
michael@0 1716 helpers.assertCursorAt(0, 22);
michael@0 1717
michael@0 1718 cm.setCursor(0, 9);
michael@0 1719 helpers.doKeys('2', '*');
michael@0 1720 helpers.assertCursorAt(1, 8);
michael@0 1721 }, { value: 'nomatch match nomatch match \nnomatch Match' });
michael@0 1722 testVim('*_no_word', function(cm, vim, helpers) {
michael@0 1723 cm.setCursor(0, 0);
michael@0 1724 helpers.doKeys('*');
michael@0 1725 helpers.assertCursorAt(0, 0);
michael@0 1726 }, { value: ' \n match \n' });
michael@0 1727 testVim('*_symbol', function(cm, vim, helpers) {
michael@0 1728 cm.setCursor(0, 0);
michael@0 1729 helpers.doKeys('*');
michael@0 1730 helpers.assertCursorAt(1, 0);
michael@0 1731 }, { value: ' /}\n/} match \n' });
michael@0 1732 testVim('#', function(cm, vim, helpers) {
michael@0 1733 cm.setCursor(0, 9);
michael@0 1734 helpers.doKeys('#');
michael@0 1735 helpers.assertCursorAt(1, 8);
michael@0 1736
michael@0 1737 cm.setCursor(0, 9);
michael@0 1738 helpers.doKeys('2', '#');
michael@0 1739 helpers.assertCursorAt(0, 22);
michael@0 1740 }, { value: 'nomatch match nomatch match \nnomatch Match' });
michael@0 1741 testVim('*_seek', function(cm, vim, helpers) {
michael@0 1742 // Should skip over space and symbols.
michael@0 1743 cm.setCursor(0, 3);
michael@0 1744 helpers.doKeys('*');
michael@0 1745 helpers.assertCursorAt(0, 22);
michael@0 1746 }, { value: ' := match nomatch match \nnomatch Match' });
michael@0 1747 testVim('#', function(cm, vim, helpers) {
michael@0 1748 // Should skip over space and symbols.
michael@0 1749 cm.setCursor(0, 3);
michael@0 1750 helpers.doKeys('#');
michael@0 1751 helpers.assertCursorAt(1, 8);
michael@0 1752 }, { value: ' := match nomatch match \nnomatch Match' });
michael@0 1753 testVim('macro_insert', function(cm, vim, helpers) {
michael@0 1754 cm.setCursor(0, 0);
michael@0 1755 helpers.doKeys('q', 'a', '0', 'i');
michael@0 1756 cm.replaceRange('foo', cm.getCursor());
michael@0 1757 helpers.doInsertModeKeys('Esc');
michael@0 1758 helpers.doKeys('q', '@', 'a');
michael@0 1759 eq('foofoo', cm.getValue());
michael@0 1760 }, { value: ''});
michael@0 1761 testVim('macro_space', function(cm, vim, helpers) {
michael@0 1762 cm.setCursor(0, 0);
michael@0 1763 helpers.doKeys('<Space>', '<Space>');
michael@0 1764 helpers.assertCursorAt(0, 2);
michael@0 1765 helpers.doKeys('q', 'a', '<Space>', '<Space>', 'q');
michael@0 1766 helpers.assertCursorAt(0, 4);
michael@0 1767 helpers.doKeys('@', 'a');
michael@0 1768 helpers.assertCursorAt(0, 6);
michael@0 1769 helpers.doKeys('@', 'a');
michael@0 1770 helpers.assertCursorAt(0, 8);
michael@0 1771 }, { value: 'one line of text.'});
michael@0 1772 testVim('macro_parens', function(cm, vim, helpers) {
michael@0 1773 cm.setCursor(0, 0);
michael@0 1774 helpers.doKeys('q', 'z', 'i');
michael@0 1775 cm.replaceRange('(', cm.getCursor());
michael@0 1776 helpers.doInsertModeKeys('Esc');
michael@0 1777 helpers.doKeys('e', 'a');
michael@0 1778 cm.replaceRange(')', cm.getCursor());
michael@0 1779 helpers.doInsertModeKeys('Esc');
michael@0 1780 helpers.doKeys('q');
michael@0 1781 helpers.doKeys('w', '@', 'z');
michael@0 1782 helpers.doKeys('w', '@', 'z');
michael@0 1783 eq('(see) (spot) (run)', cm.getValue());
michael@0 1784 }, { value: 'see spot run'});
michael@0 1785 testVim('macro_overwrite', function(cm, vim, helpers) {
michael@0 1786 cm.setCursor(0, 0);
michael@0 1787 helpers.doKeys('q', 'z', '0', 'i');
michael@0 1788 cm.replaceRange('I ', cm.getCursor());
michael@0 1789 helpers.doInsertModeKeys('Esc');
michael@0 1790 helpers.doKeys('q');
michael@0 1791 helpers.doKeys('e');
michael@0 1792 // Now replace the macro with something else.
michael@0 1793 helpers.doKeys('q', 'z', 'a');
michael@0 1794 cm.replaceRange('.', cm.getCursor());
michael@0 1795 helpers.doInsertModeKeys('Esc');
michael@0 1796 helpers.doKeys('q');
michael@0 1797 helpers.doKeys('e', '@', 'z');
michael@0 1798 helpers.doKeys('e', '@', 'z');
michael@0 1799 eq('I see. spot. run.', cm.getValue());
michael@0 1800 }, { value: 'see spot run'});
michael@0 1801 testVim('macro_search_f', function(cm, vim, helpers) {
michael@0 1802 cm.setCursor(0, 0);
michael@0 1803 helpers.doKeys('q', 'a', 'f', ' ');
michael@0 1804 helpers.assertCursorAt(0,3);
michael@0 1805 helpers.doKeys('q', '0');
michael@0 1806 helpers.assertCursorAt(0,0);
michael@0 1807 helpers.doKeys('@', 'a');
michael@0 1808 helpers.assertCursorAt(0,3);
michael@0 1809 }, { value: 'The quick brown fox jumped over the lazy dog.'});
michael@0 1810 testVim('macro_search_2f', function(cm, vim, helpers) {
michael@0 1811 cm.setCursor(0, 0);
michael@0 1812 helpers.doKeys('q', 'a', '2', 'f', ' ');
michael@0 1813 helpers.assertCursorAt(0,9);
michael@0 1814 helpers.doKeys('q', '0');
michael@0 1815 helpers.assertCursorAt(0,0);
michael@0 1816 helpers.doKeys('@', 'a');
michael@0 1817 helpers.assertCursorAt(0,9);
michael@0 1818 }, { value: 'The quick brown fox jumped over the lazy dog.'});
michael@0 1819 testVim('yank_register', function(cm, vim, helpers) {
michael@0 1820 cm.setCursor(0, 0);
michael@0 1821 helpers.doKeys('"', 'a', 'y', 'y');
michael@0 1822 helpers.doKeys('j', '"', 'b', 'y', 'y');
michael@0 1823 cm.openDialog = helpers.fakeOpenDialog('registers');
michael@0 1824 cm.openNotification = helpers.fakeOpenNotification(function(text) {
michael@0 1825 is(/a\s+foo/.test(text));
michael@0 1826 is(/b\s+bar/.test(text));
michael@0 1827 });
michael@0 1828 helpers.doKeys(':');
michael@0 1829 }, { value: 'foo\nbar'});
michael@0 1830 testVim('macro_register', function(cm, vim, helpers) {
michael@0 1831 cm.setCursor(0, 0);
michael@0 1832 helpers.doKeys('q', 'a', 'i');
michael@0 1833 cm.replaceRange('gangnam', cm.getCursor());
michael@0 1834 helpers.doInsertModeKeys('Esc');
michael@0 1835 helpers.doKeys('q');
michael@0 1836 helpers.doKeys('q', 'b', 'o');
michael@0 1837 cm.replaceRange('style', cm.getCursor());
michael@0 1838 helpers.doInsertModeKeys('Esc');
michael@0 1839 helpers.doKeys('q');
michael@0 1840 cm.openDialog = helpers.fakeOpenDialog('registers');
michael@0 1841 cm.openNotification = helpers.fakeOpenNotification(function(text) {
michael@0 1842 is(/a\s+i/.test(text));
michael@0 1843 is(/b\s+o/.test(text));
michael@0 1844 });
michael@0 1845 helpers.doKeys(':');
michael@0 1846 }, { value: ''});
michael@0 1847 testVim('.', function(cm, vim, helpers) {
michael@0 1848 cm.setCursor(0, 0);
michael@0 1849 helpers.doKeys('2', 'd', 'w');
michael@0 1850 helpers.doKeys('.');
michael@0 1851 eq('5 6', cm.getValue());
michael@0 1852 }, { value: '1 2 3 4 5 6'});
michael@0 1853 testVim('._repeat', function(cm, vim, helpers) {
michael@0 1854 cm.setCursor(0, 0);
michael@0 1855 helpers.doKeys('2', 'd', 'w');
michael@0 1856 helpers.doKeys('3', '.');
michael@0 1857 eq('6', cm.getValue());
michael@0 1858 }, { value: '1 2 3 4 5 6'});
michael@0 1859 testVim('._insert', function(cm, vim, helpers) {
michael@0 1860 helpers.doKeys('i');
michael@0 1861 cm.replaceRange('test', cm.getCursor());
michael@0 1862 helpers.doInsertModeKeys('Esc');
michael@0 1863 helpers.doKeys('.');
michael@0 1864 eq('testestt', cm.getValue());
michael@0 1865 helpers.assertCursorAt(0, 6);
michael@0 1866 }, { value: ''});
michael@0 1867 testVim('._insert_repeat', function(cm, vim, helpers) {
michael@0 1868 helpers.doKeys('i');
michael@0 1869 cm.replaceRange('test', cm.getCursor());
michael@0 1870 cm.setCursor(0, 4);
michael@0 1871 helpers.doInsertModeKeys('Esc');
michael@0 1872 helpers.doKeys('2', '.');
michael@0 1873 eq('testesttestt', cm.getValue());
michael@0 1874 helpers.assertCursorAt(0, 10);
michael@0 1875 }, { value: ''});
michael@0 1876 testVim('._repeat_insert', function(cm, vim, helpers) {
michael@0 1877 helpers.doKeys('3', 'i');
michael@0 1878 cm.replaceRange('te', cm.getCursor());
michael@0 1879 cm.setCursor(0, 2);
michael@0 1880 helpers.doInsertModeKeys('Esc');
michael@0 1881 helpers.doKeys('.');
michael@0 1882 eq('tetettetetee', cm.getValue());
michael@0 1883 helpers.assertCursorAt(0, 10);
michael@0 1884 }, { value: ''});
michael@0 1885 testVim('._insert_o', function(cm, vim, helpers) {
michael@0 1886 helpers.doKeys('o');
michael@0 1887 cm.replaceRange('z', cm.getCursor());
michael@0 1888 cm.setCursor(1, 1);
michael@0 1889 helpers.doInsertModeKeys('Esc');
michael@0 1890 helpers.doKeys('.');
michael@0 1891 eq('\nz\nz', cm.getValue());
michael@0 1892 helpers.assertCursorAt(2, 0);
michael@0 1893 }, { value: ''});
michael@0 1894 testVim('._insert_o_repeat', function(cm, vim, helpers) {
michael@0 1895 helpers.doKeys('o');
michael@0 1896 cm.replaceRange('z', cm.getCursor());
michael@0 1897 helpers.doInsertModeKeys('Esc');
michael@0 1898 cm.setCursor(1, 0);
michael@0 1899 helpers.doKeys('2', '.');
michael@0 1900 eq('\nz\nz\nz', cm.getValue());
michael@0 1901 helpers.assertCursorAt(3, 0);
michael@0 1902 }, { value: ''});
michael@0 1903 testVim('._insert_o_indent', function(cm, vim, helpers) {
michael@0 1904 helpers.doKeys('o');
michael@0 1905 cm.replaceRange('z', cm.getCursor());
michael@0 1906 helpers.doInsertModeKeys('Esc');
michael@0 1907 cm.setCursor(1, 2);
michael@0 1908 helpers.doKeys('.');
michael@0 1909 eq('{\n z\n z', cm.getValue());
michael@0 1910 helpers.assertCursorAt(2, 2);
michael@0 1911 }, { value: '{'});
michael@0 1912 testVim('._insert_cw', function(cm, vim, helpers) {
michael@0 1913 helpers.doKeys('c', 'w');
michael@0 1914 cm.replaceRange('test', cm.getCursor());
michael@0 1915 helpers.doInsertModeKeys('Esc');
michael@0 1916 cm.setCursor(0, 3);
michael@0 1917 helpers.doKeys('2', 'l');
michael@0 1918 helpers.doKeys('.');
michael@0 1919 eq('test test word3', cm.getValue());
michael@0 1920 helpers.assertCursorAt(0, 8);
michael@0 1921 }, { value: 'word1 word2 word3' });
michael@0 1922 testVim('._insert_cw_repeat', function(cm, vim, helpers) {
michael@0 1923 // For some reason, repeat cw in desktop VIM will does not repeat insert mode
michael@0 1924 // changes. Will conform to that behavior.
michael@0 1925 helpers.doKeys('c', 'w');
michael@0 1926 cm.replaceRange('test', cm.getCursor());
michael@0 1927 helpers.doInsertModeKeys('Esc');
michael@0 1928 cm.setCursor(0, 4);
michael@0 1929 helpers.doKeys('l');
michael@0 1930 helpers.doKeys('2', '.');
michael@0 1931 eq('test test', cm.getValue());
michael@0 1932 helpers.assertCursorAt(0, 8);
michael@0 1933 }, { value: 'word1 word2 word3' });
michael@0 1934 testVim('._delete', function(cm, vim, helpers) {
michael@0 1935 cm.setCursor(0, 5);
michael@0 1936 helpers.doKeys('i');
michael@0 1937 helpers.doInsertModeKeys('Backspace', 'Esc');
michael@0 1938 helpers.doKeys('.');
michael@0 1939 eq('zace', cm.getValue());
michael@0 1940 helpers.assertCursorAt(0, 1);
michael@0 1941 }, { value: 'zabcde'});
michael@0 1942 testVim('._delete_repeat', function(cm, vim, helpers) {
michael@0 1943 cm.setCursor(0, 6);
michael@0 1944 helpers.doKeys('i');
michael@0 1945 helpers.doInsertModeKeys('Backspace', 'Esc');
michael@0 1946 helpers.doKeys('2', '.');
michael@0 1947 eq('zzce', cm.getValue());
michael@0 1948 helpers.assertCursorAt(0, 1);
michael@0 1949 }, { value: 'zzabcde'});
michael@0 1950 testVim('f;', function(cm, vim, helpers) {
michael@0 1951 cm.setCursor(0, 0);
michael@0 1952 helpers.doKeys('f', 'x');
michael@0 1953 helpers.doKeys(';');
michael@0 1954 helpers.doKeys('2', ';');
michael@0 1955 eq(9, cm.getCursor().ch);
michael@0 1956 }, { value: '01x3xx678x'});
michael@0 1957 testVim('F;', function(cm, vim, helpers) {
michael@0 1958 cm.setCursor(0, 8);
michael@0 1959 helpers.doKeys('F', 'x');
michael@0 1960 helpers.doKeys(';');
michael@0 1961 helpers.doKeys('2', ';');
michael@0 1962 eq(2, cm.getCursor().ch);
michael@0 1963 }, { value: '01x3xx6x8x'});
michael@0 1964 testVim('t;', function(cm, vim, helpers) {
michael@0 1965 cm.setCursor(0, 0);
michael@0 1966 helpers.doKeys('t', 'x');
michael@0 1967 helpers.doKeys(';');
michael@0 1968 helpers.doKeys('2', ';');
michael@0 1969 eq(8, cm.getCursor().ch);
michael@0 1970 }, { value: '01x3xx678x'});
michael@0 1971 testVim('T;', function(cm, vim, helpers) {
michael@0 1972 cm.setCursor(0, 9);
michael@0 1973 helpers.doKeys('T', 'x');
michael@0 1974 helpers.doKeys(';');
michael@0 1975 helpers.doKeys('2', ';');
michael@0 1976 eq(2, cm.getCursor().ch);
michael@0 1977 }, { value: '0xx3xx678x'});
michael@0 1978 testVim('f,', function(cm, vim, helpers) {
michael@0 1979 cm.setCursor(0, 6);
michael@0 1980 helpers.doKeys('f', 'x');
michael@0 1981 helpers.doKeys(',');
michael@0 1982 helpers.doKeys('2', ',');
michael@0 1983 eq(2, cm.getCursor().ch);
michael@0 1984 }, { value: '01x3xx678x'});
michael@0 1985 testVim('F,', function(cm, vim, helpers) {
michael@0 1986 cm.setCursor(0, 3);
michael@0 1987 helpers.doKeys('F', 'x');
michael@0 1988 helpers.doKeys(',');
michael@0 1989 helpers.doKeys('2', ',');
michael@0 1990 eq(9, cm.getCursor().ch);
michael@0 1991 }, { value: '01x3xx678x'});
michael@0 1992 testVim('t,', function(cm, vim, helpers) {
michael@0 1993 cm.setCursor(0, 6);
michael@0 1994 helpers.doKeys('t', 'x');
michael@0 1995 helpers.doKeys(',');
michael@0 1996 helpers.doKeys('2', ',');
michael@0 1997 eq(3, cm.getCursor().ch);
michael@0 1998 }, { value: '01x3xx678x'});
michael@0 1999 testVim('T,', function(cm, vim, helpers) {
michael@0 2000 cm.setCursor(0, 4);
michael@0 2001 helpers.doKeys('T', 'x');
michael@0 2002 helpers.doKeys(',');
michael@0 2003 helpers.doKeys('2', ',');
michael@0 2004 eq(8, cm.getCursor().ch);
michael@0 2005 }, { value: '01x3xx67xx'});
michael@0 2006 testVim('fd,;', function(cm, vim, helpers) {
michael@0 2007 cm.setCursor(0, 0);
michael@0 2008 helpers.doKeys('f', '4');
michael@0 2009 cm.setCursor(0, 0);
michael@0 2010 helpers.doKeys('d', ';');
michael@0 2011 eq('56789', cm.getValue());
michael@0 2012 helpers.doKeys('u');
michael@0 2013 cm.setCursor(0, 9);
michael@0 2014 helpers.doKeys('d', ',');
michael@0 2015 eq('01239', cm.getValue());
michael@0 2016 }, { value: '0123456789'});
michael@0 2017 testVim('Fd,;', function(cm, vim, helpers) {
michael@0 2018 cm.setCursor(0, 9);
michael@0 2019 helpers.doKeys('F', '4');
michael@0 2020 cm.setCursor(0, 9);
michael@0 2021 helpers.doKeys('d', ';');
michael@0 2022 eq('01239', cm.getValue());
michael@0 2023 helpers.doKeys('u');
michael@0 2024 cm.setCursor(0, 0);
michael@0 2025 helpers.doKeys('d', ',');
michael@0 2026 eq('56789', cm.getValue());
michael@0 2027 }, { value: '0123456789'});
michael@0 2028 testVim('td,;', function(cm, vim, helpers) {
michael@0 2029 cm.setCursor(0, 0);
michael@0 2030 helpers.doKeys('t', '4');
michael@0 2031 cm.setCursor(0, 0);
michael@0 2032 helpers.doKeys('d', ';');
michael@0 2033 eq('456789', cm.getValue());
michael@0 2034 helpers.doKeys('u');
michael@0 2035 cm.setCursor(0, 9);
michael@0 2036 helpers.doKeys('d', ',');
michael@0 2037 eq('012349', cm.getValue());
michael@0 2038 }, { value: '0123456789'});
michael@0 2039 testVim('Td,;', function(cm, vim, helpers) {
michael@0 2040 cm.setCursor(0, 9);
michael@0 2041 helpers.doKeys('T', '4');
michael@0 2042 cm.setCursor(0, 9);
michael@0 2043 helpers.doKeys('d', ';');
michael@0 2044 eq('012349', cm.getValue());
michael@0 2045 helpers.doKeys('u');
michael@0 2046 cm.setCursor(0, 0);
michael@0 2047 helpers.doKeys('d', ',');
michael@0 2048 eq('456789', cm.getValue());
michael@0 2049 }, { value: '0123456789'});
michael@0 2050 testVim('fc,;', function(cm, vim, helpers) {
michael@0 2051 cm.setCursor(0, 0);
michael@0 2052 helpers.doKeys('f', '4');
michael@0 2053 cm.setCursor(0, 0);
michael@0 2054 helpers.doKeys('c', ';', 'Esc');
michael@0 2055 eq('56789', cm.getValue());
michael@0 2056 helpers.doKeys('u');
michael@0 2057 cm.setCursor(0, 9);
michael@0 2058 helpers.doKeys('c', ',');
michael@0 2059 eq('01239', cm.getValue());
michael@0 2060 }, { value: '0123456789'});
michael@0 2061 testVim('Fc,;', function(cm, vim, helpers) {
michael@0 2062 cm.setCursor(0, 9);
michael@0 2063 helpers.doKeys('F', '4');
michael@0 2064 cm.setCursor(0, 9);
michael@0 2065 helpers.doKeys('c', ';', 'Esc');
michael@0 2066 eq('01239', cm.getValue());
michael@0 2067 helpers.doKeys('u');
michael@0 2068 cm.setCursor(0, 0);
michael@0 2069 helpers.doKeys('c', ',');
michael@0 2070 eq('56789', cm.getValue());
michael@0 2071 }, { value: '0123456789'});
michael@0 2072 testVim('tc,;', function(cm, vim, helpers) {
michael@0 2073 cm.setCursor(0, 0);
michael@0 2074 helpers.doKeys('t', '4');
michael@0 2075 cm.setCursor(0, 0);
michael@0 2076 helpers.doKeys('c', ';', 'Esc');
michael@0 2077 eq('456789', cm.getValue());
michael@0 2078 helpers.doKeys('u');
michael@0 2079 cm.setCursor(0, 9);
michael@0 2080 helpers.doKeys('c', ',');
michael@0 2081 eq('012349', cm.getValue());
michael@0 2082 }, { value: '0123456789'});
michael@0 2083 testVim('Tc,;', function(cm, vim, helpers) {
michael@0 2084 cm.setCursor(0, 9);
michael@0 2085 helpers.doKeys('T', '4');
michael@0 2086 cm.setCursor(0, 9);
michael@0 2087 helpers.doKeys('c', ';', 'Esc');
michael@0 2088 eq('012349', cm.getValue());
michael@0 2089 helpers.doKeys('u');
michael@0 2090 cm.setCursor(0, 0);
michael@0 2091 helpers.doKeys('c', ',');
michael@0 2092 eq('456789', cm.getValue());
michael@0 2093 }, { value: '0123456789'});
michael@0 2094 testVim('fy,;', function(cm, vim, helpers) {
michael@0 2095 cm.setCursor(0, 0);
michael@0 2096 helpers.doKeys('f', '4');
michael@0 2097 cm.setCursor(0, 0);
michael@0 2098 helpers.doKeys('y', ';', 'P');
michael@0 2099 eq('012340123456789', cm.getValue());
michael@0 2100 helpers.doKeys('u');
michael@0 2101 cm.setCursor(0, 9);
michael@0 2102 helpers.doKeys('y', ',', 'P');
michael@0 2103 eq('012345678456789', cm.getValue());
michael@0 2104 }, { value: '0123456789'});
michael@0 2105 testVim('Fy,;', function(cm, vim, helpers) {
michael@0 2106 cm.setCursor(0, 9);
michael@0 2107 helpers.doKeys('F', '4');
michael@0 2108 cm.setCursor(0, 9);
michael@0 2109 helpers.doKeys('y', ';', 'p');
michael@0 2110 eq('012345678945678', cm.getValue());
michael@0 2111 helpers.doKeys('u');
michael@0 2112 cm.setCursor(0, 0);
michael@0 2113 helpers.doKeys('y', ',', 'P');
michael@0 2114 eq('012340123456789', cm.getValue());
michael@0 2115 }, { value: '0123456789'});
michael@0 2116 testVim('ty,;', function(cm, vim, helpers) {
michael@0 2117 cm.setCursor(0, 0);
michael@0 2118 helpers.doKeys('t', '4');
michael@0 2119 cm.setCursor(0, 0);
michael@0 2120 helpers.doKeys('y', ';', 'P');
michael@0 2121 eq('01230123456789', cm.getValue());
michael@0 2122 helpers.doKeys('u');
michael@0 2123 cm.setCursor(0, 9);
michael@0 2124 helpers.doKeys('y', ',', 'p');
michael@0 2125 eq('01234567895678', cm.getValue());
michael@0 2126 }, { value: '0123456789'});
michael@0 2127 testVim('Ty,;', function(cm, vim, helpers) {
michael@0 2128 cm.setCursor(0, 9);
michael@0 2129 helpers.doKeys('T', '4');
michael@0 2130 cm.setCursor(0, 9);
michael@0 2131 helpers.doKeys('y', ';', 'p');
michael@0 2132 eq('01234567895678', cm.getValue());
michael@0 2133 helpers.doKeys('u');
michael@0 2134 cm.setCursor(0, 0);
michael@0 2135 helpers.doKeys('y', ',', 'P');
michael@0 2136 eq('01230123456789', cm.getValue());
michael@0 2137 }, { value: '0123456789'});
michael@0 2138 testVim('HML', function(cm, vim, helpers) {
michael@0 2139 var lines = 35;
michael@0 2140 var textHeight = cm.defaultTextHeight();
michael@0 2141 cm.setSize(600, lines*textHeight);
michael@0 2142 cm.setCursor(120, 0);
michael@0 2143 helpers.doKeys('H');
michael@0 2144 helpers.assertCursorAt(86, 2);
michael@0 2145 helpers.doKeys('L');
michael@0 2146 helpers.assertCursorAt(120, 4);
michael@0 2147 helpers.doKeys('M');
michael@0 2148 helpers.assertCursorAt(103,4);
michael@0 2149 }, { value: (function(){
michael@0 2150 var lines = new Array(100);
michael@0 2151 var upper = ' xx\n';
michael@0 2152 var lower = ' xx\n';
michael@0 2153 upper = lines.join(upper);
michael@0 2154 lower = lines.join(lower);
michael@0 2155 return upper + lower;
michael@0 2156 })()});
michael@0 2157
michael@0 2158 var zVals = ['zb','zz','zt','z-','z.','z<CR>'].map(function(e, idx){
michael@0 2159 var lineNum = 250;
michael@0 2160 var lines = 35;
michael@0 2161 testVim(e, function(cm, vim, helpers) {
michael@0 2162 var k1 = e[0];
michael@0 2163 var k2 = e.substring(1);
michael@0 2164 var textHeight = cm.defaultTextHeight();
michael@0 2165 cm.setSize(600, lines*textHeight);
michael@0 2166 cm.setCursor(lineNum, 0);
michael@0 2167 helpers.doKeys(k1, k2);
michael@0 2168 zVals[idx] = cm.getScrollInfo().top;
michael@0 2169 }, { value: (function(){
michael@0 2170 return new Array(500).join('\n');
michael@0 2171 })()});
michael@0 2172 });
michael@0 2173 testVim('zb<zz', function(cm, vim, helpers){
michael@0 2174 eq(zVals[0]<zVals[1], true);
michael@0 2175 });
michael@0 2176 testVim('zz<zt', function(cm, vim, helpers){
michael@0 2177 eq(zVals[1]<zVals[2], true);
michael@0 2178 });
michael@0 2179 testVim('zb==z-', function(cm, vim, helpers){
michael@0 2180 eq(zVals[0], zVals[3]);
michael@0 2181 });
michael@0 2182 testVim('zz==z.', function(cm, vim, helpers){
michael@0 2183 eq(zVals[1], zVals[4]);
michael@0 2184 });
michael@0 2185 testVim('zt==z<CR>', function(cm, vim, helpers){
michael@0 2186 eq(zVals[2], zVals[5]);
michael@0 2187 });
michael@0 2188
michael@0 2189 var moveTillCharacterSandbox =
michael@0 2190 'The quick brown fox \n'
michael@0 2191 'jumped over the lazy dog.'
michael@0 2192 testVim('moveTillCharacter', function(cm, vim, helpers){
michael@0 2193 cm.setCursor(0, 0);
michael@0 2194 // Search for the 'q'.
michael@0 2195 cm.openDialog = helpers.fakeOpenDialog('q');
michael@0 2196 helpers.doKeys('/');
michael@0 2197 eq(4, cm.getCursor().ch);
michael@0 2198 // Jump to just before the first o in the list.
michael@0 2199 helpers.doKeys('t');
michael@0 2200 helpers.doKeys('o');
michael@0 2201 eq('The quick brown fox \n', cm.getValue());
michael@0 2202 // Delete that one character.
michael@0 2203 helpers.doKeys('d');
michael@0 2204 helpers.doKeys('t');
michael@0 2205 helpers.doKeys('o');
michael@0 2206 eq('The quick bown fox \n', cm.getValue());
michael@0 2207 // Delete everything until the next 'o'.
michael@0 2208 helpers.doKeys('.');
michael@0 2209 eq('The quick box \n', cm.getValue());
michael@0 2210 // An unmatched character should have no effect.
michael@0 2211 helpers.doKeys('d');
michael@0 2212 helpers.doKeys('t');
michael@0 2213 helpers.doKeys('q');
michael@0 2214 eq('The quick box \n', cm.getValue());
michael@0 2215 // Matches should only be possible on single lines.
michael@0 2216 helpers.doKeys('d');
michael@0 2217 helpers.doKeys('t');
michael@0 2218 helpers.doKeys('z');
michael@0 2219 eq('The quick box \n', cm.getValue());
michael@0 2220 // After all that, the search for 'q' should still be active, so the 'N' command
michael@0 2221 // can run it again in reverse. Use that to delete everything back to the 'q'.
michael@0 2222 helpers.doKeys('d');
michael@0 2223 helpers.doKeys('N');
michael@0 2224 eq('The ox \n', cm.getValue());
michael@0 2225 eq(4, cm.getCursor().ch);
michael@0 2226 }, { value: moveTillCharacterSandbox});
michael@0 2227 testVim('searchForPipe', function(cm, vim, helpers){
michael@0 2228 CodeMirror.Vim.setOption('pcre', false);
michael@0 2229 cm.setCursor(0, 0);
michael@0 2230 // Search for the '|'.
michael@0 2231 cm.openDialog = helpers.fakeOpenDialog('|');
michael@0 2232 helpers.doKeys('/');
michael@0 2233 eq(4, cm.getCursor().ch);
michael@0 2234 }, { value: 'this|that'});
michael@0 2235
michael@0 2236
michael@0 2237 var scrollMotionSandbox =
michael@0 2238 '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
michael@0 2239 '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
michael@0 2240 '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
michael@0 2241 '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n';
michael@0 2242 testVim('scrollMotion', function(cm, vim, helpers){
michael@0 2243 var prevCursor, prevScrollInfo;
michael@0 2244 cm.setCursor(0, 0);
michael@0 2245 // ctrl-y at the top of the file should have no effect.
michael@0 2246 helpers.doKeys('<C-y>');
michael@0 2247 eq(0, cm.getCursor().line);
michael@0 2248 prevScrollInfo = cm.getScrollInfo();
michael@0 2249 helpers.doKeys('<C-e>');
michael@0 2250 eq(1, cm.getCursor().line);
michael@0 2251 is(prevScrollInfo.top < cm.getScrollInfo().top);
michael@0 2252 // Jump to the end of the sandbox.
michael@0 2253 cm.setCursor(1000, 0);
michael@0 2254 prevCursor = cm.getCursor();
michael@0 2255 // ctrl-e at the bottom of the file should have no effect.
michael@0 2256 helpers.doKeys('<C-e>');
michael@0 2257 eq(prevCursor.line, cm.getCursor().line);
michael@0 2258 prevScrollInfo = cm.getScrollInfo();
michael@0 2259 helpers.doKeys('<C-y>');
michael@0 2260 eq(prevCursor.line - 1, cm.getCursor().line);
michael@0 2261 is(prevScrollInfo.top > cm.getScrollInfo().top);
michael@0 2262 }, { value: scrollMotionSandbox});
michael@0 2263
michael@0 2264 var squareBracketMotionSandbox = ''+
michael@0 2265 '({\n'+//0
michael@0 2266 ' ({\n'+//11
michael@0 2267 ' /*comment {\n'+//2
michael@0 2268 ' */(\n'+//3
michael@0 2269 '#else \n'+//4
michael@0 2270 ' /* )\n'+//5
michael@0 2271 '#if }\n'+//6
michael@0 2272 ' )}*/\n'+//7
michael@0 2273 ')}\n'+//8
michael@0 2274 '{}\n'+//9
michael@0 2275 '#else {{\n'+//10
michael@0 2276 '{}\n'+//11
michael@0 2277 '}\n'+//12
michael@0 2278 '{\n'+//13
michael@0 2279 '#endif\n'+//14
michael@0 2280 '}\n'+//15
michael@0 2281 '}\n'+//16
michael@0 2282 '#else';//17
michael@0 2283 testVim('[[, ]]', function(cm, vim, helpers) {
michael@0 2284 cm.setCursor(0, 0);
michael@0 2285 helpers.doKeys(']', ']');
michael@0 2286 helpers.assertCursorAt(9,0);
michael@0 2287 helpers.doKeys('2', ']', ']');
michael@0 2288 helpers.assertCursorAt(13,0);
michael@0 2289 helpers.doKeys(']', ']');
michael@0 2290 helpers.assertCursorAt(17,0);
michael@0 2291 helpers.doKeys('[', '[');
michael@0 2292 helpers.assertCursorAt(13,0);
michael@0 2293 helpers.doKeys('2', '[', '[');
michael@0 2294 helpers.assertCursorAt(9,0);
michael@0 2295 helpers.doKeys('[', '[');
michael@0 2296 helpers.assertCursorAt(0,0);
michael@0 2297 }, { value: squareBracketMotionSandbox});
michael@0 2298 testVim('[], ][', function(cm, vim, helpers) {
michael@0 2299 cm.setCursor(0, 0);
michael@0 2300 helpers.doKeys(']', '[');
michael@0 2301 helpers.assertCursorAt(12,0);
michael@0 2302 helpers.doKeys('2', ']', '[');
michael@0 2303 helpers.assertCursorAt(16,0);
michael@0 2304 helpers.doKeys(']', '[');
michael@0 2305 helpers.assertCursorAt(17,0);
michael@0 2306 helpers.doKeys('[', ']');
michael@0 2307 helpers.assertCursorAt(16,0);
michael@0 2308 helpers.doKeys('2', '[', ']');
michael@0 2309 helpers.assertCursorAt(12,0);
michael@0 2310 helpers.doKeys('[', ']');
michael@0 2311 helpers.assertCursorAt(0,0);
michael@0 2312 }, { value: squareBracketMotionSandbox});
michael@0 2313 testVim('[{, ]}', function(cm, vim, helpers) {
michael@0 2314 cm.setCursor(4, 10);
michael@0 2315 helpers.doKeys('[', '{');
michael@0 2316 helpers.assertCursorAt(2,12);
michael@0 2317 helpers.doKeys('2', '[', '{');
michael@0 2318 helpers.assertCursorAt(0,1);
michael@0 2319 cm.setCursor(4, 10);
michael@0 2320 helpers.doKeys(']', '}');
michael@0 2321 helpers.assertCursorAt(6,11);
michael@0 2322 helpers.doKeys('2', ']', '}');
michael@0 2323 helpers.assertCursorAt(8,1);
michael@0 2324 cm.setCursor(0,1);
michael@0 2325 helpers.doKeys(']', '}');
michael@0 2326 helpers.assertCursorAt(8,1);
michael@0 2327 helpers.doKeys('[', '{');
michael@0 2328 helpers.assertCursorAt(0,1);
michael@0 2329 }, { value: squareBracketMotionSandbox});
michael@0 2330 testVim('[(, ])', function(cm, vim, helpers) {
michael@0 2331 cm.setCursor(4, 10);
michael@0 2332 helpers.doKeys('[', '(');
michael@0 2333 helpers.assertCursorAt(3,14);
michael@0 2334 helpers.doKeys('2', '[', '(');
michael@0 2335 helpers.assertCursorAt(0,0);
michael@0 2336 cm.setCursor(4, 10);
michael@0 2337 helpers.doKeys(']', ')');
michael@0 2338 helpers.assertCursorAt(5,11);
michael@0 2339 helpers.doKeys('2', ']', ')');
michael@0 2340 helpers.assertCursorAt(8,0);
michael@0 2341 helpers.doKeys('[', '(');
michael@0 2342 helpers.assertCursorAt(0,0);
michael@0 2343 helpers.doKeys(']', ')');
michael@0 2344 helpers.assertCursorAt(8,0);
michael@0 2345 }, { value: squareBracketMotionSandbox});
michael@0 2346 testVim('[*, ]*, [/, ]/', function(cm, vim, helpers) {
michael@0 2347 forEach(['*', '/'], function(key){
michael@0 2348 cm.setCursor(7, 0);
michael@0 2349 helpers.doKeys('2', '[', key);
michael@0 2350 helpers.assertCursorAt(2,2);
michael@0 2351 helpers.doKeys('2', ']', key);
michael@0 2352 helpers.assertCursorAt(7,5);
michael@0 2353 });
michael@0 2354 }, { value: squareBracketMotionSandbox});
michael@0 2355 testVim('[#, ]#', function(cm, vim, helpers) {
michael@0 2356 cm.setCursor(10, 3);
michael@0 2357 helpers.doKeys('2', '[', '#');
michael@0 2358 helpers.assertCursorAt(4,0);
michael@0 2359 helpers.doKeys('5', ']', '#');
michael@0 2360 helpers.assertCursorAt(17,0);
michael@0 2361 cm.setCursor(10, 3);
michael@0 2362 helpers.doKeys(']', '#');
michael@0 2363 helpers.assertCursorAt(14,0);
michael@0 2364 }, { value: squareBracketMotionSandbox});
michael@0 2365 testVim('[m, ]m, [M, ]M', function(cm, vim, helpers) {
michael@0 2366 cm.setCursor(11, 0);
michael@0 2367 helpers.doKeys('[', 'm');
michael@0 2368 helpers.assertCursorAt(10,7);
michael@0 2369 helpers.doKeys('4', '[', 'm');
michael@0 2370 helpers.assertCursorAt(1,3);
michael@0 2371 helpers.doKeys('5', ']', 'm');
michael@0 2372 helpers.assertCursorAt(11,0);
michael@0 2373 helpers.doKeys('[', 'M');
michael@0 2374 helpers.assertCursorAt(9,1);
michael@0 2375 helpers.doKeys('3', ']', 'M');
michael@0 2376 helpers.assertCursorAt(15,0);
michael@0 2377 helpers.doKeys('5', '[', 'M');
michael@0 2378 helpers.assertCursorAt(7,3);
michael@0 2379 }, { value: squareBracketMotionSandbox});
michael@0 2380
michael@0 2381 // Ex mode tests
michael@0 2382 testVim('ex_go_to_line', function(cm, vim, helpers) {
michael@0 2383 cm.setCursor(0, 0);
michael@0 2384 helpers.doEx('4');
michael@0 2385 helpers.assertCursorAt(3, 0);
michael@0 2386 }, { value: 'a\nb\nc\nd\ne\n'});
michael@0 2387 testVim('ex_write', function(cm, vim, helpers) {
michael@0 2388 var tmp = CodeMirror.commands.save;
michael@0 2389 var written;
michael@0 2390 var actualCm;
michael@0 2391 CodeMirror.commands.save = function(cm) {
michael@0 2392 written = true;
michael@0 2393 actualCm = cm;
michael@0 2394 };
michael@0 2395 // Test that w, wr, wri ... write all trigger :write.
michael@0 2396 var command = 'write';
michael@0 2397 for (var i = 1; i < command.length; i++) {
michael@0 2398 written = false;
michael@0 2399 actualCm = null;
michael@0 2400 helpers.doEx(command.substring(0, i));
michael@0 2401 eq(written, true);
michael@0 2402 eq(actualCm, cm);
michael@0 2403 }
michael@0 2404 CodeMirror.commands.save = tmp;
michael@0 2405 });
michael@0 2406 testVim('ex_sort', function(cm, vim, helpers) {
michael@0 2407 helpers.doEx('sort');
michael@0 2408 eq('Z\na\nb\nc\nd', cm.getValue());
michael@0 2409 }, { value: 'b\nZ\nd\nc\na'});
michael@0 2410 testVim('ex_sort_reverse', function(cm, vim, helpers) {
michael@0 2411 helpers.doEx('sort!');
michael@0 2412 eq('d\nc\nb\na', cm.getValue());
michael@0 2413 }, { value: 'b\nd\nc\na'});
michael@0 2414 testVim('ex_sort_range', function(cm, vim, helpers) {
michael@0 2415 helpers.doEx('2,3sort');
michael@0 2416 eq('b\nc\nd\na', cm.getValue());
michael@0 2417 }, { value: 'b\nd\nc\na'});
michael@0 2418 testVim('ex_sort_oneline', function(cm, vim, helpers) {
michael@0 2419 helpers.doEx('2sort');
michael@0 2420 // Expect no change.
michael@0 2421 eq('b\nd\nc\na', cm.getValue());
michael@0 2422 }, { value: 'b\nd\nc\na'});
michael@0 2423 testVim('ex_sort_ignoreCase', function(cm, vim, helpers) {
michael@0 2424 helpers.doEx('sort i');
michael@0 2425 eq('a\nb\nc\nd\nZ', cm.getValue());
michael@0 2426 }, { value: 'b\nZ\nd\nc\na'});
michael@0 2427 testVim('ex_sort_unique', function(cm, vim, helpers) {
michael@0 2428 helpers.doEx('sort u');
michael@0 2429 eq('Z\na\nb\nc\nd', cm.getValue());
michael@0 2430 }, { value: 'b\nZ\na\na\nd\na\nc\na'});
michael@0 2431 testVim('ex_sort_decimal', function(cm, vim, helpers) {
michael@0 2432 helpers.doEx('sort d');
michael@0 2433 eq('d3\n s5\n6\n.9', cm.getValue());
michael@0 2434 }, { value: '6\nd3\n s5\n.9'});
michael@0 2435 testVim('ex_sort_decimal_negative', function(cm, vim, helpers) {
michael@0 2436 helpers.doEx('sort d');
michael@0 2437 eq('z-9\nd3\n s5\n6\n.9', cm.getValue());
michael@0 2438 }, { value: '6\nd3\n s5\n.9\nz-9'});
michael@0 2439 testVim('ex_sort_decimal_reverse', function(cm, vim, helpers) {
michael@0 2440 helpers.doEx('sort! d');
michael@0 2441 eq('.9\n6\n s5\nd3', cm.getValue());
michael@0 2442 }, { value: '6\nd3\n s5\n.9'});
michael@0 2443 testVim('ex_sort_hex', function(cm, vim, helpers) {
michael@0 2444 helpers.doEx('sort x');
michael@0 2445 eq(' s5\n6\n.9\n&0xB\nd3', cm.getValue());
michael@0 2446 }, { value: '6\nd3\n s5\n&0xB\n.9'});
michael@0 2447 testVim('ex_sort_octal', function(cm, vim, helpers) {
michael@0 2448 helpers.doEx('sort o');
michael@0 2449 eq('.8\n.9\nd3\n s5\n6', cm.getValue());
michael@0 2450 }, { value: '6\nd3\n s5\n.9\n.8'});
michael@0 2451 testVim('ex_sort_decimal_mixed', function(cm, vim, helpers) {
michael@0 2452 helpers.doEx('sort d');
michael@0 2453 eq('y\nz\nc1\nb2\na3', cm.getValue());
michael@0 2454 }, { value: 'a3\nz\nc1\ny\nb2'});
michael@0 2455 testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) {
michael@0 2456 helpers.doEx('sort! d');
michael@0 2457 eq('a3\nb2\nc1\nz\ny', cm.getValue());
michael@0 2458 }, { value: 'a3\nz\nc1\ny\nb2'});
michael@0 2459
michael@0 2460 // Basic substitute tests.
michael@0 2461 testVim('ex_substitute_same_line', function(cm, vim, helpers) {
michael@0 2462 cm.setCursor(1, 0);
michael@0 2463 helpers.doEx('s/one/two');
michael@0 2464 eq('one one\n two two', cm.getValue());
michael@0 2465 }, { value: 'one one\n one one'});
michael@0 2466 testVim('ex_substitute_global', function(cm, vim, helpers) {
michael@0 2467 cm.setCursor(1, 0);
michael@0 2468 helpers.doEx('%s/one/two');
michael@0 2469 eq('two two\n two two', cm.getValue());
michael@0 2470 }, { value: 'one one\n one one'});
michael@0 2471 testVim('ex_substitute_input_range', function(cm, vim, helpers) {
michael@0 2472 cm.setCursor(1, 0);
michael@0 2473 helpers.doEx('1,3s/\\d/0');
michael@0 2474 eq('0\n0\n0\n4', cm.getValue());
michael@0 2475 }, { value: '1\n2\n3\n4' });
michael@0 2476 testVim('ex_substitute_visual_range', function(cm, vim, helpers) {
michael@0 2477 cm.setCursor(1, 0);
michael@0 2478 // Set last visual mode selection marks '< and '> at lines 2 and 4
michael@0 2479 helpers.doKeys('V', '2', 'j', 'v');
michael@0 2480 helpers.doEx('\'<,\'>s/\\d/0');
michael@0 2481 eq('1\n0\n0\n0\n5', cm.getValue());
michael@0 2482 }, { value: '1\n2\n3\n4\n5' });
michael@0 2483 testVim('ex_substitute_empty_query', function(cm, vim, helpers) {
michael@0 2484 // If the query is empty, use last query.
michael@0 2485 cm.setCursor(1, 0);
michael@0 2486 cm.openDialog = helpers.fakeOpenDialog('1');
michael@0 2487 helpers.doKeys('/');
michael@0 2488 helpers.doEx('s//b');
michael@0 2489 eq('abb ab2 ab3', cm.getValue());
michael@0 2490 }, { value: 'a11 a12 a13' });
michael@0 2491 testVim('ex_substitute_javascript', function(cm, vim, helpers) {
michael@0 2492 CodeMirror.Vim.setOption('pcre', false);
michael@0 2493 cm.setCursor(1, 0);
michael@0 2494 // Throw all the things that javascript likes to treat as special values
michael@0 2495 // into the replace part. All should be literal (this is VIM).
michael@0 2496 helpers.doEx('s/\\(\\d+\\)/$$ $\' $` $& \\1/')
michael@0 2497 eq('a $$ $\' $` $& 0 b', cm.getValue());
michael@0 2498 }, { value: 'a 0 b' });
michael@0 2499
michael@0 2500 // More complex substitute tests that test both pcre and nopcre options.
michael@0 2501 function testSubstitute(name, options) {
michael@0 2502 testVim(name + '_pcre', function(cm, vim, helpers) {
michael@0 2503 cm.setCursor(1, 0);
michael@0 2504 CodeMirror.Vim.setOption('pcre', true);
michael@0 2505 helpers.doEx(options.expr);
michael@0 2506 eq(options.expectedValue, cm.getValue());
michael@0 2507 }, options);
michael@0 2508 // If no noPcreExpr is defined, assume that it's the same as the expr.
michael@0 2509 var noPcreExpr = options.noPcreExpr ? options.noPcreExpr : options.expr;
michael@0 2510 testVim(name + '_nopcre', function(cm, vim, helpers) {
michael@0 2511 cm.setCursor(1, 0);
michael@0 2512 CodeMirror.Vim.setOption('pcre', false);
michael@0 2513 helpers.doEx(noPcreExpr);
michael@0 2514 eq(options.expectedValue, cm.getValue());
michael@0 2515 }, options);
michael@0 2516 }
michael@0 2517 testSubstitute('ex_substitute_capture', {
michael@0 2518 value: 'a11 a12 a13',
michael@0 2519 expectedValue: 'a1111 a1212 a1313',
michael@0 2520 // $n is a backreference
michael@0 2521 expr: 's/(\\d+)/$1$1/',
michael@0 2522 // \n is a backreference.
michael@0 2523 noPcreExpr: 's/\\(\\d+\\)/\\1\\1/'});
michael@0 2524 testSubstitute('ex_substitute_capture2', {
michael@0 2525 value: 'a 0 b',
michael@0 2526 expectedValue: 'a $00 b',
michael@0 2527 expr: 's/(\\d+)/$$$1$1/',
michael@0 2528 noPcreExpr: 's/\\(\\d+\\)/$\\1\\1/'});
michael@0 2529 testSubstitute('ex_substitute_nocapture', {
michael@0 2530 value: 'a11 a12 a13',
michael@0 2531 expectedValue: 'a$1$1 a$1$1 a$1$1',
michael@0 2532 expr: 's/(\\d+)/$$1$$1',
michael@0 2533 noPcreExpr: 's/\\(\\d+\\)/$1$1/'});
michael@0 2534 testSubstitute('ex_substitute_nocapture2', {
michael@0 2535 value: 'a 0 b',
michael@0 2536 expectedValue: 'a $10 b',
michael@0 2537 expr: 's/(\\d+)/$$1$1',
michael@0 2538 noPcreExpr: 's/\\(\\d+\\)/\\$1\\1/'});
michael@0 2539 testSubstitute('ex_substitute_nocapture', {
michael@0 2540 value: 'a b c',
michael@0 2541 expectedValue: 'a $ c',
michael@0 2542 expr: 's/b/$$/',
michael@0 2543 noPcreExpr: 's/b/$/'});
michael@0 2544 testSubstitute('ex_substitute_slash_regex', {
michael@0 2545 value: 'one/two \n three/four',
michael@0 2546 expectedValue: 'one|two \n three|four',
michael@0 2547 expr: '%s/\\//|'});
michael@0 2548 testSubstitute('ex_substitute_pipe_regex', {
michael@0 2549 value: 'one|two \n three|four',
michael@0 2550 expectedValue: 'one,two \n three,four',
michael@0 2551 expr: '%s/\\|/,/',
michael@0 2552 noPcreExpr: '%s/|/,/'});
michael@0 2553 testSubstitute('ex_substitute_or_regex', {
michael@0 2554 value: 'one|two \n three|four',
michael@0 2555 expectedValue: 'ana|twa \n thraa|faar',
michael@0 2556 expr: '%s/o|e|u/a',
michael@0 2557 noPcreExpr: '%s/o\\|e\\|u/a'});
michael@0 2558 testSubstitute('ex_substitute_or_word_regex', {
michael@0 2559 value: 'one|two \n three|four',
michael@0 2560 expectedValue: 'five|five \n three|four',
michael@0 2561 expr: '%s/(one|two)/five/',
michael@0 2562 noPcreExpr: '%s/\\(one\\|two\\)/five'});
michael@0 2563 testSubstitute('ex_substitute_backslashslash_regex', {
michael@0 2564 value: 'one\\two \n three\\four',
michael@0 2565 expectedValue: 'one,two \n three,four',
michael@0 2566 expr: '%s/\\\\/,'});
michael@0 2567 testSubstitute('ex_substitute_slash_replacement', {
michael@0 2568 value: 'one,two \n three,four',
michael@0 2569 expectedValue: 'one/two \n three/four',
michael@0 2570 expr: '%s/,/\\/'});
michael@0 2571 testSubstitute('ex_substitute_backslash_replacement', {
michael@0 2572 value: 'one,two \n three,four',
michael@0 2573 expectedValue: 'one\\two \n three\\four',
michael@0 2574 expr: '%s/,/\\\\/g'});
michael@0 2575 testSubstitute('ex_substitute_multibackslash_replacement', {
michael@0 2576 value: 'one,two \n three,four',
michael@0 2577 expectedValue: 'one\\\\\\\\two \n three\\\\\\\\four', // 2*8 backslashes.
michael@0 2578 expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes.
michael@0 2579 testSubstitute('ex_substitute_braces_word', {
michael@0 2580 value: 'ababab abb ab{2}',
michael@0 2581 expectedValue: 'ab abb ab{2}',
michael@0 2582 expr: '%s/(ab){2}//g',
michael@0 2583 noPcreExpr: '%s/\\(ab\\)\\{2\\}//g'});
michael@0 2584 testSubstitute('ex_substitute_braces_range', {
michael@0 2585 value: 'a aa aaa aaaa',
michael@0 2586 expectedValue: 'a a',
michael@0 2587 expr: '%s/a{2,3}//g',
michael@0 2588 noPcreExpr: '%s/a\\{2,3\\}//g'});
michael@0 2589 testSubstitute('ex_substitute_braces_literal', {
michael@0 2590 value: 'ababab abb ab{2}',
michael@0 2591 expectedValue: 'ababab abb ',
michael@0 2592 expr: '%s/ab\\{2\\}//g',
michael@0 2593 noPcreExpr: '%s/ab{2}//g'});
michael@0 2594 testSubstitute('ex_substitute_braces_char', {
michael@0 2595 value: 'ababab abb ab{2}',
michael@0 2596 expectedValue: 'ababab ab{2}',
michael@0 2597 expr: '%s/ab{2}//g',
michael@0 2598 noPcreExpr: '%s/ab\\{2\\}//g'});
michael@0 2599 testSubstitute('ex_substitute_braces_no_escape', {
michael@0 2600 value: 'ababab abb ab{2}',
michael@0 2601 expectedValue: 'ababab ab{2}',
michael@0 2602 expr: '%s/ab{2}//g',
michael@0 2603 noPcreExpr: '%s/ab\\{2}//g'});
michael@0 2604 testSubstitute('ex_substitute_count', {
michael@0 2605 value: '1\n2\n3\n4',
michael@0 2606 expectedValue: '1\n0\n0\n4',
michael@0 2607 expr: 's/\\d/0/i 2'});
michael@0 2608 testSubstitute('ex_substitute_count_with_range', {
michael@0 2609 value: '1\n2\n3\n4',
michael@0 2610 expectedValue: '1\n2\n0\n0',
michael@0 2611 expr: '1,3s/\\d/0/ 3'});
michael@0 2612 function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) {
michael@0 2613 testVim(name, function(cm, vim, helpers) {
michael@0 2614 var savedOpenDialog = cm.openDialog;
michael@0 2615 var savedKeyName = CodeMirror.keyName;
michael@0 2616 var onKeyDown;
michael@0 2617 var recordedCallback;
michael@0 2618 var closed = true; // Start out closed, set false on second openDialog.
michael@0 2619 function close() {
michael@0 2620 closed = true;
michael@0 2621 }
michael@0 2622 // First openDialog should save callback.
michael@0 2623 cm.openDialog = function(template, callback, options) {
michael@0 2624 recordedCallback = callback;
michael@0 2625 }
michael@0 2626 // Do first openDialog.
michael@0 2627 helpers.doKeys(':');
michael@0 2628 // Second openDialog should save keyDown handler.
michael@0 2629 cm.openDialog = function(template, callback, options) {
michael@0 2630 onKeyDown = options.onKeyDown;
michael@0 2631 closed = false;
michael@0 2632 };
michael@0 2633 // Return the command to Vim and trigger second openDialog.
michael@0 2634 recordedCallback(command);
michael@0 2635 // The event should really use keyCode, but here just mock it out and use
michael@0 2636 // key and replace keyName to just return key.
michael@0 2637 CodeMirror.keyName = function (e) { return e.key; }
michael@0 2638 keys = keys.toUpperCase();
michael@0 2639 for (var i = 0; i < keys.length; i++) {
michael@0 2640 is(!closed);
michael@0 2641 onKeyDown({ key: keys.charAt(i) }, '', close);
michael@0 2642 }
michael@0 2643 try {
michael@0 2644 eq(expectedValue, cm.getValue());
michael@0 2645 helpers.assertCursorAt(finalPos);
michael@0 2646 is(closed);
michael@0 2647 } catch(e) {
michael@0 2648 throw e
michael@0 2649 } finally {
michael@0 2650 // Restore overriden functions.
michael@0 2651 CodeMirror.keyName = savedKeyName;
michael@0 2652 cm.openDialog = savedOpenDialog;
michael@0 2653 }
michael@0 2654 }, { value: initialValue });
michael@0 2655 };
michael@0 2656 testSubstituteConfirm('ex_substitute_confirm_emptydoc',
michael@0 2657 '%s/x/b/c', '', '', '', makeCursor(0, 0));
michael@0 2658 testSubstituteConfirm('ex_substitute_confirm_nomatch',
michael@0 2659 '%s/x/b/c', 'ba a\nbab', 'ba a\nbab', '', makeCursor(0, 0));
michael@0 2660 testSubstituteConfirm('ex_substitute_confirm_accept',
michael@0 2661 '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'yyy', makeCursor(1, 1));
michael@0 2662 testSubstituteConfirm('ex_substitute_confirm_random_keys',
michael@0 2663 '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'ysdkywerty', makeCursor(1, 1));
michael@0 2664 testSubstituteConfirm('ex_substitute_confirm_some',
michael@0 2665 '%s/a/b/c', 'ba a\nbab', 'bb a\nbbb', 'yny', makeCursor(1, 1));
michael@0 2666 testSubstituteConfirm('ex_substitute_confirm_all',
michael@0 2667 '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'a', makeCursor(1, 1));
michael@0 2668 testSubstituteConfirm('ex_substitute_confirm_accept_then_all',
michael@0 2669 '%s/a/b/c', 'ba a\nbab', 'bb b\nbbb', 'ya', makeCursor(1, 1));
michael@0 2670 testSubstituteConfirm('ex_substitute_confirm_quit',
michael@0 2671 '%s/a/b/c', 'ba a\nbab', 'bb a\nbab', 'yq', makeCursor(0, 3));
michael@0 2672 testSubstituteConfirm('ex_substitute_confirm_last',
michael@0 2673 '%s/a/b/c', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
michael@0 2674 testSubstituteConfirm('ex_substitute_confirm_oneline',
michael@0 2675 '1s/a/b/c', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
michael@0 2676 testSubstituteConfirm('ex_substitute_confirm_range_accept',
michael@0 2677 '1,2s/a/b/c', 'aa\na \na\na', 'bb\nb \na\na', 'yyy', makeCursor(1, 0));
michael@0 2678 testSubstituteConfirm('ex_substitute_confirm_range_some',
michael@0 2679 '1,3s/a/b/c', 'aa\na \na\na', 'ba\nb \nb\na', 'ynyy', makeCursor(2, 0));
michael@0 2680 testSubstituteConfirm('ex_substitute_confirm_range_all',
michael@0 2681 '1,3s/a/b/c', 'aa\na \na\na', 'bb\nb \nb\na', 'a', makeCursor(2, 0));
michael@0 2682 testSubstituteConfirm('ex_substitute_confirm_range_last',
michael@0 2683 '1,3s/a/b/c', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0));
michael@0 2684 //:noh should clear highlighting of search-results but allow to resume search through n
michael@0 2685 testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {
michael@0 2686 cm.openDialog = helpers.fakeOpenDialog('match');
michael@0 2687 helpers.doKeys('?');
michael@0 2688 helpers.doEx('noh');
michael@0 2689 eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared');
michael@0 2690 helpers.doKeys('n');
michael@0 2691 helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting');
michael@0 2692 }, { value: 'match nope match \n nope Match' });
michael@0 2693 testVim('set_boolean', function(cm, vim, helpers) {
michael@0 2694 CodeMirror.Vim.defineOption('testoption', true, 'boolean');
michael@0 2695 // Test default value is set.
michael@0 2696 is(CodeMirror.Vim.getOption('testoption'));
michael@0 2697 try {
michael@0 2698 // Test fail to set to non-boolean
michael@0 2699 CodeMirror.Vim.setOption('testoption', '5');
michael@0 2700 fail();
michael@0 2701 } catch (expected) {};
michael@0 2702 // Test setOption
michael@0 2703 CodeMirror.Vim.setOption('testoption', false);
michael@0 2704 is(!CodeMirror.Vim.getOption('testoption'));
michael@0 2705 });
michael@0 2706 testVim('ex_set_boolean', function(cm, vim, helpers) {
michael@0 2707 CodeMirror.Vim.defineOption('testoption', true, 'boolean');
michael@0 2708 // Test default value is set.
michael@0 2709 is(CodeMirror.Vim.getOption('testoption'));
michael@0 2710 try {
michael@0 2711 // Test fail to set to non-boolean
michael@0 2712 helpers.doEx('set testoption=22');
michael@0 2713 fail();
michael@0 2714 } catch (expected) {};
michael@0 2715 // Test setOption
michael@0 2716 helpers.doEx('set notestoption');
michael@0 2717 is(!CodeMirror.Vim.getOption('testoption'));
michael@0 2718 });
michael@0 2719 testVim('set_string', function(cm, vim, helpers) {
michael@0 2720 CodeMirror.Vim.defineOption('testoption', 'a', 'string');
michael@0 2721 // Test default value is set.
michael@0 2722 eq('a', CodeMirror.Vim.getOption('testoption'));
michael@0 2723 try {
michael@0 2724 // Test fail to set non-string.
michael@0 2725 CodeMirror.Vim.setOption('testoption', true);
michael@0 2726 fail();
michael@0 2727 } catch (expected) {};
michael@0 2728 try {
michael@0 2729 // Test fail to set 'notestoption'
michael@0 2730 CodeMirror.Vim.setOption('notestoption', 'b');
michael@0 2731 fail();
michael@0 2732 } catch (expected) {};
michael@0 2733 // Test setOption
michael@0 2734 CodeMirror.Vim.setOption('testoption', 'c');
michael@0 2735 eq('c', CodeMirror.Vim.getOption('testoption'));
michael@0 2736 });
michael@0 2737 testVim('ex_set_string', function(cm, vim, helpers) {
michael@0 2738 CodeMirror.Vim.defineOption('testoption', 'a', 'string');
michael@0 2739 // Test default value is set.
michael@0 2740 eq('a', CodeMirror.Vim.getOption('testoption'));
michael@0 2741 try {
michael@0 2742 // Test fail to set 'notestoption'
michael@0 2743 helpers.doEx('set notestoption=b');
michael@0 2744 fail();
michael@0 2745 } catch (expected) {};
michael@0 2746 // Test setOption
michael@0 2747 helpers.doEx('set testoption=c')
michael@0 2748 eq('c', CodeMirror.Vim.getOption('testoption'));
michael@0 2749 });
michael@0 2750 // TODO: Reset key maps after each test.
michael@0 2751 testVim('ex_map_key2key', function(cm, vim, helpers) {
michael@0 2752 helpers.doEx('map a x');
michael@0 2753 helpers.doKeys('a');
michael@0 2754 helpers.assertCursorAt(0, 0);
michael@0 2755 eq('bc', cm.getValue());
michael@0 2756 }, { value: 'abc' });
michael@0 2757 testVim('ex_unmap_key2key', function(cm, vim, helpers) {
michael@0 2758 helpers.doEx('unmap a');
michael@0 2759 helpers.doKeys('a');
michael@0 2760 eq('vim-insert', cm.getOption('keyMap'));
michael@0 2761 }, { value: 'abc' });
michael@0 2762 testVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) {
michael@0 2763 try {
michael@0 2764 helpers.doEx('unmap a');
michael@0 2765 fail();
michael@0 2766 } catch (expected) {}
michael@0 2767 helpers.doKeys('a');
michael@0 2768 eq('vim-insert', cm.getOption('keyMap'));
michael@0 2769 }, { value: 'abc' });
michael@0 2770 testVim('ex_map_key2key_to_colon', function(cm, vim, helpers) {
michael@0 2771 helpers.doEx('map ; :');
michael@0 2772 var dialogOpened = false;
michael@0 2773 cm.openDialog = function() {
michael@0 2774 dialogOpened = true;
michael@0 2775 }
michael@0 2776 helpers.doKeys(';');
michael@0 2777 eq(dialogOpened, true);
michael@0 2778 });
michael@0 2779 testVim('ex_map_ex2key:', function(cm, vim, helpers) {
michael@0 2780 helpers.doEx('map :del x');
michael@0 2781 helpers.doEx('del');
michael@0 2782 helpers.assertCursorAt(0, 0);
michael@0 2783 eq('bc', cm.getValue());
michael@0 2784 }, { value: 'abc' });
michael@0 2785 testVim('ex_map_ex2ex', function(cm, vim, helpers) {
michael@0 2786 helpers.doEx('map :del :w');
michael@0 2787 var tmp = CodeMirror.commands.save;
michael@0 2788 var written = false;
michael@0 2789 var actualCm;
michael@0 2790 CodeMirror.commands.save = function(cm) {
michael@0 2791 written = true;
michael@0 2792 actualCm = cm;
michael@0 2793 };
michael@0 2794 helpers.doEx('del');
michael@0 2795 CodeMirror.commands.save = tmp;
michael@0 2796 eq(written, true);
michael@0 2797 eq(actualCm, cm);
michael@0 2798 });
michael@0 2799 testVim('ex_map_key2ex', function(cm, vim, helpers) {
michael@0 2800 helpers.doEx('map a :w');
michael@0 2801 var tmp = CodeMirror.commands.save;
michael@0 2802 var written = false;
michael@0 2803 var actualCm;
michael@0 2804 CodeMirror.commands.save = function(cm) {
michael@0 2805 written = true;
michael@0 2806 actualCm = cm;
michael@0 2807 };
michael@0 2808 helpers.doKeys('a');
michael@0 2809 CodeMirror.commands.save = tmp;
michael@0 2810 eq(written, true);
michael@0 2811 eq(actualCm, cm);
michael@0 2812 });
michael@0 2813 testVim('ex_map_key2key_visual_api', function(cm, vim, helpers) {
michael@0 2814 CodeMirror.Vim.map('b', ':w', 'visual');
michael@0 2815 var tmp = CodeMirror.commands.save;
michael@0 2816 var written = false;
michael@0 2817 var actualCm;
michael@0 2818 CodeMirror.commands.save = function(cm) {
michael@0 2819 written = true;
michael@0 2820 actualCm = cm;
michael@0 2821 };
michael@0 2822 // Mapping should not work in normal mode.
michael@0 2823 helpers.doKeys('b');
michael@0 2824 eq(written, false);
michael@0 2825 // Mapping should work in visual mode.
michael@0 2826 helpers.doKeys('v', 'b');
michael@0 2827 eq(written, true);
michael@0 2828 eq(actualCm, cm);
michael@0 2829
michael@0 2830 CodeMirror.commands.save = tmp;
michael@0 2831 });
michael@0 2832
michael@0 2833 // Testing registration of functions as ex-commands and mapping to <Key>-keys
michael@0 2834 testVim('ex_api_test', function(cm, vim, helpers) {
michael@0 2835 var res=false;
michael@0 2836 var val='from';
michael@0 2837 CodeMirror.Vim.defineEx('extest','ext',function(cm,params){
michael@0 2838 if(params.args)val=params.args[0];
michael@0 2839 else res=true;
michael@0 2840 });
michael@0 2841 helpers.doEx(':ext to');
michael@0 2842 eq(val,'to','Defining ex-command failed');
michael@0 2843 CodeMirror.Vim.map('<C-CR><Space>',':ext');
michael@0 2844 helpers.doKeys('<C-CR>','<Space>');
michael@0 2845 is(res,'Mapping to key failed');
michael@0 2846 });
michael@0 2847 // For now, this test needs to be last because it messes up : for future tests.
michael@0 2848 testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) {
michael@0 2849 helpers.doEx('map : x');
michael@0 2850 helpers.doKeys(':');
michael@0 2851 helpers.assertCursorAt(0, 0);
michael@0 2852 eq('bc', cm.getValue());
michael@0 2853 }, { value: 'abc' });
michael@0 2854
michael@0 2855 // Test event handlers
michael@0 2856 testVim('beforeSelectionChange', function(cm, vim, helpers) {
michael@0 2857 cm.setCursor(0, 100);
michael@0 2858 eqPos(cm.getCursor('head'), cm.getCursor('anchor'));
michael@0 2859 }, { value: 'abc' });

mercurial