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