1" Test for textobjects
2
3source check.vim
4CheckFeature textobjects
5
6func CpoM(line, useM, expected)
7  new
8
9  if a:useM
10    set cpoptions+=M
11  else
12    set cpoptions-=M
13  endif
14
15  call setline(1, a:line)
16
17  call setreg('"', '')
18  normal! ggfrmavi)y
19  call assert_equal(getreg('"'), a:expected[0])
20
21  call setreg('"', '')
22  normal! `afbmavi)y
23  call assert_equal(getreg('"'), a:expected[1])
24
25  call setreg('"', '')
26  normal! `afgmavi)y
27  call assert_equal(getreg('"'), a:expected[2])
28
29  q!
30endfunc
31
32func Test_inner_block_without_cpo_M()
33  call CpoM('(red \(blue) green)', 0, ['red \(blue', 'red \(blue', ''])
34endfunc
35
36func Test_inner_block_with_cpo_M_left_backslash()
37  call CpoM('(red \(blue) green)', 1, ['red \(blue) green', 'blue', 'red \(blue) green'])
38endfunc
39
40func Test_inner_block_with_cpo_M_right_backslash()
41  call CpoM('(red (blue\) green)', 1, ['red (blue\) green', 'blue\', 'red (blue\) green'])
42endfunc
43
44func Test_quote_selection_selection_exclusive()
45  new
46  call setline(1, "a 'bcde' f")
47  set selection=exclusive
48
49  exe "norm! fdvhi'y"
50  call assert_equal('bcde', @")
51
52  let @"='dummy'
53  exe "norm! $gevi'y"
54  call assert_equal('bcde', @")
55
56  let @"='dummy'
57  exe "norm! 0fbhvi'y"
58  call assert_equal('bcde', @")
59
60  set selection&vim
61  bw!
62endfunc
63
64func Test_quote_selection_selection_exclusive_abort()
65  new
66  set selection=exclusive
67  call setline(1, "'abzzc'")
68  let exp_curs = [0, 1, 6, 0]
69  call cursor(1,1)
70  exe 'norm! fcdvi"'
71  " make sure to end visual mode to have a clear state
72  exe "norm! \<esc>"
73  call assert_equal(exp_curs, getpos('.'))
74  call cursor(1,1)
75  exe 'norm! fcvi"'
76  exe "norm! \<esc>"
77  call assert_equal(exp_curs, getpos('.'))
78  call cursor(1,2)
79  exe 'norm! vfcoi"'
80  exe "norm! \<esc>"
81  let exp_curs = [0, 1, 2, 0]
82  let exp_visu = [0, 1, 7, 0]
83  call assert_equal(exp_curs, getpos('.'))
84  call assert_equal(exp_visu, getpos("'>"))
85  set selection&vim
86  bw!
87endfunc
88
89" Tests for string and html text objects
90func Test_string_html_objects()
91  enew!
92
93  let t = '"wo\"rd\\" foo'
94  put =t
95  normal! da"
96  call assert_equal('foo', getline('.'))
97
98  let t = "'foo' 'bar' 'piep'"
99  put =t
100  normal! 0va'a'rx
101  call assert_equal("xxxxxxxxxxxx'piep'", getline('.'))
102
103  let t = "bla bla `quote` blah"
104  put =t
105  normal! 02f`da`
106  call assert_equal("bla bla blah", getline('.'))
107
108  let t = 'out " in "noXno"'
109  put =t
110  normal! 0fXdi"
111  call assert_equal('out " in ""', getline('.'))
112
113  let t = "\"'\" 'blah' rep 'buh'"
114  put =t
115  normal! 03f'vi'ry
116  call assert_equal("\"'\" 'blah'yyyyy'buh'", getline('.'))
117
118  set quoteescape=+*-
119  let t = "bla `s*`d-`+++`l**` b`la"
120  put =t
121  normal! di`
122  call assert_equal("bla `` b`la", getline('.'))
123
124  let t = 'voo "nah" sdf " asdf" sdf " sdf" sd'
125  put =t
126  normal! $F"va"oha"i"rz
127  call assert_equal('voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd', getline('.'))
128
129  let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
130  put =t
131  normal! fXdit
132  call assert_equal('-<b>asdf<i></i>asdf</b>-', getline('.'))
133
134  let t = "-<b>asdX<i>a<i />sdf</i>asdf</b>-"
135  put =t
136  normal! 0fXdit
137  call assert_equal('-<b></b>-', getline('.'))
138
139  let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
140  put =t
141  normal! fXdat
142  call assert_equal('-<b>asdfasdf</b>-', getline('.'))
143
144  let t = "-<b>asdX<i>as<b />df</i>asdf</b>-"
145  put =t
146  normal! 0fXdat
147  call assert_equal('--', getline('.'))
148
149  let t = "-<b>\ninnertext object\n</b>"
150  put =t
151  normal! dit
152  call assert_equal('-<b></b>', getline('.'))
153
154  " copy the tag block from leading indentation before the start tag
155  let t = "    <b>\ntext\n</b>"
156  $put =t
157  normal! 2kvaty
158  call assert_equal("<b>\ntext\n</b>", @")
159
160  " copy the tag block from the end tag
161  let t = "<title>\nwelcome\n</title>"
162  $put =t
163  normal! $vaty
164  call assert_equal("<title>\nwelcome\n</title>", @")
165
166  " copy the outer tag block from a tag without an end tag
167  let t = "<html>\n<title>welcome\n</html>"
168  $put =t
169  normal! k$vaty
170  call assert_equal("<html>\n<title>welcome\n</html>", @")
171
172  set quoteescape&
173  enew!
174endfunc
175
176func Test_empty_html_tag()
177  new
178  call setline(1, '<div></div>')
179  normal 0citxxx
180  call assert_equal('<div>xxx</div>', getline(1))
181
182  call setline(1, '<div></div>')
183  normal 0f<cityyy
184  call assert_equal('<div>yyy</div>', getline(1))
185
186  call setline(1, '<div></div>')
187  normal 0f<vitsaaa
188  call assert_equal('aaa', getline(1))
189
190  " selecting a tag block in an non-empty blank line should fail
191  call setline(1, '    ')
192  call assert_beeps('normal $vaty')
193
194  bwipe!
195endfunc
196
197" Tests for match() and matchstr()
198func Test_match()
199  call assert_equal("b", matchstr("abcd", ".", 0, 2))
200  call assert_equal("bc", matchstr("abcd", "..", 0, 2))
201  call assert_equal("c", matchstr("abcd", ".", 2, 0))
202  call assert_equal("a", matchstr("abcd", ".", 0, -1))
203  call assert_equal(-1, match("abcd", ".", 0, 5))
204  call assert_equal(0 , match("abcd", ".", 0, -1))
205  call assert_equal(0 , match('abc', '.', 0, 1))
206  call assert_equal(1 , match('abc', '.', 0, 2))
207  call assert_equal(2 , match('abc', '.', 0, 3))
208  call assert_equal(-1, match('abc', '.', 0, 4))
209  call assert_equal(1 , match('abc', '.', 1, 1))
210  call assert_equal(2 , match('abc', '.', 2, 1))
211  call assert_equal(-1, match('abc', '.', 3, 1))
212  call assert_equal(3 , match('abc', '$', 0, 1))
213  call assert_equal(-1, match('abc', '$', 0, 2))
214  call assert_equal(3 , match('abc', '$', 1, 1))
215  call assert_equal(3 , match('abc', '$', 2, 1))
216  call assert_equal(3 , match('abc', '$', 3, 1))
217  call assert_equal(-1, match('abc', '$', 4, 1))
218  call assert_equal(0 , match('abc', '\zs', 0, 1))
219  call assert_equal(1 , match('abc', '\zs', 0, 2))
220  call assert_equal(2 , match('abc', '\zs', 0, 3))
221  call assert_equal(3 , match('abc', '\zs', 0, 4))
222  call assert_equal(-1, match('abc', '\zs', 0, 5))
223  call assert_equal(1 , match('abc', '\zs', 1, 1))
224  call assert_equal(2 , match('abc', '\zs', 2, 1))
225  call assert_equal(3 , match('abc', '\zs', 3, 1))
226  call assert_equal(-1, match('abc', '\zs', 4, 1))
227endfunc
228
229" This was causing an illegal memory access
230func Test_inner_tag()
231  new
232  norm ixxx
233  call feedkeys("v", 'xt')
234  insert
235x
236x
237.
238  norm it
239  q!
240endfunc
241
242func Test_sentence()
243  enew!
244  call setline(1, 'A sentence.  A sentence?  A sentence!')
245
246  normal yis
247  call assert_equal('A sentence.', @")
248  normal yas
249  call assert_equal('A sentence.  ', @")
250
251  normal )
252
253  normal yis
254  call assert_equal('A sentence?', @")
255  normal yas
256  call assert_equal('A sentence?  ', @")
257
258  normal )
259
260  normal yis
261  call assert_equal('A sentence!', @")
262  normal yas
263  call assert_equal('  A sentence!', @")
264
265  normal 0
266  normal 2yis
267  call assert_equal('A sentence.  ', @")
268  normal 3yis
269  call assert_equal('A sentence.  A sentence?', @")
270  normal 2yas
271  call assert_equal('A sentence.  A sentence?  ', @")
272
273  %delete _
274endfunc
275
276func Test_sentence_with_quotes()
277  enew!
278  call setline(1, 'A "sentence."  A sentence.')
279
280  normal yis
281  call assert_equal('A "sentence."', @")
282  normal yas
283  call assert_equal('A "sentence."  ', @")
284
285  normal )
286
287  normal yis
288  call assert_equal('A sentence.', @")
289  normal yas
290  call assert_equal('  A sentence.', @")
291
292  %delete _
293endfunc
294
295func Test_sentence_with_cursor_on_delimiter()
296  enew!
297  call setline(1, "A '([sentence.])'  A sentence.")
298
299  normal! 15|yis
300  call assert_equal("A '([sentence.])'", @")
301  normal! 15|yas
302  call assert_equal("A '([sentence.])'  ", @")
303
304  normal! 16|yis
305  call assert_equal("A '([sentence.])'", @")
306  normal! 16|yas
307  call assert_equal("A '([sentence.])'  ", @")
308
309  normal! 17|yis
310  call assert_equal("A '([sentence.])'", @")
311  normal! 17|yas
312  call assert_equal("A '([sentence.])'  ", @")
313
314  %delete _
315endfunc
316
317" Test for the paragraph (ap) text object
318func Test_paragraph()
319  new
320  call setline(1, ['First line.', 'Second line.', 'Third line.'])
321  call cursor(2, 1)
322  normal vapy
323  call assert_equal("First line.\nSecond line.\nThird line.\n", @")
324
325  call cursor(2, 1)
326  call assert_beeps('normal vapapy')
327
328  call setline(1, ['First line.', 'Second line.', '  ', ''])
329  call cursor(1, 1)
330  normal vapy
331  call assert_equal("First line.\nSecond line.\n  \n\n", @")
332
333  call setline(1, ['', '', '', 'First line.', 'Second line.'])
334  call cursor(2, 1)
335  normal yap
336  call assert_equal("\n\n\nFirst line.\nSecond line.\n", @")
337  call assert_beeps('normal 3yap')
338  exe "normal \<C-C>"
339
340  %d
341  call setline(1, ['  ', '  ', '  '])
342  call cursor(2, 1)
343  normal Vipy
344  call assert_equal("  \n  \n  \n", @")
345  call cursor(2, 1)
346  call assert_beeps("normal Vipip")
347  exe "normal \<C-C>"
348
349  close!
350endfunc
351
352" Tests for text object aw
353func Test_textobj_a_word()
354  new
355  call append(0, ['foobar,eins,foobar', 'foo,zwei,foo    '])
356  " diw
357  norm! 1gg0diw
358  call assert_equal([',eins,foobar', 'foo,zwei,foo    ', ''], getline(1,'$'))
359  " daw
360  norm! 2ggEdaw
361  call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$'))
362  " daw the last word in a line
363  call setline(1, ['foo bar', 'foo bar', ''])
364  call cursor(1, 5)
365  normal daw
366  call assert_equal('foo', getline(1))
367  " aw in visual mode
368  call cursor(2, 5)
369  normal! vawx
370  call assert_equal('foo', getline(2))
371  %d
372  call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo   "])
373  " diW
374  norm! 2ggwd2iW
375  call assert_equal(['foo	eins	foobar', 'foo	foo   ', ''], getline(1,'$'))
376  " daW
377  norm! 1ggd2aW
378  call assert_equal(['foobar', 'foo	foo   ', ''], getline(1,'$'))
379
380  %d
381  call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo   "])
382  " aw in visual line mode switches to characterwise mode
383  norm! 2gg$Vawd
384  call assert_equal(['foo	eins	foobar', 'foo	zwei	foo'], getline(1,'$'))
385  norm! 1gg$Viwd
386  call assert_equal(['foo	eins	', 'foo	zwei	foo'], getline(1,'$'))
387
388  " visually selecting a tab before a word with 'selection' set to 'exclusive'
389  set selection=exclusive
390  normal gg3lvlawy
391  call assert_equal("\teins", @")
392  " visually selecting a tab before a word with 'selection' set to 'inclusive'
393  set selection=inclusive
394  normal gg3lvlawy
395  call assert_equal("\teins\t", @")
396  set selection&
397
398  " selecting a word with no non-space characters in a buffer fails
399  %d
400  call setline(1, '    ')
401  call assert_beeps('normal 3lyaw')
402
403  " visually selecting words backwards with no more words to select
404  call setline(1, 'one two')
405  call assert_beeps('normal 2lvh2aw')
406  exe "normal \<C-C>"
407  call assert_beeps('normal $vh3aw')
408  exe "normal \<C-C>"
409  call setline(1, ['', 'one two'])
410  call assert_beeps('normal 2G2lvh3aw')
411  exe "normal \<C-C>"
412
413  " selecting words forward with no more words to select
414  %d
415  call setline(1, 'one a')
416  call assert_beeps('normal 0y3aw')
417  call setline(1, 'one two ')
418  call assert_beeps('normal 0y3aw')
419  call assert_beeps('normal 03ly2aw')
420
421  " clean up
422  bw!
423endfunc
424
425" Test for is and as text objects
426func Test_textobj_sentence()
427  new
428  call append(0, ['This is a test. With some sentences!', '',
429        \ 'Even with a question? And one more. And no sentence here'])
430  " Test for dis - does not remove trailing whitespace
431  norm! 1gg0dis
432  call assert_equal([' With some sentences!', '',
433        \ 'Even with a question? And one more. And no sentence here', ''],
434        \ getline(1,'$'))
435  " Test for das - removes leading whitespace
436  norm! 3ggf?ldas
437  call assert_equal([' With some sentences!', '',
438        \ 'Even with a question? And no sentence here', ''], getline(1,'$'))
439  " when used in visual mode, is made characterwise
440  norm! 3gg$Visy
441  call assert_equal('v', visualmode())
442  " reset visualmode()
443  norm! 3ggVy
444  norm! 3gg$Vasy
445  call assert_equal('v', visualmode())
446  " basic testing for textobjects a< and at
447  %d
448  call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>','    </div>', ' '])
449  " a<
450  norm! 1gg0da<
451  call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', '    </div>', ' '], getline(1,'$'))
452  norm! 1pj
453  call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', '    </div>', ' '], getline(1,'$'))
454  " at
455  norm! d2at
456  call assert_equal([' '], getline(1,'$'))
457  %d
458  call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>','    </div>', ' '])
459  " i<
460  norm! 1gg0di<
461  call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', '    </div>', ' '], getline(1,'$'))
462  norm! 1Pj
463  call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', '    </div>', ' '], getline(1,'$'))
464  norm! d2it
465  call assert_equal(['<div></div>',' '], getline(1,'$'))
466  " basic testing for a[ and i[ text object
467  %d
468  call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
469  norm! 3gg0di[
470  call assert_equal([' ', '[', ']'], getline(1,'$'))
471  call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
472  norm! 3gg0ftd2a[
473  call assert_equal([' '], getline(1,'$'))
474
475  " clean up
476  bw!
477endfunc
478
479" Test for quote (', " and `) textobjects
480func Test_textobj_quote()
481  new
482
483  " Test for i" when cursor is in front of a quoted object
484  call append(0, 'foo "bar"')
485  norm! 1gg0di"
486  call assert_equal(['foo ""', ''], getline(1,'$'))
487
488  " Test for visually selecting an inner quote
489  %d
490  " extend visual selection from one quote to the next
491  call setline(1, 'color "red" color "blue"')
492  call cursor(1, 7)
493  normal v4li"y
494  call assert_equal('"red" color "blue', @")
495
496  " try to extend visual selection from one quote to a non-existing quote
497  call setline(1, 'color "red" color blue')
498  call cursor(1, 7)
499  call feedkeys('v4li"y', 'xt')
500  call assert_equal('"red"', @")
501
502  " try to extend visual selection from one quote to a next partial quote
503  call setline(1, 'color "red" color "blue')
504  call cursor(1, 7)
505  normal v4li"y
506  call assert_equal('"red" color ', @")
507
508  " select a quote backwards in visual mode
509  call cursor(1, 12)
510  normal vhi"y
511  call assert_equal('red" ', @")
512  call assert_equal(8, col('.'))
513
514  " select a quote backwards in visual mode from outside the quote
515  call cursor(1, 17)
516  normal v2hi"y
517  call assert_equal('red', @")
518  call assert_equal(8, col('.'))
519
520  " visually selecting a quote with 'selection' set to 'exclusive'
521  call setline(1, 'He said "How are you?"')
522  set selection=exclusive
523  normal 012lv2li"y
524  call assert_equal('How are you?', @")
525  set selection&
526
527  " try copy a quote object with a single quote in the line
528  call setline(1, "Smith's car")
529  call cursor(1, 6)
530  call assert_beeps("normal yi'")
531  call assert_beeps("normal 2lyi'")
532
533  " selecting space before and after a quoted string
534  call setline(1, "some    'special'    string")
535  normal 0ya'
536  call assert_equal("'special'    ", @")
537  call setline(1, "some    'special'string")
538  normal 0ya'
539  call assert_equal("    'special'", @")
540
541  close!
542endfunc
543
544" vim: shiftwidth=2 sts=2 expandtab
545