blob: cb27f5877c98dcac974c0d82ec2a70e07535f155 [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')
Bram Moolenaarb0f94c12019-06-13 22:19:53 +02005 throw 'Skipped, textprop feature missing'
Bram Moolenaar98aefe72018-12-13 22:20:09 +01006endif
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})))
Bram Moolenaarf0884c52019-05-24 21:22:29 +020072
73 call assert_fails("call prop_type_add('one', {'bufnr': 98764})", "E158:")
Bram Moolenaar98aefe72018-12-13 22:20:09 +010074endfunc
75
76func AddPropTypes()
77 call prop_type_add('one', {})
78 call prop_type_add('two', {})
79 call prop_type_add('three', {})
80 call prop_type_add('whole', {})
81endfunc
82
83func DeletePropTypes()
84 call prop_type_delete('one')
85 call prop_type_delete('two')
86 call prop_type_delete('three')
87 call prop_type_delete('whole')
88endfunc
89
90func SetupPropsInFirstLine()
91 call setline(1, 'one two three')
92 call prop_add(1, 1, {'length': 3, 'id': 11, 'type': 'one'})
93 call prop_add(1, 5, {'length': 3, 'id': 12, 'type': 'two'})
Bram Moolenaar4164bb22019-01-04 23:09:49 +010094 call prop_add(1, 9, {'length': 5, 'id': 13, 'type': 'three'})
Bram Moolenaar98aefe72018-12-13 22:20:09 +010095 call prop_add(1, 1, {'length': 13, 'id': 14, 'type': 'whole'})
96endfunc
97
Bram Moolenaar4164bb22019-01-04 23:09:49 +010098func Get_expected_props()
99 return [
100 \ {'col': 1, 'length': 13, 'id': 14, 'type': 'whole', 'start': 1, 'end': 1},
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100101 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
102 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100103 \ {'col': 9, 'length': 5, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100104 \ ]
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100105endfunc
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100106
107func Test_prop_add()
108 new
109 call AddPropTypes()
110 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100111 let expected_props = Get_expected_props()
112 call assert_equal(expected_props, prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100113 call assert_fails("call prop_add(10, 1, {'length': 1, 'id': 14, 'type': 'whole'})", 'E966:')
114 call assert_fails("call prop_add(1, 22, {'length': 1, 'id': 14, 'type': 'whole'})", 'E964:')
115
116 " Insert a line above, text props must still be there.
117 call append(0, 'empty')
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100118 call assert_equal(expected_props, prop_list(2))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100119 " Delete a line above, text props must still be there.
120 1del
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100121 call assert_equal(expected_props, prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100122
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100123 " Prop without length or end column is zero length
124 call prop_clear(1)
125 call prop_add(1, 5, {'type': 'two'})
126 let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}]
127 call assert_equal(expected, prop_list(1))
128
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200129 call assert_fails("call prop_add(1, 5, {'type': 'two', 'bufnr': 234343})", 'E158:')
130
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100131 call DeletePropTypes()
132 bwipe!
133endfunc
134
135func Test_prop_remove()
136 new
137 call AddPropTypes()
138 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100139 let props = Get_expected_props()
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100140 call assert_equal(props, prop_list(1))
141
142 " remove by id
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200143 call assert_equal(1, prop_remove({'id': 12}, 1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100144 unlet props[2]
145 call assert_equal(props, prop_list(1))
146
147 " remove by type
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200148 call assert_equal(1, prop_remove({'type': 'one'}, 1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100149 unlet props[1]
150 call assert_equal(props, prop_list(1))
151
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200152 " remove from unknown buffer
153 call assert_fails("call prop_remove({'type': 'one', 'bufnr': 123456}, 1)", 'E158:')
154
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100155 call DeletePropTypes()
156 bwipe!
157endfunc
158
Bram Moolenaar196d1572019-01-02 23:47:18 +0100159func SetupOneLine()
160 call setline(1, 'xonex xtwoxx')
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200161 normal gg0
Bram Moolenaar196d1572019-01-02 23:47:18 +0100162 call AddPropTypes()
163 call prop_add(1, 2, {'length': 3, 'id': 11, 'type': 'one'})
164 call prop_add(1, 8, {'length': 3, 'id': 12, 'type': 'two'})
165 let expected = [
166 \ {'col': 2, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
167 \ {'col': 8, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
168 \]
169 call assert_equal(expected, prop_list(1))
170 return expected
171endfunc
172
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100173func Test_prop_add_remove_buf()
174 new
175 let bufnr = bufnr('')
176 call AddPropTypes()
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100177 for lnum in range(1, 4)
178 call setline(lnum, 'one two three')
179 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100180 wincmd w
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100181 for lnum in range(1, 4)
182 call prop_add(lnum, 1, {'length': 3, 'id': 11, 'type': 'one', 'bufnr': bufnr})
183 call prop_add(lnum, 5, {'length': 3, 'id': 12, 'type': 'two', 'bufnr': bufnr})
184 call prop_add(lnum, 11, {'length': 3, 'id': 13, 'type': 'three', 'bufnr': bufnr})
185 endfor
186
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100187 let props = [
188 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
189 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
190 \ {'col': 11, 'length': 3, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
191 \]
192 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100193
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100194 " remove by id
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100195 let before_props = deepcopy(props)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100196 unlet props[1]
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100197
198 call prop_remove({'id': 12, 'bufnr': bufnr}, 1)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100199 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100200 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
201 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr}))
202 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr}))
203
204 call prop_remove({'id': 12, 'bufnr': bufnr}, 3, 4)
205 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
206 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
207 call assert_equal(props, prop_list(3, {'bufnr': bufnr}))
208 call assert_equal(props, prop_list(4, {'bufnr': bufnr}))
209
210 call prop_remove({'id': 12, 'bufnr': bufnr})
211 for lnum in range(1, 4)
212 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr}))
213 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100214
215 " remove by type
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100216 let before_props = deepcopy(props)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100217 unlet props[0]
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100218
219 call prop_remove({'type': 'one', 'bufnr': bufnr}, 1)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100220 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100221 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
222 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr}))
223 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr}))
224
225 call prop_remove({'type': 'one', 'bufnr': bufnr}, 3, 4)
226 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
227 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
228 call assert_equal(props, prop_list(3, {'bufnr': bufnr}))
229 call assert_equal(props, prop_list(4, {'bufnr': bufnr}))
230
231 call prop_remove({'type': 'one', 'bufnr': bufnr})
232 for lnum in range(1, 4)
233 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr}))
234 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100235
236 call DeletePropTypes()
237 wincmd w
238 bwipe!
239endfunc
240
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100241func Test_prop_backspace()
242 new
243 set bs=2
Bram Moolenaar196d1572019-01-02 23:47:18 +0100244 let expected = SetupOneLine() " 'xonex xtwoxx'
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100245
246 exe "normal 0li\<BS>\<Esc>fxli\<BS>\<Esc>"
247 call assert_equal('one xtwoxx', getline(1))
248 let expected[0].col = 1
249 let expected[1].col = 6
250 call assert_equal(expected, prop_list(1))
251
252 call DeletePropTypes()
253 bwipe!
254 set bs&
255endfunc
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100256
Bram Moolenaar196d1572019-01-02 23:47:18 +0100257func Test_prop_replace()
258 new
259 set bs=2
260 let expected = SetupOneLine() " 'xonex xtwoxx'
261
262 exe "normal 0Ryyy\<Esc>"
263 call assert_equal('yyyex xtwoxx', getline(1))
264 call assert_equal(expected, prop_list(1))
265
266 exe "normal ftRyy\<BS>"
267 call assert_equal('yyyex xywoxx', getline(1))
268 call assert_equal(expected, prop_list(1))
269
270 exe "normal 0fwRyy\<BS>"
271 call assert_equal('yyyex xyyoxx', getline(1))
272 call assert_equal(expected, prop_list(1))
273
274 exe "normal 0foRyy\<BS>\<BS>"
275 call assert_equal('yyyex xyyoxx', getline(1))
276 call assert_equal(expected, prop_list(1))
277
278 call DeletePropTypes()
279 bwipe!
280 set bs&
281endfunc
282
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200283func Test_prop_open_line()
284 new
285
286 " open new line, props stay in top line
287 let expected = SetupOneLine() " 'xonex xtwoxx'
288 exe "normal o\<Esc>"
289 call assert_equal('xonex xtwoxx', getline(1))
290 call assert_equal('', getline(2))
291 call assert_equal(expected, prop_list(1))
292 call DeletePropTypes()
293
294 " move all props to next line
295 let expected = SetupOneLine() " 'xonex xtwoxx'
296 exe "normal 0i\<CR>\<Esc>"
297 call assert_equal('', getline(1))
298 call assert_equal('xonex xtwoxx', getline(2))
299 call assert_equal(expected, prop_list(2))
300 call DeletePropTypes()
301
302 " split just before prop, move all props to next line
303 let expected = SetupOneLine() " 'xonex xtwoxx'
304 exe "normal 0li\<CR>\<Esc>"
305 call assert_equal('x', getline(1))
306 call assert_equal('onex xtwoxx', getline(2))
307 let expected[0].col -= 1
308 let expected[1].col -= 1
309 call assert_equal(expected, prop_list(2))
310 call DeletePropTypes()
311
312 " split inside prop, split first prop
313 let expected = SetupOneLine() " 'xonex xtwoxx'
314 exe "normal 0lli\<CR>\<Esc>"
315 call assert_equal('xo', getline(1))
316 call assert_equal('nex xtwoxx', getline(2))
317 let exp_first = [deepcopy(expected[0])]
318 let exp_first[0].length = 1
319 call assert_equal(exp_first, prop_list(1))
320 let expected[0].col = 1
321 let expected[0].length = 2
322 let expected[1].col -= 2
323 call assert_equal(expected, prop_list(2))
324 call DeletePropTypes()
325
Bram Moolenaar5c65e6a2019-05-17 11:08:56 +0200326 " split just after first prop, second prop move to next line
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200327 let expected = SetupOneLine() " 'xonex xtwoxx'
328 exe "normal 0fea\<CR>\<Esc>"
329 call assert_equal('xone', getline(1))
330 call assert_equal('x xtwoxx', getline(2))
331 let exp_first = expected[0:0]
332 call assert_equal(exp_first, prop_list(1))
Bram Moolenaar5c65e6a2019-05-17 11:08:56 +0200333 let expected = expected[1:1]
334 let expected[0].col -= 4
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200335 call assert_equal(expected, prop_list(2))
336 call DeletePropTypes()
337
338 bwipe!
339 set bs&
340endfunc
341
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100342func Test_prop_clear()
343 new
344 call AddPropTypes()
345 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100346 call assert_equal(Get_expected_props(), prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100347
348 call prop_clear(1)
349 call assert_equal([], prop_list(1))
350
351 call DeletePropTypes()
352 bwipe!
353endfunc
354
355func Test_prop_clear_buf()
356 new
357 call AddPropTypes()
358 call SetupPropsInFirstLine()
359 let bufnr = bufnr('')
360 wincmd w
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100361 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100362
363 call prop_clear(1, 1, {'bufnr': bufnr})
364 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
365
366 wincmd w
367 call DeletePropTypes()
368 bwipe!
369endfunc
370
Bram Moolenaar21b50382019-01-04 18:07:24 +0100371func Test_prop_setline()
372 new
373 call AddPropTypes()
374 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100375 call assert_equal(Get_expected_props(), prop_list(1))
Bram Moolenaar21b50382019-01-04 18:07:24 +0100376
377 call setline(1, 'foobar')
378 call assert_equal([], prop_list(1))
379
380 call DeletePropTypes()
381 bwipe!
382endfunc
383
384func Test_prop_setbufline()
385 new
386 call AddPropTypes()
387 call SetupPropsInFirstLine()
388 let bufnr = bufnr('')
389 wincmd w
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100390 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar21b50382019-01-04 18:07:24 +0100391
392 call setbufline(bufnr, 1, 'foobar')
393 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
394
395 wincmd w
396 call DeletePropTypes()
397 bwipe!
398endfunc
399
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100400func Test_prop_substitute()
401 new
402 " Set first line to 'one two three'
403 call AddPropTypes()
404 call SetupPropsInFirstLine()
405 let expected_props = Get_expected_props()
406 call assert_equal(expected_props, prop_list(1))
407
408 " Change "n" in "one" to XX: 'oXXe two three'
409 s/n/XX/
410 let expected_props[0].length += 1
411 let expected_props[1].length += 1
412 let expected_props[2].col += 1
413 let expected_props[3].col += 1
414 call assert_equal(expected_props, prop_list(1))
415
416 " Delete "t" in "two" and "three" to XX: 'oXXe wo hree'
417 s/t//g
418 let expected_props[0].length -= 2
419 let expected_props[2].length -= 1
420 let expected_props[3].length -= 1
421 let expected_props[3].col -= 1
422 call assert_equal(expected_props, prop_list(1))
423
424 " Split the line by changing w to line break: 'oXXe ', 'o hree'
425 " The long prop is split and spans both lines.
426 " The props on "two" and "three" move to the next line.
427 s/w/\r/
428 let new_props = [
429 \ copy(expected_props[0]),
430 \ copy(expected_props[2]),
431 \ copy(expected_props[3]),
432 \ ]
433 let expected_props[0].length = 5
434 unlet expected_props[3]
435 unlet expected_props[2]
436 call assert_equal(expected_props, prop_list(1))
437
438 let new_props[0].length = 6
439 let new_props[1].col = 1
440 let new_props[1].length = 1
441 let new_props[2].col = 3
442 call assert_equal(new_props, prop_list(2))
443
444 call DeletePropTypes()
445 bwipe!
446endfunc
447
Bram Moolenaar663bc892019-01-08 23:07:24 +0100448func Test_prop_change_indent()
449 call prop_type_add('comment', {'highlight': 'Directory'})
450 new
451 call setline(1, [' xxx', 'yyyyy'])
452 call prop_add(2, 2, {'length': 2, 'type': 'comment'})
453 let expect = {'col': 2, 'length': 2, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
454 call assert_equal([expect], prop_list(2))
455
456 set shiftwidth=3
457 normal 2G>>
458 call assert_equal(' yyyyy', getline(2))
459 let expect.col += 3
460 call assert_equal([expect], prop_list(2))
461
462 normal 2G==
463 call assert_equal(' yyyyy', getline(2))
464 let expect.col = 6
465 call assert_equal([expect], prop_list(2))
466
467 call prop_clear(2)
468 call prop_add(2, 2, {'length': 5, 'type': 'comment'})
469 let expect.col = 2
470 let expect.length = 5
471 call assert_equal([expect], prop_list(2))
472
473 normal 2G<<
474 call assert_equal(' yyyyy', getline(2))
475 let expect.length = 2
476 call assert_equal([expect], prop_list(2))
477
478 set shiftwidth&
479 call prop_type_delete('comment')
480endfunc
481
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100482" Setup a three line prop in lines 2 - 4.
483" Add short props in line 1 and 5.
484func Setup_three_line_prop()
485 new
486 call setline(1, ['one', 'twotwo', 'three', 'fourfour', 'five'])
487 call prop_add(1, 2, {'length': 1, 'type': 'comment'})
488 call prop_add(2, 4, {'end_lnum': 4, 'end_col': 5, 'type': 'comment'})
489 call prop_add(5, 2, {'length': 1, 'type': 'comment'})
490endfunc
491
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100492func Test_prop_multiline()
493 call prop_type_add('comment', {'highlight': 'Directory'})
494 new
495 call setline(1, ['xxxxxxx', 'yyyyyyyyy', 'zzzzzzzz'])
496
497 " start halfway line 1, end halfway line 3
498 call prop_add(1, 3, {'end_lnum': 3, 'end_col': 5, 'type': 'comment'})
499 let expect1 = {'col': 3, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
500 call assert_equal([expect1], prop_list(1))
501 let expect2 = {'col': 1, 'length': 10, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
502 call assert_equal([expect2], prop_list(2))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100503 let expect3 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100504 call assert_equal([expect3], prop_list(3))
505 call prop_clear(1, 3)
506
507 " include all three lines
508 call prop_add(1, 1, {'end_lnum': 3, 'end_col': 999, 'type': 'comment'})
509 let expect1.col = 1
510 let expect1.length = 8
511 call assert_equal([expect1], prop_list(1))
512 call assert_equal([expect2], prop_list(2))
513 let expect3.length = 9
514 call assert_equal([expect3], prop_list(3))
515 call prop_clear(1, 3)
516
517 bwipe!
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100518
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100519 " Test deleting the first line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100520 call Setup_three_line_prop()
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100521 let expect_short = {'col': 2, 'length': 1, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
522 call assert_equal([expect_short], prop_list(1))
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100523 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
524 call assert_equal([expect2], prop_list(2))
525 2del
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100526 call assert_equal([expect_short], prop_list(1))
527 let expect2 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
528 call assert_equal([expect2], prop_list(2))
529 bwipe!
530
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100531 " Test deleting the last line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100532 call Setup_three_line_prop()
533 let expect3 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
534 call assert_equal([expect3], prop_list(3))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100535 let expect4 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100536 call assert_equal([expect4], prop_list(4))
537 4del
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100538 let expect3.end = 1
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100539 call assert_equal([expect3], prop_list(3))
540 call assert_equal([expect_short], prop_list(4))
541 bwipe!
542
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100543 " Test appending a line below the multi-line text prop start.
Bram Moolenaarb56ac042018-12-28 23:22:40 +0100544 call Setup_three_line_prop()
545 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
546 call assert_equal([expect2], prop_list(2))
547 call append(2, "new line")
548 call assert_equal([expect2], prop_list(2))
549 let expect3 = {'col': 1, 'length': 9, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
550 call assert_equal([expect3], prop_list(3))
551 bwipe!
552
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100553 call prop_type_delete('comment')
554endfunc
555
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100556func Test_prop_byteoff()
557 call prop_type_add('comment', {'highlight': 'Directory'})
558 new
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100559 call setline(1, ['line1', 'second line', ''])
Bram Moolenaar8cf734e2018-12-26 01:09:00 +0100560 set ff=unix
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100561 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100562 call prop_add(1, 1, {'end_col': 3, 'type': 'comment'})
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100563 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100564
565 bwipe!
566 call prop_type_delete('comment')
567endfunc
568
Bram Moolenaar7f1664e2019-01-04 17:21:24 +0100569func Test_prop_undo()
570 new
571 call prop_type_add('comment', {'highlight': 'Directory'})
572 call setline(1, ['oneone', 'twotwo', 'three'])
573 " Set 'undolevels' to break changes into undo-able pieces.
574 set ul&
575
576 call prop_add(1, 3, {'end_col': 5, 'type': 'comment'})
577 let expected = [{'col': 3, 'length': 2, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
578 call assert_equal(expected, prop_list(1))
579
580 " Insert a character, then undo.
581 exe "normal 0lllix\<Esc>"
582 set ul&
583 let expected[0].length = 3
584 call assert_equal(expected, prop_list(1))
585 undo
586 let expected[0].length = 2
587 call assert_equal(expected, prop_list(1))
588
589 " Delete a character, then undo
590 exe "normal 0lllx"
591 set ul&
592 let expected[0].length = 1
593 call assert_equal(expected, prop_list(1))
594 undo
595 let expected[0].length = 2
596 call assert_equal(expected, prop_list(1))
597
598 " Delete the line, then undo
599 1d
600 set ul&
601 call assert_equal([], prop_list(1))
602 undo
603 call assert_equal(expected, prop_list(1))
604
605 " Insert a character, delete two characters, then undo with "U"
606 exe "normal 0lllix\<Esc>"
607 set ul&
608 let expected[0].length = 3
609 call assert_equal(expected, prop_list(1))
610 exe "normal 0lllxx"
611 set ul&
612 let expected[0].length = 1
613 call assert_equal(expected, prop_list(1))
614 normal U
615 let expected[0].length = 2
616 call assert_equal(expected, prop_list(1))
617
Bram Moolenaar338dfda2019-05-19 15:19:57 +0200618 " substitute a word, then undo
619 call setline(1, 'the number 123 is highlighted.')
620 call prop_add(1, 12, {'length': 3, 'type': 'comment'})
621 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
622 call assert_equal(expected, prop_list(1))
623 set ul&
624 1s/number/foo
625 let expected[0].col = 9
626 call assert_equal(expected, prop_list(1))
627 undo
628 let expected[0].col = 12
629 call assert_equal(expected, prop_list(1))
Bram Moolenaarf3333b02019-05-19 22:53:40 +0200630 call prop_clear(1)
631
632 " substitute with backslash
633 call setline(1, 'the number 123 is highlighted.')
634 call prop_add(1, 12, {'length': 3, 'type': 'comment'})
635 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
636 call assert_equal(expected, prop_list(1))
637 1s/the/\The
638 call assert_equal(expected, prop_list(1))
639 1s/^/\\
640 let expected[0].col += 1
641 call assert_equal(expected, prop_list(1))
642 1s/^/\~
643 let expected[0].col += 1
644 call assert_equal(expected, prop_list(1))
645 1s/123/12\\3
646 let expected[0].length += 1
647 call assert_equal(expected, prop_list(1))
648 call prop_clear(1)
Bram Moolenaar338dfda2019-05-19 15:19:57 +0200649
Bram Moolenaar7f1664e2019-01-04 17:21:24 +0100650 bwipe!
651 call prop_type_delete('comment')
652endfunc
653
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100654" screenshot test with textprop highlighting
Bram Moolenaar8055d172019-05-17 22:57:26 +0200655func Test_textprop_screenshot_various()
Bram Moolenaared79d1e2019-02-22 14:38:58 +0100656 " The Vim running in the terminal needs to use utf-8.
657 if !CanRunVimInTerminal() || g:orig_encoding != 'utf-8'
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200658 throw 'Skipped: cannot make screendumps or not using utf-8'
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100659 endif
660 call writefile([
Bram Moolenaarde24a872019-05-05 15:48:00 +0200661 \ "call setline(1, ["
662 \ .. "'One two',"
663 \ .. "'Numbér 123 änd thœn 4¾7.',"
664 \ .. "'--aa--bb--cc--dd--',"
665 \ .. "'// comment with error in it',"
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200666 \ .. "'first line',"
667 \ .. "' second line ',"
668 \ .. "'third line',"
669 \ .. "' fourth line',"
Bram Moolenaarde24a872019-05-05 15:48:00 +0200670 \ .. "])",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100671 \ "hi NumberProp ctermfg=blue",
672 \ "hi LongProp ctermbg=yellow",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200673 \ "hi BackgroundProp ctermbg=lightgrey",
674 \ "hi UnderlineProp cterm=underline",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100675 \ "call prop_type_add('number', {'highlight': 'NumberProp'})",
676 \ "call prop_type_add('long', {'highlight': 'LongProp'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100677 \ "call prop_type_add('start', {'highlight': 'NumberProp', 'start_incl': 1})",
678 \ "call prop_type_add('end', {'highlight': 'NumberProp', 'end_incl': 1})",
679 \ "call prop_type_add('both', {'highlight': 'NumberProp', 'start_incl': 1, 'end_incl': 1})",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200680 \ "call prop_type_add('background', {'highlight': 'BackgroundProp', 'combine': 1})",
681 \ "call prop_type_add('error', {'highlight': 'UnderlineProp', 'combine': 1})",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100682 \ "call prop_add(1, 4, {'end_lnum': 3, 'end_col': 3, 'type': 'long'})",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100683 \ "call prop_add(2, 9, {'length': 3, 'type': 'number'})",
684 \ "call prop_add(2, 24, {'length': 4, 'type': 'number'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100685 \ "call prop_add(3, 3, {'length': 2, 'type': 'number'})",
686 \ "call prop_add(3, 7, {'length': 2, 'type': 'start'})",
687 \ "call prop_add(3, 11, {'length': 2, 'type': 'end'})",
688 \ "call prop_add(3, 15, {'length': 2, 'type': 'both'})",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200689 \ "call prop_add(4, 12, {'length': 10, 'type': 'background'})",
690 \ "call prop_add(4, 17, {'length': 5, 'type': 'error'})",
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200691 \ "call prop_add(5, 7, {'length': 4, 'type': 'long'})",
692 \ "call prop_add(6, 1, {'length': 8, 'type': 'long'})",
693 \ "call prop_add(8, 1, {'length': 1, 'type': 'long'})",
694 \ "call prop_add(8, 11, {'length': 4, 'type': 'long'})",
Bram Moolenaarbfd45122019-05-17 13:05:07 +0200695 \ "set number cursorline",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100696 \ "hi clear SpellBad",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100697 \ "set spell",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200698 \ "syn match Comment '//.*'",
699 \ "hi Comment ctermfg=green",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100700 \ "normal 3G0llix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>",
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100701 \ "normal 3G0lli\<BS>\<Esc>",
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200702 \ "normal 6G0i\<BS>\<Esc>",
703 \ "normal 3J",
704 \ "normal 3G",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100705 \], 'XtestProp')
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200706 let buf = RunVimInTerminal('-S XtestProp', {'rows': 8})
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100707 call VerifyScreenDump(buf, 'Test_textprop_01', {})
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100708
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100709 " clean up
710 call StopVimInTerminal(buf)
Bram Moolenaar2f21fa82018-12-31 20:05:56 +0100711 call delete('XtestProp')
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100712endfunc
Bram Moolenaar8055d172019-05-17 22:57:26 +0200713
714func RunTestVisualBlock(width, dump)
715 call writefile([
716 \ "call setline(1, ["
717 \ .. "'xxxxxxxxx 123 x',"
718 \ .. "'xxxxxxxx 123 x',"
719 \ .. "'xxxxxxx 123 x',"
720 \ .. "'xxxxxx 123 x',"
721 \ .. "'xxxxx 123 x',"
722 \ .. "'xxxx 123 xx',"
723 \ .. "'xxx 123 xxx',"
724 \ .. "'xx 123 xxxx',"
725 \ .. "'x 123 xxxxx',"
726 \ .. "' 123 xxxxxx',"
727 \ .. "])",
728 \ "hi SearchProp ctermbg=yellow",
729 \ "call prop_type_add('search', {'highlight': 'SearchProp'})",
730 \ "call prop_add(1, 11, {'length': 3, 'type': 'search'})",
731 \ "call prop_add(2, 10, {'length': 3, 'type': 'search'})",
732 \ "call prop_add(3, 9, {'length': 3, 'type': 'search'})",
733 \ "call prop_add(4, 8, {'length': 3, 'type': 'search'})",
734 \ "call prop_add(5, 7, {'length': 3, 'type': 'search'})",
735 \ "call prop_add(6, 6, {'length': 3, 'type': 'search'})",
736 \ "call prop_add(7, 5, {'length': 3, 'type': 'search'})",
737 \ "call prop_add(8, 4, {'length': 3, 'type': 'search'})",
738 \ "call prop_add(9, 3, {'length': 3, 'type': 'search'})",
739 \ "call prop_add(10, 2, {'length': 3, 'type': 'search'})",
740 \ "normal 1G6|\<C-V>" .. repeat('l', a:width - 1) .. "10jx",
741 \], 'XtestPropVis')
742 let buf = RunVimInTerminal('-S XtestPropVis', {'rows': 12})
743 call VerifyScreenDump(buf, 'Test_textprop_vis_' .. a:dump, {})
744
745 " clean up
746 call StopVimInTerminal(buf)
747 call delete('XtestPropVis')
748endfunc
749
750" screenshot test with Visual block mode operations
751func Test_textprop_screenshot_visual()
752 if !CanRunVimInTerminal()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +0200753 throw 'Skipped: cannot make screendumps'
Bram Moolenaar8055d172019-05-17 22:57:26 +0200754 endif
755
756 " Delete two columns while text props are three chars wide.
757 call RunTestVisualBlock(2, '01')
758
759 " Same, but delete four columns
760 call RunTestVisualBlock(4, '02')
761endfunc
Bram Moolenaard79eef22019-05-24 20:41:55 +0200762
763" Adding a text property to a new buffer should not fail
764func Test_textprop_empty_buffer()
765 call prop_type_add('comment', {'highlight': 'Search'})
766 new
767 call prop_add(1, 1, {'type': 'comment'})
768 close
Bram Moolenaaradfde112019-05-25 22:11:45 +0200769 call prop_type_delete('comment')
770endfunc
771
772" Adding a text property to an empty buffer and then editing another
773func Test_textprop_empty_buffer_next()
774 call prop_type_add("xxx", {})
775 call prop_add(1, 1, {"type": "xxx"})
776 next X
777 call prop_type_delete('xxx')
Bram Moolenaard79eef22019-05-24 20:41:55 +0200778endfunc
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200779
780func Test_textprop_remove_from_buf()
781 new
782 let buf = bufnr('')
783 call prop_type_add('one', {'bufnr': buf})
784 call prop_add(1, 1, {'type': 'one', 'id': 234})
785 file x
786 edit y
787 call prop_remove({'id': 234, 'bufnr': buf}, 1)
788 call prop_type_delete('one', {'bufnr': buf})
789 bwipe! x
790 close
791endfunc