1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 2014 Miquel Sabaté Solà <mikisabate@gmail.com>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "modes.h"
9 #include <inputmode/kateviinputmode.h>
10 #include <katebuffer.h>
11 #include <kateconfig.h>
12 #include <katedocument.h>
13 #include <kateview.h>
14 
15 using namespace KTextEditor;
16 
QTEST_MAIN(ModesTest)17 QTEST_MAIN(ModesTest)
18 
19 // BEGIN: Normal mode.
20 
21 void ModesTest::NormalMotionsTests()
22 {
23     // Test moving around an empty document (nothing should happen)
24     DoTest("", "jkhl", "");
25     DoTest("", "ggG$0", "");
26 
27     // Testing "l"
28     DoTest("bar", "lx", "br");
29     DoTest("bar", "2lx", "ba");
30     DoTest("0123456789012345", "13lx", "012345678901245");
31     DoTest("bar", "10lx", "ba");
32 
33     // Testing "h"
34     DoTest("bar", "llhx", "br");
35     DoTest("bar", "10l10hx", "ar");
36     DoTest("0123456789012345", "13l10hx", "012456789012345");
37     DoTest("bar", "ll5hx", "ar");
38 
39     // Testing "j"
40     DoTest("bar\nbar", "jx", "bar\nar");
41     DoTest("bar\nbar", "10jx", "bar\nar");
42     DoTest("bar\nbara", "lljx", "bar\nbaa");
43     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");
44 
45     // Testing "k"
46     DoTest("bar\nbar", "jx", "bar\nar");
47     DoTest("bar\nbar\nbar", "jj100kx", "ar\nbar\nbar");
48     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");
49 
50     // Testing "w"
51     DoTest("bar", "wx", "ba");
52     DoTest("foo bar", "wx", "foo ar");
53     DoTest("foo bar", "lwx", "foo ar");
54     DoTest("quux(foo, bar, baz);", "wxwxwxwx2wx", "quuxfoo ar baz;");
55     DoTest("foo\nbar\nbaz", "wxwx", "foo\nar\naz");
56     DoTest("1 2 3\n4 5 6", "ld3w", "1\n4 5 6");
57     DoTest("foo\nbar baz", "gU2w", "FOO\nBAR baz");
58     DoTest("FOO\nBAR BAZ", "gu2w", "foo\nbar BAZ");
59     DoTest("bar(\n123", "llwrX", "barX\n123");
60 
61     // Testing "W"
62     DoTest("bar", "Wx", "ba");
63     DoTest("foo bar", "Wx", "foo ar");
64     DoTest("foo bar", "2lWx", "foo ar");
65     DoTest("quux(foo, bar, baz);", "WxWx", "quux(foo, ar, az);");
66     DoTest("foo\nbar\nbaz", "WxWx", "foo\nar\naz");
67     DoTest(" foo(bar xyz", "Wx", " oo(bar xyz");
68 
69     // Testing "b"
70     DoTest("bar", "lbx", "ar");
71     DoTest("foo bar baz", "2wbx", "foo ar baz");
72     DoTest("foo bar", "w20bx", "oo bar");
73     DoTest("quux(foo, bar, baz);", "2W4l2bx2bx", "quux(foo, ar, az);");
74     DoTest("foo\nbar\nbaz", "WWbx", "foo\nar\nbaz");
75     DoTest("  foo", "lbrX", "X foo");
76     DoTest("  foo", "llbrX", "X foo");
77 
78     // Testing "B"
79     DoTest("bar", "lBx", "ar");
80     DoTest("foo bar baz", "2wBx", "foo ar baz");
81     DoTest("foo bar", "w20Bx", "oo bar");
82     DoTest("quux(foo, bar, baz);", "2W4lBBx", "quux(foo, ar, baz);");
83     DoTest("foo\nbar", "WlBx", "foo\nar");
84 
85     // Testing "e"
86     DoTest("quux(foo, bar, baz);", "exex2ex10ex", "quu(fo, bar baz)");
87     DoTest("", "ce", "");
88     DoTest(" ", "lceX", "X");
89     DoTest("", "cE", "");
90 
91     // Testing "E"
92     DoTest("quux(foo, bar, baz);", "ExEx10Ex", "quux(foo bar baz)");
93 
94     // Testing "$"
95     DoTest("foo\nbar\nbaz", "$x3$x", "fo\nbar\nba");
96 
97     // Testing "0"
98     DoTest(" foo", "$0x", "foo");
99 
100     // Testing "#" & "*"
101     DoTest("1 1 1", "2#x", "1  1");
102     DoTest("foo bar foo bar", "#xlll#x", "foo ar oo bar");
103     DoTest("(foo (bar (foo( bar))))", "#xll#x", "(foo (ar (oo( bar))))");
104     DoTest("(foo (bar (foo( bar))))", "*x", "(foo (bar (oo( bar))))");
105     DoTest("foo bar foobar foo", "*rX", "foo bar foobar Xoo"); // Whole word only.
106     DoTest("foo bar foobar foo", "$#rX", "Xoo bar foobar foo"); // Whole word only.
107     DoTest("fOo foo fOo", "*rX", "fOo Xoo fOo"); // Case insensitive.
108     DoTest("fOo foo fOo", "$#rX", "fOo Xoo fOo"); // Case insensitive.
109     DoTest("fOo foo fOo", "*ggnrX", "fOo Xoo fOo"); // Flag that the search to repeat is case insensitive.
110     DoTest("fOo foo fOo", "$#ggNrX", "fOo Xoo fOo"); // Flag that the search to repeat is case insensitive.
111     DoTest("bar foo", "$*rX", "bar Xoo");
112     DoTest("bar foo", "$#rX", "bar Xoo");
113     // Test that calling # on the last, blank line of a document does not go into an infinite loop.
114     DoTest("foo\n", "j#", "foo\n");
115 
116     // Testing "-"
117     DoTest("0\n1\n2\n3\n4\n5", "5j-x2-x", "0\n1\n\n3\n\n5");
118 
119     // Testing "^"
120     DoTest(" foo bar", "$^x", " oo bar");
121 
122     // Testing "gg"
123     DoTest("1\n2\n3\n4\n5", "4jggx", "\n2\n3\n4\n5");
124 
125     // Testing "G"
126     DoTest("1\n2\n3\n4\n5", "Gx", "1\n2\n3\n4\n");
127 
128     // Testing "ge"
129     DoTest("quux(foo, bar, baz);", "9lgexgex$gex", "quux(fo bar, ba);");
130     DoTest("foo", "llgerX", "Xoo");
131     DoTest("   foo", "$gerX", "X  foo");
132     DoTest("   foo foo", "$2gerX", "X  foo foo");
133 
134     // Testing "gE"
135     DoTest("quux(foo, bar, baz);", "9lgExgEx$gEx", "quux(fo bar baz);");
136     DoTest("   foo", "$gErX", "X  foo");
137     DoTest("   foo foo", "$2gErX", "X  foo foo");
138     DoTest("   !foo$!\"", "$gErX", "X  !foo$!\"");
139     DoTest("   !foo$!\"", "$2gErX", "X  !foo$!\"");
140 
141     // Testing "|"
142     DoTest("123456789", "3|rx4|rx8|rx1|rx", "x2xx567x9");
143 
144     // Testing "`"
145     DoTest("foo\nbar\nbaz", "lmaj`arx", "fxo\nbar\nbaz");
146 
147     // Testing "'"
148     DoTest("foo\nbar\nbaz", "lmaj'arx", "xoo\nbar\nbaz");
149 
150     // Testing "%"
151     DoTest("foo{\n}\n", "$d%", "foo\n");
152     DoTest("FOO{\nBAR}BAZ", "lllgu%", "FOO{\nbar}BAZ");
153     DoTest("foo{\nbar}baz", "lllgU%", "foo{\nBAR}baz");
154     DoTest("foo{\nbar\n}", "llly%p", "foo{{\nbar\n}\nbar\n}");
155     // Regression bug for test where yanking with % would actually move the cursor.
156     DoTest("a()", "y%x", "()");
157     // Regression test for the bug I added fixing the bug above ;)
158     DoTest("foo(bar)", "y%P", "foo(bar)foo(bar)");
159     // Regression test for adjacent brackets
160     DoTest("foo((bar)baz)", "y%P", "foo((bar)baz)foo((bar)baz)");
161     // Regression test for "empty" bracket ranges
162     DoTest("()123", "%%llx", "()23");
163 
164     // Testing percentage "<N>%"
165     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%", "20%dd", "10%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%");
166 
167     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%", "50%dd", "10%\n20%\n30%\n40%\n60%\n70%\n80%\n90%\n100%");
168 
169     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70\n80%\n90%\n100%", "65%dd", "10%\n20%\n30%\n40%\n50%\n60%\n80%\n90%\n100%");
170 
171     DoTest("10%\n20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%", "5j10%dd", "20%\n30%\n40%\n50%\n60%\n70%\n80%\n90%\n100%");
172 
173     // ctrl-left and ctrl-right.
174     DoTest("foo bar xyz", "\\ctrl-\\rightrX", "foo Xar xyz");
175     DoTest("foo bar xyz", "$\\ctrl-\\leftrX", "foo bar Xyz");
176 
177     // Enter/ Return.
178     DoTest("foo\n\t \t bar", "\\enterr.", "foo\n\t \t .ar");
179     DoTest("foo\n\t \t bar", "\\returnr.", "foo\n\t \t .ar");
180 
181     // TEXT OBJECTS
182     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci'", "foo \"bar baz ('first', '' or 'third')\"");
183 
184     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lca'", "foo \"bar baz ('first',  or 'third')\"");
185 
186     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci(", "foo \"bar baz ()\"");
187 
188     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci(", "foo \"bar baz ()\"");
189 
190     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lcib", "foo \"bar baz ()\"");
191     // Quick test that bracket object works in visual mode.
192     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lvibd", "foo \"bar baz ()\"");
193     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lvabd", "foo \"bar baz \"");
194 
195     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lca)", "foo \"bar baz \"");
196 
197     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lci\"", "foo \"\"");
198 
199     DoTest("foo \"bar baz ('first', 'second' or 'third')\"", "8w2lda\"", "foo ");
200 
201     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lci[", "foo \"bar []\"");
202 
203     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lci]", "foo \"bar []\"");
204 
205     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lca[", "foo \"bar \"");
206 
207     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "9w2lci{", "foo \"bar [baz ({} or 'third')]\"");
208 
209     DoTest("foo \"bar [baz ({'first', 'second'} or 'third')]\"", "7w2lca}", "foo \"bar [baz ( or 'third')]\"");
210 
211     DoTest("{foo { bar { (baz) \"asd\" }} {1} {2} {3} {4} {5} }", "ldiB", "{}");
212 
213     // Inner/ A Word.
214     DoTest("", "diw", "");
215     DoTest(" ", "diw", "");
216     DoTest("  ", "diw", "");
217     DoTest("foo", "daw", "");
218     DoTest("foo", "ldaw", "");
219     DoTest("foo", "cawxyz\\esc", "xyz");
220     DoTest("foo bar baz", "daw", "bar baz");
221     DoTest("foo bar baz", "cawxyz\\esc", "xyzbar baz");
222     DoTest("foo bar baz", "wdaw", "foo baz");
223     DoTest("foo bar baz", "wldaw", "foo baz");
224     DoTest("foo bar baz", "wlldaw", "foo baz");
225     DoTest("foo bar baz", "wcawxyz\\esc", "foo xyzbaz");
226     DoTest("foo bar baz", "wwdaw", "foo bar");
227     DoTest("foo bar baz   ", "wwdaw", "foo bar ");
228     DoTest("foo bar baz", "wwcawxyz\\esc", "foo barxyz");
229     DoTest("foo bar baz\n123", "jdaw", "foo bar baz\n");
230     DoTest("foo bar baz\n123", "jcawxyz\\esc", "foo bar baz\nxyz");
231     DoTest("foo bar baz\n123", "wwdaw", "foo bar\n123");
232     DoTest("foo bar baz\n123", "wwcawxyz\\esc", "foo barxyz\n123");
233     DoTest("foo bar      baz\n123", "wwdaw", "foo bar\n123");
234     DoTest("foo bar      baz\n123", "wwcawxyz\\esc", "foo barxyz\n123");
235     DoTest("foo bar baz \n123", "wwdaw", "foo bar \n123");
236     DoTest("foo bar baz \n123", "wwcawxyz\\esc", "foo bar xyz\n123");
237     DoTest("foo bar      baz \n123", "wwdaw", "foo bar      \n123");
238     DoTest("foo bar      baz \n123", "wwcawxyz\\esc", "foo bar      xyz\n123");
239     DoTest("foo    bar", "llldaw", "foo");
240     DoTest("foo    bar", "lllcawxyz\\esc", "fooxyz");
241     DoTest("foo    bar", "lllldaw", "foo");
242     DoTest("foo    bar", "llllcawxyz\\esc", "fooxyz");
243     DoTest("    bar", "daw", "");
244     DoTest("    bar", "ldaw", "");
245     DoTest("    bar", "llldaw", "");
246     DoTest("    bar", "lllldaw", "    ");
247     DoTest("    bar", "cawxyz\\esc", "xyz");
248     DoTest("    bar", "lcawxyz\\esc", "xyz");
249     DoTest("    bar", "lllcawxyz\\esc", "xyz");
250     DoTest("foo   ", "llldaw", "foo   ");
251     DoTest("foo   ", "lllldaw", "foo   ");
252     DoTest("foo   ", "llllldaw", "foo   ");
253     DoTest("foo   ", "lllcawxyz\\esc", "foo  ");
254     DoTest("foo   ", "llllcawxyz\\esc", "foo  ");
255     DoTest("foo   ", "lllllcawxyz\\esc", "foo  ");
256     DoTest("foo   \nbar", "llldaw", "foo");
257     DoTest("foo   \nbar", "lllldaw", "foo");
258     DoTest("foo   \nbar", "llllldaw", "foo");
259     DoTest("foo   \nbar", "lllcawxyz\\esc", "fooxyz");
260     DoTest("foo   \nbar", "llllcawxyz\\esc", "fooxyz");
261     DoTest("foo   \nbar", "lllllcawxyz\\esc", "fooxyz");
262     DoTest("foo   \n   bar", "jdaw", "foo   \n");
263     DoTest("foo   \n   bar", "jldaw", "foo   \n");
264     DoTest("foo   \n   bar", "jlldaw", "foo   \n");
265     DoTest("foo   \n   bar", "jcawxyz\\esc", "foo   \nxyz");
266     DoTest("foo   \n   bar", "jlcawxyz\\esc", "foo   \nxyz");
267     DoTest("foo   \n   bar", "jllcawxyz\\esc", "foo   \nxyz");
268     DoTest("foo bar", "2daw", "");
269     DoTest("foo bar", "2cawxyz\\esc", "xyz");
270     DoTest("foo bar baz", "2daw", "baz");
271     DoTest("foo bar baz", "2cawxyz\\esc", "xyzbaz");
272     DoTest("foo bar baz", "3daw", "");
273     DoTest("foo bar baz", "3cawxyz\\esc", "xyz");
274     DoTest("foo bar\nbaz", "2daw", "\nbaz");
275     DoTest("foo bar\nbaz", "2cawxyz\\esc", "xyz\nbaz");
276     DoTest("foo bar\nbaz 123", "3daw", "123");
277     DoTest("foo bar\nbaz 123", "3cawxyz\\esc", "xyz123");
278     DoTest("foo bar \nbaz 123", "3daw", "123");
279     DoTest("foo bar \nbaz 123", "3cawxyz\\esc", "xyz123");
280     DoTest("foo bar baz", "lll2daw", "foo");
281     DoTest("foo bar baz", "lll2cawxyz\\esc", "fooxyz");
282     DoTest("   bar baz", "2daw", "");
283     DoTest("   bar baz", "2cawxyz\\esc", "xyz");
284     DoTest("   bar baz 123", "2daw", " 123");
285     DoTest("   bar baz 123", "2cawxyz\\esc", "xyz 123");
286     DoTest("   bar baz\n123", "3daw", "");
287     DoTest("   bar baz\n123", "3cawxyz\\esc", "xyz");
288     DoTest("   bar baz\n  123", "3daw", "");
289     DoTest("   bar baz\n  123", "3cawxyz\\esc", "xyz");
290     DoTest("   bar baz\n  123", "2daw", "\n  123");
291     DoTest("   bar baz\n  123", "2cawxyz\\esc", "xyz\n  123");
292     DoTest("   bar baz\n  123 456 789", "j2daw", "   bar baz\n 789");
293     DoTest("   bar baz\n  123 456 789", "j2cawxyz\\esc", "   bar baz\nxyz 789");
294     DoTest("foo\nbar\n", "2daw", "");
295     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4daw", "bar baz\njkl");
296     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4cawxyz\\esc", "bar baz\nxyzjkl");
297     DoTest("   bar baz\n  123 \n456\n789 abc \njkl", "j4daw", "   bar baz\njkl");
298     DoTest("   bar baz\n  123 456 789", "j2cawxyz\\esc", "   bar baz\nxyz 789");
299     DoTest("foo b123r xyz", "wdaw", "foo xyz");
300     DoTest("foo b123r xyz", "wldaw", "foo xyz");
301     DoTest("foo b123r xyz", "wlldaw", "foo xyz");
302     DoTest("foo b123r xyz", "wllldaw", "foo xyz");
303     DoTest("foo b123r xyz", "wlllldaw", "foo xyz");
304     DoTest("1 2 3 4 5 6", "daw", "2 3 4 5 6");
305     DoTest("1 2 3 4 5 6", "ldaw", "1 3 4 5 6");
306     DoTest("1 2 3 4 5 6", "lldaw", "1 3 4 5 6");
307     DoTest("1 2 3 4 5 6", "llldaw", "1 2 4 5 6");
308     DoTest("!foo!", "ldaw", "!!");
309     DoTest("! foo !", "ldaw", "! !");
310     DoTest("! foo !", "lldaw", "! !");
311     DoTest("! foo (", "l2daw", "!");
312     DoTest("! foo(\n123", "l2daw", "!\n123");
313     DoTest("  !foo(\n123", "lll2daw", "  !\n123");
314     DoTest("  !!foo(\n123", "llll2daw", "  !!\n123");
315     DoTest("  !foo( \n123", "lll2daw", "  !\n123");
316     DoTest("  !!!!(", "llldaw", "  ");
317     DoTest("  !!!!(", "lll2daw", "  !!!!(");
318     DoTest("  !!!!(\n!!!", "lll2daw", "");
319     DoTest("  !!!!(\n!!!", "llll2daw", "");
320 
321     // Inner/ A WORD
322     // Behave the same as a Word if there are no non-word chars.
323     DoTest("", "diW", "");
324     DoTest(" ", "diW", "");
325     DoTest("  ", "diW", "");
326     DoTest("foo", "daW", "");
327     DoTest("foo", "ldaW", "");
328     DoTest("foo", "caWxyz\\esc", "xyz");
329     DoTest("foo bar baz", "daW", "bar baz");
330     DoTest("foo bar baz", "caWxyz\\esc", "xyzbar baz");
331     DoTest("foo bar baz", "wdaW", "foo baz");
332     DoTest("foo bar baz", "wldaW", "foo baz");
333     DoTest("foo bar baz", "wlldaW", "foo baz");
334     DoTest("foo bar baz", "wcaWxyz\\esc", "foo xyzbaz");
335     DoTest("foo bar baz", "wwdaW", "foo bar");
336     DoTest("foo bar baz   ", "wwdaW", "foo bar ");
337     DoTest("foo bar baz", "wwcaWxyz\\esc", "foo barxyz");
338     DoTest("foo bar baz\n123", "jdaW", "foo bar baz\n");
339     DoTest("foo bar baz\n123", "jcaWxyz\\esc", "foo bar baz\nxyz");
340     DoTest("foo bar baz\n123", "wwdaW", "foo bar\n123");
341     DoTest("foo bar baz\n123", "wwcaWxyz\\esc", "foo barxyz\n123");
342     DoTest("foo bar      baz\n123", "wwdaW", "foo bar\n123");
343     DoTest("foo bar      baz\n123", "wwcaWxyz\\esc", "foo barxyz\n123");
344     DoTest("foo bar baz \n123", "wwdaW", "foo bar \n123");
345     DoTest("foo bar baz \n123", "wwcaWxyz\\esc", "foo bar xyz\n123");
346     DoTest("foo bar      baz \n123", "wwdaW", "foo bar      \n123");
347     DoTest("foo bar      baz \n123", "wwcaWxyz\\esc", "foo bar      xyz\n123");
348     DoTest("foo    bar", "llldaW", "foo");
349     DoTest("foo    bar", "lllcaWxyz\\esc", "fooxyz");
350     DoTest("foo    bar", "lllldaW", "foo");
351     DoTest("foo    bar", "llllcaWxyz\\esc", "fooxyz");
352     DoTest("    bar", "daW", "");
353     DoTest("    bar", "ldaW", "");
354     DoTest("    bar", "llldaW", "");
355     DoTest("    bar", "lllldaW", "    ");
356     DoTest("    bar", "caWxyz\\esc", "xyz");
357     DoTest("    bar", "lcaWxyz\\esc", "xyz");
358     DoTest("    bar", "lllcaWxyz\\esc", "xyz");
359     DoTest("foo   ", "llldaW", "foo   ");
360     DoTest("foo   ", "lllldaW", "foo   ");
361     DoTest("foo   ", "llllldaW", "foo   ");
362     DoTest("foo   ", "lllcaWxyz\\esc", "foo  ");
363     DoTest("foo   ", "llllcaWxyz\\esc", "foo  ");
364     DoTest("foo   ", "lllllcaWxyz\\esc", "foo  ");
365     DoTest("foo   \nbar", "llldaW", "foo");
366     DoTest("foo   \nbar", "lllldaW", "foo");
367     DoTest("foo   \nbar", "llllldaW", "foo");
368     DoTest("foo   \nbar", "lllcaWxyz\\esc", "fooxyz");
369     DoTest("foo   \nbar", "llllcaWxyz\\esc", "fooxyz");
370     DoTest("foo   \nbar", "lllllcaWxyz\\esc", "fooxyz");
371     DoTest("foo   \n   bar", "jdaW", "foo   \n");
372     DoTest("foo   \n   bar", "jldaW", "foo   \n");
373     DoTest("foo   \n   bar", "jlldaW", "foo   \n");
374     DoTest("foo   \n   bar", "jcaWxyz\\esc", "foo   \nxyz");
375     DoTest("foo   \n   bar", "jlcaWxyz\\esc", "foo   \nxyz");
376     DoTest("foo   \n   bar", "jllcaWxyz\\esc", "foo   \nxyz");
377     DoTest("foo bar", "2daW", "");
378     DoTest("foo bar", "2caWxyz\\esc", "xyz");
379     DoTest("foo bar baz", "2daW", "baz");
380     DoTest("foo bar baz", "2caWxyz\\esc", "xyzbaz");
381     DoTest("foo bar baz", "3daW", "");
382     DoTest("foo bar baz", "3caWxyz\\esc", "xyz");
383     DoTest("foo bar\nbaz", "2daW", "\nbaz");
384     DoTest("foo bar\nbaz", "2caWxyz\\esc", "xyz\nbaz");
385     DoTest("foo bar\nbaz 123", "3daW", "123");
386     DoTest("foo bar\nbaz 123", "3caWxyz\\esc", "xyz123");
387     DoTest("foo bar \nbaz 123", "3daW", "123");
388     DoTest("foo bar \nbaz 123", "3caWxyz\\esc", "xyz123");
389     DoTest("foo bar baz", "lll2daW", "foo");
390     DoTest("foo bar baz", "lll2caWxyz\\esc", "fooxyz");
391     DoTest("   bar baz", "2daW", "");
392     DoTest("   bar baz", "2caWxyz\\esc", "xyz");
393     DoTest("   bar baz 123", "2daW", " 123");
394     DoTest("   bar baz 123", "2caWxyz\\esc", "xyz 123");
395     DoTest("   bar baz\n123", "3daW", "");
396     DoTest("   bar baz\n123", "3caWxyz\\esc", "xyz");
397     DoTest("   bar baz\n  123", "3daW", "");
398     DoTest("   bar baz\n  123", "3caWxyz\\esc", "xyz");
399     DoTest("   bar baz\n  123", "2daW", "\n  123");
400     DoTest("   bar baz\n  123", "2caWxyz\\esc", "xyz\n  123");
401     DoTest("   bar baz\n  123 456 789", "j2daW", "   bar baz\n 789");
402     DoTest("   bar baz\n  123 456 789", "j2caWxyz\\esc", "   bar baz\nxyz 789");
403     DoTest("foo\nbar\n", "2daW", "");
404     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4daW", "bar baz\njkl");
405     DoTest("bar baz\n123 \n456\n789 abc \njkl", "j4caWxyz\\esc", "bar baz\nxyzjkl");
406     DoTest("   bar baz\n  123 \n456\n789 abc \njkl", "j4daW", "   bar baz\njkl");
407     DoTest("   bar baz\n  123 456 789", "j2caWxyz\\esc", "   bar baz\nxyz 789");
408     DoTest("foo b123r xyz", "wdaW", "foo xyz");
409     DoTest("foo b123r xyz", "wldaW", "foo xyz");
410     DoTest("foo b123r xyz", "wlldaW", "foo xyz");
411     DoTest("foo b123r xyz", "wllldaW", "foo xyz");
412     DoTest("foo b123r xyz", "wlllldaW", "foo xyz");
413     DoTest("1 2 3 4 5 6", "daW", "2 3 4 5 6");
414     DoTest("1 2 3 4 5 6", "ldaW", "1 3 4 5 6");
415     DoTest("1 2 3 4 5 6", "lldaW", "1 3 4 5 6");
416     DoTest("1 2 3 4 5 6", "llldaW", "1 2 4 5 6");
417     // Now with non-word characters.
418     DoTest("fo(o", "daW", "");
419     DoTest("fo(o", "ldaW", "");
420     DoTest("fo(o", "lldaW", "");
421     DoTest("fo(o", "llldaW", "");
422     DoTest("fo(o )!)!)ffo", "2daW", "");
423     DoTest("fo(o", "diW", "");
424     DoTest("fo(o", "ldiW", "");
425     DoTest("fo(o", "lldiW", "");
426     DoTest("fo(o", "llldiW", "");
427     DoTest("foo \"\"B!!", "fBdaW", "foo");
428 
429     // Inner / Sentence text object ("is")
430     DoTest("", "cis", "");
431     DoTest("hello", "cis", "");
432     DoTest("hello", "flcis", "");
433     DoTest("hello. bye", "cisX", "X bye");
434     DoTest("hello. bye", "f.cisX", "X bye");
435     DoTest("hello.  bye", "fbcisX", "hello.  X");
436     DoTest("hello\n\nbye.", "cisX", "X\n\nbye.");
437     DoTest("Hello. Bye.\n", "GcisX", "Hello. Bye.\nX");
438     DoTest("hello. by.. another.", "cisX", "X by.. another.");
439     DoTest("hello. by.. another.", "fbcisX", "hello. X another.");
440     DoTest("hello. by.. another.\n", "GcisX", "hello. by.. another.\nX");
441     DoTest("hello. yay\nis this a string?!?.. another.\n", "fycisX", "hello. X another.\n");
442     DoTest("hello. yay\nis this a string?!?.. another.\n", "jcisX", "hello. X another.\n");
443     DoTest("This is a sentence.\nThis is another sentence.", "jdis", "This is a sentence.\n");
444 
445     // Around / Sentence text object ("as")
446     DoTest("", "cas", "");
447     DoTest("hello", "cas", "");
448     DoTest("hello", "flcas", "");
449     DoTest("hello. bye", "casX", "Xbye");
450     DoTest("hello. bye", "f.casX", "Xbye");
451     DoTest("hello. bye.", "fbcasX", "hello.X");
452     DoTest("hello. bye", "fbcasX", "hello.X");
453     DoTest("hello\n\nbye.", "casX", "X\n\nbye.");
454     DoTest("Hello. Bye.\n", "GcasX", "Hello. Bye.\nX");
455     DoTest("hello. by.. another.", "casX", "Xby.. another.");
456     DoTest("hello. by.. another.", "fbcasX", "hello. Xanother.");
457     DoTest("hello. by.. another.\n", "GcasX", "hello. by.. another.\nX");
458     DoTest("hello. yay\nis this a string?!?.. another.\n", "fycasX", "hello. Xanother.\n");
459     DoTest("hello. yay\nis this a string?!?.. another.\n", "jcasX", "hello. Xanother.\n");
460     DoTest("hello. yay\nis this a string?!?.. \t       another.\n", "jcasX", "hello. Xanother.\n");
461 
462     // Inner / Paragraph text object ("ip")
463     DoTest("", "cip", "");
464     DoTest("\nhello", "cipX", "X\nhello");
465     DoTest("\nhello\n\nanother. text.", "jcipX", "\nX\n\nanother. text.");
466     DoTest("\nhello\n\n\nanother. text.", "jjcipX", "\nhello\nX\nanother. text.");
467     DoTest("\nhello\n\n\nanother. text.", "jjjcipX", "\nhello\nX\nanother. text.");
468     DoTest("\nhello\n\n\nanother. text.", "jjjjcipX", "\nhello\n\n\nX");
469     DoTest("hello\n\n", "jcipX", "hello\nX");
470     DoTest("hello\n\n", "jjcipX", "hello\nX");
471 
472     // Around / Paragraph text object ("ap")
473     DoTest("", "cap", "");
474     DoTest("\nhello", "capX", "X");
475     DoTest("\nhello\n\nanother.text.", "jcapX", "\nX\nanother.text.");
476     DoTest("\nhello\n\nanother.text.\n\n\nAnother.", "jjjcapX", "\nhello\n\nX\nAnother.");
477     DoTest("\nhello\n\nanother.text.\n\n\nAnother.", "jjjjjcapX", "\nhello\n\nanother.text.\nX");
478     DoTest("hello\n\n\n", "jjcapX", "hello\n\n\n");
479     DoTest("hello\n\nasd", "jjjcapX", "hello\nX");
480 
481     DoTest("{\nfoo\n}", "jdiB", "{\n}");
482     DoTest("{\n}", "diB", "{\n}");
483     DoTest("{\nfoo}", "jdiB", "{\n}");
484     DoTest("{foo\nbar\nbaz}", "jdiB", "{}");
485     DoTest("{foo\nbar\n  \t\t }", "jdiB", "{\n  \t\t }");
486     DoTest("{foo\nbar\n  \t\ta}", "jdiB", "{}");
487     DoTest("\t{\n\t}", "ldiB", "\t{\n\t}");
488     // Quick test to see whether inner curly bracket works in visual mode.
489     DoTest("{\nfoo}", "jviBd", "{\n}");
490     DoTest("{\nfoo}", "jvaBd", "");
491     // Regression test for viB not working if there is a blank line before the closing }.
492     DoTest("{\nfoo\n\n}", "viBd", "{\n}");
493     // The inner block text object does not include the line containing the opening brace if
494     // the opening brace is the last character on its line and there is only whitespace before the closing brace.
495     // (In particular: >iB should not indent the line containing the opening brace under these conditions).
496     DoTest("{\nfoo\n}", "j>iB", "{\n  foo\n}");
497     // Similarly, in such conditions, deleting the inner block should leave the cursor on closing brace line, not the
498     // opening.
499     DoTest("{\nfoo\n}", "jdiBiX", "{\nX}");
500     // Yanking and pasting such a text object should be treated as linewise.
501     DoTest("{\nfoo\nbar\n}", "jyiBjp", "{\nfoo\nbar\nfoo\nbar\n}");
502     // Changing such a text object should delete everything but one line, which we will begin insertion at.
503     DoTest("{\nfoo\nbar\n}", "jciBbaz\\esc", "{\nbaz\n}");
504     // Make sure we remove the "last motion was a *linewise* curly text object" flag when we next parse a motion!
505     DoTest("{\nfoo\n}", "jciBbaz xyz\\escdiw", "{\nbaz \n}");
506     DoTest("{\nfoo\nbar\n}", "jviBbd", "{\nar\n}");
507 
508     DoTest("int main() {\n  printf( \"HelloWorld!\\n\" );\n  return 0;\n} ", "jda}xr;", "int main();");
509 
510     DoTest("QList<QString>", "wwldi>", "QList<>");
511     DoTest("QList<QString>", "wwlda<", "QList");
512     DoTest("<>\n<title>Title</title>\n</head>", "di<jci>\\ctrl-c", "<>\n<>Title</title>\n</head>");
513 
514     DoTest("foo bar baz", "wldiw", "foo  baz");
515 
516     DoTest("foo bar baz", "wldawx", "foo az");
517 
518     DoTest("foo ( \n bar\n)baz", "jdi(", "foo ()baz");
519     DoTest("foo ( \n bar\n)baz", "jda(", "foo baz");
520     DoTest("(foo(bar)baz)", "ldi)", "()");
521     DoTest("(foo(bar)baz)", "lca(\\ctrl-c", "");
522     DoTest("( foo ( bar ) )baz", "di(", "()baz");
523     DoTest("( foo ( bar ) )baz", "da(", "baz");
524     DoTest("[foo [ bar] [(a)b [c]d ]]", "$hda]", "[foo [ bar] ]");
525     DoTest("(a)", "di(", "()");
526     DoTest("(ab)", "di(", "()");
527     DoTest("(abc)", "di(", "()");
528 
529     DoTest("hi!))))}}]]", "di]di}da)di)da]", "hi!))))}}]]");
530 
531     DoTest("foo \"bar\" baz", "4ldi\"", "foo \"\" baz");
532     DoTest("foo \"bar\" baz", "8lca\"\\ctrl-c", "foo  baz");
533 
534     DoTest("foo 'bar' baz", "4lca'\\ctrl-c", "foo  baz");
535     DoTest("foo 'bar' baz", "8ldi'", "foo '' baz");
536 
537     DoTest("foo `bar` baz", "4lca`\\ctrl-c", "foo  baz");
538     DoTest("foo `bar` baz", "8ldi`", "foo `` baz");
539 
540     DoTest("()", "di(", "()");
541     DoTest("\"\"", "di\"", "\"\"");
542 
543     // Comma text object
544     DoTest("func(aaaa);", "llllldi,", "func();");
545     DoTest("func(aaaa);", "lllllda,", "func;");
546     DoTest("//Hello, world!\nfunc(a[0] > 2);", "jf>di,", "//Hello, world!\nfunc();");
547     DoTest("//Hello, world!\nfunc(a[0] > 2);", "jf>da,", "//Hello, world!\nfunc;");
548     DoTest("//Hello, world!\na[] = {135};", "jf3di,", "//Hello, world!\na[] = {};");
549 
550     // Some corner case tests for t/ T, mainly dealing with how a ; after e.g. a ta will
551     // start searching for the next a *after* the character after the cursor.
552     // Hard to explain; I'll let the test-cases do the talking :)
553     DoTest("bar baz", "ta;x", "bar az");
554     // Ensure we reset the flag that says we must search starting from the character after the cursor!
555     DoTest("bar baz", "ta;^tax", "ar baz");
556     // Corresponding tests for T
557     DoTest("bar baz", "$Ta;x", "ba baz");
558     // Ensure we reset the flag that says we must search starting from the character before the cursor!
559     DoTest("bar baz", "$Ta;$Tax", "bar ba");
560     // Ensure that command backwards works, too - only one test, as any additional ones would
561     // just overlap with our previous ones.
562     DoTest("aba bar", "lTa,x", "aba ar");
563     // Some tests with counting.
564     DoTest("aba bar", "2tax", "aba ar");
565     // If we can't find 3 further a's, don't move at all...
566     DoTest("aba bar", "3tax", "ba bar");
567     // ... except if we are repeating the last search, in which case stop at the last
568     // one that we do find.
569     DoTest("aba bar", "ta2;x", "aba ar");
570 
571     // Don't move if we can't find any matches at all, or fewer than we require.
572     DoTest("nocapitalc", "lltCx", "noapitalc");
573     DoTest("nocapitalc", "llTCx", "noapitalc");
574 
575     DoTest("123c456", "2tcx", "23c456");
576     DoTest("123c456", "$2Tcx", "123c45");
577     // Commands with searches that do not find anything, or find less than required, should do nothing.
578     DoTest("foo", "dtk", "foo");
579     DoTest("foomxyz", "d2tm", "foomxyz");
580     DoTest("foo", "dfk", "foo");
581     DoTest("foomxyz", "d2fm", "foomxyz");
582     DoTest("foo", "$dTk", "foo");
583     DoTest("foomxyz", "$d2Fm", "foomxyz");
584     // They should also return a range marked as invalid.
585     DoTest("foo bar", "gUF(", "foo bar");
586     DoTest("foo bar", "gUf(", "foo bar");
587     DoTest("foo bar", "gUt(", "foo bar");
588     DoTest("foo bar", "gUT(", "foo bar");
589 
590     // Changes using backward motions don't consume cursor character
591     DoTest("foo bar", "$dTf", "fr");
592     DoTest("foo bar", "$c2Fo", "fr");
593 
594     // Regression test for special-handling of "/" and "?" keys: these shouldn't interfere
595     // with character searches.
596     DoTest("foo /", "f/rX", "foo X");
597     // d{f,F}{/,?}
598     DoTest("foo/bar?baz", "df/", "bar?baz");
599     DoTest("foo/bar?baz", "f/df?", "foobaz");
600     DoTest("foo/bar?baz", "df?", "baz");
601     DoTest("foo/bar?baz", "f?dF/", "foo?baz");
602     // d{t,T}{/,?}
603     DoTest("foo/bar?baz", "dt/", "/bar?baz");
604     DoTest("foo/bar?baz", "t/dt?", "fo?baz");
605     DoTest("foo/bar?baz", "dt?", "?baz");
606     DoTest("foo/bar?baz", "t?dT/", "foo/r?baz");
607     // c{f,F}{/,?}
608     DoTest("foo/bar?baz", "cf/qux\\esc", "quxbar?baz");
609     DoTest("foo/bar?baz", "f/cf?qux\\esc", "fooquxbaz");
610     DoTest("foo/bar?baz", "cf?qux\\esc", "quxbaz");
611     DoTest("foo/bar?baz", "f?cF/qux\\esc", "fooqux?baz");
612     // c{t,T}{/,?}
613     DoTest("foo/bar?baz", "ct/qux\\esc", "qux/bar?baz");
614     DoTest("foo/bar?baz", "t/ct?qux\\esc", "foqux?baz");
615     DoTest("foo/bar?baz", "ct?qux\\esc", "qux?baz");
616     DoTest("foo/bar?baz", "t?cT/qux\\esc", "foo/quxr?baz");
617     // y{f,F}{/,?}
618     DoTest("foo/bar?baz", "yf/p", "ffoo/oo/bar?baz");
619     DoTest("foo/bar?baz", "f/yf?p", "foo//bar?bar?baz");
620     DoTest("foo/bar?baz", "yf?p", "ffoo/bar?oo/bar?baz");
621     DoTest("foo/bar?baz", "f?yF/p", "foo/bar?/barbaz");
622     // y{t,T}{/,?}
623     DoTest("foo/bar?baz", "yt/p", "ffoooo/bar?baz");
624     DoTest("foo/bar?baz", "t/yt?p", "fooo/bar/bar?baz");
625     DoTest("foo/bar?baz", "yt?p", "ffoo/baroo/bar?baz");
626     DoTest("foo/bar?baz", "t?yT/p", "foo/barba?baz");
627 
628     // gU, gu, g~.
629     DoTest("foo/bar?baz", "gUf/", "FOO/bar?baz");
630     DoTest("FOO/bar?baz", "g~f?", "foo/BAR?baz");
631     DoTest("foo/BAR?baz", "guf?", "foo/bar?baz");
632 
633     // Not adding tests for =f/, >t?, <F?, gqT/ :
634     //  Not likely to be used with those motions.
635     // gw and g@ are currently not supported by ktexteditor's vimode
636 
637     // Using registers
638     DoTest("foo/bar?baz", "\"2df?", "baz");
639     DoTest("foo/bar?baz", "\"_ct/qux", "qux/bar?baz");
640 
641     // counted find on change/deletion != find digit
642     DoTest("foo2barbaz", "df2ax", "bxarbaz");
643     DoTest("foo2barbaz", "d2fax", "");
644 
645     // Motion to lines starting with { or }
646     DoTest("{\nfoo\n}", "][x", "{\nfoo\n");
647     DoTest("{\nfoo\n}", "j[[x", "\nfoo\n}");
648     DoTest("bar\n{\nfoo\n}", "]]x", "bar\n\nfoo\n}");
649     DoTest("{\nfoo\n}\nbar", "jjj[]x", "{\nfoo\n\nbar");
650     DoTest("bar\nfoo\n}", "d][", "}");
651     DoTest("bar\n{\nfoo\n}", "d]]", "{\nfoo\n}");
652     DoTest("bar\nfoo\n}", "ld][", "b\n}");
653     DoTest("{\nfoo\n}", "jld[[", "oo\n}");
654     DoTest("bar\n{\nfoo\n}", "ld]]", "b\n{\nfoo\n}");
655     DoTest("{\nfoo\n}\nbar", "jjjld[]", "{\nfoo\nar");
656 
657     // Testing the "(" motion
658     DoTest("", "(", "");
659     DoTest("\nhello.", "fh(iX", "X\nhello.");
660     DoTest("\n   hello.", "jfe(iX", "X\n   hello.");
661     DoTest("hello. world.", "fr(iX", "Xhello. world.");
662     DoTest("hello. world.\n", "j(iX", "hello. Xworld.\n");
663     DoTest("hello. world\nyay. lol.\n", "jfl(iX", "hello. Xworld\nyay. lol.\n");
664     DoTest("Hello.\n\n", "jj(iX", "XHello.\n\n");
665     DoTest("\nHello.", "j(iX", "X\nHello.");
666     DoTest("\n\n\nHello.", "jj(iX", "X\n\n\nHello.");
667     DoTest("Hello! Bye!", "fB(iX", "XHello! Bye!");
668     DoTest("Hello! Bye! Hye!", "fH(iX", "Hello! XBye! Hye!");
669     DoTest("\nHello. Bye.. Asd.\n\n\n\nAnother.", "jjjj(iX", "\nHello. Bye.. XAsd.\n\n\n\nAnother.");
670 
671     // Testing the ")" motion
672     DoTest("", ")", "");
673     DoTest("\nhello.", ")iX", "\nXhello.");
674     DoTest("hello. world.", ")iX", "hello. Xworld.");
675     DoTest("hello. world\n\nasd.", "))iX", "hello. world\nX\nasd.");
676     DoTest("hello. wor\nld.?? Asd", "))iX", "hello. wor\nld.?? XAsd");
677     DoTest("hello. wor\nld.?? Asd", "jfA(iX", "hello. Xwor\nld.?? Asd");
678     DoTest("Hello.\n\n\nWorld.", ")iX", "Hello.\nX\n\nWorld.");
679     DoTest("Hello.\n\n\nWorld.", "))iX", "Hello.\n\n\nXWorld.");
680     DoTest("Hello.\n\n", ")iX", "Hello.\nX\n");
681     DoTest("Hello.\n\n", "))iX", "Hello.\n\nX");
682     DoTest("Hello. ", ")aX", "Hello. X");
683     DoTest("Hello?? Bye!", ")iX", "Hello?? XBye!");
684 
685     // Testing "{" and "}" motions
686     DoTest("", "{}", "");
687     DoTest("foo", "{}dd", "");
688     DoTest("foo\n\nbar", "}dd", "foo\nbar");
689     DoTest("foo\n\nbar\n\nbaz", "3}x", "foo\n\nbar\n\nba");
690     DoTest("foo\n\nbar\n\nbaz", "3}{dd{dd", "foo\nbar\nbaz");
691     DoTest("foo\nfoo\n\nbar\n\nbaz", "5}{dd{dd", "foo\nfoo\nbar\nbaz");
692     DoTest("foo\nfoo\n\nbar\n\nbaz", "5}3{x", "oo\nfoo\n\nbar\n\nbaz");
693     DoTest("foo\n\n\nbar", "10}{{x", "oo\n\n\nbar");
694     DoTest("foo\n\n\nbar", "}}x", "foo\n\n\nba");
695     DoTest("foo\n\n\nbar\n", "}}dd", "foo\n\n\nbar");
696 
697     // Testing the position of the cursor in some cases of the "c" command.
698     DoTest("(a, b, c)", "cibX", "(X)");
699     DoTest("(a, b, c)", "f)cibX", "(X)");
700     DoTest("(a, b, c)", "ci(X", "(X)");
701     DoTest("(a, b, c)", "ci)X", "(X)");
702     DoTest("[a, b, c]", "ci[X", "[X]");
703     DoTest("[a, b, c]", "ci]X", "[X]");
704     DoTest("{a, b, c}", "ciBX", "{X}");
705     DoTest("{a, b, c}", "ci{X", "{X}");
706     DoTest("{a, b, c}", "ci}X", "{X}");
707     DoTest("<a, b, c>", "ci<X", "<X>");
708     DoTest("<a, b, c>", "ci>X", "<X>");
709 
710     // Things like "cn" and "cN" don't crash.
711     DoTest("Hello", "cn", "Hello");
712     DoTest("Hello", "cN", "Hello");
713 }
714 
NormalCommandsTests()715 void ModesTest::NormalCommandsTests()
716 {
717     // Testing "J"
718     DoTest("foo\nbar", "J", "foo bar");
719     DoTest("foo\nbar", "JrX", "fooXbar");
720     DoTest("foo\nbar\nxyz\n123", "3J", "foo bar xyz\n123");
721     DoTest("foo\nbar\nxyz\n123", "3JrX", "foo barXxyz\n123");
722     DoTest("foo\nbar\nxyz\n12345\n789", "4JrX", "foo bar xyzX12345\n789");
723     DoTest("foo\nbar\nxyz\n12345\n789", "6JrX", "Xoo\nbar\nxyz\n12345\n789");
724     DoTest("foo\nbar\nxyz\n12345\n789", "j5JrX", "foo\nXar\nxyz\n12345\n789");
725     DoTest("foo\nbar\nxyz\n12345\n789", "7JrX", "Xoo\nbar\nxyz\n12345\n789");
726     DoTest("\n\n", "J", "\n");
727     DoTest("foo\n\t   \t\t  bar", "JrX", "fooXbar");
728     DoTest("foo\n\t   \t\t", "J", "foo ");
729     DoTest("foo\n\t   \t\t", "JrX", "fooX");
730 
731     // Testing "dd"
732     DoTest("foo\nbar", "dd", "bar");
733     DoTest("foo\nbar", "2dd", "");
734     DoTest("foo\nbar\n", "Gdd", "foo\nbar");
735     // Testing numbered registers
736     DoTest("hello\nworld", "dddd\"2p\"1p", "\nhello\nworld");
737     DoTest("foo\nbar", "ddD\"1p", "\nfoo");
738     DoTest("abc\nlmn\nxyz", "dddd\"2dd\"1p\"2p", "\nxyz\nlmn");
739     DoTest("123\n456", "dd\"add\"1p\"2p", "\n456\n123");
740     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");
741 
742     // Testing "D"
743     DoTest("foo bar", "lllD", "foo");
744     DoTest("foo\nfoo2\nfoo3", "l2D", "f\nfoo3");
745     DoTest("qwerty", "d frDai", "wei");
746     // Testing small delete (-) register
747     DoTest("12345\n67890", "ddD\"-p", "67890");
748     DoTest("foo\nbar\nhello world", "ld$dj$\"-p", "hello worldoo");
749     DoTest("123\n456", "Dj\"aD\"-p", "\n123");
750     DoTest("abc\nlmn\nxyz", "yyjlYjxk\"-p", "abc\nlmyn\nxz");
751 
752     // Testing "d"
753     DoTest("foobar", "ld2l", "fbar");
754     DoTest("1 2 3\n4 5 6", "ld100l", "1\n4 5 6");
755 
756     DoTest("123\n", "d10l", "\n");
757     DoTest("123\n", "10lx", "12\n");
758 
759     // Testing "Y"
760     DoTest("qwerty", "ld Yep", "qertyerty");
761     // Testing ""<x>y" where x is in a-z (overwrite/insert to register)
762     DoTest("x", "\"ayh\"Ayl\"ap", "xx");
763     DoTest("xy", "\"byll\"byll\"bp", "xyy");
764     DoTest("xyz", "\"cy3l$\"cp", "xyzxyz");
765     DoTest("abz", "\"xyll\"yyll\"zyll\"zp\"xp\"yp", "abzzab");
766     DoTest("abcdwxyz", "\"byh\"ayll\"Byll\"cyll\"dyll\"dyl\"zye$\"zp\"ap\"Cp\"bp\"dp", "abcdwxyzwxyzacbw");
767     // Testing "<X>y" where X is in A-Z (append-copy)
768     DoTest("foo bar ", "\"ayew\"Aye$\"ap", "foo bar foobar");
769     DoTest("foo bar 2", "\"ayew\"Ayew\"aye\"ap", "foo bar 22");
770     DoTest("123 foo ", "\"ayew\"zye\"Aye0\"Zy4l$\"Zp\"ap", "123 foo foo123 123foo");
771 
772     // Testing "X"
773     DoTest("ABCD", "$XX", "AD");
774     DoTest("foo", "XP", "foo");
775 
776     // Testing Del key
777     DoTest("foo", "\\home\\delete", "oo");
778     DoTest("foo", "$\\delete", "fo");
779 
780     // Delete. Note that when sent properly via Qt, the key event text() will inexplicably be "127",
781     // which can trip up the key parser. Duplicate this oddity here.
782     BeginTest("xyz");
783     TestPressKey("l");
784     QKeyEvent *deleteKeyDown = new QKeyEvent(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, "127");
785     QApplication::postEvent(kate_view->focusProxy(), deleteKeyDown);
786     QApplication::sendPostedEvents();
787     QKeyEvent *deleteKeyUp = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Delete, Qt::NoModifier, "127");
788     QApplication::postEvent(kate_view->focusProxy(), deleteKeyUp);
789     QApplication::sendPostedEvents();
790     FinishTest("xz");
791 
792     // Testing "gu"
793     DoTest("FOO\nBAR BAZ", "guj", "foo\nbar baz");
794     DoTest("AbCDF", "gu3l", "abcDF");
795 
796     // Testing "guu"
797     DoTest("FOO", "guu", "foo");
798     DoTest("FOO\nBAR\nBAZ", "2guu", "foo\nbar\nBAZ");
799     DoTest("", "guu", "");
800 
801     // Testing "gU"
802     DoTest("aBcdf", "gU2l", "ABcdf");
803     DoTest("foo\nbar baz", "gUj", "FOO\nBAR BAZ");
804 
805     // Testing "gUU"
806     DoTest("foo", "gUU", "FOO");
807     DoTest("foo\nbar\nbaz", "2gUU", "FOO\nBAR\nbaz");
808     DoTest("", "gUU", "");
809 
810     // Testing "g~"
811     DoTest("fOo BAr", "lg~fA", "foO bar");
812     DoTest("fOo BAr", "$hg~FO", "foO bAr");
813     DoTest("fOo BAr", "lf~fZ", "fOo BAr");
814     DoTest("{\nfOo BAr\n}", "jg~iB", "{\nFoO baR\n}");
815 
816     // Testing "g~~"
817     DoTest("", "g~~", "");
818     DoTest("\nfOo\nbAr", "g~~", "\nfOo\nbAr");
819     DoTest("fOo\nbAr\nBaz", "g~~", "FoO\nbAr\nBaz");
820     DoTest("fOo\nbAr\nBaz\nfAR", "j2g~~", "fOo\nBaR\nbAZ\nfAR");
821     DoTest("fOo\nbAr\nBaz", "jlg~~rX", "fOo\nXaR\nBaz");
822     DoTest("fOo\nbAr\nBaz\nfAR", "jl2g~~rX", "fOo\nBXR\nbAZ\nfAR");
823 
824     // Testing "s"
825     DoTest("substitute char repeat", "w4scheck\\esc", "substitute check repeat");
826 
827     // Testing "r".
828     DoTest("foobar", "l2r.", "f..bar");
829     DoTest("foobar", "l5r.", "f.....");
830     // Do nothing if the count is too high.
831     DoTest("foobar", "l6r.", "foobar");
832 
833     // Testing "Ctrl-o" and "Ctrl-i"
834     DoTest("abc\ndef\nghi", "Gx\\ctrl-ox", "bc\ndef\nhi");
835     DoTest("{\n}", "%\\ctrl-ox", "\n}");
836     DoTest("Foo foo.\nBar bar.\nBaz baz.", "lmajlmb`a`b\\ctrl-ox", "Fo foo.\nBar bar.\nBaz baz.");
837     DoTest("Foo foo.\nBar bar.\nBaz baz.", "lmajlmb`a`bj\\ctrl-o\\ctrl-ix", "Foo foo.\nBar bar.\nBa baz.");
838 
839     // Testing "gq" (reformat) text
840     DoTest("foo\nbar", "gqq", "foo\nbar");
841     DoTest("foo\nbar", "2gqq", "foo bar");
842     DoTest("foo\nbar\nbaz", "jgqj", "foo\nbar baz");
843     DoTest("foo\nbar\n\n\n", "gqap", "foo bar\n\n\n");
844 
845     // when setting the text to wrap at column 10, this should be re-formatted to
846     // span several lines ...
847     kate_document->setWordWrapAt(10);
848     DoTest("foo bar foo bar foo bar", "gqq", "foo bar \nfoo bar \nfoo bar");
849 
850     // ... and when re-setting it to column 80 again, they should be joined again
851     kate_document->setWordWrapAt(80);
852     DoTest("foo bar\nfoo bar\nfoo bar", "gqG", "foo bar foo bar foo bar");
853 
854     // test >> and << (indent and de-indent)
855     kate_document->config()->setReplaceTabsDyn(true);
856 
857     DoTest("foo\nbar", ">>", "  foo\nbar");
858     DoTest("foo\nbar", "2>>", "  foo\n  bar");
859     DoTest("foo\nbar", "100>>", "  foo\n  bar");
860 
861     DoTest("fop\nbar", "yiwjlgpx", "fop\nbafop");
862     DoTest("fop\nbar", "yiwjlgPx", "fop\nbfopr");
863 
864     DoTest("repeat\nindent", "2>>2>>", "    repeat\n    indent");
865 
866     // make sure we record correct history when indenting
867     DoTest("repeat\nindent and undo", "2>>2>>2>>uu", "  repeat\n  indent and undo");
868     DoTest("repeat\nunindent and undo", "2>>2>>2<<u", "    repeat\n    unindent and undo");
869 
870     // Yank and paste op\ngid into bar i.e. text spanning lines, but not linewise.
871     DoTest("fop\ngid\nbar", "lvjyjjgpx", "fop\ngid\nbaop\ngi");
872     DoTest("fop\ngid\nbar", "lvjyjjgPx", "fop\ngid\nbop\ngir");
873     DoTest("fop\ngid\nbar", "lvjyjjpx", "fop\ngid\nbap\ngir");
874     DoTest("fop\ngid\nbar", "lvjyjjPx", "fop\ngid\nbp\ngiar");
875     // Linewise
876     DoTest("fop\ngid\nbar\nhuv", "yjjjgpx", "fop\ngid\nbar\nfop\ngid\nuv");
877     DoTest("fop\ngid\nbar\nhuv", "yjjjgPx", "fop\ngid\nfop\ngid\nar\nhuv");
878     DoTest("fop\ngid", "yjjgpx", "fop\ngid\nfop\nid");
879     DoTest("fop\ngid\nbar\nhuv", "yjjjPx", "fop\ngid\nop\ngid\nbar\nhuv");
880 
881     DoTest("fop\nbar", "yiwjlpx", "fop\nbafor");
882     DoTest("fop\nbar", "yiwjlPx", "fop\nbfoar");
883 
884     // Indented paste.
885     // ]p behaves as ordinary paste if not linewise, and on unindented line.
886     DoTest("foo bar", "wyiwgg]p", "fbaroo bar");
887     // ]p behaves as ordinary paste if not linewise, even on indented line.
888     DoTest("  foo bar", "wwyiwggw]p", "  fbaroo bar");
889     // [p behaves as ordinary Paste (P) if not linewise, and on unindented line.
890     DoTest("foo bar", "wyiwgg[p", "barfoo bar");
891     // [p behaves as ordinary Paste (P) if not linewise, even on indented line.
892     DoTest("  foo bar", "wwyiw0w[p", "  barfoo bar");
893     // Prepend the spaces from the current line to the beginning of a single, pasted line.
894     DoTest("  foo bar\nxyz", "jVygg]p", "  foo bar\n  xyz\nxyz");
895     // Prepend the spaces from the current line to the beginning of each pasted line.
896     DoTest("  foo bar\nxyz\nnose", "jVjygg]p", "  foo bar\n  xyz\n  nose\nxyz\nnose");
897     const bool oldReplaceTabsDyn = kate_document->config()->replaceTabsDyn();
898     kate_document->config()->setReplaceTabsDyn(false);
899     // Tabs as well as spaces!
900     DoTest("  \tfoo bar\nxyz\nnose", "jVjygg]p", "  \tfoo bar\n  \txyz\n  \tnose\nxyz\nnose");
901     // Same for [p.
902     DoTest("  \tfoo bar\nxyz\nnose", "jVjygg[p", "  \txyz\n  \tnose\n  \tfoo bar\nxyz\nnose");
903     // Test if everything works if the current line has no non-whitespace.
904     DoTest("\t \nbar", "jVygg]p", "\t \n\t bar\nbar");
905     // Test if everything works if the current line is empty.
906     DoTest("\nbar", "jVygg]p", "\nbar\nbar");
907     // Unindent a pasted indented line if the current line has no indent.
908     DoTest("foo\n  \tbar", "jVygg]p", "foo\nbar\n  \tbar");
909     // Unindent subsequent lines, too - TODO - this assumes that each subsequent line has
910     // *identical* trailing whitespace to the first pasted line: Vim seems to be able to
911     // deal with cases where this does not hold.
912     DoTest("foo\n  \tbar\n  \txyz", "jVjygg]p", "foo\nbar\nxyz\n  \tbar\n  \txyz");
913     DoTest("foo\n  \tbar\n  \t  xyz", "jVjygg]p", "foo\nbar\n  xyz\n  \tbar\n  \t  xyz");
914     kate_document->config()->setReplaceTabsDyn(oldReplaceTabsDyn);
915 
916     // Some special cases of cw/ cW.
917     DoTest("foo bar", "cwxyz\\esc", "xyz bar");
918     DoTest("foo+baz bar", "cWxyz\\esc", "xyz bar");
919     DoTest("foo+baz bar", "cwxyz\\esc", "xyz+baz bar");
920     DoTest(" foo bar", "cwxyz\\esc", "xyzfoo bar");
921     DoTest(" foo+baz bar", "cWxyz\\esc", "xyzfoo+baz bar");
922     DoTest(" foo+baz bar", "cwxyz\\esc", "xyzfoo+baz bar");
923     DoTest("\\foo bar", "cWxyz\\esc", "xyz bar");
924     DoTest("foo   ", "lllcwxyz\\esc", "fooxyz");
925 
926     DoTest("foo", "yr", "foo");
927     QCOMPARE(kate_view->renderer()->caretStyle(), KateRenderer::Block);
928 
929     // BUG #332523
930     const bool oldDynWordWrap = KateViewConfig::global()->dynWordWrap();
931     BeginTest("asdasdasd\nasdasdasdasdasdasdasd");
932     kate_document->setWordWrap(true);
933     kate_document->setWordWrapAt(10);
934     TestPressKey("Jii");
935     FinishTest("iasdasdasd\n \nasdasdasda \nsdasdasdas \nd");
936     kate_document->setWordWrap(oldDynWordWrap);
937 }
938 
NormalControlTests()939 void ModesTest::NormalControlTests()
940 {
941     // Testing "Ctrl-x"
942     DoTest("150", "101\\ctrl-x", "49");
943     DoTest("1", "\\ctrl-x\\ctrl-x\\ctrl-x\\ctrl-x", "-3");
944     DoTest("0xabcdef", "1000000\\ctrl-x", "0x9c8baf");
945     DoTest("0x0000f", "\\ctrl-x", "0x0000e");
946     // Octal numbers should retain leading 0's.
947     DoTest("00010", "\\ctrl-x", "00007");
948 
949     // Testing "Ctrl-a"
950     DoTest("150", "101\\ctrl-a", "251");
951     DoTest("1000", "\\ctrl-ax", "100");
952     DoTest("-1", "1\\ctrl-a", "0");
953     DoTest("-1", "l1\\ctrl-a", "0");
954     DoTest("0x0000f", "\\ctrl-a", "0x00010");
955     // Decimal with leading 0's - increment, and strip leading 0's, like Vim.
956     DoTest("0000193", "\\ctrl-a", "194");
957     // If a number begins with 0, parse it as octal if we can. The resulting number should retain the
958     // leadingi 0.
959     DoTest("07", "\\ctrl-a", "010");
960     DoTest("5", "5\\ctrl-a.", "15");
961     DoTest("5", "5\\ctrl-a2.", "12");
962     DoTest("5", "5\\ctrl-a2.10\\ctrl-a", "22");
963     DoTest(" 5 ", "l\\ctrl-ax", "  ");
964     // If there's no parseable number under the cursor, look to the right to see if we can find one.
965     DoTest("aaaa0xbcX", "\\ctrl-a", "aaaa0xbdX");
966     DoTest("1 1", "l\\ctrl-a", "1 2");
967     // We can skip across word boundaries in our search if need be.
968     DoTest("aaaa 0xbcX", "\\ctrl-a", "aaaa 0xbdX");
969     // If we can't find a parseable number anywhere, don't change anything.
970     DoTest("foo", "\\ctrl-a", "foo");
971     // 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.
972     DoTest("1 ", "l\\ctrl-a", "1 ");
973     // ctrl-a/x algorithm involves stepping back to the previous word: don't crash if this is on the previous line
974     // and at a column greater than the length of the current line.
975     DoTest(" a a\n1", "j\\ctrl-a", " a a\n2");
976     DoTest(" a a    a\n  1", "jll\\ctrl-a", " a a    a\n  2");
977     // Regression test.
978     DoTest("1w3", "l\\ctrl-a", "1w4");
979 
980     // Test "Ctrl-a/x" on a blank document/ blank line.
981     DoTest("", "\\ctrl-a", "");
982     DoTest("", "\\ctrl-x", "");
983     DoTest("foo\n", "j\\ctrl-x", "foo\n");
984     DoTest("foo\n", "j\\ctrl-a", "foo\n");
985 
986     // Testing "Ctrl-r"
987     DoTest("foobar", "d3lu\\ctrl-r", "bar");
988     DoTest("line 1\nline 2\n", "ddu\\ctrl-r", "line 2\n");
989 }
990 
NormalNotYetImplementedFeaturesTests()991 void ModesTest::NormalNotYetImplementedFeaturesTests()
992 {
993     QSKIP("This tests never worked :(", SkipAll);
994 
995     // Testing "))"
996     DoTest("Foo foo. Bar bar.", "))\\ctrl-ox", "Foo foo. ar bar.");
997     DoTest("Foo foo.\nBar bar.\nBaz baz.", ")))\\ctrl-ox\\ctrl-ox", "Foo foo.\nar bar.\nBaz baz.");
998     DoTest("Foo foo.\nBar bar.\nBaz baz.", "))\\ctrl-ox\\ctrl-ix", "Foo foo.\nBar bar.\naz baz.");
999     DoTest("Foo foo.\nBar bar.\nBaz baz.", "))\\ctrl-ox\\ctrl-ix", "Foo foo.\nBar bar.\naz baz.");
1000 }
1001 
1002 // END: Normal mode.
1003 
1004 // BEGIN: Insert mode.
1005 
InsertTests()1006 void ModesTest::InsertTests()
1007 {
1008     // Basic stuff.
1009     DoTest("bar", "s\\ctrl-c", "ar");
1010     DoTest("bar", "ls\\ctrl-cx", "r");
1011     DoTest("foo\nbar", "S\\ctrl-c", "\nbar");
1012     DoTest("baz bar", "lA\\ctrl-cx", "baz ba");
1013     DoTest("baz bar", "la\\ctrl-cx", "bz bar");
1014     DoTest("foo\nbar\nbaz", "C\\ctrl-c", "\nbar\nbaz");
1015     DoTest("foo bar baz", "c2w\\ctrl-c", " baz");
1016     DoTest("foo\nbar\nbaz", "jo\\ctrl-c", "foo\nbar\n\nbaz");
1017     DoTest("foo\nbar\nbaz", "jO\\ctrl-c", "foo\n\nbar\nbaz");
1018     DoTest("foo\nbar", "O\\ctrl-c", "\nfoo\nbar");
1019     DoTest("foo\nbar", "o\\ctrl-c", "foo\n\nbar");
1020     DoTest("foo bar", "wlI\\ctrl-cx", "oo bar");
1021     DoTest("foo bar", "wli\\ctrl-cx", "foo ar");
1022     DoTest("foo bar", "wlihello\\ctrl-c", "foo bhelloar");
1023 
1024     // With count.
1025     DoTest("", "5ihello\\esc", "hellohellohellohellohello");
1026     DoTest("bar", "5ahello\\esc", "bhellohellohellohellohelloar");
1027     DoTest("   bar", "5Ihello\\esc", "   hellohellohellohellohellobar");
1028     DoTest("bar", "5Ahello\\esc", "barhellohellohellohellohello");
1029     DoTest("", "5ihello\\ctrl-c", "hello");
1030     DoTest("bar", "5ohello\\esc", "bar\nhello\nhello\nhello\nhello\nhello");
1031     DoTest("bar", "5Ohello\\esc", "hello\nhello\nhello\nhello\nhello\nbar");
1032     DoTest("bar", "Ohello\\escu", "bar");
1033     DoTest("bar", "5Ohello\\escu", "bar");
1034     DoTest("bar", "ohello\\escu", "bar");
1035     DoTest("bar", "5ohello\\escu", "bar");
1036     DoTest("foo\nbar", "j5Ohello\\esc", "foo\nhello\nhello\nhello\nhello\nhello\nbar");
1037     DoTest("bar", "5ohello\\esc2ixyz\\esc", "bar\nhello\nhello\nhello\nhello\nhellxyzxyzo");
1038     DoTest("", "ihello\\esc5.", "hellhellohellohellohellohelloo");
1039 
1040     // Ensure that the flag that says that counted repeats should begin on a new line is reset.
1041     DoTest("foo", "obar\\ctrl-c5ixyz\\esc", "foo\nbaxyzxyzxyzxyzxyzr");
1042     DoTest("foo", "obar\\ctrl-cgg\\ctrl-vlljAxyz\\esc5i123\\esc", "fooxy123123123123123z\nbarxyz");
1043     DoTest("foo foo foo", "c3wbar\\esc", "bar");
1044     DoTest("abc", "lOxyz", "xyz\nabc");
1045 
1046     // Test that our test driver can handle newlines during insert mode :)
1047     DoTest("", "ia\\returnb", "a\nb");
1048 }
1049 
InsertKeysTests()1050 void ModesTest::InsertKeysTests()
1051 {
1052     // Ctrl-w
1053     DoTest("foobar", "$i\\ctrl-w", "r");
1054     DoTest("foobar\n", "A\\ctrl-w", "\n");
1055     DoTest("   foo", "i\\ctrl-wX\\esc", "X   foo");
1056     DoTest("   foo", "lli\\ctrl-wX\\esc", "X foo");
1057 
1058     // Ctrl-u
1059     DoTest("", "i\\ctrl-u", "");
1060     DoTest("foobar", "i\\ctrl-u", "foobar");
1061     DoTest("foobar", "fbi\\ctrl-u", "bar");
1062     DoTest("foobar\nsecond", "ji\\ctrl-u", "foobarsecond");
1063     DoTest("foobar\n  second", "jwi\\ctrl-u", "foobar\nsecond");
1064     DoTest("foobar\n  second", "jfci\\ctrl-u", "foobar\n  cond");
1065     DoTest("foobar\n  second", "j$a\\ctrl-u", "foobar\n  ");
1066 
1067     // Ctrl-e
1068     DoTest("foo\nbar", "i\\ctrl-e", "bfoo\nbar");
1069     DoTest("foo\nbar", "i\\ctrl-e\\ctrl-e\\ctrl-e", "barfoo\nbar");
1070     DoTest("foo\nb", "i\\ctrl-e\\ctrl-e", "bfoo\nb");
1071 
1072     // Ctrl-y
1073     DoTest("foo\nbar", "ji\\ctrl-y", "foo\nfbar");
1074     DoTest("foo\nbar", "ji\\ctrl-y\\ctrl-y\\ctrl-y", "foo\nfoobar");
1075     DoTest("f\nbar", "ji\\ctrl-y\\ctrl-y", "f\nfbar");
1076 
1077     // Ctrl-R
1078     DoTest("barbaz", "\"ay3li\\ctrl-ra", "barbarbaz");
1079     DoTest("barbaz", "\"ay3li\\ctrl-raX", "barXbarbaz");
1080     DoTest("bar\nbaz", "\"byylli\\ctrl-rb", "bar\nbar\nbaz");
1081     DoTest("Hello", "0yei\\ctrl-r\"", "HelloHello");
1082 
1083     // Ctrl-O
1084     DoTest("foo bar baz", "3li\\ctrl-od2w", "foobaz");
1085     DoTest("foo bar baz", "3li\\ctrl-od2w\\ctrl-w", "baz");
1086     DoTest("foo bar baz", "i\\ctrl-o3l\\ctrl-w", " bar baz");
1087     DoTest("foo\nbar\nbaz", "li\\ctrl-oj\\ctrl-w\\ctrl-oj\\ctrl-w", "foo\nar\naz");
1088 
1089     // Test that the text written after the Ctrl-O command completes is treated as
1090     // an insertion of text (rather than a sequence of commands) when repeated via "."
1091     DoTest("", "isausage\\ctrl-obugo\\esc.", "ugugoosausage");
1092 
1093     // 'Step back' on Ctrl-O if at the end of the line
1094     DoTest("foo bar baz", "A\\ctrl-ox", "foo bar ba");
1095 
1096     // Paste acts as gp when executing in a Ctrl-O
1097     DoTest("foo bar baz", "yiwea\\ctrl-opd", "foo foodbar baz");
1098     DoTest("bar", "A\\ctrl-o\\ctrl-chx", "br");
1099     DoTest("bar", "A\\ctrl-o\\eschx", "br");
1100 
1101     // Ctrl-D & Ctrl-T
1102     DoTest("foo", "i\\ctrl-t", "  foo");
1103     DoTest(" foo", "i\\ctrl-d", "foo");
1104     DoTest("foo\nbar", "i\\ctrl-t\\ctrl-d", "foo\nbar");
1105 
1106     // Ctrl-H
1107     DoTest("foo", "i\\ctrl-h", "foo");
1108     DoTest(" foo", "li\\ctrl-h", "foo");
1109     DoTest("foo\nbar", "ji\\ctrl-h", "foobar");
1110     DoTest("1234567890", "A\\ctrl-h\\ctrl-h\\ctrl-h\\ctrl-h\\ctrl-h", "12345");
1111     DoTest("1\n2\n3", "GA\\ctrl-h\\ctrl-h\\ctrl-h\\ctrl-h", "1");
1112 
1113     // Ctrl-J
1114     DoTest("foo", "i\\ctrl-j", "\nfoo");
1115     DoTest("foo", "lli\\ctrl-j", "fo\no");
1116     DoTest("foo\nbar", "ji\\ctrl-j", "foo\n\nbar");
1117     DoTest("foobar", "A\\ctrl-j", "foobar\n");
1118     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");
1119 
1120     // Ctrl-left & Ctrl-right.
1121     DoTest("foo bar", "i\\ctrl-\\rightX\\esc", "foo Xbar");
1122     DoTest("foo bar", "i\\ctrl-\\right\\ctrl-\\rightX\\esc", "foo barX");
1123     DoTest("foo", "\\endi\\ctrl-\\left\\ctrl-\\leftX", "Xfoo"); // we crashed here before
1124 
1125     // Special keys: enter, return, insert, etc.
1126     DoTest("", "ifoo\\enterbar", "foo\nbar");
1127     DoTest("", "ifoo\\returnbar", "foo\nbar");
1128     DoTest("", "\\insertfoo", "foo");
1129     DoTest("foo bar", "i\\home\\delete", "oo bar");
1130 }
1131 
1132 // END: Insert mode.
1133 
1134 // BEGIN: Visual mode.
1135 
VisualMotionsTests()1136 void ModesTest::VisualMotionsTests()
1137 {
1138     // Basic motions.
1139     DoTest("\n", "vjcX", "X");
1140     DoTest("foobar", "vlllx", "ar");
1141     DoTest("foo\nbar", "Vd", "bar");
1142     DoTest("Hello.\nWorld", "2lvjcX", "HeXld");
1143     DoTest("Three. Different. Sentences.\n\n", "vapcX", "X");
1144     DoTest("1234\n1234\n1234", "l\\ctrl-vljjd", "14\n14\n14");
1145     QCOMPARE(kate_view->blockSelection(), false);
1146     DoTest("Three. Different. Sentences.", "v)cX", "Xifferent. Sentences.");
1147     DoTest("Three. Different. Sentences.", "v)cX", "Xifferent. Sentences.");
1148     DoTest("Three. Different. Sentences.", "v)cX", "Xifferent. Sentences.");
1149     DoTest("Three. Different. Sentences.", "viWcX", "X Different. Sentences.");
1150     DoTest("Three. Different. Sentences.", "viwcX", "X. Different. Sentences.");
1151     DoTest("Three. Different. Sentences.", "vaWcX", "XDifferent. Sentences.");
1152     DoTest("Three. Different. Sentences.", "vawcX", "X. Different. Sentences.");
1153     DoTest("Three. Different. Sentences.", "vascX", "XDifferent. Sentences.");
1154     DoTest("Three. Different. Sentences.", "viscX", "X Different. Sentences.");
1155     DoTest("Three. Different. Sentences.", "vapcX", "X");
1156     DoTest("Three. Different. Sentences.", "vipcX", "X");
1157     DoTest("Hello.\n", "vap\\esciX", "Hello.\nX");
1158     // Make sure cursor is properly moved to the start of paragraph and sentence text objects
1159     DoTest("Hello.\nWorld.", "jvapX", "");
1160     DoTest("Hello.\nWorld.", "jvasX", "Hello.\n");
1161 
1162     // With count.
1163     DoTest("12345678", "lv3lyx", "1345678");
1164     DoTest("12345678", "$hv3hyx", "1235678");
1165     DoTest("aaa\nbbb", "lvj~x", "aA\nBBb");
1166     DoTest("123\n456", "jlvkyx", "13\n456");
1167     DoTest("12\n34", "lVjyx", "2\n34");
1168     DoTest("ab\ncd", "jVlkgux", "a\ncd");
1169     DoTest("ABCD\nABCD\nABCD\nABCD", "lj\\ctrl-vjlgux", "ABCD\nAcD\nAbcD\nABCD");
1170     DoTest("abcd\nabcd\nabcd\nabcd", "jjjlll\\ctrl-vkkhgUx", "abcd\nabD\nabCD\nabCD");
1171 
1172     // Cancelling visual mode should not reset the cursor.
1173     DoTest("12345678", "lv3l\\escx", "1234678");
1174     DoTest("12345678", "lv3l\\ctrl-cx", "1234678");
1175 
1176     // Don't forget to clear the flag that says we shouldn't reset the cursor, though!
1177     DoTest("12345678", "lv3l\\ctrl-cxv3lyx", "123478");
1178     DoTest("12345678", "y\\escv3lyx", "2345678");
1179 
1180     // Regression test for ][ in Visual Mode.
1181     DoTest("foo {\n\n}", "lV][d", "");
1182 
1183     // Misc tests for motions starting in front of the Visual Mode start point.
1184     DoTest("{foo}", "lvb%x", "{");
1185     DoTest("foo bar", "wvbfax", "foo r");
1186     DoTest("(foo bar)", "wwv^%x", "(foo ");
1187 
1188     // * and #
1189     DoTest("foo foo", "v*x", "oo");
1190     DoTest("foo foo", "wv#x", "oo");
1191 
1192     // Quick test that "{" and "}" motions work in visual mode
1193     DoTest("foo\n\n\nbar\n", "v}}d", "");
1194     DoTest("\n\nfoo\nbar\n", "jjjv{d", "\nar\n");
1195 
1196     // ctrl-left and ctrl-right
1197     DoTest("foo bar xyz", "v\\ctrl-\\rightd", "ar xyz");
1198     DoTest("foo bar xyz", "$v\\ctrl-\\leftd", "foo bar ");
1199 }
1200 
VisualCommandsTests()1201 void ModesTest::VisualCommandsTests()
1202 {
1203     // Testing "d"
1204     DoTest("foobarbaz", "lvlkkjl2ld", "fbaz");
1205     DoTest("foobar", "v$d", "");
1206     DoTest("foo\nbar\nbaz", "jVlld", "foo\nbaz");
1207     DoTest("01\n02\n03\n04\n05", "Vjdj.", "03");
1208 
1209     // Testing Del key
1210     DoTest("foobarbaz", "lvlkkjl2l\\delete", "fbaz");
1211 
1212     // Testing "D"
1213     DoTest("foo\nbar\nbaz", "lvjlD", "baz");
1214     DoTest("foo\nbar", "l\\ctrl-vjD", "f\nb");
1215     DoTest("foo\nbar", "VjkD", "bar");
1216     DoTest("Test:\n  - One\n  - Two", "jfnVDia", "Test:\n  a- Two");
1217     DoTest("Test:\n  - One\n  - Two", "jjfwVDia", "Test:\n  a- One");
1218 
1219     // Testing "gU", "U"
1220     DoTest("foo bar", "vwgU", "FOO Bar");
1221     DoTest("foo\nbar\nbaz", "VjjU", "FOO\nBAR\nBAZ");
1222     DoTest("foo\nbar\nbaz", "\\ctrl-vljjU", "FOo\nBAr\nBAz");
1223     DoTest("aaaa\nbbbb\ncccc", "\\ctrl-vljgUjll.", "AAaa\nBBBB\nccCC");
1224 
1225     // Testing "gu", "u"
1226     DoTest("TEST", "Vgu", "test");
1227     DoTest("TeSt", "vlgu", "teSt");
1228     DoTest("FOO\nBAR\nBAZ", "\\ctrl-vljju", "foO\nbaR\nbaZ");
1229     DoTest("AAAA\nBBBB\nCCCC\nDDDD", "vjlujjl.", "aaaa\nbbBB\nCccc\ndddD");
1230 
1231     // Testing "gv"
1232     DoTest("foo\nbar\nxyz", "l\\ctrl-vjj\\ctrl-cgvr.", "f.o\nb.r\nx.z");
1233 
1234     // Testing "g~"
1235     DoTest("fOo bAr", "Vg~", "FoO BaR");
1236     DoTest("foo\nbAr\nxyz", "l\\ctrl-vjjg~", "fOo\nbar\nxYz");
1237 
1238     // Testing "y"
1239     DoTest("foobar", "Vypp", "foobar\nfoobar\nfoobar");
1240     DoTest("foo\nbar", "lvjlyp", "fooo\nbaro\nbar");
1241     DoTest("foo\nbar", "Vjlllypddxxxdd", "foo\nbar");
1242     DoTest("12\n12", "\\ctrl-vjyp", "112\n112");
1243     DoTest("1234\n1234\n1234\n1234", "lj\\ctrl-vljyp", "1234\n122334\n122334\n1234");
1244 
1245     // Testing "Y"
1246     DoTest("foo\nbar", "llvjypx", "foo\nbar\nbar");
1247     DoTest("foo\nbar", "VYp", "foo\nfoo\nbar");
1248 
1249     // Testing "m."
1250     DoTest("foo\nbar", "vljmavgg`ax", "foo\nbr");
1251     DoTest("1\n2\n3\n4", "Vjmajjmb\\:'a,'bd\\", "1");
1252 
1253     // Testing ">"
1254     DoTest("foo\nbar", "vj>", "  foo\n  bar");
1255     DoTest("foo\nbar\nbaz", "jVj>", "foo\n  bar\n  baz");
1256     DoTest("foo", "vl3>", "      foo");
1257     DoTest("indent\nrepeat", "V>.", "    indent\nrepeat");
1258     DoTest("indent\nrepeat", "Vj>.", "    indent\n    repeat");
1259     DoTest("indent\nrepeat\non\nothers", "Vj>jj.", "  indent\n  repeat\n  on\n  others");
1260     DoTest("foo\nbar\nbaz", "jjVk>.", "foo\n    bar\n    baz");
1261 
1262     // Testing "<"
1263     DoTest(" foo", "vl<", "foo");
1264     DoTest("foo\n    bar\n    baz", "jjVk<.", "foo\nbar\nbaz");
1265 
1266     // Testing "o"
1267     DoTest("foobar", "lv2lo2ld", "fooar");
1268     DoTest("foo\nbar", "jvllokld", "f");
1269     DoTest("12\n12", "\\ctrl-vjlold", "1\n1");
1270 
1271     // Testing "~"
1272     DoTest("foobar", "lv2l~", "fOOBar");
1273     DoTest("FooBar", "V~", "fOObAR");
1274     DoTest("foo\nbar", "\\ctrl-vjl~", "FOo\nBAr");
1275 
1276     // Testing "r"
1277     DoTest("foobar", "Vra", "aaaaaa");
1278     DoTest("foo\nbar", "jlvklrx", "fox\nxxr");
1279     DoTest("123\n123", "l\\ctrl-vljrx", "1xx\n1xx");
1280     DoTest("a", "r\\ctrl-c", "a");
1281     DoTest("a", "r\\ctrl-[", "a");
1282     DoTest("a", "r\\keypad-0", "0");
1283     DoTest("a", "r\\keypad-9", "9");
1284     DoTest("foo\nbar", "l\\ctrl-vjr\\keypad-9", "f9o\nb9r");
1285 
1286     // Testing "gq"
1287     DoTest("foo\nbar\nbaz", "Vgq", "foo\nbar\nbaz");
1288     DoTest("foo\nbar\nbaz", "Vjgq", "foo bar\nbaz");
1289 
1290     // Testing "<<"/">>"
1291     kate_document->config()->setReplaceTabsDyn(true);
1292     DoTest("foo\nbar\nbaz", "V>>", "  foo\nbar\nbaz");
1293     DoTest("foo\nbar\nbaz", "Vj>>", "  foo\n  bar\nbaz");
1294     DoTest("foo\nbar\nbaz", "V2j>>", "  foo\n  bar\n  baz");
1295     DoTest("foo\nbar\nbaz", "V10>>", "                    foo\nbar\nbaz");
1296     DoTest("foo\nbar\nbaz", "V2j3>>", "      foo\n      bar\n      baz");
1297 
1298     DoTest("  foo\nbar\nbaz", "V<<", "foo\nbar\nbaz");
1299     DoTest("foo\nbar\nbaz", "V>>V<<", "foo\nbar\nbaz");
1300     DoTest("    foo\n    bar\n    baz", "V2j<<", "  foo\n  bar\n  baz");
1301 
1302     // Testing block append
1303     DoTest("averyverylongline\nshortline\nshorter\n", "jjV$kkAb\\esc", "averyverylonglineb\nshortlineb\nshorterb\n");
1304     DoTest("averyverylongline\nshortline\n", "V$jAb\\esc", "averyverylonglineb\nshortlineb\n");
1305 
1306     // Testing "J"
1307     DoTest("foo\nbar\nxyz\nbaz\n123\n456", "jVjjjJ", "foo\nbar xyz baz 123\n456");
1308     DoTest("foo\nbar\nxyz\nbaz\n123\n456", "jjjjVkkkJ", "foo\nbar xyz baz 123\n456");
1309     DoTest("foo\nbar\nxyz\nbaz\n123456\n789", "jjjjVkkkJrX", "foo\nbar xyz bazX123456\n789");
1310     DoTest("foo\nbar\nxyz\n", "VGJ", "foo bar xyz ");
1311 
1312     // Testing undo behaviour with c and cc
1313     DoTest("foo", "ciwbar\\escu", "foo");
1314     DoTest("foo", "ccbar\\escu", "foo");
1315 
1316     // Pasting should replace the current selection.
1317     DoTest("foo bar xyz", "yiwwviwp", "foo foo xyz");
1318 
1319     // Undo should undo both paste and removal of selection.
1320     DoTest("foo bar xyz", "yiwwviwpu", "foo bar xyz");
1321     DoTest("foo\nbar\n123\nxyz", "yiwjVjp", "foo\nfoo\nxyz");
1322 
1323     // Set the *whole* selection to the given text object, even if the cursor is no
1324     // longer at the position where Visual Mode was started.
1325     // This seems to work (in Vim) only when the start of the given text object occurs before them
1326     // start position of Visual Mode.
1327     DoTest("{\nfoo\nbar\nxyz\n}", "jjvliBd", "{\n}");
1328     DoTest("foo[hello]", "fhlvli[d", "foo[]");
1329     DoTest("foo(hello)", "fhlvli(d", "foo()");
1330     DoTest("foo<hello>", "fhlvli<d", "foo<>");
1331     DoTest("foo\"hello\"", "fhlvli\"d", "foo\"\"");
1332     DoTest("foo'hello'", "fhlvli'd", "foo''");
1333 
1334     // A couple of spot tests, where the beginning of the text object occurs after the start position of Visual Mode;
1335     // the selection should  remain unchanged if we the text object motion is triggered, here.
1336     DoTest("foobarxyz\n(12345)", "llvjibd", "fo345)");
1337     DoTest("foobarxyz\n{12345}", "llvjiBd", "fo345}");
1338     // Cursor should end up at the end of the text object.
1339     DoTest("foo[hello]", "fhlvli[\\escrX", "foo[hellX]");
1340     // Ensure we reset the flag that says that the current motion is a text object!
1341     DoTest("foo[hello]", "jfhlvli[^d", "ello]");
1342 
1343     // proper yanking in block mode
1344     {
1345         BeginTest("aaaa\nbbbb\ncccc\ndddd");
1346         TestPressKey("lj\\ctrl-vljy");
1347         KateBuffer &buffer = kate_document->buffer();
1348         QVector<Kate::TextRange *> ranges = buffer.rangesForLine(1, kate_view, true);
1349         QCOMPARE(ranges.size(), 1);
1350         const KTextEditor::Range &range = ranges[0]->toRange();
1351         QCOMPARE(range.start().column(), 1);
1352         QCOMPARE(range.end().column(), 3);
1353     }
1354 
1355     // proper selection in block mode after switching to cmdline
1356     {
1357         BeginTest("aaaa\nbbbb\ncccc\ndddd");
1358         TestPressKey("lj\\ctrl-vlj:");
1359         QCOMPARE(kate_view->selectionText(), QString("bb\ncc"));
1360     }
1361 
1362     // BUG #328277 - make sure kate doesn't crash
1363     BeginTest("aaa\nbbb");
1364     TestPressKey("Vj>u>.");
1365     QCOMPARE(kate_view->renderer()->caretStyle(), KateRenderer::Block);
1366     FinishTest("aaa\nbbb");
1367 }
1368 
VisualExternalTests()1369 void ModesTest::VisualExternalTests()
1370 {
1371     // Test that selecting a range "externally" to Vim (i.e. via the mouse, or
1372     // one of the ktexteditor api's) switches us into Visual Mode.
1373     BeginTest("foo bar");
1374 
1375     // Actually selects "oo " (i.e. without the "b").
1376     kate_view->setSelection(Range(0, 1, 0, 4));
1377     TestPressKey("d");
1378     FinishTest("fbar");
1379 
1380     // Always return to normal mode when undoing/redoing.
1381     BeginTest("");
1382     TestPressKey("iHello World!\\esc");
1383     TestPressKey("0wvlldu");
1384     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::NormalMode);
1385     QCOMPARE(kate_view->selectionText(), QString(""));
1386     QCOMPARE(kate_document->text(), QString("Hello World!"));
1387     TestPressKey("u");
1388     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::NormalMode);
1389     QCOMPARE(kate_document->text(), QString(""));
1390     TestPressKey("\\ctrl-r");
1391     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::NormalMode);
1392     FinishTest("Hello World!");
1393 
1394     // Make sure that we don't screw up selection after an undo.
1395     BeginTest("Hola\nHola\nHello\nHallo\n");
1396     TestPressKey("jVjduVk");
1397     QCOMPARE(vi_input_mode_manager->getCurrentViMode(), KateVi::VisualLineMode);
1398     QCOMPARE(kate_view->selectionText(), QString("Hola\nHello"));
1399     FinishTest("Hola\nHola\nHello\nHallo\n");
1400 
1401     // Test that, if kate_view has a selection before the Vi mode stuff is loaded, then we
1402     // end up in Visual Mode: this mimics what happens if we click on a Find result in
1403     // KDevelop's "grepview" plugin.
1404     delete kate_view;
1405     kate_view = new KTextEditor::ViewPrivate(kate_document, mainWindow);
1406     kate_view->setInputMode(View::NormalInputMode);
1407     mainWindowLayout->addWidget(kate_view);
1408     kate_document->setText("foo bar");
1409     kate_view->setSelection(Range(Cursor(0, 1), Cursor(0, 4)));
1410     QCOMPARE(kate_document->text(kate_view->selectionRange()), QString("oo "));
1411     kate_view->setInputMode(View::ViInputMode);
1412     qDebug() << "selected: " << kate_document->text(kate_view->selectionRange());
1413     QVERIFY(kate_view->currentInputMode()->viewInputMode() == View::ViInputMode);
1414     vi_input_mode = dynamic_cast<KateViInputMode *>(kate_view->currentInputMode());
1415     vi_input_mode_manager = vi_input_mode->viInputModeManager();
1416     QVERIFY(vi_input_mode_manager->getCurrentViMode() == KateVi::VisualMode);
1417     TestPressKey("l");
1418     QCOMPARE(kate_document->text(kate_view->selectionRange()), QString("oo b"));
1419     TestPressKey("d");
1420     QCOMPARE(kate_document->text(), QString("far"));
1421 
1422     // Test returning to correct mode when selecting ranges with mouse
1423     BeginTest("foo bar\nbar baz");
1424     TestPressKey("i"); // get me into insert mode
1425     kate_view->setSelection(Range(0, 1, 1, 4));
1426     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::VisualMode);
1427     kate_view->setSelection(Range::invalid());
1428     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::InsertMode);
1429     TestPressKey("\\esc"); // get me into normal mode
1430     kate_view->setSelection(Range(0, 1, 1, 4));
1431     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::VisualMode);
1432     kate_view->setSelection(Range::invalid());
1433     QCOMPARE((int)vi_input_mode_manager->getCurrentViMode(), (int)KateVi::NormalMode);
1434 }
1435 
1436 // END: Visual mode.
1437 
1438 // BEGIN: Command mode.
1439 
CommandTests()1440 void ModesTest::CommandTests()
1441 {
1442     // Testing ":<num>"
1443     DoTest("foo\nbar\nbaz", "\\:2\\x", "foo\nar\nbaz");
1444     DoTest("foo\nbar\nbaz", "jmak\\:'a\\x", "foo\nar\nbaz");
1445     DoTest("foo\nbar\nbaz", "\\:$\\x", "foo\nbar\naz");
1446 
1447     // Testing ":y", ":yank"
1448     DoTest("foo\nbar\nbaz", "\\:3y\\p", "foo\nbaz\nbar\nbaz");
1449     DoTest("foo\nbar\nbaz", "\\:2y a 2\\\"ap", "foo\nbar\nbaz\nbar\nbaz");
1450     DoTest("foo\nbar\nbaz", "\\:y\\p", "foo\nfoo\nbar\nbaz");
1451     DoTest("foo\nbar\nbaz", "\\:3,1y\\p", "foo\nfoo\nbar\nbaz\nbar\nbaz");
1452 
1453     // Testing ">"
1454     DoTest("foo", "\\:>\\", "  foo");
1455     DoTest("   foo", "\\:<\\", "  foo");
1456 
1457     DoTest("foo\nbar", "\\:2>\\", "foo\n  bar");
1458     DoTest("   foo\nbaz", "\\:1<\\", "  foo\nbaz");
1459 
1460     DoTest("foo\nundo", "\\:2>\\u", "foo\nundo");
1461     DoTest("  foo\nundo", "\\:1<\\u", "  foo\nundo");
1462 
1463     DoTest("indent\nmultiline\ntext", "\\:1,2>\\", "  indent\n  multiline\ntext");
1464     DoTest("indent\nmultiline\n+undo", "\\:1,2>\\:1,2>\\:1,2>\\u", "    indent\n    multiline\n+undo");
1465     // doesn't test correctly, why?
1466     // DoTest("indent\nmultiline\n+undo", "\\:1,2>\\:1,2<\\u", "  indent\n  multiline\n+undo");
1467 
1468     // Testing ":c", ":change"
1469     DoTest("foo\nbar\nbaz", "\\:2change\\", "foo\n\nbaz");
1470     DoTest("foo\nbar\nbaz", "\\:%c\\", "");
1471     BeginTest("foo\nbar\nbaz");
1472     TestPressKey("\\:$c\\"); // Work around ambiguity in the code that parses commands to execute.
1473     TestPressKey("\\:$change\\");
1474     FinishTest("foo\nbar\n");
1475     DoTest("foo\nbar\nbaz", "ma\\:2,'achange\\", "\nbaz");
1476     DoTest("foo\nbar\nbaz", "\\:2,3c\\", "foo\n");
1477 
1478     // Testing ":j"
1479     DoTest("1\n2\n3\n4\n5", "\\:2,4j\\", "1\n2 3 4\n5");
1480 
1481     DoTest("1\n2\n3\n4", "jvj\\ctrl-c\\:'<,'>d\\enter", "1\n4");
1482     DoTest("1\n2\n3\n4", "\\:1+1+1+1d\\", "1\n2\n3");
1483     DoTest("1\n2\n3\n4", "2j\\:.,.-1d\\", "1\n4");
1484     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");
1485     DoTest("1\n2\n3\n4", "majmbjmcjmdgg\\:'a+'b+'d-'c,.d\\", "");
1486 }
1487 
CommandSedTests()1488 void ModesTest::CommandSedTests()
1489 {
1490     DoTest("foo", "\\:s/foo/bar\\", "bar");
1491     DoTest("foobarbaz", "\\:s/bar/xxx\\", "fooxxxbaz");
1492     DoTest("foo", "\\:s/bar/baz\\", "foo");
1493     DoTest("foo\nfoo\nfoo", "j\\:s/foo/bar\\", "foo\nbar\nfoo");
1494     DoTest("foo\nfoo\nfoo", "2jma2k\\:'a,'as/foo/bar\\", "foo\nfoo\nbar");
1495     DoTest("foo\nfoo\nfoo", "\\:%s/foo/bar\\", "bar\nbar\nbar");
1496     DoTest("foo\nfoo\nfoo", "\\:2,3s/foo/bar\\", "foo\nbar\nbar");
1497     DoTest("foo\nfoo\nfoo\nfoo", "j2lmajhmbgg\\:'a,'bs/foo/bar\\", "foo\nbar\nbar\nfoo");
1498     DoTest("foo\nfoo\nfoo\nfoo", "jlma2jmbgg\\:'b,'as/foo/bar\\", "foo\nbar\nbar\nbar");
1499     DoTest("foo", "\\:s/$/x/g\\", "foox");
1500     DoTest("foo", "\\:s/.*/x/g\\", "x");
1501     DoTest("abc", "\\:s/\\\\s*/x/g\\", "xaxbxc");
1502     // DoTest("abc\n123", "\\:s/\\\\s*/x/g\\", "xaxbxc\nx1x2x3"); // currently not working properly
1503 
1504     DoTest("foo/bar", "\\:s-/--\\", "foobar");
1505     DoTest("foo/bar", "\\:s_/__\\", "foobar");
1506 
1507     DoTest("foo\nfoo\nfoo", "\\:2s/foo/bar\\", "foo\nbar\nfoo");
1508     DoTest("foo\nfoo\nfoo", "2jmagg\\:'as/foo/bar\\", "foo\nfoo\nbar");
1509     DoTest("foo\nfoo\nfoo", "\\:$s/foo/bar\\", "foo\nfoo\nbar");
1510 
1511     // https://bugs.kde.org/show_bug.cgi?id=235862
1512     DoTest("try\n\nalso\nfoo", "\\:/r/,/o/s/^/ha/\\", "hatry\nha\nhaalso\nfoo");
1513     DoTest("much\nmuch\nmuch\nmuch", "\\:.,.+2s/much/try/\\", "try\ntry\ntry\nmuch");
1514 }
1515 
CommandDeleteTests()1516 void ModesTest::CommandDeleteTests()
1517 {
1518     DoTest("foo\nbar\nbaz", "\\:2d\\", "foo\nbaz");
1519     DoTest("foo\nbar\nbaz", "\\:%d\\", "");
1520     BeginTest("foo\nbar\nbaz");
1521     TestPressKey("\\:$d\\"); // Work around ambiguity in the code that parses commands to execute.
1522     TestPressKey("\\:$d\\");
1523     FinishTest("foo");
1524     DoTest("foo\nbar\nbaz", "ma\\:2,'ad\\", "baz");
1525     DoTest("foo\nbar\nbaz", "\\:/foo/,/bar/d\\", "baz");
1526     DoTest("foo\nbar\nbaz", "\\:2,3delete\\", "foo");
1527 
1528     DoTest("foo\nbar\nbaz", "\\:d\\", "bar\nbaz");
1529     DoTest("foo\nbar\nbaz", "\\:d 33\\", "");
1530     DoTest("foo\nbar\nbaz", "\\:3d a\\k\"ap", "foo\nbaz\nbar");
1531 }
1532 
1533 // END: Command mode.
1534 
1535 // BEGIN: Replace mode.
1536 
ReplaceCharacter()1537 void ModesTest::ReplaceCharacter()
1538 {
1539     DoTest("", "rr", "");
1540     DoTest("a", "rb", "b");
1541     DoTest("abc", "lr\\enter", "a\nc");
1542     DoTest("abc", "l\\backspace", "abc");
1543     DoTest("abc", "l\\left", "abc");
1544 }
1545 
ReplaceBasicTests()1546 void ModesTest::ReplaceBasicTests()
1547 {
1548     // Basic stuff.
1549     DoTest("", "Rqwerty", "qwerty");
1550     DoTest("qwerty", "R\\rightXX", "qXXrty");
1551 
1552     // Enter replace and go to the next/previous word.
1553     DoTest("foo bar", "R\\ctrl-\\rightX", "foo Xar");
1554     DoTest("foo bar", "R\\ctrl-\\right\\ctrl-\\rightX", "foo barX");
1555     DoTest("foo bar", "R\\ctrl-\\leftX", "Xoo bar");
1556     DoTest("foo bar", "R\\ctrl-\\left\\delete", "oo bar");
1557 
1558     // Enter replace mode and go up/down.
1559     DoTest("foo\nbar\nbaz", "R\\downX", "foo\nXar\nbaz");
1560     DoTest("foo\nbar\nbaz", "jjR\\upX", "foo\nXar\nbaz");
1561 
1562     // Repeat replacements
1563     DoTest("foobaz", "Rbar\\esc.", "babarz");
1564     DoTest("foobarbaz", "Rbar\\esc2.", "babarbarz");
1565     DoTest("foobarbaz", "Rbar\\esc4.", "babarbarbarbar");
1566     DoTest("foobarbaz", "Rbar\\esc2.R\\esc2.", "babarbarz");
1567 }
1568 
ReplaceUndoTests()1569 void ModesTest::ReplaceUndoTests()
1570 {
1571     // Backspace.
1572     DoTest("", "R\\backspace", "");
1573     DoTest("qwerty", "lR\\backspaceX", "Xwerty");
1574     DoTest("qwerty", "lRX\\backspace\\backspaceX", "Xwerty");
1575 
1576     // Ctrl-W
1577     DoTest("", "R\\ctrl-w", "");
1578     DoTest("Hello", "lRXX\\ctrl-w", "Hello");
1579     DoTest("Hello", "lR\t\\ctrl-w", "Hello");
1580     DoTest("Hello", "lRXX\\left\\ctrl-w", "HXXlo");
1581 
1582     // Ctrl-U
1583     DoTest("", "R\\ctrl-u", "");
1584     DoTest("Hello", "lRXX\\ctrl-u", "Hello");
1585     DoTest("Hello", "lR\t\\ctrl-u", "Hello");
1586     DoTest("Hello", "lRXX\\left\\ctrl-u", "HXXlo");
1587     DoTest("Hello World", "3lRXX XX\\ctrl-u", "Hello World");
1588 }
1589 
ReplaceInsertFromLineTests()1590 void ModesTest::ReplaceInsertFromLineTests()
1591 {
1592     // Ctrl-E: replace the current column with the column of the next line.
1593     DoTest("", "R\\ctrl-e", "");
1594     DoTest("\n", "jR\\ctrl-e", "\n");
1595     DoTest("\nqwerty", "R\\ctrl-e\\ctrl-e", "qw\nqwerty");
1596     DoTest("a\nbb", "R\\ctrl-e\\ctrl-e", "bb\nbb");
1597     DoTest("aa\n b", "R\\ctrl-e\\ctrl-e", " b\n b");
1598     DoTest("\n\tb", "R\\ctrl-e\\ctrl-e", "\tb\n\tb");
1599 
1600     // Ctrl-Y: replace the current column with the column of the previous line.
1601     DoTest("", "R\\ctrl-y", "");
1602     DoTest("qwerty\n", "jR\\ctrl-y\\ctrl-y", "qwerty\nqw");
1603     DoTest("aa\nb", "jR\\ctrl-y\\ctrl-y", "aa\naa");
1604     DoTest(" a\nbb", "jR\\ctrl-y\\ctrl-y", " a\n a");
1605     DoTest("\tb\n", "jR\\ctrl-y\\ctrl-y", "\tb\n\tb");
1606 }
1607 
1608 // END: Replace mode.
1609