blob: 4d620eab876c0cb5d90f45d120f218ddb7d70107 [file] [log] [blame]
Bram Moolenaar98aefe72018-12-13 22:20:09 +01001" Tests for defining text property types and adding text properties to the
2" buffer.
3
4if !has('textprop')
5 finish
6endif
7
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +01008source screendump.vim
9
Bram Moolenaarb9c67a52019-01-01 19:49:20 +010010" test length zero
11
Bram Moolenaar98aefe72018-12-13 22:20:09 +010012func Test_proptype_global()
13 call prop_type_add('comment', {'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1})
14 let proptypes = prop_type_list()
15 call assert_equal(1, len(proptypes))
16 call assert_equal('comment', proptypes[0])
17
18 let proptype = prop_type_get('comment')
19 call assert_equal('Directory', proptype['highlight'])
20 call assert_equal(123, proptype['priority'])
21 call assert_equal(1, proptype['start_incl'])
22 call assert_equal(1, proptype['end_incl'])
23
24 call prop_type_delete('comment')
25 call assert_equal(0, len(prop_type_list()))
26
27 call prop_type_add('one', {})
28 call assert_equal(1, len(prop_type_list()))
29 let proptype = prop_type_get('one')
30 call assert_false(has_key(proptype, 'highlight'))
31 call assert_equal(0, proptype['priority'])
32 call assert_equal(0, proptype['start_incl'])
33 call assert_equal(0, proptype['end_incl'])
34
35 call prop_type_add('two', {})
36 call assert_equal(2, len(prop_type_list()))
37 call prop_type_delete('one')
38 call assert_equal(1, len(prop_type_list()))
39 call prop_type_delete('two')
40 call assert_equal(0, len(prop_type_list()))
41endfunc
42
43func Test_proptype_buf()
44 let bufnr = bufnr('')
45 call prop_type_add('comment', {'bufnr': bufnr, 'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1})
46 let proptypes = prop_type_list({'bufnr': bufnr})
47 call assert_equal(1, len(proptypes))
48 call assert_equal('comment', proptypes[0])
49
50 let proptype = prop_type_get('comment', {'bufnr': bufnr})
51 call assert_equal('Directory', proptype['highlight'])
52 call assert_equal(123, proptype['priority'])
53 call assert_equal(1, proptype['start_incl'])
54 call assert_equal(1, proptype['end_incl'])
55
56 call prop_type_delete('comment', {'bufnr': bufnr})
57 call assert_equal(0, len(prop_type_list({'bufnr': bufnr})))
58
59 call prop_type_add('one', {'bufnr': bufnr})
60 let proptype = prop_type_get('one', {'bufnr': bufnr})
61 call assert_false(has_key(proptype, 'highlight'))
62 call assert_equal(0, proptype['priority'])
63 call assert_equal(0, proptype['start_incl'])
64 call assert_equal(0, proptype['end_incl'])
65
66 call prop_type_add('two', {'bufnr': bufnr})
67 call assert_equal(2, len(prop_type_list({'bufnr': bufnr})))
68 call prop_type_delete('one', {'bufnr': bufnr})
69 call assert_equal(1, len(prop_type_list({'bufnr': bufnr})))
70 call prop_type_delete('two', {'bufnr': bufnr})
71 call assert_equal(0, len(prop_type_list({'bufnr': bufnr})))
72endfunc
73
74func AddPropTypes()
75 call prop_type_add('one', {})
76 call prop_type_add('two', {})
77 call prop_type_add('three', {})
78 call prop_type_add('whole', {})
79endfunc
80
81func DeletePropTypes()
82 call prop_type_delete('one')
83 call prop_type_delete('two')
84 call prop_type_delete('three')
85 call prop_type_delete('whole')
86endfunc
87
88func SetupPropsInFirstLine()
89 call setline(1, 'one two three')
90 call prop_add(1, 1, {'length': 3, 'id': 11, 'type': 'one'})
91 call prop_add(1, 5, {'length': 3, 'id': 12, 'type': 'two'})
Bram Moolenaar4164bb22019-01-04 23:09:49 +010092 call prop_add(1, 9, {'length': 5, 'id': 13, 'type': 'three'})
Bram Moolenaar98aefe72018-12-13 22:20:09 +010093 call prop_add(1, 1, {'length': 13, 'id': 14, 'type': 'whole'})
94endfunc
95
Bram Moolenaar4164bb22019-01-04 23:09:49 +010096func Get_expected_props()
97 return [
98 \ {'col': 1, 'length': 13, 'id': 14, 'type': 'whole', 'start': 1, 'end': 1},
Bram Moolenaar98aefe72018-12-13 22:20:09 +010099 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
100 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100101 \ {'col': 9, 'length': 5, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100102 \ ]
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100103endfunc
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100104
105func Test_prop_add()
106 new
107 call AddPropTypes()
108 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100109 let expected_props = Get_expected_props()
110 call assert_equal(expected_props, prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100111 call assert_fails("call prop_add(10, 1, {'length': 1, 'id': 14, 'type': 'whole'})", 'E966:')
112 call assert_fails("call prop_add(1, 22, {'length': 1, 'id': 14, 'type': 'whole'})", 'E964:')
113
114 " Insert a line above, text props must still be there.
115 call append(0, 'empty')
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100116 call assert_equal(expected_props, prop_list(2))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100117 " Delete a line above, text props must still be there.
118 1del
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100119 call assert_equal(expected_props, prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100120
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100121 " Prop without length or end column is zero length
122 call prop_clear(1)
123 call prop_add(1, 5, {'type': 'two'})
124 let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}]
125 call assert_equal(expected, prop_list(1))
126
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100127 call DeletePropTypes()
128 bwipe!
129endfunc
130
131func Test_prop_remove()
132 new
133 call AddPropTypes()
134 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100135 let props = Get_expected_props()
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100136 call assert_equal(props, prop_list(1))
137
138 " remove by id
139 call prop_remove({'id': 12}, 1)
140 unlet props[2]
141 call assert_equal(props, prop_list(1))
142
143 " remove by type
144 call prop_remove({'type': 'one'}, 1)
145 unlet props[1]
146 call assert_equal(props, prop_list(1))
147
148 call DeletePropTypes()
149 bwipe!
150endfunc
151
Bram Moolenaar196d1572019-01-02 23:47:18 +0100152func SetupOneLine()
153 call setline(1, 'xonex xtwoxx')
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200154 normal gg0
Bram Moolenaar196d1572019-01-02 23:47:18 +0100155 call AddPropTypes()
156 call prop_add(1, 2, {'length': 3, 'id': 11, 'type': 'one'})
157 call prop_add(1, 8, {'length': 3, 'id': 12, 'type': 'two'})
158 let expected = [
159 \ {'col': 2, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
160 \ {'col': 8, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
161 \]
162 call assert_equal(expected, prop_list(1))
163 return expected
164endfunc
165
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100166func Test_prop_add_remove_buf()
167 new
168 let bufnr = bufnr('')
169 call AddPropTypes()
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100170 for lnum in range(1, 4)
171 call setline(lnum, 'one two three')
172 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100173 wincmd w
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100174 for lnum in range(1, 4)
175 call prop_add(lnum, 1, {'length': 3, 'id': 11, 'type': 'one', 'bufnr': bufnr})
176 call prop_add(lnum, 5, {'length': 3, 'id': 12, 'type': 'two', 'bufnr': bufnr})
177 call prop_add(lnum, 11, {'length': 3, 'id': 13, 'type': 'three', 'bufnr': bufnr})
178 endfor
179
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100180 let props = [
181 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
182 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
183 \ {'col': 11, 'length': 3, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
184 \]
185 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100186
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100187 " remove by id
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100188 let before_props = deepcopy(props)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100189 unlet props[1]
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100190
191 call prop_remove({'id': 12, 'bufnr': bufnr}, 1)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100192 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100193 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
194 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr}))
195 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr}))
196
197 call prop_remove({'id': 12, 'bufnr': bufnr}, 3, 4)
198 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
199 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
200 call assert_equal(props, prop_list(3, {'bufnr': bufnr}))
201 call assert_equal(props, prop_list(4, {'bufnr': bufnr}))
202
203 call prop_remove({'id': 12, 'bufnr': bufnr})
204 for lnum in range(1, 4)
205 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr}))
206 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100207
208 " remove by type
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100209 let before_props = deepcopy(props)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100210 unlet props[0]
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100211
212 call prop_remove({'type': 'one', 'bufnr': bufnr}, 1)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100213 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100214 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
215 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr}))
216 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr}))
217
218 call prop_remove({'type': 'one', 'bufnr': bufnr}, 3, 4)
219 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
220 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
221 call assert_equal(props, prop_list(3, {'bufnr': bufnr}))
222 call assert_equal(props, prop_list(4, {'bufnr': bufnr}))
223
224 call prop_remove({'type': 'one', 'bufnr': bufnr})
225 for lnum in range(1, 4)
226 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr}))
227 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100228
229 call DeletePropTypes()
230 wincmd w
231 bwipe!
232endfunc
233
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100234func Test_prop_backspace()
235 new
236 set bs=2
Bram Moolenaar196d1572019-01-02 23:47:18 +0100237 let expected = SetupOneLine() " 'xonex xtwoxx'
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100238
239 exe "normal 0li\<BS>\<Esc>fxli\<BS>\<Esc>"
240 call assert_equal('one xtwoxx', getline(1))
241 let expected[0].col = 1
242 let expected[1].col = 6
243 call assert_equal(expected, prop_list(1))
244
245 call DeletePropTypes()
246 bwipe!
247 set bs&
248endfunc
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100249
Bram Moolenaar196d1572019-01-02 23:47:18 +0100250func Test_prop_replace()
251 new
252 set bs=2
253 let expected = SetupOneLine() " 'xonex xtwoxx'
254
255 exe "normal 0Ryyy\<Esc>"
256 call assert_equal('yyyex xtwoxx', getline(1))
257 call assert_equal(expected, prop_list(1))
258
259 exe "normal ftRyy\<BS>"
260 call assert_equal('yyyex xywoxx', getline(1))
261 call assert_equal(expected, prop_list(1))
262
263 exe "normal 0fwRyy\<BS>"
264 call assert_equal('yyyex xyyoxx', getline(1))
265 call assert_equal(expected, prop_list(1))
266
267 exe "normal 0foRyy\<BS>\<BS>"
268 call assert_equal('yyyex xyyoxx', getline(1))
269 call assert_equal(expected, prop_list(1))
270
271 call DeletePropTypes()
272 bwipe!
273 set bs&
274endfunc
275
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200276func Test_prop_open_line()
277 new
278
279 " open new line, props stay in top line
280 let expected = SetupOneLine() " 'xonex xtwoxx'
281 exe "normal o\<Esc>"
282 call assert_equal('xonex xtwoxx', getline(1))
283 call assert_equal('', getline(2))
284 call assert_equal(expected, prop_list(1))
285 call DeletePropTypes()
286
287 " move all props to next line
288 let expected = SetupOneLine() " 'xonex xtwoxx'
289 exe "normal 0i\<CR>\<Esc>"
290 call assert_equal('', getline(1))
291 call assert_equal('xonex xtwoxx', getline(2))
292 call assert_equal(expected, prop_list(2))
293 call DeletePropTypes()
294
295 " split just before prop, move all props to next line
296 let expected = SetupOneLine() " 'xonex xtwoxx'
297 exe "normal 0li\<CR>\<Esc>"
298 call assert_equal('x', getline(1))
299 call assert_equal('onex xtwoxx', getline(2))
300 let expected[0].col -= 1
301 let expected[1].col -= 1
302 call assert_equal(expected, prop_list(2))
303 call DeletePropTypes()
304
305 " split inside prop, split first prop
306 let expected = SetupOneLine() " 'xonex xtwoxx'
307 exe "normal 0lli\<CR>\<Esc>"
308 call assert_equal('xo', getline(1))
309 call assert_equal('nex xtwoxx', getline(2))
310 let exp_first = [deepcopy(expected[0])]
311 let exp_first[0].length = 1
312 call assert_equal(exp_first, prop_list(1))
313 let expected[0].col = 1
314 let expected[0].length = 2
315 let expected[1].col -= 2
316 call assert_equal(expected, prop_list(2))
317 call DeletePropTypes()
318
Bram Moolenaar5c65e6a2019-05-17 11:08:56 +0200319 " split just after first prop, second prop move to next line
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200320 let expected = SetupOneLine() " 'xonex xtwoxx'
321 exe "normal 0fea\<CR>\<Esc>"
322 call assert_equal('xone', getline(1))
323 call assert_equal('x xtwoxx', getline(2))
324 let exp_first = expected[0:0]
325 call assert_equal(exp_first, prop_list(1))
Bram Moolenaar5c65e6a2019-05-17 11:08:56 +0200326 let expected = expected[1:1]
327 let expected[0].col -= 4
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200328 call assert_equal(expected, prop_list(2))
329 call DeletePropTypes()
330
331 bwipe!
332 set bs&
333endfunc
334
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100335func Test_prop_clear()
336 new
337 call AddPropTypes()
338 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100339 call assert_equal(Get_expected_props(), prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100340
341 call prop_clear(1)
342 call assert_equal([], prop_list(1))
343
344 call DeletePropTypes()
345 bwipe!
346endfunc
347
348func Test_prop_clear_buf()
349 new
350 call AddPropTypes()
351 call SetupPropsInFirstLine()
352 let bufnr = bufnr('')
353 wincmd w
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100354 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100355
356 call prop_clear(1, 1, {'bufnr': bufnr})
357 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
358
359 wincmd w
360 call DeletePropTypes()
361 bwipe!
362endfunc
363
Bram Moolenaar21b50382019-01-04 18:07:24 +0100364func Test_prop_setline()
365 new
366 call AddPropTypes()
367 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100368 call assert_equal(Get_expected_props(), prop_list(1))
Bram Moolenaar21b50382019-01-04 18:07:24 +0100369
370 call setline(1, 'foobar')
371 call assert_equal([], prop_list(1))
372
373 call DeletePropTypes()
374 bwipe!
375endfunc
376
377func Test_prop_setbufline()
378 new
379 call AddPropTypes()
380 call SetupPropsInFirstLine()
381 let bufnr = bufnr('')
382 wincmd w
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100383 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar21b50382019-01-04 18:07:24 +0100384
385 call setbufline(bufnr, 1, 'foobar')
386 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
387
388 wincmd w
389 call DeletePropTypes()
390 bwipe!
391endfunc
392
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100393func Test_prop_substitute()
394 new
395 " Set first line to 'one two three'
396 call AddPropTypes()
397 call SetupPropsInFirstLine()
398 let expected_props = Get_expected_props()
399 call assert_equal(expected_props, prop_list(1))
400
401 " Change "n" in "one" to XX: 'oXXe two three'
402 s/n/XX/
403 let expected_props[0].length += 1
404 let expected_props[1].length += 1
405 let expected_props[2].col += 1
406 let expected_props[3].col += 1
407 call assert_equal(expected_props, prop_list(1))
408
409 " Delete "t" in "two" and "three" to XX: 'oXXe wo hree'
410 s/t//g
411 let expected_props[0].length -= 2
412 let expected_props[2].length -= 1
413 let expected_props[3].length -= 1
414 let expected_props[3].col -= 1
415 call assert_equal(expected_props, prop_list(1))
416
417 " Split the line by changing w to line break: 'oXXe ', 'o hree'
418 " The long prop is split and spans both lines.
419 " The props on "two" and "three" move to the next line.
420 s/w/\r/
421 let new_props = [
422 \ copy(expected_props[0]),
423 \ copy(expected_props[2]),
424 \ copy(expected_props[3]),
425 \ ]
426 let expected_props[0].length = 5
427 unlet expected_props[3]
428 unlet expected_props[2]
429 call assert_equal(expected_props, prop_list(1))
430
431 let new_props[0].length = 6
432 let new_props[1].col = 1
433 let new_props[1].length = 1
434 let new_props[2].col = 3
435 call assert_equal(new_props, prop_list(2))
436
437 call DeletePropTypes()
438 bwipe!
439endfunc
440
Bram Moolenaar663bc892019-01-08 23:07:24 +0100441func Test_prop_change_indent()
442 call prop_type_add('comment', {'highlight': 'Directory'})
443 new
444 call setline(1, [' xxx', 'yyyyy'])
445 call prop_add(2, 2, {'length': 2, 'type': 'comment'})
446 let expect = {'col': 2, 'length': 2, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
447 call assert_equal([expect], prop_list(2))
448
449 set shiftwidth=3
450 normal 2G>>
451 call assert_equal(' yyyyy', getline(2))
452 let expect.col += 3
453 call assert_equal([expect], prop_list(2))
454
455 normal 2G==
456 call assert_equal(' yyyyy', getline(2))
457 let expect.col = 6
458 call assert_equal([expect], prop_list(2))
459
460 call prop_clear(2)
461 call prop_add(2, 2, {'length': 5, 'type': 'comment'})
462 let expect.col = 2
463 let expect.length = 5
464 call assert_equal([expect], prop_list(2))
465
466 normal 2G<<
467 call assert_equal(' yyyyy', getline(2))
468 let expect.length = 2
469 call assert_equal([expect], prop_list(2))
470
471 set shiftwidth&
472 call prop_type_delete('comment')
473endfunc
474
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100475" Setup a three line prop in lines 2 - 4.
476" Add short props in line 1 and 5.
477func Setup_three_line_prop()
478 new
479 call setline(1, ['one', 'twotwo', 'three', 'fourfour', 'five'])
480 call prop_add(1, 2, {'length': 1, 'type': 'comment'})
481 call prop_add(2, 4, {'end_lnum': 4, 'end_col': 5, 'type': 'comment'})
482 call prop_add(5, 2, {'length': 1, 'type': 'comment'})
483endfunc
484
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100485func Test_prop_multiline()
486 call prop_type_add('comment', {'highlight': 'Directory'})
487 new
488 call setline(1, ['xxxxxxx', 'yyyyyyyyy', 'zzzzzzzz'])
489
490 " start halfway line 1, end halfway line 3
491 call prop_add(1, 3, {'end_lnum': 3, 'end_col': 5, 'type': 'comment'})
492 let expect1 = {'col': 3, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
493 call assert_equal([expect1], prop_list(1))
494 let expect2 = {'col': 1, 'length': 10, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
495 call assert_equal([expect2], prop_list(2))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100496 let expect3 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100497 call assert_equal([expect3], prop_list(3))
498 call prop_clear(1, 3)
499
500 " include all three lines
501 call prop_add(1, 1, {'end_lnum': 3, 'end_col': 999, 'type': 'comment'})
502 let expect1.col = 1
503 let expect1.length = 8
504 call assert_equal([expect1], prop_list(1))
505 call assert_equal([expect2], prop_list(2))
506 let expect3.length = 9
507 call assert_equal([expect3], prop_list(3))
508 call prop_clear(1, 3)
509
510 bwipe!
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100511
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100512 " Test deleting the first line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100513 call Setup_three_line_prop()
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100514 let expect_short = {'col': 2, 'length': 1, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
515 call assert_equal([expect_short], prop_list(1))
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100516 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
517 call assert_equal([expect2], prop_list(2))
518 2del
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100519 call assert_equal([expect_short], prop_list(1))
520 let expect2 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
521 call assert_equal([expect2], prop_list(2))
522 bwipe!
523
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100524 " Test deleting the last line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100525 call Setup_three_line_prop()
526 let expect3 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
527 call assert_equal([expect3], prop_list(3))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100528 let expect4 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100529 call assert_equal([expect4], prop_list(4))
530 4del
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100531 let expect3.end = 1
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100532 call assert_equal([expect3], prop_list(3))
533 call assert_equal([expect_short], prop_list(4))
534 bwipe!
535
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100536 " Test appending a line below the multi-line text prop start.
Bram Moolenaarb56ac042018-12-28 23:22:40 +0100537 call Setup_three_line_prop()
538 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
539 call assert_equal([expect2], prop_list(2))
540 call append(2, "new line")
541 call assert_equal([expect2], prop_list(2))
542 let expect3 = {'col': 1, 'length': 9, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
543 call assert_equal([expect3], prop_list(3))
544 bwipe!
545
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100546 call prop_type_delete('comment')
547endfunc
548
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100549func Test_prop_byteoff()
550 call prop_type_add('comment', {'highlight': 'Directory'})
551 new
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100552 call setline(1, ['line1', 'second line', ''])
Bram Moolenaar8cf734e2018-12-26 01:09:00 +0100553 set ff=unix
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100554 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100555 call prop_add(1, 1, {'end_col': 3, 'type': 'comment'})
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100556 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100557
558 bwipe!
559 call prop_type_delete('comment')
560endfunc
561
Bram Moolenaar7f1664e2019-01-04 17:21:24 +0100562func Test_prop_undo()
563 new
564 call prop_type_add('comment', {'highlight': 'Directory'})
565 call setline(1, ['oneone', 'twotwo', 'three'])
566 " Set 'undolevels' to break changes into undo-able pieces.
567 set ul&
568
569 call prop_add(1, 3, {'end_col': 5, 'type': 'comment'})
570 let expected = [{'col': 3, 'length': 2, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
571 call assert_equal(expected, prop_list(1))
572
573 " Insert a character, then undo.
574 exe "normal 0lllix\<Esc>"
575 set ul&
576 let expected[0].length = 3
577 call assert_equal(expected, prop_list(1))
578 undo
579 let expected[0].length = 2
580 call assert_equal(expected, prop_list(1))
581
582 " Delete a character, then undo
583 exe "normal 0lllx"
584 set ul&
585 let expected[0].length = 1
586 call assert_equal(expected, prop_list(1))
587 undo
588 let expected[0].length = 2
589 call assert_equal(expected, prop_list(1))
590
591 " Delete the line, then undo
592 1d
593 set ul&
594 call assert_equal([], prop_list(1))
595 undo
596 call assert_equal(expected, prop_list(1))
597
598 " Insert a character, delete two characters, then undo with "U"
599 exe "normal 0lllix\<Esc>"
600 set ul&
601 let expected[0].length = 3
602 call assert_equal(expected, prop_list(1))
603 exe "normal 0lllxx"
604 set ul&
605 let expected[0].length = 1
606 call assert_equal(expected, prop_list(1))
607 normal U
608 let expected[0].length = 2
609 call assert_equal(expected, prop_list(1))
610
Bram Moolenaar338dfda2019-05-19 15:19:57 +0200611 " substitute a word, then undo
612 call setline(1, 'the number 123 is highlighted.')
613 call prop_add(1, 12, {'length': 3, 'type': 'comment'})
614 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
615 call assert_equal(expected, prop_list(1))
616 set ul&
617 1s/number/foo
618 let expected[0].col = 9
619 call assert_equal(expected, prop_list(1))
620 undo
621 let expected[0].col = 12
622 call assert_equal(expected, prop_list(1))
Bram Moolenaarf3333b02019-05-19 22:53:40 +0200623 call prop_clear(1)
624
625 " substitute with backslash
626 call setline(1, 'the number 123 is highlighted.')
627 call prop_add(1, 12, {'length': 3, 'type': 'comment'})
628 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
629 call assert_equal(expected, prop_list(1))
630 1s/the/\The
631 call assert_equal(expected, prop_list(1))
632 1s/^/\\
633 let expected[0].col += 1
634 call assert_equal(expected, prop_list(1))
635 1s/^/\~
636 let expected[0].col += 1
637 call assert_equal(expected, prop_list(1))
638 1s/123/12\\3
639 let expected[0].length += 1
640 call assert_equal(expected, prop_list(1))
641 call prop_clear(1)
Bram Moolenaar338dfda2019-05-19 15:19:57 +0200642
Bram Moolenaar7f1664e2019-01-04 17:21:24 +0100643 bwipe!
644 call prop_type_delete('comment')
645endfunc
646
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100647" screenshot test with textprop highlighting
Bram Moolenaar8055d172019-05-17 22:57:26 +0200648func Test_textprop_screenshot_various()
Bram Moolenaared79d1e2019-02-22 14:38:58 +0100649 " The Vim running in the terminal needs to use utf-8.
650 if !CanRunVimInTerminal() || g:orig_encoding != 'utf-8'
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100651 return
652 endif
653 call writefile([
Bram Moolenaarde24a872019-05-05 15:48:00 +0200654 \ "call setline(1, ["
655 \ .. "'One two',"
656 \ .. "'Numbér 123 änd thœn 4¾7.',"
657 \ .. "'--aa--bb--cc--dd--',"
658 \ .. "'// comment with error in it',"
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200659 \ .. "'first line',"
660 \ .. "' second line ',"
661 \ .. "'third line',"
662 \ .. "' fourth line',"
Bram Moolenaarde24a872019-05-05 15:48:00 +0200663 \ .. "])",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100664 \ "hi NumberProp ctermfg=blue",
665 \ "hi LongProp ctermbg=yellow",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200666 \ "hi BackgroundProp ctermbg=lightgrey",
667 \ "hi UnderlineProp cterm=underline",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100668 \ "call prop_type_add('number', {'highlight': 'NumberProp'})",
669 \ "call prop_type_add('long', {'highlight': 'LongProp'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100670 \ "call prop_type_add('start', {'highlight': 'NumberProp', 'start_incl': 1})",
671 \ "call prop_type_add('end', {'highlight': 'NumberProp', 'end_incl': 1})",
672 \ "call prop_type_add('both', {'highlight': 'NumberProp', 'start_incl': 1, 'end_incl': 1})",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200673 \ "call prop_type_add('background', {'highlight': 'BackgroundProp', 'combine': 1})",
674 \ "call prop_type_add('error', {'highlight': 'UnderlineProp', 'combine': 1})",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100675 \ "call prop_add(1, 4, {'end_lnum': 3, 'end_col': 3, 'type': 'long'})",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100676 \ "call prop_add(2, 9, {'length': 3, 'type': 'number'})",
677 \ "call prop_add(2, 24, {'length': 4, 'type': 'number'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100678 \ "call prop_add(3, 3, {'length': 2, 'type': 'number'})",
679 \ "call prop_add(3, 7, {'length': 2, 'type': 'start'})",
680 \ "call prop_add(3, 11, {'length': 2, 'type': 'end'})",
681 \ "call prop_add(3, 15, {'length': 2, 'type': 'both'})",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200682 \ "call prop_add(4, 12, {'length': 10, 'type': 'background'})",
683 \ "call prop_add(4, 17, {'length': 5, 'type': 'error'})",
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200684 \ "call prop_add(5, 7, {'length': 4, 'type': 'long'})",
685 \ "call prop_add(6, 1, {'length': 8, 'type': 'long'})",
686 \ "call prop_add(8, 1, {'length': 1, 'type': 'long'})",
687 \ "call prop_add(8, 11, {'length': 4, 'type': 'long'})",
Bram Moolenaarbfd45122019-05-17 13:05:07 +0200688 \ "set number cursorline",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100689 \ "hi clear SpellBad",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100690 \ "set spell",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200691 \ "syn match Comment '//.*'",
692 \ "hi Comment ctermfg=green",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100693 \ "normal 3G0llix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>",
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100694 \ "normal 3G0lli\<BS>\<Esc>",
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200695 \ "normal 6G0i\<BS>\<Esc>",
696 \ "normal 3J",
697 \ "normal 3G",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100698 \], 'XtestProp')
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200699 let buf = RunVimInTerminal('-S XtestProp', {'rows': 8})
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100700 call VerifyScreenDump(buf, 'Test_textprop_01', {})
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100701
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100702 " clean up
703 call StopVimInTerminal(buf)
Bram Moolenaar2f21fa82018-12-31 20:05:56 +0100704 call delete('XtestProp')
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100705endfunc
Bram Moolenaar8055d172019-05-17 22:57:26 +0200706
707func RunTestVisualBlock(width, dump)
708 call writefile([
709 \ "call setline(1, ["
710 \ .. "'xxxxxxxxx 123 x',"
711 \ .. "'xxxxxxxx 123 x',"
712 \ .. "'xxxxxxx 123 x',"
713 \ .. "'xxxxxx 123 x',"
714 \ .. "'xxxxx 123 x',"
715 \ .. "'xxxx 123 xx',"
716 \ .. "'xxx 123 xxx',"
717 \ .. "'xx 123 xxxx',"
718 \ .. "'x 123 xxxxx',"
719 \ .. "' 123 xxxxxx',"
720 \ .. "])",
721 \ "hi SearchProp ctermbg=yellow",
722 \ "call prop_type_add('search', {'highlight': 'SearchProp'})",
723 \ "call prop_add(1, 11, {'length': 3, 'type': 'search'})",
724 \ "call prop_add(2, 10, {'length': 3, 'type': 'search'})",
725 \ "call prop_add(3, 9, {'length': 3, 'type': 'search'})",
726 \ "call prop_add(4, 8, {'length': 3, 'type': 'search'})",
727 \ "call prop_add(5, 7, {'length': 3, 'type': 'search'})",
728 \ "call prop_add(6, 6, {'length': 3, 'type': 'search'})",
729 \ "call prop_add(7, 5, {'length': 3, 'type': 'search'})",
730 \ "call prop_add(8, 4, {'length': 3, 'type': 'search'})",
731 \ "call prop_add(9, 3, {'length': 3, 'type': 'search'})",
732 \ "call prop_add(10, 2, {'length': 3, 'type': 'search'})",
733 \ "normal 1G6|\<C-V>" .. repeat('l', a:width - 1) .. "10jx",
734 \], 'XtestPropVis')
735 let buf = RunVimInTerminal('-S XtestPropVis', {'rows': 12})
736 call VerifyScreenDump(buf, 'Test_textprop_vis_' .. a:dump, {})
737
738 " clean up
739 call StopVimInTerminal(buf)
740 call delete('XtestPropVis')
741endfunc
742
743" screenshot test with Visual block mode operations
744func Test_textprop_screenshot_visual()
745 if !CanRunVimInTerminal()
746 return
747 endif
748
749 " Delete two columns while text props are three chars wide.
750 call RunTestVisualBlock(2, '01')
751
752 " Same, but delete four columns
753 call RunTestVisualBlock(4, '02')
754endfunc
Bram Moolenaard79eef22019-05-24 20:41:55 +0200755
756" Adding a text property to a new buffer should not fail
757func Test_textprop_empty_buffer()
758 call prop_type_add('comment', {'highlight': 'Search'})
759 new
760 call prop_add(1, 1, {'type': 'comment'})
761 close
762endfunc