blob: d5069d4a70f73004a25c2fd97e6fda78c8bc708c [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'})
92 call prop_add(1, 8, {'length': 5, 'id': 13, 'type': 'three'})
93 call prop_add(1, 1, {'length': 13, 'id': 14, 'type': 'whole'})
94endfunc
95
96let s:expected_props = [{'col': 1, 'length': 13, 'id': 14, 'type': 'whole', 'start': 1, 'end': 1},
97 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
98 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
99 \ {'col': 8, 'length': 5, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
100 \ ]
101
102func Test_prop_add()
103 new
104 call AddPropTypes()
105 call SetupPropsInFirstLine()
106 call assert_equal(s:expected_props, prop_list(1))
107 call assert_fails("call prop_add(10, 1, {'length': 1, 'id': 14, 'type': 'whole'})", 'E966:')
108 call assert_fails("call prop_add(1, 22, {'length': 1, 'id': 14, 'type': 'whole'})", 'E964:')
109
110 " Insert a line above, text props must still be there.
111 call append(0, 'empty')
112 call assert_equal(s:expected_props, prop_list(2))
113 " Delete a line above, text props must still be there.
114 1del
115 call assert_equal(s:expected_props, prop_list(1))
116
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100117 " Prop without length or end column is zero length
118 call prop_clear(1)
119 call prop_add(1, 5, {'type': 'two'})
120 let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}]
121 call assert_equal(expected, prop_list(1))
122
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100123 call DeletePropTypes()
124 bwipe!
125endfunc
126
127func Test_prop_remove()
128 new
129 call AddPropTypes()
130 call SetupPropsInFirstLine()
131 let props = deepcopy(s:expected_props)
132 call assert_equal(props, prop_list(1))
133
134 " remove by id
135 call prop_remove({'id': 12}, 1)
136 unlet props[2]
137 call assert_equal(props, prop_list(1))
138
139 " remove by type
140 call prop_remove({'type': 'one'}, 1)
141 unlet props[1]
142 call assert_equal(props, prop_list(1))
143
144 call DeletePropTypes()
145 bwipe!
146endfunc
147
Bram Moolenaar196d1572019-01-02 23:47:18 +0100148func SetupOneLine()
149 call setline(1, 'xonex xtwoxx')
150 call AddPropTypes()
151 call prop_add(1, 2, {'length': 3, 'id': 11, 'type': 'one'})
152 call prop_add(1, 8, {'length': 3, 'id': 12, 'type': 'two'})
153 let expected = [
154 \ {'col': 2, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
155 \ {'col': 8, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
156 \]
157 call assert_equal(expected, prop_list(1))
158 return expected
159endfunc
160
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100161func Test_prop_add_remove_buf()
162 new
163 let bufnr = bufnr('')
164 call AddPropTypes()
165 call setline(1, 'one two three')
166 wincmd w
167 call prop_add(1, 1, {'length': 3, 'id': 11, 'type': 'one', 'bufnr': bufnr})
168 call prop_add(1, 5, {'length': 3, 'id': 12, 'type': 'two', 'bufnr': bufnr})
169 call prop_add(1, 11, {'length': 3, 'id': 13, 'type': 'three', 'bufnr': bufnr})
170
171 let props = [
172 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
173 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
174 \ {'col': 11, 'length': 3, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
175 \]
176 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
177
178 " remove by id
179 call prop_remove({'id': 12, 'bufnr': bufnr}, 1)
180 unlet props[1]
181 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
182
183 " remove by type
184 call prop_remove({'type': 'one', 'bufnr': bufnr}, 1)
185 unlet props[0]
186 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
187
188 call DeletePropTypes()
189 wincmd w
190 bwipe!
191endfunc
192
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100193func Test_prop_backspace()
194 new
195 set bs=2
Bram Moolenaar196d1572019-01-02 23:47:18 +0100196 let expected = SetupOneLine() " 'xonex xtwoxx'
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100197
198 exe "normal 0li\<BS>\<Esc>fxli\<BS>\<Esc>"
199 call assert_equal('one xtwoxx', getline(1))
200 let expected[0].col = 1
201 let expected[1].col = 6
202 call assert_equal(expected, prop_list(1))
203
204 call DeletePropTypes()
205 bwipe!
206 set bs&
207endfunc
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100208
Bram Moolenaar196d1572019-01-02 23:47:18 +0100209func Test_prop_replace()
210 new
211 set bs=2
212 let expected = SetupOneLine() " 'xonex xtwoxx'
213
214 exe "normal 0Ryyy\<Esc>"
215 call assert_equal('yyyex xtwoxx', getline(1))
216 call assert_equal(expected, prop_list(1))
217
218 exe "normal ftRyy\<BS>"
219 call assert_equal('yyyex xywoxx', getline(1))
220 call assert_equal(expected, prop_list(1))
221
222 exe "normal 0fwRyy\<BS>"
223 call assert_equal('yyyex xyyoxx', getline(1))
224 call assert_equal(expected, prop_list(1))
225
226 exe "normal 0foRyy\<BS>\<BS>"
227 call assert_equal('yyyex xyyoxx', getline(1))
228 call assert_equal(expected, prop_list(1))
229
230 call DeletePropTypes()
231 bwipe!
232 set bs&
233endfunc
234
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100235func Test_prop_clear()
236 new
237 call AddPropTypes()
238 call SetupPropsInFirstLine()
239 call assert_equal(s:expected_props, prop_list(1))
240
241 call prop_clear(1)
242 call assert_equal([], prop_list(1))
243
244 call DeletePropTypes()
245 bwipe!
246endfunc
247
248func Test_prop_clear_buf()
249 new
250 call AddPropTypes()
251 call SetupPropsInFirstLine()
252 let bufnr = bufnr('')
253 wincmd w
254 call assert_equal(s:expected_props, prop_list(1, {'bufnr': bufnr}))
255
256 call prop_clear(1, 1, {'bufnr': bufnr})
257 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
258
259 wincmd w
260 call DeletePropTypes()
261 bwipe!
262endfunc
263
Bram Moolenaar21b50382019-01-04 18:07:24 +0100264func Test_prop_setline()
265 new
266 call AddPropTypes()
267 call SetupPropsInFirstLine()
268 call assert_equal(s:expected_props, prop_list(1))
269
270 call setline(1, 'foobar')
271 call assert_equal([], prop_list(1))
272
273 call DeletePropTypes()
274 bwipe!
275endfunc
276
277func Test_prop_setbufline()
278 new
279 call AddPropTypes()
280 call SetupPropsInFirstLine()
281 let bufnr = bufnr('')
282 wincmd w
283 call assert_equal(s:expected_props, prop_list(1, {'bufnr': bufnr}))
284
285 call setbufline(bufnr, 1, 'foobar')
286 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
287
288 wincmd w
289 call DeletePropTypes()
290 bwipe!
291endfunc
292
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100293" Setup a three line prop in lines 2 - 4.
294" Add short props in line 1 and 5.
295func Setup_three_line_prop()
296 new
297 call setline(1, ['one', 'twotwo', 'three', 'fourfour', 'five'])
298 call prop_add(1, 2, {'length': 1, 'type': 'comment'})
299 call prop_add(2, 4, {'end_lnum': 4, 'end_col': 5, 'type': 'comment'})
300 call prop_add(5, 2, {'length': 1, 'type': 'comment'})
301endfunc
302
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100303func Test_prop_multiline()
304 call prop_type_add('comment', {'highlight': 'Directory'})
305 new
306 call setline(1, ['xxxxxxx', 'yyyyyyyyy', 'zzzzzzzz'])
307
308 " start halfway line 1, end halfway line 3
309 call prop_add(1, 3, {'end_lnum': 3, 'end_col': 5, 'type': 'comment'})
310 let expect1 = {'col': 3, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
311 call assert_equal([expect1], prop_list(1))
312 let expect2 = {'col': 1, 'length': 10, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
313 call assert_equal([expect2], prop_list(2))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100314 let expect3 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100315 call assert_equal([expect3], prop_list(3))
316 call prop_clear(1, 3)
317
318 " include all three lines
319 call prop_add(1, 1, {'end_lnum': 3, 'end_col': 999, 'type': 'comment'})
320 let expect1.col = 1
321 let expect1.length = 8
322 call assert_equal([expect1], prop_list(1))
323 call assert_equal([expect2], prop_list(2))
324 let expect3.length = 9
325 call assert_equal([expect3], prop_list(3))
326 call prop_clear(1, 3)
327
328 bwipe!
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100329
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100330 " Test deleting the first line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100331 call Setup_three_line_prop()
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100332 let expect_short = {'col': 2, 'length': 1, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
333 call assert_equal([expect_short], prop_list(1))
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100334 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
335 call assert_equal([expect2], prop_list(2))
336 2del
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100337 call assert_equal([expect_short], prop_list(1))
338 let expect2 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
339 call assert_equal([expect2], prop_list(2))
340 bwipe!
341
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100342 " Test deleting the last line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100343 call Setup_three_line_prop()
344 let expect3 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
345 call assert_equal([expect3], prop_list(3))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100346 let expect4 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100347 call assert_equal([expect4], prop_list(4))
348 4del
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100349 let expect3.end = 1
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100350 call assert_equal([expect3], prop_list(3))
351 call assert_equal([expect_short], prop_list(4))
352 bwipe!
353
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100354 " Test appending a line below the multi-line text prop start.
Bram Moolenaarb56ac042018-12-28 23:22:40 +0100355 call Setup_three_line_prop()
356 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
357 call assert_equal([expect2], prop_list(2))
358 call append(2, "new line")
359 call assert_equal([expect2], prop_list(2))
360 let expect3 = {'col': 1, 'length': 9, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
361 call assert_equal([expect3], prop_list(3))
362 bwipe!
363
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100364 call prop_type_delete('comment')
365endfunc
366
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100367func Test_prop_byteoff()
368 call prop_type_add('comment', {'highlight': 'Directory'})
369 new
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100370 call setline(1, ['line1', 'second line', ''])
Bram Moolenaar8cf734e2018-12-26 01:09:00 +0100371 set ff=unix
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100372 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100373 call prop_add(1, 1, {'end_col': 3, 'type': 'comment'})
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100374 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100375
376 bwipe!
377 call prop_type_delete('comment')
378endfunc
379
Bram Moolenaar7f1664e2019-01-04 17:21:24 +0100380func Test_prop_undo()
381 new
382 call prop_type_add('comment', {'highlight': 'Directory'})
383 call setline(1, ['oneone', 'twotwo', 'three'])
384 " Set 'undolevels' to break changes into undo-able pieces.
385 set ul&
386
387 call prop_add(1, 3, {'end_col': 5, 'type': 'comment'})
388 let expected = [{'col': 3, 'length': 2, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
389 call assert_equal(expected, prop_list(1))
390
391 " Insert a character, then undo.
392 exe "normal 0lllix\<Esc>"
393 set ul&
394 let expected[0].length = 3
395 call assert_equal(expected, prop_list(1))
396 undo
397 let expected[0].length = 2
398 call assert_equal(expected, prop_list(1))
399
400 " Delete a character, then undo
401 exe "normal 0lllx"
402 set ul&
403 let expected[0].length = 1
404 call assert_equal(expected, prop_list(1))
405 undo
406 let expected[0].length = 2
407 call assert_equal(expected, prop_list(1))
408
409 " Delete the line, then undo
410 1d
411 set ul&
412 call assert_equal([], prop_list(1))
413 undo
414 call assert_equal(expected, prop_list(1))
415
416 " Insert a character, delete two characters, then undo with "U"
417 exe "normal 0lllix\<Esc>"
418 set ul&
419 let expected[0].length = 3
420 call assert_equal(expected, prop_list(1))
421 exe "normal 0lllxx"
422 set ul&
423 let expected[0].length = 1
424 call assert_equal(expected, prop_list(1))
425 normal U
426 let expected[0].length = 2
427 call assert_equal(expected, prop_list(1))
428
429 bwipe!
430 call prop_type_delete('comment')
431endfunc
432
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100433" screenshot test with textprop highlighting
434funct Test_textprop_screenshots()
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100435 if !CanRunVimInTerminal() || &encoding != 'utf-8'
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100436 return
437 endif
438 call writefile([
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100439 \ "call setline(1, ['One two', 'Numbér 123 änd thœn 4¾7.', '--aa--bb--cc--dd--'])",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100440 \ "hi NumberProp ctermfg=blue",
441 \ "hi LongProp ctermbg=yellow",
442 \ "call prop_type_add('number', {'highlight': 'NumberProp'})",
443 \ "call prop_type_add('long', {'highlight': 'LongProp'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100444 \ "call prop_type_add('start', {'highlight': 'NumberProp', 'start_incl': 1})",
445 \ "call prop_type_add('end', {'highlight': 'NumberProp', 'end_incl': 1})",
446 \ "call prop_type_add('both', {'highlight': 'NumberProp', 'start_incl': 1, 'end_incl': 1})",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100447 \ "call prop_add(1, 4, {'end_lnum': 3, 'end_col': 3, 'type': 'long'})",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100448 \ "call prop_add(2, 9, {'length': 3, 'type': 'number'})",
449 \ "call prop_add(2, 24, {'length': 4, 'type': 'number'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100450 \ "call prop_add(3, 3, {'length': 2, 'type': 'number'})",
451 \ "call prop_add(3, 7, {'length': 2, 'type': 'start'})",
452 \ "call prop_add(3, 11, {'length': 2, 'type': 'end'})",
453 \ "call prop_add(3, 15, {'length': 2, 'type': 'both'})",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100454 \ "set number",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100455 \ "hi clear SpellBad",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100456 \ "set spell",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100457 \ "normal 3G0llix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>",
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100458 \ "normal 3G0lli\<BS>\<Esc>",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100459 \], 'XtestProp')
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100460 let buf = RunVimInTerminal('-S XtestProp', {'rows': 6})
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100461 call VerifyScreenDump(buf, 'Test_textprop_01', {})
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100462
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100463 " clean up
464 call StopVimInTerminal(buf)
Bram Moolenaar2f21fa82018-12-31 20:05:56 +0100465 call delete('XtestProp')
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100466endfunc