/* * Copyright (c) 2002-2016, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. * * http://www.opensource.org/licenses/bsd-license.php */ package jline.console; import static jline.console.Operation.*; import jline.console.history.History; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertTrue; /** * Unit tests for the greatest keymap binding in the world! Vi!!!! * These tests are primarily intended to test "move-mode" in VI, but * as a necessary by-product they use quite a bit of insert mode as well. */ public class ViMoveModeTest extends ConsoleReaderTestSupport { /** * For all tests we will start out in insert/edit mode. */ @Before public void setUp() throws Exception { super.setUp(); } @Test public void testMoveLeft() throws Exception { /* * There are various keys that will move you left. */ testMoveLeft("\033[D"); /* Left arrow */ testMoveLeft("h"); /* h key */ testMoveLeft("\010"); /* CTRL-H */ } public void testMoveLeft(String left) throws Exception { /* * Move left */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("0123456789")) .escape() .append(left) .append(left) .append(left) .append("iX") .enter(); assertLine("012345X6789", b, true); /* * Move left - use digit arguments. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("0123456789")) .escape() .append('3') .append(left) .append("iX") .enter(); assertLine("012345X6789", b, true); /* * Move left - use multi-digit arguments. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("0123456789ABCDEFHIJLMNOPQRSTUVWXYZ")) .escape() .append("13") .append(left) .append("iX") .enter(); assertLine("0123456789ABCDEFHIJLXMNOPQRSTUVWXYZ", b, true); /* * Delete move left. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("0123456789ABCDEFHIJLMNOPQRSTUVWXYZ")) .escape() .append("13d") .append(left) .enter(); assertLine("0123456789ABCDEFHIJLZ", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("0123456789ABCDEFHIJLMNOPQRSTUVWXYZ")) .escape() .append("d") .append(left) .append("d") .append(left) .enter(); assertLine("0123456789ABCDEFHIJLMNOPQRSTUVWZ", b, true); /* * Change move left */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("0123456789ABCDEFHIJLMNOPQRSTUVWXYZ")) .escape() .append("13c") .append(left) .append("_HI") .enter(); assertLine("0123456789ABCDEFHIJL_HIZ", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("word")) .escape() .append("c") .append(left) .append("X") .enter(); assertLine("woXd", b, true); /* * Yank left */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("word")) .escape() .append("3y") .append(left) .append("p") .enter(); assertLine("wordwor", b, true); } @Test public void testMoveRight() throws Exception { testMoveRight("\033[C"); /* right arrow */ testMoveRight("l"); /* "l" key */ testMoveRight(" "); /* space */ } public void testMoveRight(String right) throws Exception { /* * Move right */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("0123456789")) .escape() .append('0') // beginning of line .append(right) .append(right) .append(right) .append("iX") .enter(); assertLine("012X3456789", b, true); /* * Move right use digit arguments. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("0123456789ABCDEFHIJK")) .escape() .append("012") .append(right) .append("iX") .enter(); assertLine("0123456789ABXCDEFHIJK", b, true); /* * Delete move right */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("a bunch of words")) .escape() .append("05d") .append(right) .enter(); assertLine("ch of words", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("a bunch of words")) .escape() .append("0d") .append(right) .append("d") .append(right) .enter(); assertLine("bunch of words", b, true); /* * Change move right */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("a bunch of words")) .escape() .append("010c") .append(right) .append("XXX") .enter(); assertLine("XXX words", b, true); /* * Yank move right */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("a bunch of words")) .escape() .append("010y") .append(right) .append("$p") .enter(); assertLine("a bunch of wordsa bunch of", b, true); } @Test public void testCtrlD() throws Exception { /* * According to bash behavior hitting ^D anywhere in a non-empty * line is just like hitting enter. First, test at the end of the line. * The escape() puts us in move mode. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("abc")).escape().op(VI_EOF_MAYBE); assertLine("abc", b, true); /* * Since VI_EOF_MAYBE is acceptable in both move mode and insert * mode, make sure we are testing the right now. */ assertTrue(console.isKeyMap(KeyMap.VI_MOVE)); /* * Next, the middle of the line. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abc")).left().left().escape().op(VI_EOF_MAYBE); assertLine("abc", b, true); assertTrue(console.isKeyMap(KeyMap.VI_MOVE)); /* * Beginning of the line. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abc")).left().left().left().escape().op(VI_EOF_MAYBE); assertLine("abc", b, true); assertTrue(console.isKeyMap(KeyMap.VI_MOVE)); /* * Now, check the behavior of an empty buffer. This should cause * a null to be returned. I'll try it in two different ways. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abc")).back().back().back().escape().op(VI_EOF_MAYBE); assertLine(null, b, true); assertTrue(console.isKeyMap(KeyMap.VI_MOVE)); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("")).escape().op(VI_EOF_MAYBE); assertLine(null, b, true); assertTrue(console.isKeyMap(KeyMap.VI_MOVE)); } @Test public void testCtrlJ() throws Exception { /* * ENTER is CTRL-J. */ testEnter('J'); } @Test public void testCtrlK() throws Exception { /* * Ctrl-K should delete to end-of-line */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("This is a test")) .escape() .left().left().left().left() .ctrl('K') .enter(); assertLine("This is a", b, true); b = (new Buffer("hello")) .escape() .ctrl('K') .enter(); assertLine("hell", b, true); } @Test public void testCtrlL() throws Exception { /* * CTRL-L clears the screen. I can't test much but to make sure * that the cursor is where it is supposed to be. * * IMPORTANT NOTE: The CTRL-K is commented out below. Technically * it is a bug. What is supposed to happen is that the escape() * backs the cursor up one, so the CTRL-K is supposed to delete * the "o". With the CTRL-L involved, it doesn't. I suspect that * it has to do with the parsing of the stream of escape's coming * in and I'm not entirely sure it is easy to fix. Since this is * really an edge case I'm commenting it out, but I'm leaving this * comment here because it may be a sign of something lurking down the * road. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("hello")) .escape() .ctrl ('L') // .ctrl ('K') .enter (); assertLine("hello", b, true); } @Test public void testCtrlM() throws Exception { testEnter('M'); } @Test public void testCtrlP_CtrlN() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("line1")).enter() .append("line2").enter() .append("li") .escape() .ctrl('P') .ctrl('P') .enter(); assertLine("line1", b, false); console.getHistory ().clear (); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("line1")).enter() .append("line2").enter() .append("li") .escape() .ctrl('P') .ctrl('P') .ctrl('N') .enter(); assertLine("line2", b, false); /* * One last test. Make sure that when we move through history * that the cursor is moved to the front of the line. */ console.getHistory ().clear (); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aline")).enter() .append("bline").enter() .append("cli") .escape() .ctrl('P') .ctrl('P') .ctrl('N') .append ("iX") .enter(); assertLine("Xbline", b, false); } @Test public void testCtrlT() throws Exception { /* * Transpose every character exactly. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("abcdef")) .escape() // Move mode .append('0') // Beginning of line .right() // Right one .ctrl('T') // Transpose .ctrl('T') .ctrl('T') .ctrl('T') .ctrl('T') .enter(); assertLine("bcdefa", b, false); /* * Cannot transpose the first character or the last character */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abcdef")) .escape() // Move mode .append('0') // Beginning of line .ctrl('T') .ctrl('T') .append('$') // End of line .ctrl('T') .ctrl('T') .enter(); assertLine("abcdef", b, false); } @Test public void testCtrlU() throws Exception { /* * CTRL-U is "line discard", it deletes everything prior to the * current cursor position. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("all work and no play")) .escape() // Move mode .left(3) // Left to the "p" in play .ctrl('U') // Line discard .enter(); assertLine("play", b, false); /* * Nothing happens at the beginning of the line */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("donkey punch")) .escape() // Move mode .append('0') // Beginning of the line .ctrl('U') // Line discard .enter(); assertLine("donkey punch", b, false); /* * End of the line leaves an empty buffer */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("rabid hamster")) .escape() // Move mode .right() // End of line .ctrl('U') // Line discard .enter(); assertLine("", b, false); } @Test public void testCtrlW() throws Exception { /* * CTRL-W is word rubout. It deletes to the beginning of the word * you are currently sitting in, or if you are one a break character * it deletes up to the beginning of the previous word. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("oily rancid badgers")) .escape() .ctrl('W') .ctrl('W') .enter(); assertLine("oily s", b, false); /* * Test behavior with non-word characters. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("pasty bulimic rats !!!!!")) .escape() .ctrl('W') .ctrl('W') .enter(); assertLine("pasty bulimic !", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("pasty bulimic rats !!!!!")) .escape() .append("2") .ctrl('W') .enter(); assertLine("pasty bulimic !", b, false); } @Test public void testInsertComment() throws Exception { /* * The # key causes a comment to get inserted. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("putrified whales")) .escape() .append ("#"); assertLine("#putrified whales", b, false); assertTrue(console.isKeyMap(KeyMap.VI_INSERT)); } @Test public void testD() throws Exception { // D is a vim extension for delete-to-end-of-line console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("banana")) .escape() .left(2) .append("Dadaid") .enter(); assertLine("bandaid", b, false); assertTrue(console.isKeyMap(KeyMap.VI_INSERT)); } @Test public void testC() throws Exception { // C is a vim extension for change-to-end-of-line console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("yogurt")) .escape() .left(3) .append("Cyo") .enter(); assertLine("yoyo", b, false); assertTrue(console.isKeyMap(KeyMap.VI_INSERT)); } @Test public void testS() throws Exception { // S is a vim extension that is a synonum for 'cc' (clear whole line) console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("great lakes brewery")) .escape() .left(3) .append("Sdogfishhead") .enter(); assertLine("dogfishhead", b, false); assertTrue(console.isKeyMap(KeyMap.VI_INSERT)); } @Test public void testEndOfLine() throws Exception { /* * The $ key causes the cursor to move to the end of the line */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("chicken sushimi")) .escape() .left(10) .append("$a is tasty!") .enter(); assertLine("chicken sushimi is tasty!", b, false); assertTrue(console.isKeyMap(KeyMap.VI_INSERT)); /* * Delete to EOL */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("chicken sushimi")) .escape() .append("0lld$") .enter(); assertLine("ch", b, false); /* * Change to EOL */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("chicken sushimi")) .escape() .append("0llc$opsticks") .enter(); assertLine("chopsticks", b, false); /* * Yank to EOL */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("chicken sushimi")) .escape() .append("0lly$$p") .enter(); assertLine("chicken sushimiicken sushimi", b, false); } @Test public void firstPrintable() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer(" foo bar")) .escape() .append("^dw") .enter(); assertLine(" bar", b, false); } @Test public void testMatch() throws Exception { /* * The % character matches brackets (square, parens, or curly). * First, test close paren w/nesting */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("ab((cdef[[))")) .escape() // Move us back one character (on last close) .append("%aX") // Find match, add an X after it .enter(); assertLine("ab(X(cdef[[))", b, false); /* * Open paren, w/nesting */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("ab((cdef[[))")) .escape() // Move us back one character (on last close) .append('0') // Beginning of line .right(2) // Right to first open paren .append("%aX") // Match closing, add an X after it .enter(); assertLine("ab((cdef[[))X", b, false); /* * No match leaves the cursor in place */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abcd))")) .escape() .append("%aX") .enter(); assertLine("abcd))X", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("(abcd(d")) .escape() .append("0%aX") // Beginning of line, match, append X .enter(); assertLine("(Xabcd(d", b, false); /* * Delete match */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("ab(def)hij")) .escape() .append("0lld%") .enter(); assertLine("abhij", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("ab(def)")) .escape() .append("0lld%") .enter(); assertLine("ab", b, false); /* * Yank match */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("ab(def)hij")) .escape() .append("0lly%$p") .enter(); assertLine("ab(def)hij(def)", b, false); /* * Change match */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("ab(def)hij")) .escape() .append("0llc%X") .enter(); assertLine("abXhij", b, false); } @Test public void testSearch() throws Exception { /* * Tests the "/" forward search */ History history = console.getHistory(); history.clear(); history.add("aaadef"); history.add("bbbdef"); history.add("cccdef"); /* * An aborted search should leave you exactly on the * character you were on of the original term. First, I will * test aborting by deleting back over the search expression. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("I like frogs")) .escape() .left(4) // Cursor is on the "f" .append("/def") // Start a search .back(4) // Delete everything (aborts search) .append("ibig ") // Insert mode, type "big " .enter(); // Done assertLine("I like big frogs", b, false); /* * Next, hit escape to abort. This technically isn't readline * behavior, but I added it because I find it useful. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("I like frogs")) .escape() .left(4) // Cursor is on the "f" .append("/def") // Start a search .escape() // Abort the search .append("ibig ") // Insert mode, type "big " .enter(); // Done assertLine("I like big frogs", b, false); /* * Test a failed history match. This is like an abort, but it * should leave the cursor at the start of the line. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("I like frogs")) .escape() .left(4) // Cursor is on the "f" .append("/III") // Search (no match) .enter() // Kick it off. .append("iX") // With cursor at start, insert an X .enter(); assertLine("XI like frogs", b, false); /* * Test a valid search. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("I like frogs")) .escape() .left(4) // Cursor is on the "f" .append("/def") // Search (no match) .enter() // Kick it off. .append("nNiX") // Move forward two, insert an X. Note I use // use "n" and "N" to move. .enter(); assertLine("Xcccdef", b, false); /* * The previous test messed with history. */ history.clear(); history.add("aaadef"); history.add("bbbdef"); history.add("cccdef"); /* * Search backwards */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("I like frogs")) .escape() .left(4) // Cursor is on the "f" .append("?def") // Search (no match) .enter() // Kick it off. .append("nNiX") // Move forward two, insert an X. Note I use // use "n" and "N" to move. .enter(); assertLine("Xaaadef", b, false); /* * Test bug fix: use CR to terminate seach instead of newline */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abc")) .enter() .append("def") .enter() .append("hij") .enter() .escape() .append("/bc") .CR() .append("iX") .enter(); assertLine("Xabc", b, false); } @Test public void testWordRight() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("buttery frog necks")) .escape() .append("0ww") // Beginning of line, nxt word, nxt word .ctrl('U') // Kill to beginning of line .enter(); // Kick it off. assertLine("necks", b, false); b = (new Buffer("buttery frog foo")) .escape() .left(5) .append('w') .ctrl('K') // Kill to end of line .enter(); // Kick it off. assertLine("buttery frog ", b, false); b = (new Buffer("a big batch of buttery frog livers")) .escape() .append("05w") // Beg of line, 5 words right .ctrl('U') // Kill to beginning of line .enter(); // Kick it off. assertLine("frog livers", b, false); /* * Delete word right */ b = (new Buffer("a big batch of buttery frog livers")) .escape() .append("05dw") .enter(); assertLine("frog livers", b, false); b = (new Buffer("another big batch of buttery frog livers")) .escape() .append("0ldw") .enter(); assertLine("abig batch of buttery frog livers", b, false); /* * Yank word right */ b = (new Buffer("big brown pickles")) .escape() .append("02yw$p") .enter(); assertLine("big brown picklesbig brown ", b, false); /* * Change word right */ b = (new Buffer("big brown pickles")) .escape() .append("0wcwgreen") .enter(); assertLine("big green pickles", b, false); b = (new Buffer("big brown pickles")) .escape() .append("02cwlittle bitty") .enter(); assertLine("little bitty pickles", b, false); } @Test public void testWordLeft() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("lucious lark liquid ")) .escape() .append("bb") // Beginning of line, prv word, prv word .ctrl('K') // Kill to end of line .enter(); // Kick it off. assertLine("lucious ", b, false); b = (new Buffer("lucious lark liquid")) .escape() .left(2) .append('b') .ctrl('U') .enter(); assertLine("liquid", b, false); b = (new Buffer("lively lolling lark liquid")) .escape() .append("3b") .ctrl('K') // Kill to beginning of line .enter(); assertLine("lively ", b, false); } @Test public void testEndWord() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("putrid pidgen porridge")) .escape() .append("0e") .ctrl('K') // Kill to end of line .enter(); // Kick it off. assertLine("putri", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer(" putrid pidgen porridge")) .escape() .append("0e") .ctrl('K') // Kill to end of line .enter(); // Kick it off. assertLine(" putri", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("putrid pidgen porridge and mash")) .escape() .append("05l") // Beg of line, 5 right .append("3e") // 3 end-of-word .ctrl('U') // Kill to beg of line .enter(); // Kick it off. assertLine("d mash", b, false); } @Test public void testInsertBeginningOfLine() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("dessicated dog droppings")) .escape() .append("Itasty ") .enter(); assertLine("tasty dessicated dog droppings", b, false); } @Test public void testRubout() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("gross animal stuff")) .escape() .left() .append("XXX") .enter(); assertLine("gross animal ff", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("gross animal stuff")) .escape() .left() .append("50X") .enter(); assertLine("ff", b, false); } @Test public void testDelete() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("thing to delete")) .escape() .append("bbxxx") .enter(); assertLine("thing delete", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("thing to delete")) .escape() .append("bb99x") .enter(); assertLine("thing ", b, false); } @Test public void testChangeCase() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("big.LITTLE")) .escape() .append("0~~~~~~~~~~") .enter(); assertLine("BIG.little", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("big.LITTLE")) .escape() .append("020~") .enter(); assertLine("BIG.little", b, false); } @Test public void testChangeChar() throws Exception { console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("abcdefhij")) .escape() .append("0rXiY") .enter(); assertLine("YXbcdefhij", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abcdefhij")) .escape() .append("04rXiY") .enter(); assertLine("XXXYXefhij", b, false); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abcdefhij")) .escape() .append("099rZ") .enter(); assertLine("ZZZZZZZZZ", b, false); /* * Aborted replace. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abcdefhij")) .escape() .append("0r") .escape() .append("iX") .enter(); assertLine("Xabcdefhij", b, false); } @Test public void testCharSearch_f() throws Exception { /* * f = search forward for character */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("03ffiX") // start, find the third f, insert X .enter(); assertLine("aaaafaaaafaaaaXfaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("0ffffffiX") // start, find the third f, insert X .enter(); assertLine("aaaafaaaafaaaaXfaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("0ff;;iX") // start, find f, repeat fwd, repeat fwd .enter(); assertLine("aaaafaaaafaaaaXfaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("0ff;,iX") // start, find f, repeat fwd, repeat back .enter(); assertLine("aaaaXfaaaafaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("0fX3;iY") // start, find X, repeat fwd x 3, ins Y .enter(); assertLine("aaaaXaaaaXaaaaXaaaaYX", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("03dff") // start, delete to third f .enter(); assertLine("aaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("0fX2d;") // start, find X, 2 x delete repeat last search .enter(); assertLine("aaaaaaaaX", b, true); } @Test public void testCharSearch_F() throws Exception { /* * f = search forward for character */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("3FfiX") // go 3 f's back, insert X .enter(); assertLine("aaaaXfaaaafaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("FfFfFfiX") // start, find the third f back, insert X .enter(); assertLine("aaaaXfaaaafaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("Ff;iX") // start, find f, repeat fwd, repeat fwd .enter(); assertLine("aaaafaaaaXfaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("Ff;,iX") // start, rev find f, repeat, reverse .enter(); assertLine("aaaafaaaafaaaaXfaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("FX2;iY") // start, rev find X, repeat x 2, ins Y .enter(); assertLine("aaaaYXaaaaXaaaaXaaaaX", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("3dFf") // start, delete back to third f .enter(); assertLine("aaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("FX2d;") // start, find X, 2 x delete repeat last search .enter(); assertLine("aaaaXaaaaX", b, true); } @Test public void testCharSearch_t() throws Exception { /* * r = search forward for character, stopping before */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("03tfiX") .enter(); assertLine("aaaafaaaafaaaXafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("0tftftfiX") .enter(); assertLine("aaaXafaaaafaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("0tf;;iX") .enter(); assertLine("aaaXafaaaafaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("02tf;,iX") .enter(); assertLine("aaaafXaaaafaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("0tX3;iY") .enter(); assertLine("aaaaXaaaaXaaaYaXaaaaX", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("03dtf") .enter(); assertLine("faaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("0tX2d;") .enter(); assertLine("aaaXaaaaXaaaaX", b, true); } @Test public void testCharSearch_T() throws Exception { /* * r = search backward for character, stopping after */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("3TfiX") .enter(); assertLine("aaaafXaaaafaaaafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("TfTfTfiX") .enter(); assertLine("aaaafaaaafaaaafXaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("Tf;;iX") .enter(); assertLine("aaaafaaaafaaaafXaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("2Tf;,iX") .enter(); assertLine("aaaafaaaafaaaXafaaaaf", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("TX3;iY") .enter(); assertLine("aaaaXYaaaaXaaaaXaaaaX", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaafaaaafaaaafaaaaf")) .escape() .append("3dTf") .enter(); assertLine("aaaaff", b, true); console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("aaaaXaaaaXaaaaXaaaaX")) .escape() .append("TX2d;") .enter(); assertLine("aaaaXaaaaXaaaaX", b, true); } @Test public void test_dd() throws Exception { /* * This tests "dd" or delete-to + delete-to, which should kill the * current line. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("abcdef")) .escape() .append("dd") .enter(); assertLine("", b, true); /* * I found a bug here dd didn't work at position 0. This tests the fix. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abcdef")) .escape() .append("0dd") .enter(); assertLine("", b, true); } @Test public void test_yy() throws Exception { /* * This tests "yy" or yank-to + yank-to, which should yank the whole line */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("abcdef")) .escape() .append("yyp") .enter(); assertLine("abcdefabcdef", b, true); } @Test public void test_cc() throws Exception { /* * This tests "cc" or change-to + change-to, which changes the whole line */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("abcdef")) .escape() .append("ccsuck") .enter(); assertLine("suck", b, true); } /** * Used to test various forms of hitting "enter" (return). This can be * CTRL-J or CTRL-M...maybe others. * * @param enterChar The escape character that acts as enter. */ private void testEnter(char enterChar) throws Exception { /* * I want to test to make sure that I am re-entering insert mode * when enter is hit. */ console.setKeyMap(KeyMap.VI_INSERT); Buffer b = (new Buffer("abc")).escape().ctrl(enterChar); assertLine("abc", b, true); assertTrue(console.isKeyMap(KeyMap.VI_INSERT)); /* * This sort of tests the same thing by actually enter * characters after the first enter. */ console.setKeyMap(KeyMap.VI_INSERT); b = (new Buffer("abc")).escape().ctrl(enterChar) .append("def").enter(); assertLine("def", b, true); assertTrue(console.isKeyMap(KeyMap.VI_INSERT)); } /* * TODO - Test arrow key bindings */ }