File indexing completed on 2024-04-28 03:57:11

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2014 Miquel Sabaté Solà <mikisabate@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "modes.h"
0009 #include <inputmode/kateviinputmode.h>
0010 #include <katebuffer.h>
0011 #include <kateconfig.h>
0012 #include <katedocument.h>
0013 #include <katerenderer.h>
0014 #include <kateview.h>
0015 #include <vimode/emulatedcommandbar/emulatedcommandbar.h>
0016 
0017 #include <QMainWindow>
0018 #include <QTest>
0019 
0020 using namespace KTextEditor;
0021 
0022 QTEST_MAIN(ModesTest)
0023 
0024 // BEGIN: Normal mode.
0025 
0026 void ModesTest::NormalMotionsTests()
0027 {
0028     // Test moving around an empty document (nothing should happen)
0029     DoTest("", "jkhl", "");
0030     DoTest("", "ggG$0", "");
0031 
0032     // Testing "l"
0033     DoTest("bar", "lx", "br");
0034     DoTest("bar", "2lx", "ba");
0035     DoTest("0123456789012345", "13lx", "012345678901245");
0036     DoTest("bar", "10lx", "ba");
0037 
0038     // Testing "h"
0039     DoTest("bar", "llhx", "br");
0040     DoTest("bar", "10l10hx", "ar");
0041     DoTest("0123456789012345", "13l10hx", "012456789012345");
0042     DoTest("bar", "ll5hx", "ar");
0043 
0044     // Testing "j"
0045     DoTest("bar\nbar", "jx", "bar\nar");
0046     DoTest("bar\nbar", "10jx", "bar\nar");
0047     DoTest("bar\nbara", "lljx", "bar\nbaa");
0048     DoTest("0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n1\n2\n3\n4\n5\n", "13jx", "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n1\n2\n\n4\n5\n");
0049 
0050     // Testing "k"
0051     DoTest("bar\nbar", "jx", "bar\nar");
0052     DoTest("bar\nbar\nbar", "jj100kx", "ar\nbar\nbar");
0053     DoTest("0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n1\n2\n3\n4\n5\n", "13j10kx", "0\n1\n2\n\n4\n5\n6\n7\n8\n9\n0\n1\n2\n3\n4\n5\n");
0054 
0055     // Testing "w"
0056     DoTest("bar", "wx", "ba");
0057     DoTest("foo bar", "wx", "foo ar");
0058     DoTest("foo bar", "lwx", "foo ar");
0059     DoTest("quux(foo, bar, baz);", "wxwxwxwx2wx", "quuxfoo ar baz;");
0060     DoTest("foo\nbar\nbaz", "wxwx", "foo\nar\naz");
0061     DoTest("1 2 3\n4 5 6", "ld3w", "1\n4 5 6");
0062     DoTest("foo\nbar baz", "gU2w", "FOO\nBAR baz");
0063     DoTest("FOO\nBAR BAZ", "gu2w", "foo\nbar BAZ");
0064     DoTest("bar(\n123", "llwrX", "barX\n123");
0065 
0066     // Testing "W"
0067     DoTest("bar", "Wx", "ba");
0068     DoTest("foo bar", "Wx", "foo ar");
0069     DoTest("foo bar", "2lWx", "foo ar");
0070     DoTest("quux(foo, bar, baz);", "WxWx", "quux(foo, ar, az);");
0071     DoTest("foo\nbar\nbaz", "WxWx", "foo\nar\naz");
0072     DoTest(" foo(bar xyz", "Wx", " oo(bar xyz");
0073 
0074     // Testing "b"
0075     DoTest("bar", "lbx", "ar");
0076     DoTest("foo bar baz", "2wbx", "foo ar baz");
0077     DoTest("foo bar", "w20bx", "oo bar");
0078     DoTest("quux(foo, bar, baz);", "2W4l2bx2bx", "quux(foo, ar, az);");
0079     DoTest("foo\nbar\nbaz", "WWbx", "foo\nar\nbaz");
0080     DoTest("  foo", "lbrX", "X foo");
0081     DoTest("  foo", "llbrX", "X foo");
0082 
0083     // Testing "B"
0084     DoTest("bar", "lBx", "ar");
0085     DoTest("foo bar baz", "2wBx", "foo ar baz");
0086     DoTest("foo bar", "w20Bx", "oo bar");
0087     DoTest("quux(foo, bar, baz);", "2W4lBBx", "quux(foo, ar, baz);");
0088     DoTest("foo\nbar", "WlBx", "foo\nar");
0089 
0090     // Testing "e"
0091     DoTest("quux(foo, bar, baz);", "exex2ex10ex", "quu(fo, bar baz)");
0092     DoTest("", "ce", "");
0093     DoTest(" ", "lceX", "X");
0094     DoTest("", "cE", "");
0095 
0096     // Testing "E"
0097     DoTest("quux(foo, bar, baz);", "ExEx10Ex", "quux(foo bar baz)");
0098 
0099     // Testing "$"
0100     DoTest("foo\nbar\nbaz", "$x3$x", "fo\nbar\nba");
0101 
0102     // Testing "0"
0103     DoTest(" foo", "$0x", "foo");
0104 
0105     // Testing "#" & "*"
0106     DoTest("1 1 1", "2#x", "1  1");
0107     DoTest("foo bar foo bar", "#xlll#x", "foo ar oo bar");
0108     DoTest("(foo (bar (foo( bar))))", "#xll#x", "(foo (ar (oo( bar))))");
0109     DoTest("(foo (bar (foo( bar))))", "*x", "(foo (bar (oo( bar))))");
0110     DoTest("foo bar foobar foo", "*rX", "foo bar foobar Xoo"); // Whole word only.
0111     DoTest("foo bar foobar foo", "$#rX", "Xoo bar foobar foo"); // Whole word only.
0112     DoTest("fOo foo fOo", "*rX", "fOo Xoo fOo"); // Case insensitive.
0113     DoTest("fOo foo fOo", "$#rX", "fOo Xoo fOo"); // Case insensitive.
0114     DoTest("fOo foo fOo", "*ggnrX", "fOo Xoo fOo"); // Flag that the search to repeat is case insensitive.
0115     DoTest("fOo foo fOo", "$#ggNrX", "fOo Xoo fOo"); // Flag that the search to repeat is case insensitive.
0116     DoTest("bar foo", "$*rX", "bar Xoo");
0117     DoTest("bar foo", "$#rX", "bar Xoo");
0118     // Test that calling # on the last, blank line of a document does not go into an infinite loop.
0119     DoTest("foo\n", "j#", "foo\n");
0120 
0121     // Testing "-"
0122     DoTest("0\n1\n2\n3\n4\n5", "5j-x2-x", "0\n1\n\n3\n\n5");
0123     DoTest("foo\n\t \t bar\nbaz", "3j-r.", "foo\n\t \t .ar\nbaz");
0124 
0125     // Testing "^"
0126     DoTest(" foo bar", "$^x", " oo bar");
0127 
0128     // Testing "gg"
0129     DoTest("1\n2\n3\n4\n5", "4jggx", "\n2\n3\n4\n5");
0130 
0131     // Testing "G"
0132     DoTest("1\n2\n3\n4\n5", "Gx", "1\n2\n3\n4\n");
0133 
0134     // Testing "ge"
0135     DoTest("quux(foo, bar, baz);", "9lgexgex$gex", "quux(fo bar, ba);");
0136     DoTest("foo", "llgerX", "Xoo");
0137     DoTest("   foo", "$gerX", "X  foo");
0138     DoTest("   foo foo", "$2gerX", "X  foo foo");
0139 
0140     // Testing "gE"
0141     DoTest("quux(foo, bar, baz);", "9lgExgEx$gEx", "quux(fo bar baz);");
0142     DoTest("   foo", "$gErX", "X  foo");
0143     DoTest("   foo foo", "$2gErX", "X  foo foo");
0144     DoTest("   !foo$!\"", "$gErX", "X  !foo$!\"");
0145     DoTest("   !foo$!\"", "$2gErX", "X  !foo$!\"");
0146 
0147     // Testing "|"
0148     DoTest("123456789", "3|rx4|rx8|rx1|rx", "x2xx567x9");
0149 
0150     // Testing "`"
0151     DoTest("foo\nbar\nbaz", "lmaj`arx", "fxo\nbar\nbaz");
0152 
0153     // Testing "'"
0154     DoTest("foo\nbar\nbaz", "lmaj'arx", "xoo\nbar\nbaz");
0155 
0156     // Testing "%"
0157     DoTest("foo{\n}\n", "$d%", "foo\n");
0158     DoTest("FOO{\nBAR}BAZ", "lllgu%", "FOO{\nbar}BAZ");
0159     DoTest("foo{\nbar}baz", "lllgU%", "foo{\nBAR}baz");
0160     DoTest("foo{\nbar\n}", "llly%p", "foo{{\nbar\n}\nbar\n}");
0161     // Regression bug for test where yanking with % would actually move the cursor.
0162     DoTest("a()", "y%x", "()");
0163     // Regression test for the bug I added fixing the bug above ;)
0164     DoTest("foo(bar)", "y%P", "foo(bar)foo(bar)");
0165     // Regression test for adjacent brackets
0166     DoTest("foo((bar)baz)", "y%P", "foo((bar)baz)foo((bar)baz)");
0167     // Regression test for "empty" bracket ranges
0168     DoTest("()123", "%%llx", "()23");
0169 
0170     // Testing percentage "<N>%"
0171     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%", "20%dd", "10%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%");
0172 
0173     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%", "50%dd", "10%\n20%\n30%\n40%\n60%\n70%\n80%\n90%\n100%");
0174 
0175     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70\n80%\n90%\n100%", "65%dd", "10%\n20%\n30%\n40%\n50%\n60%\n80%\n90%\n100%");
0176 
0177     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%", "5j10%dd", "20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%");
0178 
0179     // ctrl-left and ctrl-right.
0180     DoTest("foo bar xyz", "\\ctrl-\\rightrX", "foo Xar xyz");
0181     DoTest("foo bar xyz", "$\\ctrl-\\leftrX", "foo bar Xyz");
0182 
0183     // Enter / Return / "+"
0184     DoTest("foo\n\t \t bar", "\\enterr.", "foo\n\t \t .ar");
0185     DoTest("foo\n\t \t bar", "\\returnr.", "foo\n\t \t .ar");
0186     DoTest("foo\n\t \t bar", "+r.", "foo\n\t \t .ar");
0187 
0188     // TEXT OBJECTS
0189     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci'", "foo \"bar baz ('first', '' or 'third')\"");
0190 
0191     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lca'", "foo \"bar baz ('first',  or 'third')\"");
0192 
0193     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci(", "foo \"bar baz ()\"");
0194 
0195     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci(", "foo \"bar baz ()\"");
0196 
0197     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lcib", "foo \"bar baz ()\"");
0198     // Quick test that bracket object works in visual mode.
0199     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lvibd", "foo \"bar baz ()\"");
0200     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lvabd", "foo \"bar baz \"");
0201 
0202     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lca)", "foo \"bar baz \"");
0203 
0204     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci\"", "foo \"\"");
0205 
0206     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lda\"", "foo ");
0207 
0208     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lci[", "foo \"bar []\"");
0209 
0210     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lci]", "foo \"bar []\"");
0211 
0212     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lca[", "foo \"bar \"");
0213 
0214     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lci{", "foo \"bar [baz ({} or 'third')]\"");
0215 
0216     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "7w2lca}", "foo \"bar [baz ( or 'third')]\"");
0217 
0218     DoTest("{foo { bar { (baz) \"asd\" }} {1} {2} {3} {4} {5} }", "ldiB", "{}");
0219 
0220     // Inner/ A Word.
0221     DoTest("", "diw", "");
0222     DoTest(" ", "diw", "");
0223     DoTest("  ", "diw", "");
0224     DoTest("foo", "daw", "");
0225     DoTest("foo", "ldaw", "");
0226     DoTest("foo", "cawxyz\\esc", "xyz");
0227     DoTest("foo bar baz", "daw", "bar baz");
0228     DoTest("foo bar baz", "cawxyz\\esc", "xyzbar baz");
0229     DoTest("foo bar baz", "wdaw", "foo baz");
0230     DoTest("foo bar baz", "wldaw", "foo baz");
0231     DoTest("foo bar baz", "wlldaw", "foo baz");
0232     DoTest("foo bar baz", "wcawxyz\\esc", "foo xyzbaz");
0233     DoTest("foo bar baz", "wwdaw", "foo bar");
0234     DoTest("foo bar baz   ", "wwdaw", "foo bar ");
0235     DoTest("foo bar baz", "wwcawxyz\\esc", "foo barxyz");
0236     DoTest("foo bar baz\n123", "jdaw", "foo bar baz\n");
0237     DoTest("foo bar baz\n123", "jcawxyz\\esc", "foo bar baz\nxyz");
0238     DoTest("foo bar baz\n123", "wwdaw", "foo bar\n123");
0239     DoTest("foo bar baz\n123", "wwcawxyz\\esc", "foo barxyz\n123");
0240     DoTest("foo bar      baz\n123", "wwdaw", "foo bar\n123");
0241     DoTest("foo bar      baz\n123", "wwcawxyz\\esc", "foo barxyz\n123");
0242     DoTest("foo bar baz \n123", "wwdaw", "foo bar \n123");
0243     DoTest("foo bar baz \n123", "wwcawxyz\\esc", "foo bar xyz\n123");
0244     DoTest("foo bar      baz \n123", "wwdaw", "foo bar      \n123");
0245     DoTest("foo bar      baz \n123", "wwcawxyz\\esc", "foo bar      xyz\n123");
0246     DoTest("foo    bar", "llldaw", "foo");
0247     DoTest("foo    bar", "lllcawxyz\\esc", "fooxyz");
0248     DoTest("foo    bar", "lllldaw", "foo");
0249     DoTest("foo    bar", "llllcawxyz\\esc", "fooxyz");
0250     DoTest("    bar", "daw", "");
0251     DoTest("    bar", "ldaw", "");
0252     DoTest("    bar", "llldaw", "");
0253     DoTest("    bar", "lllldaw", "    ");
0254     DoTest("    bar", "cawxyz\\esc", "xyz");
0255     DoTest("    bar", "lcawxyz\\esc", "xyz");
0256     DoTest("    bar", "lllcawxyz\\esc", "xyz");
0257     DoTest("foo   ", "llldaw", "foo   ");
0258     DoTest("foo   ", "lllldaw", "foo   ");
0259     DoTest("foo   ", "llllldaw", "foo   ");
0260     DoTest("foo   ", "lllcawxyz\\esc", "foo  ");
0261     DoTest("foo   ", "llllcawxyz\\esc", "foo  ");
0262     DoTest("foo   ", "lllllcawxyz\\esc", "foo  ");
0263     DoTest("foo   \nbar", "llldaw", "foo");
0264     DoTest("foo   \nbar", "lllldaw", "foo");
0265     DoTest("foo   \nbar", "llllldaw", "foo");
0266     DoTest("foo   \nbar", "lllcawxyz\\esc", "fooxyz");
0267     DoTest("foo   \nbar", "llllcawxyz\\esc", "fooxyz");
0268     DoTest("foo   \nbar", "lllllcawxyz\\esc", "fooxyz");
0269     DoTest("foo   \n   bar", "jdaw", "foo   \n");
0270     DoTest("foo   \n   bar", "jldaw", "foo   \n");
0271     DoTest("foo   \n   bar", "jlldaw", "foo   \n");
0272     DoTest("foo   \n   bar", "jcawxyz\\esc", "foo   \nxyz");
0273     DoTest("foo   \n   bar", "jlcawxyz\\esc", "foo   \nxyz");
0274     DoTest("foo   \n   bar", "jllcawxyz\\esc", "foo   \nxyz");
0275     DoTest("foo bar", "2daw", "");
0276     DoTest("foo bar", "2cawxyz\\esc", "xyz");
0277     DoTest("foo bar baz", "2daw", "baz");
0278     DoTest("foo bar baz", "2cawxyz\\esc", "xyzbaz");
0279     DoTest("foo bar baz", "3daw", "");
0280     DoTest("foo bar baz", "3cawxyz\\esc", "xyz");
0281     DoTest("foo bar\nbaz", "2daw", "\nbaz");
0282     DoTest("foo bar\nbaz", "2cawxyz\\esc", "xyz\nbaz");
0283     DoTest("foo bar\nbaz 123", "3daw", "123");
0284     DoTest("foo bar\nbaz 123", "3cawxyz\\esc", "xyz123");
0285     DoTest("foo bar \nbaz 123", "3daw", "123");
0286     DoTest("foo bar \nbaz 123", "3cawxyz\\esc", "xyz123");
0287     DoTest("foo bar baz", "lll2daw", "foo");
0288     DoTest("foo bar baz", "lll2cawxyz\\esc", "fooxyz");
0289     DoTest("   bar baz", "2daw", "");
0290     DoTest("   bar baz", "2cawxyz\\esc", "xyz");
0291     DoTest("   bar baz 123", "2daw", " 123");
0292     DoTest("   bar baz 123", "2cawxyz\\esc", "xyz 123");
0293     DoTest("   bar baz\n123", "3daw", "");
0294     DoTest("   bar baz\n123", "3cawxyz\\esc", "xyz");
0295     DoTest("   bar baz\n  123", "3daw", "");
0296     DoTest("   bar baz\n  123", "3cawxyz\\esc", "xyz");
0297     DoTest("   bar baz\n  123", "2daw", "\n  123");
0298     DoTest("   bar baz\n  123", "2cawxyz\\esc", "xyz\n  123");
0299     DoTest("   bar baz\n  123 456 789", "j2daw", "   bar baz\n 789");
0300     DoTest("   bar baz\n  123 456 789", "j2cawxyz\\esc", "   bar baz\nxyz 789");
0301     DoTest("foo\nbar\n", "2daw", "");
0302     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4daw", "bar baz\njkl");
0303     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4cawxyz\\esc", "bar baz\nxyzjkl");
0304     DoTest("   bar baz\n  123 \n456\n789 abc \njkl", "j4daw", "   bar baz\njkl");
0305     DoTest("   bar baz\n  123 456 789", "j2cawxyz\\esc", "   bar baz\nxyz 789");
0306     DoTest("foo b123r xyz", "wdaw", "foo xyz");
0307     DoTest("foo b123r xyz", "wldaw", "foo xyz");
0308     DoTest("foo b123r xyz", "wlldaw", "foo xyz");
0309     DoTest("foo b123r xyz", "wllldaw", "foo xyz");
0310     DoTest("foo b123r xyz", "wlllldaw", "foo xyz");
0311     DoTest("1 2 3 4 5 6", "daw", "2 3 4 5 6");
0312     DoTest("1 2 3 4 5 6", "ldaw", "1 3 4 5 6");
0313     DoTest("1 2 3 4 5 6", "lldaw", "1 3 4 5 6");
0314     DoTest("1 2 3 4 5 6", "llldaw", "1 2 4 5 6");
0315     DoTest("!foo!", "ldaw", "!!");
0316     DoTest("! foo !", "ldaw", "! !");
0317     DoTest("! foo !", "lldaw", "! !");
0318     DoTest("! foo (", "l2daw", "!");
0319     DoTest("! foo(\n123", "l2daw", "!\n123");
0320     DoTest("  !foo(\n123", "lll2daw", "  !\n123");
0321     DoTest("  !!foo(\n123", "llll2daw", "  !!\n123");
0322     DoTest("  !foo( \n123", "lll2daw", "  !\n123");
0323     DoTest("  !!!!(", "llldaw", "  ");
0324     DoTest("  !!!!(", "lll2daw", "  !!!!(");
0325     DoTest("  !!!!(\n!!!", "lll2daw", "");
0326     DoTest("  !!!!(\n!!!", "llll2daw", "");
0327 
0328     // Inner/ A WORD
0329     // Behave the same as a Word if there are no non-word chars.
0330     DoTest("", "diW", "");
0331     DoTest(" ", "diW", "");
0332     DoTest("  ", "diW", "");
0333     DoTest("foo", "daW", "");
0334     DoTest("foo", "ldaW", "");
0335     DoTest("foo", "caWxyz\\esc", "xyz");
0336     DoTest("foo bar baz", "daW", "bar baz");
0337     DoTest("foo bar baz", "caWxyz\\esc", "xyzbar baz");
0338     DoTest("foo bar baz", "wdaW", "foo baz");
0339     DoTest("foo bar baz", "wldaW", "foo baz");
0340     DoTest("foo bar baz", "wlldaW", "foo baz");
0341     DoTest("foo bar baz", "wcaWxyz\\esc", "foo xyzbaz");
0342     DoTest("foo bar baz", "wwdaW", "foo bar");
0343     DoTest("foo bar baz   ", "wwdaW", "foo bar ");
0344     DoTest("foo bar baz", "wwcaWxyz\\esc", "foo barxyz");
0345     DoTest("foo bar baz\n123", "jdaW", "foo bar baz\n");
0346     DoTest("foo bar baz\n123", "jcaWxyz\\esc", "foo bar baz\nxyz");
0347     DoTest("foo bar baz\n123", "wwdaW", "foo bar\n123");
0348     DoTest("foo bar baz\n123", "wwcaWxyz\\esc", "foo barxyz\n123");
0349     DoTest("foo bar      baz\n123", "wwdaW", "foo bar\n123");
0350     DoTest("foo bar      baz\n123", "wwcaWxyz\\esc", "foo barxyz\n123");
0351     DoTest("foo bar baz \n123", "wwdaW", "foo bar \n123");
0352     DoTest("foo bar baz \n123", "wwcaWxyz\\esc", "foo bar xyz\n123");
0353     DoTest("foo bar      baz \n123", "wwdaW", "foo bar      \n123");
0354     DoTest("foo bar      baz \n123", "wwcaWxyz\\esc", "foo bar      xyz\n123");
0355     DoTest("foo    bar", "llldaW", "foo");
0356     DoTest("foo    bar", "lllcaWxyz\\esc", "fooxyz");
0357     DoTest("foo    bar", "lllldaW", "foo");
0358     DoTest("foo    bar", "llllcaWxyz\\esc", "fooxyz");
0359     DoTest("    bar", "daW", "");
0360     DoTest("    bar", "ldaW", "");
0361     DoTest("    bar", "llldaW", "");
0362     DoTest("    bar", "lllldaW", "    ");
0363     DoTest("    bar", "caWxyz\\esc", "xyz");
0364     DoTest("    bar", "lcaWxyz\\esc", "xyz");
0365     DoTest("    bar", "lllcaWxyz\\esc", "xyz");
0366     DoTest("foo   ", "llldaW", "foo   ");
0367     DoTest("foo   ", "lllldaW", "foo   ");
0368     DoTest("foo   ", "llllldaW", "foo   ");
0369     DoTest("foo   ", "lllcaWxyz\\esc", "foo  ");
0370     DoTest("foo   ", "llllcaWxyz\\esc", "foo  ");
0371     DoTest("foo   ", "lllllcaWxyz\\esc", "foo  ");
0372     DoTest("foo   \nbar", "llldaW", "foo");
0373     DoTest("foo   \nbar", "lllldaW", "foo");
0374     DoTest("foo   \nbar", "llllldaW", "foo");
0375     DoTest("foo   \nbar", "lllcaWxyz\\esc", "fooxyz");
0376     DoTest("foo   \nbar", "llllcaWxyz\\esc", "fooxyz");
0377     DoTest("foo   \nbar", "lllllcaWxyz\\esc", "fooxyz");
0378     DoTest("foo   \n   bar", "jdaW", "foo   \n");
0379     DoTest("foo   \n   bar", "jldaW", "foo   \n");
0380     DoTest("foo   \n   bar", "jlldaW", "foo   \n");
0381     DoTest("foo   \n   bar", "jcaWxyz\\esc", "foo   \nxyz");
0382     DoTest("foo   \n   bar", "jlcaWxyz\\esc", "foo   \nxyz");
0383     DoTest("foo   \n   bar", "jllcaWxyz\\esc", "foo   \nxyz");
0384     DoTest("foo bar", "2daW", "");
0385     DoTest("foo bar", "2caWxyz\\esc", "xyz");
0386     DoTest("foo bar baz", "2daW", "baz");
0387     DoTest("foo bar baz", "2caWxyz\\esc", "xyzbaz");
0388     DoTest("foo bar baz", "3daW", "");
0389     DoTest("foo bar baz", "3caWxyz\\esc", "xyz");
0390     DoTest("foo bar\nbaz", "2daW", "\nbaz");
0391     DoTest("foo bar\nbaz", "2caWxyz\\esc", "xyz\nbaz");
0392     DoTest("foo bar\nbaz 123", "3daW", "123");
0393     DoTest("foo bar\nbaz 123", "3caWxyz\\esc", "xyz123");
0394     DoTest("foo bar \nbaz 123", "3daW", "123");
0395     DoTest("foo bar \nbaz 123", "3caWxyz\\esc", "xyz123");
0396     DoTest("foo bar baz", "lll2daW", "foo");
0397     DoTest("foo bar baz", "lll2caWxyz\\esc", "fooxyz");
0398     DoTest("   bar baz", "2daW", "");
0399     DoTest("   bar baz", "2caWxyz\\esc", "xyz");
0400     DoTest("   bar baz 123", "2daW", " 123");
0401     DoTest("   bar baz 123", "2caWxyz\\esc", "xyz 123");
0402     DoTest("   bar baz\n123", "3daW", "");
0403     DoTest("   bar baz\n123", "3caWxyz\\esc", "xyz");
0404     DoTest("   bar baz\n  123", "3daW", "");
0405     DoTest("   bar baz\n  123", "3caWxyz\\esc", "xyz");
0406     DoTest("   bar baz\n  123", "2daW", "\n  123");
0407     DoTest("   bar baz\n  123", "2caWxyz\\esc", "xyz\n  123");
0408     DoTest("   bar baz\n  123 456 789", "j2daW", "   bar baz\n 789");
0409     DoTest("   bar baz\n  123 456 789", "j2caWxyz\\esc", "   bar baz\nxyz 789");
0410     DoTest("foo\nbar\n", "2daW", "");
0411     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4daW", "bar baz\njkl");
0412     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4caWxyz\\esc", "bar baz\nxyzjkl");
0413     DoTest("   bar baz\n  123 \n456\n789 abc \njkl", "j4daW", "   bar baz\njkl");
0414     DoTest("   bar baz\n  123 456 789", "j2caWxyz\\esc", "   bar baz\nxyz 789");
0415     DoTest("foo b123r xyz", "wdaW", "foo xyz");
0416     DoTest("foo b123r xyz", "wldaW", "foo xyz");
0417     DoTest("foo b123r xyz", "wlldaW", "foo xyz");
0418     DoTest("foo b123r xyz", "wllldaW", "foo xyz");
0419     DoTest("foo b123r xyz", "wlllldaW", "foo xyz");
0420     DoTest("1 2 3 4 5 6", "daW", "2 3 4 5 6");
0421     DoTest("1 2 3 4 5 6", "ldaW", "1 3 4 5 6");
0422     DoTest("1 2 3 4 5 6", "lldaW", "1 3 4 5 6");
0423     DoTest("1 2 3 4 5 6", "llldaW", "1 2 4 5 6");
0424     // Now with non-word characters.
0425     DoTest("fo(o", "daW", "");
0426     DoTest("fo(o", "ldaW", "");
0427     DoTest("fo(o", "lldaW", "");
0428     DoTest("fo(o", "llldaW", "");
0429     DoTest("fo(o )!)!)ffo", "2daW", "");
0430     DoTest("fo(o", "diW", "");
0431     DoTest("fo(o", "ldiW", "");
0432     DoTest("fo(o", "lldiW", "");
0433     DoTest("fo(o", "llldiW", "");
0434     DoTest("foo \"\"B!!", "fBdaW", "foo");
0435 
0436     // Inner / Sentence text object ("is")
0437     DoTest("", "cis", "");
0438     DoTest("hello", "cis", "");
0439     DoTest("hello", "flcis", "");
0440     DoTest("hello. bye", "cisX", "X bye");
0441     DoTest("hello. bye", "f.cisX", "X bye");
0442     DoTest("hello.  bye", "fbcisX", "hello.  X");
0443     DoTest("hello\n\nbye.", "cisX", "X\n\nbye.");
0444     DoTest("Hello. Bye.\n", "GcisX", "Hello. Bye.\nX");
0445     DoTest("hello. by.. another.", "cisX", "X by.. another.");
0446     DoTest("hello. by.. another.", "fbcisX", "hello. X another.");
0447     DoTest("hello. by.. another.\n", "GcisX", "hello. by.. another.\nX");
0448     DoTest("hello. yay\nis this a string?!?.. another.\n", "fycisX", "hello. X another.\n");
0449     DoTest("hello. yay\nis this a string?!?.. another.\n", "jcisX", "hello. X another.\n");
0450     DoTest("This is a sentence.\nThis is another sentence.", "jdis", "This is a sentence.\n");
0451 
0452     // Around / Sentence text object ("as")
0453     DoTest("", "cas", "");
0454     DoTest("hello", "cas", "");
0455     DoTest("hello", "flcas", "");
0456     DoTest("hello. bye", "casX", "Xbye");
0457     DoTest("hello. bye", "f.casX", "Xbye");
0458     DoTest("hello. bye.", "fbcasX", "hello.X");
0459     DoTest("hello. bye", "fbcasX", "hello.X");
0460     DoTest("hello\n\nbye.", "casX", "X\n\nbye.");
0461     DoTest("Hello. Bye.\n", "GcasX", "Hello. Bye.\nX");
0462     DoTest("hello. by.. another.", "casX", "Xby.. another.");
0463     DoTest("hello. by.. another.", "fbcasX", "hello. Xanother.");
0464     DoTest("hello. by.. another.\n", "GcasX", "hello. by.. another.\nX");
0465     DoTest("hello. yay\nis this a string?!?.. another.\n", "fycasX", "hello. Xanother.\n");
0466     DoTest("hello. yay\nis this a string?!?.. another.\n", "jcasX", "hello. Xanother.\n");
0467     DoTest("hello. yay\nis this a string?!?.. \t       another.\n", "jcasX", "hello. Xanother.\n");
0468 
0469     // Inner / Paragraph text object ("ip")
0470     DoTest("", "cip", "");
0471     DoTest("\nhello", "cipX", "X\nhello");
0472     DoTest("\nhello\n\nanother. text.", "jcipX", "\nX\n\nanother. text.");
0473     DoTest("\nhello\n\n\nanother. text.", "jjcipX", "\nhello\nX\nanother. text.");
0474     DoTest("\nhello\n\n\nanother. text.", "jjjcipX", "\nhello\nX\nanother. text.");
0475     DoTest("\nhello\n\n\nanother. text.", "jjjjcipX", "\nhello\n\n\nX");
0476     DoTest("hello\n\n", "jcipX", "hello\nX");
0477     DoTest("hello\n\n", "jjcipX", "hello\nX");
0478 
0479     // Around / Paragraph text object ("ap")
0480     DoTest("", "cap", "");
0481     DoTest("\nhello", "capX", "X");
0482     DoTest("\nhello\n\nanother.text.", "jcapX", "\nX\nanother.text.");
0483     DoTest("\nhello\n\nanother.text.\n\n\nAnother.", "jjjcapX", "\nhello\n\nX\nAnother.");
0484     DoTest("\nhello\n\nanother.text.\n\n\nAnother.", "jjjjjcapX", "\nhello\n\nanother.text.\nX");
0485     DoTest("hello\n\n\n", "jjcapX", "hello\n\n\n");
0486     DoTest("hello\n\nasd", "jjjcapX", "hello\nX");
0487 
0488     DoTest("{\nfoo\n}", "jdiB", "{\n}");
0489     DoTest("{\n}", "diB", "{\n}");
0490     DoTest("{\nfoo}", "jdiB", "{\n}");
0491     DoTest("{foo\nbar\nbaz}", "jdiB", "{}");
0492     DoTest("{foo\nbar\n  \t\t }", "jdiB", "{\n  \t\t }");
0493     DoTest("{foo\nbar\n  \t\ta}", "jdiB", "{}");
0494     DoTest("\t{\n\t}", "ldiB", "\t{\n\t}");
0495     // Quick test to see whether inner curly bracket works in visual mode.
0496     DoTest("{\nfoo}", "jviBd", "{\n}");
0497     DoTest("{\nfoo}", "jvaBd", "");
0498     // Regression test for viB not working if there is a blank line before the closing }.
0499     DoTest("{\nfoo\n\n}", "viBd", "{\n}");
0500     // The inner block text object does not include the line containing the opening brace if
0501     // the opening brace is the last character on its line and there is only whitespace before the closing brace.
0502     // (In particular: >iB should not indent the line containing the opening brace under these conditions).
0503     DoTest("{\nfoo\n}", "j>iB", "{\n  foo\n}");
0504     // Similarly, in such conditions, deleting the inner block should leave the cursor on closing brace line, not the
0505     // opening.
0506     DoTest("{\nfoo\n}", "jdiBiX", "{\nX}");
0507     // Yanking and pasting such a text object should be treated as linewise.
0508     DoTest("{\nfoo\nbar\n}", "jyiBjp", "{\nfoo\nbar\nfoo\nbar\n}");
0509     // Changing such a text object should delete everything but one line, which we will begin insertion at.
0510     DoTest("{\nfoo\nbar\n}", "jciBbaz\\esc", "{\nbaz\n}");
0511     // Make sure we remove the "last motion was a *linewise* curly text object" flag when we next parse a motion!
0512     DoTest("{\nfoo\n}", "jciBbaz xyz\\escdiw", "{\nbaz \n}");
0513     DoTest("{\nfoo\nbar\n}", "jviBbd", "{\nar\n}");
0514 
0515     DoTest("int main() {\n  printf( \"HelloWorld!\\n\" );\n  return 0;\n} ", "jda}xr;", "int main();");
0516 
0517     DoTest("QList<QString>", "wwldi>", "QList<>");
0518     DoTest("QList<QString>", "wwlda<", "QList");
0519     DoTest("<>\n<title>Title</title>\n</head>", "di<jci>\\ctrl-c", "<>\n<>Title</title>\n</head>");
0520 
0521     DoTest("foo bar baz", "wldiw", "foo  baz");
0522 
0523     DoTest("foo bar baz", "wldawx", "foo az");
0524 
0525     DoTest("foo ( \n bar\n)baz", "jdi(", "foo ()baz");
0526     DoTest("foo ( \n bar\n)baz", "jda(", "foo baz");
0527     DoTest("(foo(bar)baz)", "ldi)", "()");
0528     DoTest("(foo(bar)baz)", "lca(\\ctrl-c", "");
0529     DoTest("( foo ( bar ) )baz", "di(", "()baz");
0530     DoTest("( foo ( bar ) )baz", "da(", "baz");
0531     DoTest("[foo [ bar] [(a)b [c]d ]]", "$hda]", "[foo [ bar] ]");
0532     DoTest("(a)", "di(", "()");
0533     DoTest("(ab)", "di(", "()");
0534     DoTest("(abc)", "di(", "()");
0535 
0536     DoTest("hi!))))}}]]", "di]di}da)di)da]", "hi!))))}}]]");
0537 
0538     DoTest("foo \"bar\" baz", "4ldi\"", "foo \"\" baz");
0539     DoTest("foo \"bar\" baz", "8lca\"\\ctrl-c", "foo  baz");
0540 
0541     DoTest("foo 'bar' baz", "4lca'\\ctrl-c", "foo  baz");
0542     DoTest("foo 'bar' baz", "8ldi'", "foo '' baz");
0543 
0544     DoTest("foo `bar` baz", "4lca`\\ctrl-c", "foo  baz");
0545     DoTest("foo `bar` baz", "8ldi`", "foo `` baz");
0546 
0547     DoTest("()", "di(", "()");
0548     DoTest("\"\"", "di\"", "\"\"");
0549 
0550     // Comma text object
0551     DoTest("func(aaaa);", "llllldi,", "func();");
0552     DoTest("func(aaaa);", "lllllda,", "func;");
0553     DoTest("//Hello, world!\nfunc(a[0] > 2);", "jf>di,", "//Hello, world!\nfunc();");
0554     DoTest("//Hello, world!\nfunc(a[0] > 2);", "jf>da,", "//Hello, world!\nfunc;");
0555     DoTest("//Hello, world!\na[] = {135};", "jf3di,", "//Hello, world!\na[] = {};");
0556 
0557     // Some corner case tests for t/ T, mainly dealing with how a ; after e.g. a ta will
0558     // start searching for the next a *after* the character after the cursor.
0559     // Hard to explain; I'll let the test-cases do the talking :)
0560     DoTest("bar baz", "ta;x", "bar az");
0561     // Ensure we reset the flag that says we must search starting from the character after the cursor!
0562     DoTest("bar baz", "ta;^tax", "ar baz");
0563     // Corresponding tests for T
0564     DoTest("bar baz", "$Ta;x", "ba baz");
0565     // Ensure we reset the flag that says we must search starting from the character before the cursor!
0566     DoTest("bar baz", "$Ta;$Tax", "bar ba");
0567     // Ensure that command backwards works, too - only one test, as any additional ones would
0568     // just overlap with our previous ones.
0569     DoTest("aba bar", "lTa,x", "aba ar");
0570     // Some tests with counting.
0571     DoTest("aba bar", "2tax", "aba ar");
0572     // If we can't find 3 further a's, don't move at all...
0573     DoTest("aba bar", "3tax", "ba bar");
0574     // ... except if we are repeating the last search, in which case stop at the last
0575     // one that we do find.
0576     DoTest("aba bar", "ta2;x", "aba ar");
0577 
0578     // Don't move if we can't find any matches at all, or fewer than we require.
0579     DoTest("nocapitalc", "lltCx", "noapitalc");
0580     DoTest("nocapitalc", "llTCx", "noapitalc");
0581 
0582     DoTest("123c456", "2tcx", "23c456");
0583     DoTest("123c456", "$2Tcx", "123c45");
0584     // Commands with searches that do not find anything, or find less than required, should do nothing.
0585     DoTest("foo", "dtk", "foo");
0586     DoTest("foomxyz", "d2tm", "foomxyz");
0587     DoTest("foo", "dfk", "foo");
0588     DoTest("foomxyz", "d2fm", "foomxyz");
0589     DoTest("foo", "$dTk", "foo");
0590     DoTest("foomxyz", "$d2Fm", "foomxyz");
0591     // They should also return a range marked as invalid.
0592     DoTest("foo bar", "gUF(", "foo bar");
0593     DoTest("foo bar", "gUf(", "foo bar");
0594     DoTest("foo bar", "gUt(", "foo bar");
0595     DoTest("foo bar", "gUT(", "foo bar");
0596 
0597     // Changes using backward motions don't consume cursor character
0598     DoTest("foo bar", "$dTf", "fr");
0599     DoTest("foo bar", "$c2Fo", "fr");
0600 
0601     // Regression test for special-handling of "/" and "?" keys: these shouldn't interfere
0602     // with character searches.
0603     DoTest("foo /", "f/rX", "foo X");
0604     // d{f,F}{/,?}
0605     DoTest("foo/bar?baz", "df/", "bar?baz");
0606     DoTest("foo/bar?baz", "f/df?", "foobaz");
0607     DoTest("foo/bar?baz", "df?", "baz");
0608     DoTest("foo/bar?baz", "f?dF/", "foo?baz");
0609     // d{t,T}{/,?}
0610     DoTest("foo/bar?baz", "dt/", "/bar?baz");
0611     DoTest("foo/bar?baz", "t/dt?", "fo?baz");
0612     DoTest("foo/bar?baz", "dt?", "?baz");
0613     DoTest("foo/bar?baz", "t?dT/", "foo/r?baz");
0614     // c{f,F}{/,?}
0615     DoTest("foo/bar?baz", "cf/qux\\esc", "quxbar?baz");
0616     DoTest("foo/bar?baz", "f/cf?qux\\esc", "fooquxbaz");
0617     DoTest("foo/bar?baz", "cf?qux\\esc", "quxbaz");
0618     DoTest("foo/bar?baz", "f?cF/qux\\esc", "fooqux?baz");
0619     // c{t,T}{/,?}
0620     DoTest("foo/bar?baz", "ct/qux\\esc", "qux/bar?baz");
0621     DoTest("foo/bar?baz", "t/ct?qux\\esc", "foqux?baz");
0622     DoTest("foo/bar?baz", "ct?qux\\esc", "qux?baz");
0623     DoTest("foo/bar?baz", "t?cT/qux\\esc", "foo/quxr?baz");
0624     // y{f,F}{/,?}
0625     DoTest("foo/bar?baz", "yf/p", "ffoo/oo/bar?baz");
0626     DoTest("foo/bar?baz", "f/yf?p", "foo//bar?bar?baz");
0627     DoTest("foo/bar?baz", "yf?p", "ffoo/bar?oo/bar?baz");
0628     DoTest("foo/bar?baz", "f?yF/p", "foo/bar?/barbaz");
0629     // y{t,T}{/,?}
0630     DoTest("foo/bar?baz", "yt/p", "ffoooo/bar?baz");
0631     DoTest("foo/bar?baz", "t/yt?p", "fooo/bar/bar?baz");
0632     DoTest("foo/bar?baz", "yt?p", "ffoo/baroo/bar?baz");
0633     DoTest("foo/bar?baz", "t?yT/p", "foo/barba?baz");
0634 
0635     // gU, gu, g~.
0636     DoTest("foo/bar?baz", "gUf/", "FOO/bar?baz");
0637     DoTest("FOO/bar?baz", "g~f?", "foo/BAR?baz");
0638     DoTest("foo/BAR?baz", "guf?", "foo/bar?baz");
0639 
0640     // Not adding tests for =f/, >t?, <F?, gqT/ :
0641     //  Not likely to be used with those motions.
0642     // gw and g@ are currently not supported by ktexteditor's vimode
0643 
0644     // Using registers
0645     DoTest("foo/bar?baz", "\"2df?", "baz");
0646     DoTest("foo/bar?baz", "\"_ct/qux", "qux/bar?baz");
0647 
0648     // counted find on change/deletion != find digit
0649     DoTest("foo2barbaz", "df2ax", "bxarbaz");
0650     DoTest("foo2barbaz", "d2fax", "");
0651 
0652     // Motion to lines starting with { or }
0653     DoTest("{\nfoo\n}", "][x", "{\nfoo\n");
0654     DoTest("{\nfoo\n}", "j[[x", "\nfoo\n}");
0655     DoTest("bar\n{\nfoo\n}", "]]x", "bar\n\nfoo\n}");
0656     DoTest("{\nfoo\n}\nbar", "jjj[]x", "{\nfoo\n\nbar");
0657     DoTest("bar\nfoo\n}", "d][", "}");
0658     DoTest("bar\n{\nfoo\n}", "d]]", "{\nfoo\n}");
0659     DoTest("bar\nfoo\n}", "ld][", "b\n}");
0660     DoTest("{\nfoo\n}", "jld[[", "oo\n}");
0661     DoTest("bar\n{\nfoo\n}", "ld]]", "b\n{\nfoo\n}");
0662     DoTest("{\nfoo\n}\nbar", "jjjld[]", "{\nfoo\nar");
0663 
0664     // Testing the "(" motion
0665     DoTest("", "(", "");
0666     DoTest("\nhello.", "fh(iX", "X\nhello.");
0667     DoTest("\n   hello.", "jfe(iX", "X\n   hello.");
0668     DoTest("hello. world.", "fr(iX", "Xhello. world.");
0669     DoTest("hello. world.\n", "j(iX", "hello. Xworld.\n");
0670     DoTest("hello. world\nyay. lol.\n", "jfl(iX", "hello. Xworld\nyay. lol.\n");
0671     DoTest("Hello.\n\n", "jj(iX", "XHello.\n\n");
0672     DoTest("\nHello.", "j(iX", "X\nHello.");
0673     DoTest("\n\n\nHello.", "jj(iX", "X\n\n\nHello.");
0674     DoTest("Hello! Bye!", "fB(iX", "XHello! Bye!");
0675     DoTest("Hello! Bye! Hye!", "fH(iX", "Hello! XBye! Hye!");
0676     DoTest("\nHello. Bye.. Asd.\n\n\n\nAnother.", "jjjj(iX", "\nHello. Bye.. XAsd.\n\n\n\nAnother.");
0677 
0678     // Testing the ")" motion
0679     DoTest("", ")", "");
0680     DoTest("\nhello.", ")iX", "\nXhello.");
0681     DoTest("hello. world.", ")iX", "hello. Xworld.");
0682     DoTest("hello. world\n\nasd.", "))iX", "hello. world\nX\nasd.");
0683     DoTest("hello. wor\nld.?? Asd", "))iX", "hello. wor\nld.?? XAsd");
0684     DoTest("hello. wor\nld.?? Asd", "jfA(iX", "hello. Xwor\nld.?? Asd");
0685     DoTest("Hello.\n\n\nWorld.", ")iX", "Hello.\nX\n\nWorld.");
0686     DoTest("Hello.\n\n\nWorld.", "))iX", "Hello.\n\n\nXWorld.");
0687     DoTest("Hello.\n\n", ")iX", "Hello.\nX\n");
0688     DoTest("Hello.\n\n", "))iX", "Hello.\n\nX");
0689     DoTest("Hello. ", ")aX", "Hello. X");
0690     DoTest("Hello?? Bye!", ")iX", "Hello?? XBye!");
0691 
0692     // Testing "{" and "}" motions
0693     DoTest("", "{}", "");
0694     DoTest("foo", "{}dd", "");
0695     DoTest("foo\n\nbar", "}dd", "foo\nbar");
0696     DoTest("foo\n\nbar\n\nbaz", "3}x", "foo\n\nbar\n\nba");
0697     DoTest("foo\n\nbar\n\nbaz", "3}{dd{dd", "foo\nbar\nbaz");
0698     DoTest("foo\nfoo\n\nbar\n\nbaz", "5}{dd{dd", "foo\nfoo\nbar\nbaz");
0699     DoTest("foo\nfoo\n\nbar\n\nbaz", "5}3{x", "oo\nfoo\n\nbar\n\nbaz");
0700     DoTest("foo\n\n\nbar", "10}{{x", "oo\n\n\nbar");
0701     DoTest("foo\n\n\nbar", "}}x", "foo\n\n\nba");
0702     DoTest("foo\n\n\nbar\n", "}}dd", "foo\n\n\nbar");
0703 
0704     // Testing the position of the cursor in some cases of the "c" command.
0705     DoTest("(a, b, c)", "cibX", "(X)");
0706     DoTest("(a, b, c)", "f)cibX", "(X)");
0707     DoTest("(a, b, c)", "ci(X", "(X)");
0708     DoTest("(a, b, c)", "ci)X", "(X)");
0709     DoTest("[a, b, c]", "ci[X", "[X]");
0710     DoTest("[a, b, c]", "ci]X", "[X]");
0711     DoTest("{a, b, c}", "ciBX", "{X}");
0712     DoTest("{a, b, c}", "ci{X", "{X}");
0713     DoTest("{a, b, c}", "ci}X", "{X}");
0714     DoTest("<a, b, c>", "ci<X", "<X>");
0715     DoTest("<a, b, c>", "ci>X", "<X>");
0716 
0717     // Things like "cn" and "cN" don't crash.
0718     DoTest("Hello", "cn", "Hello");
0719     DoTest("Hello", "cN", "Hello");
0720 }
0721 
0722 void ModesTest::NormalCommandsTests()
0723 {
0724     // Testing "J"
0725     DoTest("foo\nbar", "J", "foo bar");
0726     DoTest("foo\nbar", "JrX", "fooXbar");
0727     DoTest("foo\nbar\nxyz\n123", "3J", "foo bar xyz\n123");
0728     DoTest("foo\nbar\nxyz\n123", "3JrX", "foo barXxyz\n123");
0729     DoTest("foo\nbar\nxyz\n12345\n789", "4JrX", "foo bar xyzX12345\n789");
0730     DoTest("foo\nbar\nxyz\n12345\n789", "6JrX", "Xoo\nbar\nxyz\n12345\n789");
0731     DoTest("foo\nbar\nxyz\n12345\n789", "j5JrX", "foo\nXar\nxyz\n12345\n789");
0732     DoTest("foo\nbar\nxyz\n12345\n789", "7JrX", "Xoo\nbar\nxyz\n12345\n789");
0733     DoTest("\n\n", "J", "\n");
0734     DoTest("foo\n\t   \t\t  bar", "JrX", "fooXbar");
0735     DoTest("foo\n\t   \t\t", "J", "foo ");
0736     DoTest("foo\n\t   \t\t", "JrX", "fooX");
0737 
0738     // Testing "dd"
0739     DoTest("foo\nbar", "dd", "bar");
0740     DoTest("foo\nbar", "2dd", "");
0741     DoTest("foo\nbar\n", "Gdd", "foo\nbar");
0742     // Testing numbered registers
0743     DoTest("hello\nworld", "dddd\"2p\"1p", "\nhello\nworld");
0744     DoTest("foo\nbar", "ddD\"1p", "\nfoo");
0745     DoTest("abc\nlmn\nxyz", "dddd\"2dd\"1p\"2p", "\nxyz\nlmn");
0746     DoTest("123\n456", "dd\"add\"1p\"2p", "\n456\n123");
0747     DoTest("9\n8\n7\n6\n5\n4\n3\n2\n1\n0", "\"1dddddddddddddddd2dd\"1p\"2p\"3p\"4p\"5p\"6p\"7p\"8p\"9p", "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n0");
0748 
0749     // Testing "D"
0750     DoTest("foo bar", "lllD", "foo");
0751     DoTest("foo\nfoo2\nfoo3", "l2D", "f\nfoo3");
0752     DoTest("qwerty", "d frDai", "wei");
0753     // Testing small delete (-) register
0754     DoTest("12345\n67890", "ddD\"-p", "67890");
0755     DoTest("foo\nbar\nhello world", "ld$dj$\"-p", "hello worldoo");
0756     DoTest("123\n456", "Dj\"aD\"-p", "\n123");
0757     DoTest("abc\nlmn\nxyz", "yyjlYjxk\"-p", "abc\nlmyn\nxz");
0758 
0759     // Testing "d"
0760     DoTest("foobar", "ld2l", "fbar");
0761     DoTest("1 2 3\n4 5 6", "ld100l", "1\n4 5 6");
0762 
0763     DoTest("123\n", "d10l", "\n");
0764     DoTest("123\n", "10lx", "12\n");
0765 
0766     // Testing "Y"
0767     DoTest("qwerty", "ld Yep", "qertyerty");
0768     // Testing ""<x>y" where x is in a-z (overwrite/insert to register)
0769     DoTest("x", "\"ayh\"Ayl\"ap", "xx");
0770     DoTest("xy", "\"byll\"byll\"bp", "xyy");
0771     DoTest("xyz", "\"cy3l$\"cp", "xyzxyz");
0772     DoTest("abz", "\"xyll\"yyll\"zyll\"zp\"xp\"yp", "abzzab");
0773     DoTest("abcdwxyz", "\"byh\"ayll\"Byll\"cyll\"dyll\"dyl\"zye$\"zp\"ap\"Cp\"bp\"dp", "abcdwxyzwxyzacbw");
0774     // Testing "<X>y" where X is in A-Z (append-copy)
0775     DoTest("foo bar ", "\"ayew\"Aye$\"ap", "foo bar foobar");
0776     DoTest("foo bar 2", "\"ayew\"Ayew\"aye\"ap", "foo bar 22");
0777     DoTest("123 foo ", "\"ayew\"zye\"Aye0\"Zy4l$\"Zp\"ap", "123 foo foo123 123foo");
0778 
0779     // Testing "X"
0780     DoTest("ABCD", "$XX", "AD");
0781     DoTest("foo", "XP", "foo");
0782 
0783     // Testing Del key
0784     DoTest("foo", "\\home\\delete", "oo");
0785     DoTest("foo", "$\\delete", "fo");
0786 
0787     // Delete. Note that when sent properly via Qt, the key event text() will inexplicably be "127",
0788     // which can trip up the key parser. Duplicate this oddity here.
0789     BeginTest(QStringLiteral("xyz"));
0790     TestPressKey(QStringLiteral("l"));
0791     QKeyEvent *deleteKeyDown = new QKeyEvent(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QStringLiteral("127"));
0792     QApplication::postEvent(kate_view->focusProxy(), deleteKeyDown);
0793     QApplication::sendPostedEvents();
0794     QKeyEvent *deleteKeyUp = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Delete, Qt::NoModifier, QStringLiteral("127"));
0795     QApplication::postEvent(kate_view->focusProxy(), deleteKeyUp);
0796     QApplication::sendPostedEvents();
0797     FinishTest("xz");
0798 
0799     // Testing "gu"
0800     DoTest("FOO\nBAR BAZ", "guj", "foo\nbar baz");
0801     DoTest("AbCDF", "gu3l", "abcDF");
0802 
0803     // Testing "guu"
0804     DoTest("FOO", "guu", "foo");
0805     DoTest("FOO\nBAR\nBAZ", "2guu", "foo\nbar\nBAZ");
0806     DoTest("", "guu", "");
0807 
0808     // Testing "gU"
0809     DoTest("aBcdf", "gU2l", "ABcdf");
0810     DoTest("foo\nbar baz", "gUj", "FOO\nBAR BAZ");
0811 
0812     // Testing "gUU"
0813     DoTest("foo", "gUU", "FOO");
0814     DoTest("foo\nbar\nbaz", "2gUU", "FOO\nBAR\nbaz");
0815     DoTest("", "gUU", "");
0816 
0817     // Testing "g~"
0818     DoTest("fOo BAr", "lg~fA", "foO bar");
0819     DoTest("fOo BAr", "$hg~FO", "foO bAr");
0820     DoTest("fOo BAr", "lf~fZ", "fOo BAr");
0821     DoTest("{\nfOo BAr\n}", "jg~iB", "{\nFoO baR\n}");
0822 
0823     // Testing "g~~"
0824     DoTest("", "g~~", "");
0825     DoTest("\nfOo\nbAr", "g~~", "\nfOo\nbAr");
0826     DoTest("fOo\nbAr\nBaz", "g~~", "FoO\nbAr\nBaz");
0827     DoTest("fOo\nbAr\nBaz\nfAR", "j2g~~", "fOo\nBaR\nbAZ\nfAR");
0828     DoTest("fOo\nbAr\nBaz", "jlg~~rX", "fOo\nXaR\nBaz");
0829     DoTest("fOo\nbAr\nBaz\nfAR", "jl2g~~rX", "fOo\nBXR\nbAZ\nfAR");
0830 
0831     // Testing "s"
0832     DoTest("substitute char repeat", "w4scheck\\esc", "substitute check repeat");
0833 
0834     // Testing "r".
0835     DoTest("foobar", "l2r.", "f..bar");
0836     DoTest("foobar", "l5r.", "f.....");
0837     // Do nothing if the count is too high.
0838     DoTest("foobar", "l6r.", "foobar");
0839 
0840     // Testing "Ctrl-o" and "Ctrl-i"
0841     DoTest("abc\ndef\nghi", "Gx\\ctrl-ox", "bc\ndef\nhi");
0842     DoTest("{\n}", "%\\ctrl-ox", "\n}");
0843     DoTest("Foo foo.\nBar bar.\nBaz baz.", "lmajlmb`a`b\\ctrl-ox", "Fo foo.\nBar bar.\nBaz baz.");
0844     DoTest("Foo foo.\nBar bar.\nBaz baz.", "lmajlmb`a`bj\\ctrl-o\\ctrl-ix", "Foo foo.\nBar bar.\nBa baz.");
0845 
0846     // Testing "gq" (reformat) text
0847     DoTest("foo\nbar", "gqq", "foo\nbar");
0848     DoTest("foo\nbar", "2gqq", "foo bar");
0849     DoTest("foo\nbar\nbaz", "jgqj", "foo\nbar baz");
0850     DoTest("foo\nbar\n\n\n", "gqap", "foo bar\n\n\n");
0851 
0852     // when setting the text to wrap at column 10, this should be re-formatted to
0853     // span several lines ...
0854     kate_document->setWordWrapAt(10);
0855     DoTest("foo bar foo bar foo bar", "gqq", "foo bar \nfoo bar \nfoo bar");
0856 
0857     // ... and when re-setting it to column 80 again, they should be joined again
0858     kate_document->setWordWrapAt(80);
0859     DoTest("foo bar\nfoo bar\nfoo bar", "gqG", "foo bar foo bar foo bar");
0860 
0861     // test >> and << (indent and de-indent)
0862     kate_document->config()->setReplaceTabsDyn(true);
0863 
0864     DoTest("foo\nbar", ">>", "  foo\nbar");
0865     DoTest("foo\nbar", "2>>", "  foo\n  bar");
0866     DoTest("foo\nbar", "100>>", "  foo\n  bar");
0867 
0868     DoTest("fop\nbar", "yiwjlgpx", "fop\nbafop");
0869     DoTest("fop\nbar", "yiwjlgPx", "fop\nbfopr");
0870 
0871     DoTest("repeat\nindent", "2>>2>>", "    repeat\n    indent");
0872 
0873     // make sure we record correct history when indenting
0874     DoTest("repeat\nindent and undo", "2>>2>>2>>uu", "  repeat\n  indent and undo");
0875     DoTest("repeat\nunindent and undo", "2>>2>>2<<u", "    repeat\n    unindent and undo");
0876 
0877     // Yank and paste op\ngid into bar i.e. text spanning lines, but not linewise.
0878     DoTest("fop\ngid\nbar", "lvjyjjgpx", "fop\ngid\nbaop\ngi");
0879     DoTest("fop\ngid\nbar", "lvjyjjgPx", "fop\ngid\nbop\ngir");
0880     DoTest("fop\ngid\nbar", "lvjyjjpx", "fop\ngid\nbap\ngir");
0881     DoTest("fop\ngid\nbar", "lvjyjjPx", "fop\ngid\nbp\ngiar");
0882     // Linewise
0883     DoTest("fop\ngid\nbar\nhuv", "yjjjgpx", "fop\ngid\nbar\nfop\ngid\nuv");
0884     DoTest("fop\ngid\nbar\nhuv", "yjjjgPx", "fop\ngid\nfop\ngid\nar\nhuv");
0885     DoTest("fop\ngid", "yjjgpx", "fop\ngid\nfop\nid");
0886     DoTest("fop\ngid\nbar\nhuv", "yjjjPx", "fop\ngid\nop\ngid\nbar\nhuv");
0887 
0888     DoTest("fop\nbar", "yiwjlpx", "fop\nbafor");
0889     DoTest("fop\nbar", "yiwjlPx", "fop\nbfoar");
0890 
0891     // Indented paste.
0892     // ]p behaves as ordinary paste if not linewise, and on unindented line.
0893     DoTest("foo bar", "wyiwgg]p", "fbaroo bar");
0894     // ]p behaves as ordinary paste if not linewise, even on indented line.
0895     DoTest("  foo bar", "wwyiwggw]p", "  fbaroo bar");
0896     // [p behaves as ordinary Paste (P) if not linewise, and on unindented line.
0897     DoTest("foo bar", "wyiwgg[p", "barfoo bar");
0898     // [p behaves as ordinary Paste (P) if not linewise, even on indented line.
0899     DoTest("  foo bar", "wwyiw0w[p", "  barfoo bar");
0900     // Prepend the spaces from the current line to the beginning of a single, pasted line.
0901     DoTest("  foo bar\nxyz", "jVygg]p", "  foo bar\n  xyz\nxyz");
0902     // Prepend the spaces from the current line to the beginning of each pasted line.
0903     DoTest("  foo bar\nxyz\nnose", "jVjygg]p", "  foo bar\n  xyz\n  nose\nxyz\nnose");
0904     const bool oldReplaceTabsDyn = kate_document->config()->replaceTabsDyn();
0905     kate_document->config()->setReplaceTabsDyn(false);
0906     // Tabs as well as spaces!
0907     DoTest("  \tfoo bar\nxyz\nnose", "jVjygg]p", "  \tfoo bar\n  \txyz\n  \tnose\nxyz\nnose");
0908     // Same for [p.
0909     DoTest("  \tfoo bar\nxyz\nnose", "jVjygg[p", "  \txyz\n  \tnose\n  \tfoo bar\nxyz\nnose");
0910     // Test if everything works if the current line has no non-whitespace.
0911     DoTest("\t \nbar", "jVygg]p", "\t \n\t bar\nbar");
0912     // Test if everything works if the current line is empty.
0913     DoTest("\nbar", "jVygg]p", "\nbar\nbar");
0914     // Unindent a pasted indented line if the current line has no indent.
0915     DoTest("foo\n  \tbar", "jVygg]p", "foo\nbar\n  \tbar");
0916     // Unindent subsequent lines, too - TODO - this assumes that each subsequent line has
0917     // *identical* trailing whitespace to the first pasted line: Vim seems to be able to
0918     // deal with cases where this does not hold.
0919     DoTest("foo\n  \tbar\n  \txyz", "jVjygg]p", "foo\nbar\nxyz\n  \tbar\n  \txyz");
0920     DoTest("foo\n  \tbar\n  \t  xyz", "jVjygg]p", "foo\nbar\n  xyz\n  \tbar\n  \t  xyz");
0921     kate_document->config()->setReplaceTabsDyn(oldReplaceTabsDyn);
0922 
0923     // Some special cases of cw/ cW.
0924     DoTest("foo bar", "cwxyz\\esc", "xyz bar");
0925     DoTest("foo+baz bar", "cWxyz\\esc", "xyz bar");
0926     DoTest("foo+baz bar", "cwxyz\\esc", "xyz+baz bar");
0927     DoTest(" foo bar", "cwxyz\\esc", "xyzfoo bar");
0928     DoTest(" foo+baz bar", "cWxyz\\esc", "xyzfoo+baz bar");
0929     DoTest(" foo+baz bar", "cwxyz\\esc", "xyzfoo+baz bar");
0930     DoTest("\\foo bar", "cWxyz\\esc", "xyz bar");
0931     DoTest("foo   ", "lllcwxyz\\esc", "fooxyz");
0932 
0933     DoTest("foo", "yr", "foo");
0934     QCOMPARE(kate_view->renderer()->caretStyle(), KTextEditor::caretStyles::Block);
0935 
0936     // BUG #332523
0937     const bool oldDynWordWrap = KateViewConfig::global()->dynWordWrap();
0938     BeginTest(QStringLiteral("asdasdasd\nasdasdasdasdasdasdasd"));
0939     kate_document->setWordWrap(true);
0940     kate_document->setWordWrapAt(10);
0941     TestPressKey(QStringLiteral("Jii"));
0942     FinishTest("iasdasdasd\n \nasdasdasda \nsdasdasdas \nd");
0943     kate_document->setWordWrap(oldDynWordWrap);
0944 }
0945 
0946 void ModesTest::NormalControlTests()
0947 {
0948     // Testing "Ctrl-x"
0949     DoTest("150", "101\\ctrl-x", "49");
0950     DoTest("1", "\\ctrl-x\\ctrl-x\\ctrl-x\\ctrl-x", "-3");
0951     DoTest("0xabcdef", "1000000\\ctrl-x", "0x9c8baf");
0952     DoTest("0x0000f", "\\ctrl-x", "0x0000e");
0953     // Octal numbers should retain leading 0's.
0954     DoTest("00010", "\\ctrl-x", "00007");
0955 
0956     // Testing "Ctrl-a"
0957     DoTest("150", "101\\ctrl-a", "251");
0958     DoTest("1000", "\\ctrl-ax", "100");
0959     DoTest("-1", "1\\ctrl-a", "0");
0960     DoTest("-1", "l1\\ctrl-a", "0");
0961     DoTest("0x0000f", "\\ctrl-a", "0x00010");
0962     // Decimal with leading 0's - increment, and strip leading 0's, like Vim.
0963     DoTest("0000193", "\\ctrl-a", "194");
0964     // If a number begins with 0, parse it as octal if we can. The resulting number should retain the
0965     // leadingi 0.
0966     DoTest("07", "\\ctrl-a", "010");
0967     DoTest("5", "5\\ctrl-a.", "15");
0968     DoTest("5", "5\\ctrl-a2.", "12");
0969     DoTest("5", "5\\ctrl-a2.10\\ctrl-a", "22");
0970     DoTest(" 5 ", "l\\ctrl-ax", "  ");
0971     // If there's no parseable number under the cursor, look to the right to see if we can find one.
0972     DoTest("aaaa0xbcX", "\\ctrl-a", "aaaa0xbdX");
0973     DoTest("1 1", "l\\ctrl-a", "1 2");
0974     // We can skip across word boundaries in our search if need be.
0975     DoTest("aaaa 0xbcX", "\\ctrl-a", "aaaa 0xbdX");
0976     // If we can't find a parseable number anywhere, don't change anything.
0977     DoTest("foo", "\\ctrl-a", "foo");
0978     // Don't hang if the cursor is at the end of the line and the only number is to the immediate left of the cursor.
0979     DoTest("1 ", "l\\ctrl-a", "1 ");
0980     // ctrl-a/x algorithm involves stepping back to the previous word: don't crash if this is on the previous line
0981     // and at a column greater than the length of the current line.
0982     DoTest(" a a\n1", "j\\ctrl-a", " a a\n2");
0983     DoTest(" a a    a\n  1", "jll\\ctrl-a", " a a    a\n  2");
0984     // Regression test.
0985     DoTest("1w3", "l\\ctrl-a", "1w4");
0986 
0987     // Test "Ctrl-a/x" on a blank document/ blank line.
0988     DoTest("", "\\ctrl-a", "");
0989     DoTest("", "\\ctrl-x", "");
0990     DoTest("foo\n", "j\\ctrl-x", "foo\n");
0991     DoTest("foo\n", "j\\ctrl-a", "foo\n");
0992 
0993     // Testing "Ctrl-r"
0994     DoTest("foobar", "d3lu\\ctrl-r", "bar");
0995     DoTest("line 1\nline 2\n", "ddu\\ctrl-r", "line 2\n");
0996 }
0997 
0998 void ModesTest::NormalNotYetImplementedFeaturesTests()
0999 {
1000     QSKIP("This tests never worked :(", SkipAll);
1001 
1002     // Testing "))"
1003     DoTest("Foo foo. Bar bar.", "))\\ctrl-ox", "Foo foo. ar bar.");
1004     DoTest("Foo foo.\nBar bar.\nBaz baz.", ")))\\ctrl-ox\\ctrl-ox", "Foo foo.\nar bar.\nBaz baz.");
1005     DoTest("Foo foo.\nBar bar.\nBaz baz.", "))\\ctrl-ox\\ctrl-ix", "Foo foo.\nBar bar.\naz baz.");
1006     DoTest("Foo foo.\nBar bar.\nBaz baz.", "))\\ctrl-ox\\ctrl-ix", "Foo foo.\nBar bar.\naz baz.");
1007 }
1008 
1009 // END: Normal mode.
1010 
1011 // BEGIN: Insert mode.
1012 
1013 void ModesTest::InsertTests()
1014 {
1015     // Basic stuff.
1016     DoTest("bar", "s\\ctrl-c", "ar");
1017     DoTest("bar", "ls\\ctrl-cx", "r");
1018     DoTest("foo\nbar", "S\\ctrl-c", "\nbar");
1019     DoTest("baz bar", "lA\\ctrl-cx", "baz ba");
1020     DoTest("baz bar", "la\\ctrl-cx", "bz bar");
1021     DoTest("foo\nbar\nbaz", "C\\ctrl-c", "\nbar\nbaz");
1022     DoTest("foo bar baz", "c2w\\ctrl-c", " baz");
1023     DoTest("foo\nbar\nbaz", "jo\\ctrl-c", "foo\nbar\n\nbaz");
1024     DoTest("foo\nbar\nbaz", "jO\\ctrl-c", "foo\n\nbar\nbaz");
1025     DoTest("foo\nbar", "O\\ctrl-c", "\nfoo\nbar");
1026     DoTest("foo\nbar", "o\\ctrl-c", "foo\n\nbar");
1027     DoTest("foo bar", "wlI\\ctrl-cx", "oo bar");
1028     DoTest("foo bar", "wli\\ctrl-cx", "foo ar");
1029     DoTest("foo bar", "wlihello\\ctrl-c", "foo bhelloar");
1030 
1031     // With count.
1032     DoTest("", "5ihello\\esc", "hellohellohellohellohello");
1033     DoTest("bar", "5ahello\\esc", "bhellohellohellohellohelloar");
1034     DoTest("   bar", "5Ihello\\esc", "   hellohellohellohellohellobar");
1035     DoTest("bar", "5Ahello\\esc", "barhellohellohellohellohello");
1036     DoTest("", "5ihello\\ctrl-c", "hello");
1037     DoTest("bar", "5ohello\\esc", "bar\nhello\nhello\nhello\nhello\nhello");
1038     DoTest("bar", "5Ohello\\esc", "hello\nhello\nhello\nhello\nhello\nbar");
1039     DoTest("bar", "Ohello\\escu", "bar");
1040     DoTest("bar", "5Ohello\\escu", "bar");
1041     DoTest("bar", "ohello\\escu", "bar");
1042     DoTest("bar", "5ohello\\escu", "bar");
1043     DoTest("foo\nbar", "j5Ohello\\esc", "foo\nhello\nhello\nhello\nhello\nhello\nbar");
1044     DoTest("bar", "5ohello\\esc2ixyz\\esc", "bar\nhello\nhello\nhello\nhello\nhellxyzxyzo");
1045     DoTest("", "ihello\\esc5.", "hellhellohellohellohellohelloo");
1046 
1047     // Ensure that the flag that says that counted repeats should begin on a new line is reset.
1048     DoTest("foo", "obar\\ctrl-c5ixyz\\esc", "foo\nbaxyzxyzxyzxyzxyzr");
1049     DoTest("foo", "obar\\ctrl-cgg\\ctrl-vlljAxyz\\esc5i123\\esc", "fooxy123123123123123z\nbarxyz");
1050     DoTest("foo foo foo", "c3wbar\\esc", "bar");
1051     DoTest("abc", "lOxyz", "xyz\nabc");
1052 
1053     // Test that our test driver can handle newlines during insert mode :)
1054     DoTest("", "ia\\returnb", "a\nb");
1055 }
1056 
1057 void ModesTest::InsertKeysTests()
1058 {
1059     // Ctrl-w
1060     DoTest("foobar", "$i\\ctrl-w", "r");
1061     DoTest("foobar\n", "A\\ctrl-w", "\n");
1062     DoTest("   foo", "i\\ctrl-wX\\esc", "X   foo");
1063     DoTest("   foo", "lli\\ctrl-wX\\esc", "X foo");
1064 
1065     // Ctrl-u
1066     DoTest("", "i\\ctrl-u", "");
1067     DoTest("foobar", "i\\ctrl-u", "foobar");
1068     DoTest("foobar", "fbi\\ctrl-u", "bar");
1069     DoTest("foobar\nsecond", "ji\\ctrl-u", "foobarsecond");
1070     DoTest("foobar\n  second", "jwi\\ctrl-u", "foobar\nsecond");
1071     DoTest("foobar\n  second", "jfci\\ctrl-u", "foobar\n  cond");
1072     DoTest("foobar\n  second", "j$a\\ctrl-u", "foobar\n  ");
1073 
1074     // Ctrl-e
1075     DoTest("foo\nbar", "i\\ctrl-e", "bfoo\nbar");
1076     DoTest("foo\nbar", "i\\ctrl-e\\ctrl-e\\ctrl-e", "barfoo\nbar");
1077     DoTest("foo\nb", "i\\ctrl-e\\ctrl-e", "bfoo\nb");
1078 
1079     // Ctrl-y
1080     DoTest("foo\nbar", "ji\\ctrl-y", "foo\nfbar");
1081     DoTest("foo\nbar", "ji\\ctrl-y\\ctrl-y\\ctrl-y", "foo\nfoobar");
1082     DoTest("f\nbar", "ji\\ctrl-y\\ctrl-y", "f\nfbar");
1083 
1084     // Ctrl-R
1085     DoTest("barbaz", "\"ay3li\\ctrl-ra", "barbarbaz");
1086     DoTest("barbaz", "\"ay3li\\ctrl-raX", "barXbarbaz");
1087     DoTest("bar\nbaz", "\"byylli\\ctrl-rb", "bar\nbar\nbaz");
1088     DoTest("Hello", "0yei\\ctrl-r\"", "HelloHello");
1089 
1090     // Ctrl-O
1091     DoTest("foo bar baz", "3li\\ctrl-od2w", "foobaz");
1092     DoTest("foo bar baz", "3li\\ctrl-od2w\\ctrl-w", "baz");
1093     DoTest("foo bar baz", "i\\ctrl-o3l\\ctrl-w", " bar baz");
1094     DoTest("foo\nbar\nbaz", "li\\ctrl-oj\\ctrl-w\\ctrl-oj\\ctrl-w", "foo\nar\naz");
1095 
1096     // Test that the text written after the Ctrl-O command completes is treated as
1097     // an insertion of text (rather than a sequence of commands) when repeated via "."
1098     DoTest("", "isausage\\ctrl-obugo\\esc.", "ugugoosausage");
1099 
1100     // 'Step back' on Ctrl-O if at the end of the line
1101     DoTest("foo bar baz", "A\\ctrl-ox", "foo bar ba");
1102 
1103     // Paste acts as gp when executing in a Ctrl-O
1104     DoTest("foo bar baz", "yiwea\\ctrl-opd", "foo foodbar baz");
1105     DoTest("bar", "A\\ctrl-o\\ctrl-chx", "br");
1106     DoTest("bar", "A\\ctrl-o\\eschx", "br");
1107 
1108     // Ctrl-D & Ctrl-T
1109     DoTest("foo", "i\\ctrl-t", "  foo");
1110     DoTest(" foo", "i\\ctrl-d", "foo");
1111     DoTest("foo\nbar", "i\\ctrl-t\\ctrl-d", "foo\nbar");
1112 
1113     // Ctrl-H
1114     DoTest("foo", "i\\ctrl-h", "foo");
1115     DoTest(" foo", "li\\ctrl-h", "foo");
1116     DoTest("foo\nbar", "ji\\ctrl-h", "foobar");
1117     DoTest("1234567890", "A\\ctrl-h\\ctrl-h\\ctrl-h\\ctrl-h\\ctrl-h", "12345");
1118     DoTest("1\n2\n3", "GA\\ctrl-h\\ctrl-h\\ctrl-h\\ctrl-h", "1");
1119 
1120     // Ctrl-J
1121     DoTest("foo", "i\\ctrl-j", "\nfoo");
1122     DoTest("foo", "lli\\ctrl-j", "fo\no");
1123     DoTest("foo\nbar", "ji\\ctrl-j", "foo\n\nbar");
1124     DoTest("foobar", "A\\ctrl-j", "foobar\n");
1125     DoTest("foobar", "li\\ctrl-j\\ctrl-cli\\ctrl-j\\ctrl-cli\\ctrl-j\\ctrl-cli\\ctrl-j\\ctrl-cli\\ctrl-j\\ctrl-c", "f\no\no\nb\na\nr");
1126 
1127     // Ctrl-left & Ctrl-right.
1128     DoTest("foo bar", "i\\ctrl-\\rightX\\esc", "foo Xbar");
1129     DoTest("foo bar", "i\\ctrl-\\right\\ctrl-\\rightX\\esc", "foo barX");
1130     DoTest("foo", "\\endi\\ctrl-\\left\\ctrl-\\leftX", "Xfoo"); // we crashed here before
1131 
1132     // Special keys: enter, return, insert, etc.
1133     DoTest("", "ifoo\\enterbar", "foo\nbar");
1134     DoTest("", "ifoo\\returnbar", "foo\nbar");
1135     DoTest("", "\\insertfoo", "foo");
1136     DoTest("foo bar", "i\\home\\delete", "oo bar");
1137 
1138     // BUG #451076, don't want an extra newline when using the "Find" action from the menu or Ctrl-F
1139     BaseTest::ensureKateViewVisible(); // required for the bug to trigger
1140     BeginTest(QStringLiteral("foobar"));
1141     TestPressKey(QStringLiteral("i"));
1142     kate_view->find();
1143     TestPressKey(QStringLiteral("bar\\return"));
1144     // ensure the cursor is at 'foo_b_ar'
1145     QCOMPARE(kate_view->cursorPosition().line(), 0);
1146     QCOMPARE(kate_view->cursorPosition().column(), 3);
1147     FinishTest("foobar");
1148     // hide the view again
1149     kate_view->hide();
1150     mainWindow->hide();
1151 }
1152 
1153 // END: Insert mode.
1154 
1155 // BEGIN: Visual mode.
1156 
1157 void ModesTest::VisualMotionsTests()
1158 {
1159     // Basic motions.
1160     DoTest("\n", "vjcX", "X");
1161     DoTest("foobar", "vlllx", "ar");
1162     DoTest("foo\nbar", "Vd", "bar");
1163     DoTest("Hello.\nWorld", "2lvjcX", "HeXld");
1164     DoTest("Three. Different. Sentences.\n\n", "vapcX", "X");
1165     DoTest("1234\n1234\n1234", "l\\ctrl-vljjd", "14\n14\n14");
1166     QCOMPARE(kate_view->blockSelection(), false);
1167     DoTest("Three. Different. Sentences.", "v)cX", "Xifferent. Sentences.");
1168     DoTest("Three. Different. Sentences.", "v)cX", "Xifferent. Sentences.");
1169     DoTest("Three. Different. Sentences.", "v)cX", "Xifferent. Sentences.");
1170     DoTest("Three. Different. Sentences.", "viWcX", "X Different. Sentences.");
1171     DoTest("Three. Different. Sentences.", "viwcX", "X. Different. Sentences.");
1172     DoTest("Three. Different. Sentences.", "vaWcX", "XDifferent. Sentences.");
1173     DoTest("Three. Different. Sentences.", "vawcX", "X. Different. Sentences.");
1174     DoTest("Three. Different. Sentences.", "vascX", "XDifferent. Sentences.");
1175     DoTest("Three. Different. Sentences.", "viscX", "X Different. Sentences.");
1176     DoTest("Three. Different. Sentences.", "vapcX", "X");
1177     DoTest("Three. Different. Sentences.", "vipcX", "X");
1178     DoTest("Hello.\n", "vap\\esciX", "Hello.\nX");
1179     // Make sure cursor is properly moved to the start of paragraph and sentence text objects
1180     DoTest("Hello.\nWorld.", "jvapX", "");
1181     DoTest("Hello.\nWorld.", "jvasX", "Hello.\n");
1182 
1183     // With count.
1184     DoTest("12345678", "lv3lyx", "1345678");
1185     DoTest("12345678", "$hv3hyx", "1235678");
1186     DoTest("aaa\nbbb", "lvj~x", "aA\nBBb");
1187     DoTest("123\n456", "jlvkyx", "13\n456");
1188     DoTest("12\n34", "lVjyx", "2\n34");
1189     DoTest("ab\ncd", "jVlkgux", "a\ncd");
1190     DoTest("ABCD\nABCD\nABCD\nABCD", "lj\\ctrl-vjlgux", "ABCD\nAcD\nAbcD\nABCD");
1191     DoTest("abcd\nabcd\nabcd\nabcd", "jjjlll\\ctrl-vkkhgUx", "abcd\nabD\nabCD\nabCD");
1192 
1193     // Cancelling visual mode should not reset the cursor.
1194     DoTest("12345678", "lv3l\\escx", "1234678");
1195     DoTest("12345678", "lv3l\\ctrl-cx", "1234678");
1196 
1197     // Don't forget to clear the flag that says we shouldn't reset the cursor, though!
1198     DoTest("12345678", "lv3l\\ctrl-cxv3lyx", "123478");
1199     DoTest("12345678", "y\\escv3lyx", "2345678");
1200 
1201     // Regression test for ][ in Visual Mode.
1202     DoTest("foo {\n\n}", "lV][d", "");
1203 
1204     // Misc tests for motions starting in front of the Visual Mode start point.
1205     DoTest("{foo}", "lvb%x", "{");
1206     DoTest("foo bar", "wvbfax", "foo r");
1207     DoTest("(foo bar)", "wwv^%x", "(foo ");
1208 
1209     // * and #
1210     DoTest("foo foo", "v*x", "oo");
1211     DoTest("foo foo", "wv#x", "oo");
1212 
1213     // Quick test that "{" and "}" motions work in visual mode
1214     DoTest("foo\n\n\nbar\n", "v}}d", "");
1215     DoTest("\n\nfoo\nbar\n", "jjjv{d", "\nar\n");
1216 
1217     // ctrl-left and ctrl-right
1218     DoTest("foo bar xyz", "v\\ctrl-\\rightd", "ar xyz");
1219     DoTest("foo bar xyz", "$v\\ctrl-\\leftd", "foo bar ");
1220 }
1221 
1222 void ModesTest::VisualCommandsTests()
1223 {
1224     // Testing "d"
1225     DoTest("foobarbaz", "lvlkkjl2ld", "fbaz");
1226     DoTest("foobar", "v$d", "");
1227     DoTest("foo\nbar\nbaz", "jVlld", "foo\nbaz");
1228     DoTest("01\n02\n03\n04\n05", "Vjdj.", "03");
1229 
1230     // Testing Del key
1231     DoTest("foobarbaz", "lvlkkjl2l\\delete", "fbaz");
1232 
1233     // Testing "D"
1234     DoTest("foo\nbar\nbaz", "lvjlD", "baz");
1235     DoTest("foo\nbar", "l\\ctrl-vjD", "f\nb");
1236     DoTest("foo\nbar", "VjkD", "bar");
1237     DoTest("Test:\n  - One\n  - Two", "jfnVDia", "Test:\n  a- Two");
1238     DoTest("Test:\n  - One\n  - Two", "jjfwVDia", "Test:\n  a- One");
1239 
1240     // Testing "gU", "U"
1241     DoTest("foo bar", "vwgU", "FOO Bar");
1242     DoTest("foo\nbar\nbaz", "VjjU", "FOO\nBAR\nBAZ");
1243     DoTest("foo\nbar\nbaz", "\\ctrl-vljjU", "FOo\nBAr\nBAz");
1244     DoTest("aaaa\nbbbb\ncccc", "\\ctrl-vljgUjll.", "AAaa\nBBBB\nccCC");
1245 
1246     // Testing "gu", "u"
1247     DoTest("TEST", "Vgu", "test");
1248     DoTest("TeSt", "vlgu", "teSt");
1249     DoTest("FOO\nBAR\nBAZ", "\\ctrl-vljju", "foO\nbaR\nbaZ");
1250     DoTest("AAAA\nBBBB\nCCCC\nDDDD", "vjlujjl.", "aaaa\nbbBB\nCccc\ndddD");
1251 
1252     // Testing "gv"
1253     DoTest("foo\nbar\nxyz", "l\\ctrl-vjj\\ctrl-cgvr.", "f.o\nb.r\nx.z");
1254 
1255     // Testing "g~"
1256     DoTest("fOo bAr", "Vg~", "FoO BaR");
1257     DoTest("foo\nbAr\nxyz", "l\\ctrl-vjjg~", "fOo\nbar\nxYz");
1258 
1259     // Testing "y"
1260     DoTest("foobar", "Vypp", "foobar\nfoobar\nfoobar");
1261     DoTest("foo\nbar", "lvjlyp", "fooo\nbaro\nbar");
1262     DoTest("foo\nbar", "Vjlllypddxxxdd", "foo\nbar");
1263     DoTest("12\n12", "\\ctrl-vjyp", "112\n112");
1264     DoTest("1234\n1234\n1234\n1234", "lj\\ctrl-vljyp", "1234\n122334\n122334\n1234");
1265 
1266     // Testing "Y"
1267     DoTest("foo\nbar", "llvjypx", "foo\nbar\nbar");
1268     DoTest("foo\nbar", "VYp", "foo\nfoo\nbar");
1269 
1270     // Testing "m."
1271     DoTest("foo\nbar", "vljmavgg`ax", "foo\nbr");
1272     DoTest("1\n2\n3\n4", "Vjmajjmb\\:'a,'bd\\", "1");
1273 
1274     // Testing ">"
1275     DoTest("foo\nbar", "vj>", "  foo\n  bar");
1276     DoTest("foo\nbar\nbaz", "jVj>", "foo\n  bar\n  baz");
1277     DoTest("foo", "vl3>", "      foo");
1278     DoTest("indent\nrepeat", "V>.", "    indent\nrepeat");
1279     DoTest("indent\nrepeat", "Vj>.", "    indent\n    repeat");
1280     DoTest("indent\nrepeat\non\nothers", "Vj>jj.", "  indent\n  repeat\n  on\n  others");
1281     DoTest("foo\nbar\nbaz", "jjVk>.", "foo\n    bar\n    baz");
1282 
1283     // Testing "<"
1284     DoTest(" foo", "vl<", "foo");
1285     DoTest("foo\n    bar\n    baz", "jjVk<.", "foo\nbar\nbaz");
1286 
1287     // Testing "o"
1288     DoTest("foobar", "lv2lo2ld", "fooar");
1289     DoTest("foo\nbar", "jvllokld", "f");
1290     DoTest("12\n12", "\\ctrl-vjlold", "1\n1");
1291 
1292     // Testing "~"
1293     DoTest("foobar", "lv2l~", "fOOBar");
1294     DoTest("FooBar", "V~", "fOObAR");
1295     DoTest("foo\nbar", "\\ctrl-vjl~", "FOo\nBAr");
1296 
1297     // Testing "r"
1298     DoTest("foobar", "Vra", "aaaaaa");
1299     DoTest("foo\nbar", "jlvklrx", "fox\nxxr");
1300     DoTest("123\n123", "l\\ctrl-vljrx", "1xx\n1xx");
1301     DoTest("a", "r\\ctrl-c", "a");
1302     DoTest("a", "r\\ctrl-[", "a");
1303     DoTest("a", "r\\keypad-0", "0");
1304     DoTest("a", "r\\keypad-9", "9");
1305     DoTest("foo\nbar", "l\\ctrl-vjr\\keypad-9", "f9o\nb9r");
1306 
1307     // Testing "gq"
1308     DoTest("foo\nbar\nbaz", "Vgq", "foo\nbar\nbaz");
1309     DoTest("foo\nbar\nbaz", "Vjgq", "foo bar\nbaz");
1310 
1311     // Testing "<<"/">>"
1312     kate_document->config()->setReplaceTabsDyn(true);
1313     DoTest("foo\nbar\nbaz", "V>>", "  foo\nbar\nbaz");
1314     DoTest("foo\nbar\nbaz", "Vj>>", "  foo\n  bar\nbaz");
1315     DoTest("foo\nbar\nbaz", "V2j>>", "  foo\n  bar\n  baz");
1316     DoTest("foo\nbar\nbaz", "V10>>", "                    foo\nbar\nbaz");
1317     DoTest("foo\nbar\nbaz", "V2j3>>", "      foo\n      bar\n      baz");
1318 
1319     DoTest("  foo\nbar\nbaz", "V<<", "foo\nbar\nbaz");
1320     DoTest("foo\nbar\nbaz", "V>>V<<", "foo\nbar\nbaz");
1321     DoTest("    foo\n    bar\n    baz", "V2j<<", "  foo\n  bar\n  baz");
1322 
1323     // Testing block append
1324     DoTest("averyverylongline\nshortline\nshorter\n", "jjV$kkAb\\esc", "averyverylonglineb\nshortlineb\nshorterb\n");
1325     DoTest("averyverylongline\nshortline\n", "V$jAb\\esc", "averyverylonglineb\nshortlineb\n");
1326 
1327     // Testing "J"
1328     DoTest("foo\nbar\nxyz\nbaz\n123\n456", "jVjjjJ", "foo\nbar xyz baz 123\n456");
1329     DoTest("foo\nbar\nxyz\nbaz\n123\n456", "jjjjVkkkJ", "foo\nbar xyz baz 123\n456");
1330     DoTest("foo\nbar\nxyz\nbaz\n123456\n789", "jjjjVkkkJrX", "foo\nbar xyz bazX123456\n789");
1331     DoTest("foo\nbar\nxyz\n", "VGJ", "foo bar xyz ");
1332 
1333     // Testing undo behaviour with c and cc
1334     DoTest("foo", "ciwbar\\escu", "foo");
1335     DoTest("foo", "ccbar\\escu", "foo");
1336 
1337     // Pasting should replace the current selection.
1338     DoTest("foo bar xyz", "yiwwviwp", "foo foo xyz");
1339 
1340     // Undo should undo both paste and removal of selection.
1341     DoTest("foo bar xyz", "yiwwviwpu", "foo bar xyz");
1342     DoTest("foo\nbar\n123\nxyz", "yiwjVjp", "foo\nfoo\nxyz");
1343 
1344     // Set the *whole* selection to the given text object, even if the cursor is no
1345     // longer at the position where Visual Mode was started.
1346     // This seems to work (in Vim) only when the start of the given text object occurs before them
1347     // start position of Visual Mode.
1348     DoTest("{\nfoo\nbar\nxyz\n}", "jjvliBd", "{\n}");
1349     DoTest("foo[hello]", "fhlvli[d", "foo[]");
1350     DoTest("foo(hello)", "fhlvli(d", "foo()");
1351     DoTest("foo<hello>", "fhlvli<d", "foo<>");
1352     DoTest("foo\"hello\"", "fhlvli\"d", "foo\"\"");
1353     DoTest("foo'hello'", "fhlvli'd", "foo''");
1354 
1355     // A couple of spot tests, where the beginning of the text object occurs after the start position of Visual Mode;
1356     // the selection should  remain unchanged if we the text object motion is triggered, here.
1357     DoTest("foobarxyz\n(12345)", "llvjibd", "fo345)");
1358     DoTest("foobarxyz\n{12345}", "llvjiBd", "fo345}");
1359     // Cursor should end up at the end of the text object.
1360     DoTest("foo[hello]", "fhlvli[\\escrX", "foo[hellX]");
1361     // Ensure we reset the flag that says that the current motion is a text object!
1362     DoTest("foo[hello]", "jfhlvli[^d", "ello]");
1363 
1364     // proper yanking in block mode
1365     {
1366         BeginTest(QStringLiteral("aaaa\nbbbb\ncccc\ndddd"));
1367         TestPressKey(QStringLiteral("lj\\ctrl-vljy"));
1368         KateBuffer &buffer = kate_document->buffer();
1369         QList<Kate::TextRange *> ranges = buffer.rangesForLine(1, kate_view, true);
1370         QCOMPARE(ranges.size(), 1);
1371         KTextEditor::Range range = ranges[0]->toRange();
1372         QCOMPARE(range.start().column(), 1);
1373         QCOMPARE(range.end().column(), 3);
1374     }
1375 
1376     // proper selection in block mode after switching to cmdline
1377     {
1378         BeginTest(QStringLiteral("aaaa\nbbbb\ncccc\ndddd"));
1379         TestPressKey(QStringLiteral("lj\\ctrl-vlj:"));
1380         QCOMPARE(kate_view->selectionText(), QStringLiteral("bb\ncc"));
1381     }
1382 
1383     // BUG #328277 - make sure kate doesn't crash
1384     BeginTest(QStringLiteral("aaa\nbbb"));
1385     TestPressKey(QStringLiteral("Vj>u>."));
1386     QCOMPARE(kate_view->renderer()->caretStyle(), KTextEditor::caretStyles::Block);
1387     FinishTest("aaa\nbbb");
1388 }
1389 
1390 void ModesTest::VisualExternalTests()
1391 {
1392     // Test that selecting a range "externally" to Vim (i.e. via the mouse, or
1393     // one of the ktexteditor api's) switches us into Visual Mode.
1394     BeginTest(QStringLiteral("foo bar"));
1395 
1396     // Actually selects "oo " (i.e. without the "b").
1397     kate_view->setSelection(Range(0, 1, 0, 4));
1398     TestPressKey(QStringLiteral("d"));
1399     FinishTest("fbar");
1400 
1401     // Always return to normal mode when undoing/redoing.
1402     BeginTest(QLatin1String(""));
1403     TestPressKey(QStringLiteral("iHello World!\\esc"));
1404     TestPressKey(QStringLiteral("0wvlldu"));
1405     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::NormalMode);
1406     QCOMPARE(kate_view->selectionText(), QLatin1String(""));
1407     QCOMPARE(kate_document->text(), QStringLiteral("Hello World!"));
1408     TestPressKey(QStringLiteral("u"));
1409     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::NormalMode);
1410     QCOMPARE(kate_document->text(), QLatin1String(""));
1411     TestPressKey(QStringLiteral("\\ctrl-r"));
1412     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::NormalMode);
1413     FinishTest("Hello World!");
1414 
1415     // Make sure that we don't screw up selection after an undo.
1416     BeginTest(QStringLiteral("Hola\nHola\nHello\nHallo\n"));
1417     TestPressKey(QStringLiteral("jVjduVk"));
1418     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::VisualLineMode);
1419     QCOMPARE(kate_view->selectionText(), QStringLiteral("Hola\nHello"));
1420     FinishTest("Hola\nHola\nHello\nHallo\n");
1421 
1422     // Test that, if kate_view has a selection before the Vi mode stuff is loaded, then we
1423     // end up in Visual Mode: this mimics what happens if we click on a Find result in
1424     // KDevelop's "grepview" plugin.
1425     delete kate_view;
1426     kate_view = new KTextEditor::ViewPrivate(kate_document, mainWindow);
1427     kate_view->setInputMode(View::NormalInputMode);
1428     mainWindowLayout->addWidget(kate_view);
1429     kate_document->setText(QStringLiteral("foo bar"));
1430     kate_view->setSelection(Range(Cursor(0, 1), Cursor(0, 4)));
1431     QCOMPARE(kate_document->text(kate_view->selectionRange()), QStringLiteral("oo "));
1432     kate_view->setInputMode(View::ViInputMode);
1433     qDebug() << "selected: " << kate_document->text(kate_view->selectionRange());
1434     QVERIFY(kate_view->currentInputMode()->viewInputMode() == View::ViInputMode);
1435     vi_input_mode = static_cast<KateViInputMode *>(kate_view->currentInputMode());
1436     vi_input_mode_manager = vi_input_mode->viInputModeManager();
1437     QVERIFY(vi_input_mode_manager->getCurrentViMode() == KateVi::VisualMode);
1438     TestPressKey(QStringLiteral("l"));
1439     QCOMPARE(kate_document->text(kate_view->selectionRange()), QStringLiteral("oo b"));
1440     TestPressKey(QStringLiteral("d"));
1441     QCOMPARE(kate_document->text(), QStringLiteral("far"));
1442 
1443     // Test returning to correct mode when selecting ranges with mouse
1444     BeginTest(QStringLiteral("foo bar\nbar baz"));
1445     TestPressKey(QStringLiteral("i")); // get me into insert mode
1446     kate_view->setSelection(Range(0, 1, 1, 4));
1447     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::VisualMode);
1448     kate_view->setSelection(Range::invalid());
1449     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::InsertMode);
1450     TestPressKey(QStringLiteral("\\esc")); // get me into normal mode
1451     kate_view->setSelection(Range(0, 1, 1, 4));
1452     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::VisualMode);
1453     kate_view->setSelection(Range::invalid());
1454     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::NormalMode);
1455 }
1456 
1457 // END: Visual mode.
1458 
1459 // BEGIN: Command mode.
1460 
1461 void ModesTest::CommandTests()
1462 {
1463     // Testing ":<num>"
1464     DoTest("foo\nbar\nbaz", "\\:2\\x", "foo\nar\nbaz");
1465     DoTest("foo\nbar\nbaz", "jmak\\:'a\\x", "foo\nar\nbaz");
1466     DoTest("foo\nbar\nbaz", "\\:$\\x", "foo\nbar\naz");
1467 
1468     // Testing ":y", ":yank"
1469     DoTest("foo\nbar\nbaz", "\\:3y\\p", "foo\nbaz\nbar\nbaz");
1470     DoTest("foo\nbar\nbaz", "\\:2y a 2\\\"ap", "foo\nbar\nbaz\nbar\nbaz");
1471     DoTest("foo\nbar\nbaz", "\\:y\\p", "foo\nfoo\nbar\nbaz");
1472     DoTest("foo\nbar\nbaz", "\\:3,1y\\p", "foo\nfoo\nbar\nbaz\nbar\nbaz");
1473 
1474     // Testing ">"
1475     DoTest("foo", "\\:>\\", "  foo");
1476     DoTest("   foo", "\\:<\\", "  foo");
1477 
1478     DoTest("foo\nbar", "\\:2>\\", "foo\n  bar");
1479     DoTest("   foo\nbaz", "\\:1<\\", "  foo\nbaz");
1480 
1481     DoTest("foo\nundo", "\\:2>\\u", "foo\nundo");
1482     DoTest("  foo\nundo", "\\:1<\\u", "  foo\nundo");
1483 
1484     DoTest("indent\nmultiline\ntext", "\\:1,2>\\", "  indent\n  multiline\ntext");
1485     DoTest("indent\nmultiline\n+undo", "\\:1,2>\\:1,2>\\:1,2>\\u", "    indent\n    multiline\n+undo");
1486     // doesn't test correctly, why?
1487     // DoTest("indent\nmultiline\n+undo", "\\:1,2>\\:1,2<\\u", "  indent\n  multiline\n+undo");
1488 
1489     // Testing ":c", ":change"
1490     DoTest("foo\nbar\nbaz", "\\:2change\\", "foo\n\nbaz");
1491     DoTest("foo\nbar\nbaz", "\\:%c\\", "");
1492     BeginTest(QStringLiteral("foo\nbar\nbaz"));
1493     TestPressKey(QStringLiteral("\\:$c\\")); // Work around ambiguity in the code that parses commands to execute.
1494     TestPressKey(QStringLiteral("\\:$change\\"));
1495     FinishTest("foo\nbar\n");
1496     DoTest("foo\nbar\nbaz", "ma\\:2,'achange\\", "\nbaz");
1497     DoTest("foo\nbar\nbaz", "\\:2,3c\\", "foo\n");
1498 
1499     // Testing ":j"
1500     DoTest("1\n2\n3\n4\n5", "\\:2,4j\\", "1\n2 3 4\n5");
1501 
1502     DoTest("1\n2\n3\n4", "jvj\\ctrl-c\\:'<,'>d\\enter", "1\n4");
1503     DoTest("1\n2\n3\n4", "\\:1+1+1+1d\\", "1\n2\n3");
1504     DoTest("1\n2\n3\n4", "2j\\:.,.-1d\\", "1\n4");
1505     DoTest("1\n2\n3\n4", "\\:.+200-100-100+20-5-5-5-5+.-.,$-1+1-2+2-3+3-4+4-5+5-6+6-7+7-1000+1000+0-0-$+$-.+.-1d\\", "4");
1506     DoTest("1\n2\n3\n4", "majmbjmcjmdgg\\:'a+'b+'d-'c,.d\\", "");
1507 }
1508 
1509 void ModesTest::CommandSedTests()
1510 {
1511     DoTest("foo", "\\:s/foo/bar\\", "bar");
1512     DoTest("foobarbaz", "\\:s/bar/xxx\\", "fooxxxbaz");
1513     DoTest("foo", "\\:s/bar/baz\\", "foo");
1514     DoTest("foo\nfoo\nfoo", "j\\:s/foo/bar\\", "foo\nbar\nfoo");
1515     DoTest("foo\nfoo\nfoo", "2jma2k\\:'a,'as/foo/bar\\", "foo\nfoo\nbar");
1516     DoTest("foo\nfoo\nfoo", "\\:%s/foo/bar\\", "bar\nbar\nbar");
1517     DoTest("foo\nfoo\nfoo", "\\:2,3s/foo/bar\\", "foo\nbar\nbar");
1518     DoTest("foo\nfoo\nfoo\nfoo", "j2lmajhmbgg\\:'a,'bs/foo/bar\\", "foo\nbar\nbar\nfoo");
1519     DoTest("foo\nfoo\nfoo\nfoo", "jlma2jmbgg\\:'b,'as/foo/bar\\", "foo\nbar\nbar\nbar");
1520     DoTest("foo", "\\:s/$/x/g\\", "foox");
1521     DoTest("foo", "\\:s/.*/x/g\\", "x");
1522     DoTest("abc", "\\:s/\\\\s*/x/g\\", "xaxbxc");
1523     // DoTest("abc\n123", "\\:s/\\\\s*/x/g\\", "xaxbxc\nx1x2x3"); // currently not working properly
1524 
1525     DoTest("foo/bar", "\\:s-/--\\", "foobar");
1526     DoTest("foo/bar", "\\:s_/__\\", "foobar");
1527 
1528     DoTest("foo\nfoo\nfoo", "\\:2s/foo/bar\\", "foo\nbar\nfoo");
1529     DoTest("foo\nfoo\nfoo", "2jmagg\\:'as/foo/bar\\", "foo\nfoo\nbar");
1530     DoTest("foo\nfoo\nfoo", "\\:$s/foo/bar\\", "foo\nfoo\nbar");
1531 
1532     // https://bugs.kde.org/show_bug.cgi?id=235862
1533     DoTest("try\n\nalso\nfoo", "\\:/r/,/o/s/^/ha/\\", "hatry\nha\nhaalso\nfoo");
1534     DoTest("much\nmuch\nmuch\nmuch", "\\:.,.+2s/much/try/\\", "try\ntry\ntry\nmuch");
1535 }
1536 
1537 void ModesTest::CommandDeleteTests()
1538 {
1539     DoTest("foo\nbar\nbaz", "\\:2d\\", "foo\nbaz");
1540     DoTest("foo\nbar\nbaz", "\\:%d\\", "");
1541     BeginTest(QStringLiteral("foo\nbar\nbaz"));
1542     TestPressKey(QStringLiteral("\\:$d\\")); // Work around ambiguity in the code that parses commands to execute.
1543     TestPressKey(QStringLiteral("\\:$d\\"));
1544     FinishTest("foo");
1545     DoTest("foo\nbar\nbaz", "ma\\:2,'ad\\", "baz");
1546     DoTest("foo\nbar\nbaz", "\\:/foo/,/bar/d\\", "baz");
1547     DoTest("foo\nbar\nbaz", "\\:2,3delete\\", "foo");
1548 
1549     DoTest("foo\nbar\nbaz", "\\:d\\", "bar\nbaz");
1550     DoTest("foo\nbar\nbaz", "\\:d 33\\", "");
1551     DoTest("foo\nbar\nbaz", "\\:3d a\\k\"ap", "foo\nbaz\nbar");
1552 }
1553 
1554 // END: Command mode.
1555 
1556 // BEGIN: Replace mode.
1557 
1558 void ModesTest::ReplaceCharacter()
1559 {
1560     DoTest("", "rr", "");
1561     DoTest("a", "rb", "b");
1562     DoTest("abc", "lr\\enter", "a\nc");
1563     DoTest("abc", "l\\backspace", "abc");
1564     DoTest("abc", "l\\left", "abc");
1565 }
1566 
1567 void ModesTest::ReplaceBasicTests()
1568 {
1569     // Basic stuff.
1570     DoTest("", "Rqwerty", "qwerty");
1571     DoTest("qwerty", "R\\rightXX", "qXXrty");
1572 
1573     // Enter replace and go to the next/previous word.
1574     DoTest("foo bar", "R\\ctrl-\\rightX", "foo Xar");
1575     DoTest("foo bar", "R\\ctrl-\\right\\ctrl-\\rightX", "foo barX");
1576     DoTest("foo bar", "R\\ctrl-\\leftX", "Xoo bar");
1577     DoTest("foo bar", "R\\ctrl-\\left\\delete", "oo bar");
1578 
1579     // Enter replace mode and go up/down.
1580     DoTest("foo\nbar\nbaz", "R\\downX", "foo\nXar\nbaz");
1581     DoTest("foo\nbar\nbaz", "jjR\\upX", "foo\nXar\nbaz");
1582 
1583     // Repeat replacements
1584     DoTest("foobaz", "Rbar\\esc.", "babarz");
1585     DoTest("foobarbaz", "Rbar\\esc2.", "babarbarz");
1586     DoTest("foobarbaz", "Rbar\\esc4.", "babarbarbarbar");
1587     DoTest("foobarbaz", "Rbar\\esc2.R\\esc2.", "babarbarz");
1588 
1589     // BUG #451076, don't want an extra newline when using the "Find" action from the menu or Ctrl-F
1590     BaseTest::ensureKateViewVisible(); // required for the bug to trigger
1591     BeginTest(QStringLiteral("foobar"));
1592     TestPressKey(QStringLiteral("R"));
1593     kate_view->find();
1594     TestPressKey(QStringLiteral("bar\\return"));
1595     // ensure the cursor is at 'foo_b_ar'
1596     QCOMPARE(kate_view->cursorPosition().line(), 0);
1597     QCOMPARE(kate_view->cursorPosition().column(), 3);
1598     FinishTest("foobar");
1599     // hide the view again
1600     kate_view->hide();
1601     mainWindow->hide();
1602 }
1603 
1604 void ModesTest::ReplaceUndoTests()
1605 {
1606     // Backspace.
1607     DoTest("", "R\\backspace", "");
1608     DoTest("qwerty", "lR\\backspaceX", "Xwerty");
1609     DoTest("qwerty", "lRX\\backspace\\backspaceX", "Xwerty");
1610 
1611     // Ctrl-W
1612     DoTest("", "R\\ctrl-w", "");
1613     DoTest("Hello", "lRXX\\ctrl-w", "Hello");
1614     DoTest("Hello", "lR\t\\ctrl-w", "Hello");
1615     DoTest("Hello", "lRXX\\left\\ctrl-w", "HXXlo");
1616 
1617     // Ctrl-U
1618     DoTest("", "R\\ctrl-u", "");
1619     DoTest("Hello", "lRXX\\ctrl-u", "Hello");
1620     DoTest("Hello", "lR\t\\ctrl-u", "Hello");
1621     DoTest("Hello", "lRXX\\left\\ctrl-u", "HXXlo");
1622     DoTest("Hello World", "3lRXX XX\\ctrl-u", "Hello World");
1623 }
1624 
1625 void ModesTest::ReplaceInsertFromLineTests()
1626 {
1627     // Ctrl-E: replace the current column with the column of the next line.
1628     DoTest("", "R\\ctrl-e", "");
1629     DoTest("\n", "jR\\ctrl-e", "\n");
1630     DoTest("\nqwerty", "R\\ctrl-e\\ctrl-e", "qw\nqwerty");
1631     DoTest("a\nbb", "R\\ctrl-e\\ctrl-e", "bb\nbb");
1632     DoTest("aa\n b", "R\\ctrl-e\\ctrl-e", " b\n b");
1633     DoTest("\n\tb", "R\\ctrl-e\\ctrl-e", "\tb\n\tb");
1634 
1635     // Ctrl-Y: replace the current column with the column of the previous line.
1636     DoTest("", "R\\ctrl-y", "");
1637     DoTest("qwerty\n", "jR\\ctrl-y\\ctrl-y", "qwerty\nqw");
1638     DoTest("aa\nb", "jR\\ctrl-y\\ctrl-y", "aa\naa");
1639     DoTest(" a\nbb", "jR\\ctrl-y\\ctrl-y", " a\n a");
1640     DoTest("\tb\n", "jR\\ctrl-y\\ctrl-y", "\tb\n\tb");
1641 }
1642 
1643 // END: Replace mode.
1644 #include "moc_modes.cpp"