blob: c71f1a7d4dfe3cf99eb463ef13ae3af43ded36c0 [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
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02004source check.vim
5CheckFeature textprop
Bram Moolenaar98aefe72018-12-13 22:20:09 +01006
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +01007source screendump.vim
8
Bram Moolenaarb9c67a52019-01-01 19:49:20 +01009" test length zero
10
Bram Moolenaar98aefe72018-12-13 22:20:09 +010011func Test_proptype_global()
12 call prop_type_add('comment', {'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1})
13 let proptypes = prop_type_list()
14 call assert_equal(1, len(proptypes))
15 call assert_equal('comment', proptypes[0])
16
17 let proptype = prop_type_get('comment')
18 call assert_equal('Directory', proptype['highlight'])
19 call assert_equal(123, proptype['priority'])
20 call assert_equal(1, proptype['start_incl'])
21 call assert_equal(1, proptype['end_incl'])
22
23 call prop_type_delete('comment')
24 call assert_equal(0, len(prop_type_list()))
25
26 call prop_type_add('one', {})
27 call assert_equal(1, len(prop_type_list()))
Bram Moolenaara5a78822019-09-04 21:57:18 +020028 let proptype = 'one'->prop_type_get()
Bram Moolenaar98aefe72018-12-13 22:20:09 +010029 call assert_false(has_key(proptype, 'highlight'))
30 call assert_equal(0, proptype['priority'])
31 call assert_equal(0, proptype['start_incl'])
32 call assert_equal(0, proptype['end_incl'])
33
34 call prop_type_add('two', {})
35 call assert_equal(2, len(prop_type_list()))
36 call prop_type_delete('one')
37 call assert_equal(1, len(prop_type_list()))
38 call prop_type_delete('two')
39 call assert_equal(0, len(prop_type_list()))
40endfunc
41
42func Test_proptype_buf()
43 let bufnr = bufnr('')
44 call prop_type_add('comment', {'bufnr': bufnr, 'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1})
45 let proptypes = prop_type_list({'bufnr': bufnr})
46 call assert_equal(1, len(proptypes))
47 call assert_equal('comment', proptypes[0])
48
49 let proptype = prop_type_get('comment', {'bufnr': bufnr})
50 call assert_equal('Directory', proptype['highlight'])
51 call assert_equal(123, proptype['priority'])
52 call assert_equal(1, proptype['start_incl'])
53 call assert_equal(1, proptype['end_incl'])
54
55 call prop_type_delete('comment', {'bufnr': bufnr})
Bram Moolenaara5a78822019-09-04 21:57:18 +020056 call assert_equal(0, len({'bufnr': bufnr}->prop_type_list()))
Bram Moolenaar98aefe72018-12-13 22:20:09 +010057
58 call prop_type_add('one', {'bufnr': bufnr})
59 let proptype = prop_type_get('one', {'bufnr': bufnr})
60 call assert_false(has_key(proptype, 'highlight'))
61 call assert_equal(0, proptype['priority'])
62 call assert_equal(0, proptype['start_incl'])
63 call assert_equal(0, proptype['end_incl'])
64
65 call prop_type_add('two', {'bufnr': bufnr})
66 call assert_equal(2, len(prop_type_list({'bufnr': bufnr})))
67 call prop_type_delete('one', {'bufnr': bufnr})
68 call assert_equal(1, len(prop_type_list({'bufnr': bufnr})))
69 call prop_type_delete('two', {'bufnr': bufnr})
70 call assert_equal(0, len(prop_type_list({'bufnr': bufnr})))
Bram Moolenaarf0884c52019-05-24 21:22:29 +020071
72 call assert_fails("call prop_type_add('one', {'bufnr': 98764})", "E158:")
Bram Moolenaar98aefe72018-12-13 22:20:09 +010073endfunc
74
75func AddPropTypes()
76 call prop_type_add('one', {})
77 call prop_type_add('two', {})
78 call prop_type_add('three', {})
79 call prop_type_add('whole', {})
80endfunc
81
82func DeletePropTypes()
83 call prop_type_delete('one')
84 call prop_type_delete('two')
85 call prop_type_delete('three')
86 call prop_type_delete('whole')
87endfunc
88
89func SetupPropsInFirstLine()
90 call setline(1, 'one two three')
91 call prop_add(1, 1, {'length': 3, 'id': 11, 'type': 'one'})
Bram Moolenaara5a78822019-09-04 21:57:18 +020092 eval 1->prop_add(5, {'length': 3, 'id': 12, 'type': 'two'})
Bram Moolenaar4164bb22019-01-04 23:09:49 +010093 call prop_add(1, 9, {'length': 5, 'id': 13, 'type': 'three'})
Bram Moolenaar98aefe72018-12-13 22:20:09 +010094 call prop_add(1, 1, {'length': 13, 'id': 14, 'type': 'whole'})
95endfunc
96
Bram Moolenaar4164bb22019-01-04 23:09:49 +010097func Get_expected_props()
98 return [
99 \ {'col': 1, 'length': 13, 'id': 14, 'type': 'whole', 'start': 1, 'end': 1},
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100100 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
101 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100102 \ {'col': 9, 'length': 5, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100103 \ ]
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100104endfunc
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100105
106func Test_prop_add()
107 new
108 call AddPropTypes()
109 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100110 let expected_props = Get_expected_props()
111 call assert_equal(expected_props, prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100112 call assert_fails("call prop_add(10, 1, {'length': 1, 'id': 14, 'type': 'whole'})", 'E966:')
113 call assert_fails("call prop_add(1, 22, {'length': 1, 'id': 14, 'type': 'whole'})", 'E964:')
114
115 " Insert a line above, text props must still be there.
116 call append(0, 'empty')
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100117 call assert_equal(expected_props, prop_list(2))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100118 " Delete a line above, text props must still be there.
119 1del
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100120 call assert_equal(expected_props, prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100121
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100122 " Prop without length or end column is zero length
123 call prop_clear(1)
124 call prop_add(1, 5, {'type': 'two'})
125 let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}]
126 call assert_equal(expected, prop_list(1))
127
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200128 call assert_fails("call prop_add(1, 5, {'type': 'two', 'bufnr': 234343})", 'E158:')
129
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100130 call DeletePropTypes()
131 bwipe!
132endfunc
133
134func Test_prop_remove()
135 new
136 call AddPropTypes()
137 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100138 let props = Get_expected_props()
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100139 call assert_equal(props, prop_list(1))
140
141 " remove by id
Bram Moolenaara5a78822019-09-04 21:57:18 +0200142 call assert_equal(1, {'id': 12}->prop_remove(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100143 unlet props[2]
144 call assert_equal(props, prop_list(1))
145
146 " remove by type
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200147 call assert_equal(1, prop_remove({'type': 'one'}, 1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100148 unlet props[1]
149 call assert_equal(props, prop_list(1))
150
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200151 " remove from unknown buffer
152 call assert_fails("call prop_remove({'type': 'one', 'bufnr': 123456}, 1)", 'E158:')
153
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100154 call DeletePropTypes()
155 bwipe!
156endfunc
157
Bram Moolenaar196d1572019-01-02 23:47:18 +0100158func SetupOneLine()
159 call setline(1, 'xonex xtwoxx')
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200160 normal gg0
Bram Moolenaar196d1572019-01-02 23:47:18 +0100161 call AddPropTypes()
162 call prop_add(1, 2, {'length': 3, 'id': 11, 'type': 'one'})
163 call prop_add(1, 8, {'length': 3, 'id': 12, 'type': 'two'})
164 let expected = [
165 \ {'col': 2, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
166 \ {'col': 8, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
167 \]
168 call assert_equal(expected, prop_list(1))
169 return expected
170endfunc
171
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100172func Test_prop_add_remove_buf()
173 new
174 let bufnr = bufnr('')
175 call AddPropTypes()
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100176 for lnum in range(1, 4)
177 call setline(lnum, 'one two three')
178 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100179 wincmd w
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100180 for lnum in range(1, 4)
181 call prop_add(lnum, 1, {'length': 3, 'id': 11, 'type': 'one', 'bufnr': bufnr})
182 call prop_add(lnum, 5, {'length': 3, 'id': 12, 'type': 'two', 'bufnr': bufnr})
183 call prop_add(lnum, 11, {'length': 3, 'id': 13, 'type': 'three', 'bufnr': bufnr})
184 endfor
185
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100186 let props = [
187 \ {'col': 1, 'length': 3, 'id': 11, 'type': 'one', 'start': 1, 'end': 1},
188 \ {'col': 5, 'length': 3, 'id': 12, 'type': 'two', 'start': 1, 'end': 1},
189 \ {'col': 11, 'length': 3, 'id': 13, 'type': 'three', 'start': 1, 'end': 1},
190 \]
191 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100192
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100193 " remove by id
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100194 let before_props = deepcopy(props)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100195 unlet props[1]
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100196
197 call prop_remove({'id': 12, 'bufnr': bufnr}, 1)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100198 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100199 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
200 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr}))
201 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr}))
202
203 call prop_remove({'id': 12, 'bufnr': bufnr}, 3, 4)
204 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
205 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
206 call assert_equal(props, prop_list(3, {'bufnr': bufnr}))
207 call assert_equal(props, prop_list(4, {'bufnr': bufnr}))
208
209 call prop_remove({'id': 12, 'bufnr': bufnr})
210 for lnum in range(1, 4)
211 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr}))
212 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100213
214 " remove by type
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100215 let before_props = deepcopy(props)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100216 unlet props[0]
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100217
218 call prop_remove({'type': 'one', 'bufnr': bufnr}, 1)
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100219 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar0a2f5782019-03-22 13:20:43 +0100220 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
221 call assert_equal(before_props, prop_list(3, {'bufnr': bufnr}))
222 call assert_equal(before_props, prop_list(4, {'bufnr': bufnr}))
223
224 call prop_remove({'type': 'one', 'bufnr': bufnr}, 3, 4)
225 call assert_equal(props, prop_list(1, {'bufnr': bufnr}))
226 call assert_equal(before_props, prop_list(2, {'bufnr': bufnr}))
227 call assert_equal(props, prop_list(3, {'bufnr': bufnr}))
228 call assert_equal(props, prop_list(4, {'bufnr': bufnr}))
229
230 call prop_remove({'type': 'one', 'bufnr': bufnr})
231 for lnum in range(1, 4)
232 call assert_equal(props, prop_list(lnum, {'bufnr': bufnr}))
233 endfor
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100234
235 call DeletePropTypes()
236 wincmd w
237 bwipe!
238endfunc
239
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100240func Test_prop_backspace()
241 new
242 set bs=2
Bram Moolenaar196d1572019-01-02 23:47:18 +0100243 let expected = SetupOneLine() " 'xonex xtwoxx'
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100244
245 exe "normal 0li\<BS>\<Esc>fxli\<BS>\<Esc>"
246 call assert_equal('one xtwoxx', getline(1))
247 let expected[0].col = 1
248 let expected[1].col = 6
249 call assert_equal(expected, prop_list(1))
250
251 call DeletePropTypes()
252 bwipe!
253 set bs&
254endfunc
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100255
Bram Moolenaar196d1572019-01-02 23:47:18 +0100256func Test_prop_replace()
257 new
258 set bs=2
259 let expected = SetupOneLine() " 'xonex xtwoxx'
260
261 exe "normal 0Ryyy\<Esc>"
262 call assert_equal('yyyex xtwoxx', getline(1))
263 call assert_equal(expected, prop_list(1))
264
265 exe "normal ftRyy\<BS>"
266 call assert_equal('yyyex xywoxx', getline(1))
267 call assert_equal(expected, prop_list(1))
268
269 exe "normal 0fwRyy\<BS>"
270 call assert_equal('yyyex xyyoxx', getline(1))
271 call assert_equal(expected, prop_list(1))
272
273 exe "normal 0foRyy\<BS>\<BS>"
274 call assert_equal('yyyex xyyoxx', getline(1))
275 call assert_equal(expected, prop_list(1))
276
277 call DeletePropTypes()
278 bwipe!
279 set bs&
280endfunc
281
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200282func Test_prop_open_line()
283 new
284
285 " open new line, props stay in top line
286 let expected = SetupOneLine() " 'xonex xtwoxx'
287 exe "normal o\<Esc>"
288 call assert_equal('xonex xtwoxx', getline(1))
289 call assert_equal('', getline(2))
290 call assert_equal(expected, prop_list(1))
291 call DeletePropTypes()
292
293 " move all props to next line
294 let expected = SetupOneLine() " 'xonex xtwoxx'
295 exe "normal 0i\<CR>\<Esc>"
296 call assert_equal('', getline(1))
297 call assert_equal('xonex xtwoxx', getline(2))
298 call assert_equal(expected, prop_list(2))
299 call DeletePropTypes()
300
301 " split just before prop, move all props to next line
302 let expected = SetupOneLine() " 'xonex xtwoxx'
303 exe "normal 0li\<CR>\<Esc>"
304 call assert_equal('x', getline(1))
305 call assert_equal('onex xtwoxx', getline(2))
306 let expected[0].col -= 1
307 let expected[1].col -= 1
308 call assert_equal(expected, prop_list(2))
309 call DeletePropTypes()
310
311 " split inside prop, split first prop
312 let expected = SetupOneLine() " 'xonex xtwoxx'
313 exe "normal 0lli\<CR>\<Esc>"
314 call assert_equal('xo', getline(1))
315 call assert_equal('nex xtwoxx', getline(2))
316 let exp_first = [deepcopy(expected[0])]
317 let exp_first[0].length = 1
318 call assert_equal(exp_first, prop_list(1))
319 let expected[0].col = 1
320 let expected[0].length = 2
321 let expected[1].col -= 2
322 call assert_equal(expected, prop_list(2))
323 call DeletePropTypes()
324
Bram Moolenaar5c65e6a2019-05-17 11:08:56 +0200325 " split just after first prop, second prop move to next line
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200326 let expected = SetupOneLine() " 'xonex xtwoxx'
327 exe "normal 0fea\<CR>\<Esc>"
328 call assert_equal('xone', getline(1))
329 call assert_equal('x xtwoxx', getline(2))
330 let exp_first = expected[0:0]
331 call assert_equal(exp_first, prop_list(1))
Bram Moolenaar5c65e6a2019-05-17 11:08:56 +0200332 let expected = expected[1:1]
333 let expected[0].col -= 4
Bram Moolenaar45dd07f2019-05-15 22:45:37 +0200334 call assert_equal(expected, prop_list(2))
335 call DeletePropTypes()
336
337 bwipe!
338 set bs&
339endfunc
340
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100341func Test_prop_clear()
342 new
343 call AddPropTypes()
344 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100345 call assert_equal(Get_expected_props(), prop_list(1))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100346
Bram Moolenaara5a78822019-09-04 21:57:18 +0200347 eval 1->prop_clear()
348 call assert_equal([], 1->prop_list())
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100349
350 call DeletePropTypes()
351 bwipe!
352endfunc
353
354func Test_prop_clear_buf()
355 new
356 call AddPropTypes()
357 call SetupPropsInFirstLine()
358 let bufnr = bufnr('')
359 wincmd w
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100360 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar98aefe72018-12-13 22:20:09 +0100361
362 call prop_clear(1, 1, {'bufnr': bufnr})
363 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
364
365 wincmd w
366 call DeletePropTypes()
367 bwipe!
368endfunc
369
Bram Moolenaar21b50382019-01-04 18:07:24 +0100370func Test_prop_setline()
371 new
372 call AddPropTypes()
373 call SetupPropsInFirstLine()
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100374 call assert_equal(Get_expected_props(), prop_list(1))
Bram Moolenaar21b50382019-01-04 18:07:24 +0100375
376 call setline(1, 'foobar')
377 call assert_equal([], prop_list(1))
378
379 call DeletePropTypes()
380 bwipe!
381endfunc
382
383func Test_prop_setbufline()
384 new
385 call AddPropTypes()
386 call SetupPropsInFirstLine()
387 let bufnr = bufnr('')
388 wincmd w
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100389 call assert_equal(Get_expected_props(), prop_list(1, {'bufnr': bufnr}))
Bram Moolenaar21b50382019-01-04 18:07:24 +0100390
391 call setbufline(bufnr, 1, 'foobar')
392 call assert_equal([], prop_list(1, {'bufnr': bufnr}))
393
394 wincmd w
395 call DeletePropTypes()
396 bwipe!
397endfunc
398
Bram Moolenaar4164bb22019-01-04 23:09:49 +0100399func Test_prop_substitute()
400 new
401 " Set first line to 'one two three'
402 call AddPropTypes()
403 call SetupPropsInFirstLine()
404 let expected_props = Get_expected_props()
405 call assert_equal(expected_props, prop_list(1))
406
407 " Change "n" in "one" to XX: 'oXXe two three'
408 s/n/XX/
409 let expected_props[0].length += 1
410 let expected_props[1].length += 1
411 let expected_props[2].col += 1
412 let expected_props[3].col += 1
413 call assert_equal(expected_props, prop_list(1))
414
415 " Delete "t" in "two" and "three" to XX: 'oXXe wo hree'
416 s/t//g
417 let expected_props[0].length -= 2
418 let expected_props[2].length -= 1
419 let expected_props[3].length -= 1
420 let expected_props[3].col -= 1
421 call assert_equal(expected_props, prop_list(1))
422
423 " Split the line by changing w to line break: 'oXXe ', 'o hree'
424 " The long prop is split and spans both lines.
425 " The props on "two" and "three" move to the next line.
426 s/w/\r/
427 let new_props = [
428 \ copy(expected_props[0]),
429 \ copy(expected_props[2]),
430 \ copy(expected_props[3]),
431 \ ]
432 let expected_props[0].length = 5
433 unlet expected_props[3]
434 unlet expected_props[2]
435 call assert_equal(expected_props, prop_list(1))
436
437 let new_props[0].length = 6
438 let new_props[1].col = 1
439 let new_props[1].length = 1
440 let new_props[2].col = 3
441 call assert_equal(new_props, prop_list(2))
442
443 call DeletePropTypes()
444 bwipe!
445endfunc
446
Bram Moolenaar663bc892019-01-08 23:07:24 +0100447func Test_prop_change_indent()
448 call prop_type_add('comment', {'highlight': 'Directory'})
449 new
450 call setline(1, [' xxx', 'yyyyy'])
451 call prop_add(2, 2, {'length': 2, 'type': 'comment'})
452 let expect = {'col': 2, 'length': 2, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
453 call assert_equal([expect], prop_list(2))
454
455 set shiftwidth=3
456 normal 2G>>
457 call assert_equal(' yyyyy', getline(2))
458 let expect.col += 3
459 call assert_equal([expect], prop_list(2))
460
461 normal 2G==
462 call assert_equal(' yyyyy', getline(2))
463 let expect.col = 6
464 call assert_equal([expect], prop_list(2))
465
466 call prop_clear(2)
467 call prop_add(2, 2, {'length': 5, 'type': 'comment'})
468 let expect.col = 2
469 let expect.length = 5
470 call assert_equal([expect], prop_list(2))
471
472 normal 2G<<
473 call assert_equal(' yyyyy', getline(2))
474 let expect.length = 2
475 call assert_equal([expect], prop_list(2))
476
477 set shiftwidth&
478 call prop_type_delete('comment')
479endfunc
480
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100481" Setup a three line prop in lines 2 - 4.
482" Add short props in line 1 and 5.
483func Setup_three_line_prop()
484 new
485 call setline(1, ['one', 'twotwo', 'three', 'fourfour', 'five'])
486 call prop_add(1, 2, {'length': 1, 'type': 'comment'})
487 call prop_add(2, 4, {'end_lnum': 4, 'end_col': 5, 'type': 'comment'})
488 call prop_add(5, 2, {'length': 1, 'type': 'comment'})
489endfunc
490
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100491func Test_prop_multiline()
Bram Moolenaara5a78822019-09-04 21:57:18 +0200492 eval 'comment'->prop_type_add({'highlight': 'Directory'})
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100493 new
494 call setline(1, ['xxxxxxx', 'yyyyyyyyy', 'zzzzzzzz'])
495
496 " start halfway line 1, end halfway line 3
497 call prop_add(1, 3, {'end_lnum': 3, 'end_col': 5, 'type': 'comment'})
498 let expect1 = {'col': 3, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
499 call assert_equal([expect1], prop_list(1))
500 let expect2 = {'col': 1, 'length': 10, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
501 call assert_equal([expect2], prop_list(2))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100502 let expect3 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100503 call assert_equal([expect3], prop_list(3))
504 call prop_clear(1, 3)
505
506 " include all three lines
507 call prop_add(1, 1, {'end_lnum': 3, 'end_col': 999, 'type': 'comment'})
508 let expect1.col = 1
509 let expect1.length = 8
510 call assert_equal([expect1], prop_list(1))
511 call assert_equal([expect2], prop_list(2))
512 let expect3.length = 9
513 call assert_equal([expect3], prop_list(3))
514 call prop_clear(1, 3)
515
516 bwipe!
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100517
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100518 " Test deleting the first line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100519 call Setup_three_line_prop()
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100520 let expect_short = {'col': 2, 'length': 1, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
521 call assert_equal([expect_short], prop_list(1))
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100522 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
523 call assert_equal([expect2], prop_list(2))
524 2del
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100525 call assert_equal([expect_short], prop_list(1))
526 let expect2 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
527 call assert_equal([expect2], prop_list(2))
528 bwipe!
529
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100530 " Test deleting the last line of a multi-line prop.
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100531 call Setup_three_line_prop()
532 let expect3 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
533 call assert_equal([expect3], prop_list(3))
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100534 let expect4 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100535 call assert_equal([expect4], prop_list(4))
536 4del
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100537 let expect3.end = 1
Bram Moolenaarc1a9bc12018-12-28 21:59:29 +0100538 call assert_equal([expect3], prop_list(3))
539 call assert_equal([expect_short], prop_list(4))
540 bwipe!
541
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100542 " Test appending a line below the multi-line text prop start.
Bram Moolenaarb56ac042018-12-28 23:22:40 +0100543 call Setup_three_line_prop()
544 let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
545 call assert_equal([expect2], prop_list(2))
546 call append(2, "new line")
547 call assert_equal([expect2], prop_list(2))
548 let expect3 = {'col': 1, 'length': 9, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
549 call assert_equal([expect3], prop_list(3))
550 bwipe!
551
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100552 call prop_type_delete('comment')
553endfunc
554
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100555func Test_prop_byteoff()
556 call prop_type_add('comment', {'highlight': 'Directory'})
557 new
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100558 call setline(1, ['line1', 'second line', ''])
Bram Moolenaar8cf734e2018-12-26 01:09:00 +0100559 set ff=unix
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100560 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100561 call prop_add(1, 1, {'end_col': 3, 'type': 'comment'})
Bram Moolenaar00b1e042018-12-26 23:42:10 +0100562 call assert_equal(19, line2byte(3))
Bram Moolenaarb413d2e2018-12-25 23:15:46 +0100563
564 bwipe!
565 call prop_type_delete('comment')
566endfunc
567
Bram Moolenaar7f1664e2019-01-04 17:21:24 +0100568func Test_prop_undo()
569 new
570 call prop_type_add('comment', {'highlight': 'Directory'})
571 call setline(1, ['oneone', 'twotwo', 'three'])
572 " Set 'undolevels' to break changes into undo-able pieces.
573 set ul&
574
575 call prop_add(1, 3, {'end_col': 5, 'type': 'comment'})
576 let expected = [{'col': 3, 'length': 2, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
577 call assert_equal(expected, prop_list(1))
578
579 " Insert a character, then undo.
580 exe "normal 0lllix\<Esc>"
581 set ul&
582 let expected[0].length = 3
583 call assert_equal(expected, prop_list(1))
584 undo
585 let expected[0].length = 2
586 call assert_equal(expected, prop_list(1))
587
588 " Delete a character, then undo
589 exe "normal 0lllx"
590 set ul&
591 let expected[0].length = 1
592 call assert_equal(expected, prop_list(1))
593 undo
594 let expected[0].length = 2
595 call assert_equal(expected, prop_list(1))
596
597 " Delete the line, then undo
598 1d
599 set ul&
600 call assert_equal([], prop_list(1))
601 undo
602 call assert_equal(expected, prop_list(1))
603
604 " Insert a character, delete two characters, then undo with "U"
605 exe "normal 0lllix\<Esc>"
606 set ul&
607 let expected[0].length = 3
608 call assert_equal(expected, prop_list(1))
609 exe "normal 0lllxx"
610 set ul&
611 let expected[0].length = 1
612 call assert_equal(expected, prop_list(1))
613 normal U
614 let expected[0].length = 2
615 call assert_equal(expected, prop_list(1))
616
Bram Moolenaar338dfda2019-05-19 15:19:57 +0200617 " substitute a word, then undo
618 call setline(1, 'the number 123 is highlighted.')
619 call prop_add(1, 12, {'length': 3, 'type': 'comment'})
620 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
621 call assert_equal(expected, prop_list(1))
622 set ul&
623 1s/number/foo
624 let expected[0].col = 9
625 call assert_equal(expected, prop_list(1))
626 undo
627 let expected[0].col = 12
628 call assert_equal(expected, prop_list(1))
Bram Moolenaarf3333b02019-05-19 22:53:40 +0200629 call prop_clear(1)
630
631 " substitute with backslash
632 call setline(1, 'the number 123 is highlighted.')
633 call prop_add(1, 12, {'length': 3, 'type': 'comment'})
634 let expected = [{'col': 12, 'length': 3, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
635 call assert_equal(expected, prop_list(1))
636 1s/the/\The
637 call assert_equal(expected, prop_list(1))
638 1s/^/\\
639 let expected[0].col += 1
640 call assert_equal(expected, prop_list(1))
641 1s/^/\~
642 let expected[0].col += 1
643 call assert_equal(expected, prop_list(1))
644 1s/123/12\\3
645 let expected[0].length += 1
646 call assert_equal(expected, prop_list(1))
647 call prop_clear(1)
Bram Moolenaar338dfda2019-05-19 15:19:57 +0200648
Bram Moolenaar7f1664e2019-01-04 17:21:24 +0100649 bwipe!
650 call prop_type_delete('comment')
651endfunc
652
Bram Moolenaarecafcc12019-11-16 20:41:51 +0100653func Test_prop_delete_text()
654 new
655 call prop_type_add('comment', {'highlight': 'Directory'})
656 call setline(1, ['oneone', 'twotwo', 'three'])
657
658 " zero length property
659 call prop_add(1, 3, {'type': 'comment'})
660 let expected = [{'col': 3, 'length': 0, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
661 call assert_equal(expected, prop_list(1))
662
663 " delete one char moves the property
664 normal! x
665 let expected = [{'col': 2, 'length': 0, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
666 call assert_equal(expected, prop_list(1))
667
668 " delete char of the property has no effect
669 normal! lx
670 let expected = [{'col': 2, 'length': 0, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
671 call assert_equal(expected, prop_list(1))
672
673 " delete more chars moves property to first column, is not deleted
674 normal! 0xxxx
675 let expected = [{'col': 1, 'length': 0, 'id': 0, 'type': 'comment', 'start': 1, 'end': 1} ]
676 call assert_equal(expected, prop_list(1))
677
678 bwipe!
679 call prop_type_delete('comment')
680endfunc
681
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100682" screenshot test with textprop highlighting
Bram Moolenaar8055d172019-05-17 22:57:26 +0200683func Test_textprop_screenshot_various()
Bram Moolenaar34390282019-10-16 14:38:26 +0200684 CheckScreendump
Bram Moolenaared79d1e2019-02-22 14:38:58 +0100685 " The Vim running in the terminal needs to use utf-8.
Bram Moolenaar34390282019-10-16 14:38:26 +0200686 if g:orig_encoding != 'utf-8'
687 throw 'Skipped: not using utf-8'
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100688 endif
689 call writefile([
Bram Moolenaarde24a872019-05-05 15:48:00 +0200690 \ "call setline(1, ["
691 \ .. "'One two',"
692 \ .. "'Numbér 123 änd thœn 4¾7.',"
693 \ .. "'--aa--bb--cc--dd--',"
694 \ .. "'// comment with error in it',"
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200695 \ .. "'first line',"
696 \ .. "' second line ',"
697 \ .. "'third line',"
698 \ .. "' fourth line',"
Bram Moolenaarde24a872019-05-05 15:48:00 +0200699 \ .. "])",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100700 \ "hi NumberProp ctermfg=blue",
701 \ "hi LongProp ctermbg=yellow",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200702 \ "hi BackgroundProp ctermbg=lightgrey",
703 \ "hi UnderlineProp cterm=underline",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100704 \ "call prop_type_add('number', {'highlight': 'NumberProp'})",
Bram Moolenaara5a78822019-09-04 21:57:18 +0200705 \ "call prop_type_add('long', {'highlight': 'NumberProp'})",
706 \ "call prop_type_change('long', {'highlight': 'LongProp'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100707 \ "call prop_type_add('start', {'highlight': 'NumberProp', 'start_incl': 1})",
708 \ "call prop_type_add('end', {'highlight': 'NumberProp', 'end_incl': 1})",
709 \ "call prop_type_add('both', {'highlight': 'NumberProp', 'start_incl': 1, 'end_incl': 1})",
Bram Moolenaardbd43162019-11-09 21:28:14 +0100710 \ "call prop_type_add('background', {'highlight': 'BackgroundProp', 'combine': 0})",
711 \ "call prop_type_add('backgroundcomb', {'highlight': 'NumberProp', 'combine': 1})",
712 \ "eval 'backgroundcomb'->prop_type_change({'highlight': 'BackgroundProp'})",
Bram Moolenaar58e32ab2019-11-12 22:44:22 +0100713 \ "call prop_type_add('error', {'highlight': 'UnderlineProp'})",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100714 \ "call prop_add(1, 4, {'end_lnum': 3, 'end_col': 3, 'type': 'long'})",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100715 \ "call prop_add(2, 9, {'length': 3, 'type': 'number'})",
716 \ "call prop_add(2, 24, {'length': 4, 'type': 'number'})",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100717 \ "call prop_add(3, 3, {'length': 2, 'type': 'number'})",
718 \ "call prop_add(3, 7, {'length': 2, 'type': 'start'})",
719 \ "call prop_add(3, 11, {'length': 2, 'type': 'end'})",
720 \ "call prop_add(3, 15, {'length': 2, 'type': 'both'})",
Bram Moolenaardbd43162019-11-09 21:28:14 +0100721 \ "call prop_add(4, 6, {'length': 3, 'type': 'background'})",
722 \ "call prop_add(4, 12, {'length': 10, 'type': 'backgroundcomb'})",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200723 \ "call prop_add(4, 17, {'length': 5, 'type': 'error'})",
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200724 \ "call prop_add(5, 7, {'length': 4, 'type': 'long'})",
725 \ "call prop_add(6, 1, {'length': 8, 'type': 'long'})",
726 \ "call prop_add(8, 1, {'length': 1, 'type': 'long'})",
727 \ "call prop_add(8, 11, {'length': 4, 'type': 'long'})",
Bram Moolenaarbfd45122019-05-17 13:05:07 +0200728 \ "set number cursorline",
Bram Moolenaarb9c67a52019-01-01 19:49:20 +0100729 \ "hi clear SpellBad",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100730 \ "set spell",
Bram Moolenaarde24a872019-05-05 15:48:00 +0200731 \ "syn match Comment '//.*'",
732 \ "hi Comment ctermfg=green",
Bram Moolenaar44746aa2019-01-02 00:02:11 +0100733 \ "normal 3G0llix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>lllix\<Esc>",
Bram Moolenaar33c8ca92019-01-02 18:00:27 +0100734 \ "normal 3G0lli\<BS>\<Esc>",
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200735 \ "normal 6G0i\<BS>\<Esc>",
736 \ "normal 3J",
737 \ "normal 3G",
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100738 \], 'XtestProp')
Bram Moolenaar80e737c2019-05-17 19:56:34 +0200739 let buf = RunVimInTerminal('-S XtestProp', {'rows': 8})
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100740 call VerifyScreenDump(buf, 'Test_textprop_01', {})
Bram Moolenaare3d31b02018-12-24 23:07:04 +0100741
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100742 " clean up
743 call StopVimInTerminal(buf)
Bram Moolenaar2f21fa82018-12-31 20:05:56 +0100744 call delete('XtestProp')
Bram Moolenaarc6d86dc2018-12-31 13:57:36 +0100745endfunc
Bram Moolenaar8055d172019-05-17 22:57:26 +0200746
747func RunTestVisualBlock(width, dump)
748 call writefile([
749 \ "call setline(1, ["
750 \ .. "'xxxxxxxxx 123 x',"
751 \ .. "'xxxxxxxx 123 x',"
752 \ .. "'xxxxxxx 123 x',"
753 \ .. "'xxxxxx 123 x',"
754 \ .. "'xxxxx 123 x',"
755 \ .. "'xxxx 123 xx',"
756 \ .. "'xxx 123 xxx',"
757 \ .. "'xx 123 xxxx',"
758 \ .. "'x 123 xxxxx',"
759 \ .. "' 123 xxxxxx',"
760 \ .. "])",
761 \ "hi SearchProp ctermbg=yellow",
762 \ "call prop_type_add('search', {'highlight': 'SearchProp'})",
763 \ "call prop_add(1, 11, {'length': 3, 'type': 'search'})",
764 \ "call prop_add(2, 10, {'length': 3, 'type': 'search'})",
765 \ "call prop_add(3, 9, {'length': 3, 'type': 'search'})",
766 \ "call prop_add(4, 8, {'length': 3, 'type': 'search'})",
767 \ "call prop_add(5, 7, {'length': 3, 'type': 'search'})",
768 \ "call prop_add(6, 6, {'length': 3, 'type': 'search'})",
769 \ "call prop_add(7, 5, {'length': 3, 'type': 'search'})",
770 \ "call prop_add(8, 4, {'length': 3, 'type': 'search'})",
771 \ "call prop_add(9, 3, {'length': 3, 'type': 'search'})",
772 \ "call prop_add(10, 2, {'length': 3, 'type': 'search'})",
773 \ "normal 1G6|\<C-V>" .. repeat('l', a:width - 1) .. "10jx",
774 \], 'XtestPropVis')
775 let buf = RunVimInTerminal('-S XtestPropVis', {'rows': 12})
776 call VerifyScreenDump(buf, 'Test_textprop_vis_' .. a:dump, {})
777
778 " clean up
779 call StopVimInTerminal(buf)
780 call delete('XtestPropVis')
781endfunc
782
783" screenshot test with Visual block mode operations
784func Test_textprop_screenshot_visual()
Bram Moolenaar34390282019-10-16 14:38:26 +0200785 CheckScreendump
Bram Moolenaar8055d172019-05-17 22:57:26 +0200786
787 " Delete two columns while text props are three chars wide.
788 call RunTestVisualBlock(2, '01')
789
790 " Same, but delete four columns
791 call RunTestVisualBlock(4, '02')
792endfunc
Bram Moolenaard79eef22019-05-24 20:41:55 +0200793
Bram Moolenaara956bf62019-06-19 17:34:24 +0200794func Test_textprop_after_tab()
Bram Moolenaar34390282019-10-16 14:38:26 +0200795 CheckScreendump
Bram Moolenaar37e66cf2019-06-19 18:16:10 +0200796
Bram Moolenaara956bf62019-06-19 17:34:24 +0200797 let lines =<< trim END
798 call setline(1, [
799 \ "\txxx",
800 \ "x\txxx",
801 \ ])
802 hi SearchProp ctermbg=yellow
803 call prop_type_add('search', {'highlight': 'SearchProp'})
804 call prop_add(1, 2, {'length': 3, 'type': 'search'})
805 call prop_add(2, 3, {'length': 3, 'type': 'search'})
806 END
807 call writefile(lines, 'XtestPropTab')
808 let buf = RunVimInTerminal('-S XtestPropTab', {'rows': 6})
809 call VerifyScreenDump(buf, 'Test_textprop_tab', {})
810
811 " clean up
812 call StopVimInTerminal(buf)
813 call delete('XtestPropTab')
814endfunc
815
Bram Moolenaar34390282019-10-16 14:38:26 +0200816func Test_textprop_with_syntax()
817 CheckScreendump
818
819 let lines =<< trim END
820 call setline(1, [
821 \ "(abc)",
822 \ ])
823 syn match csParens "[()]" display
824 hi! link csParens MatchParen
825
826 call prop_type_add('TPTitle', #{ highlight: 'Title' })
827 call prop_add(1, 2, #{type: 'TPTitle', end_col: 5})
828 END
829 call writefile(lines, 'XtestPropSyn')
830 let buf = RunVimInTerminal('-S XtestPropSyn', {'rows': 6})
831 call VerifyScreenDump(buf, 'Test_textprop_syn_1', {})
832
833 " clean up
834 call StopVimInTerminal(buf)
835 call delete('XtestPropSyn')
836endfunc
837
Bram Moolenaard79eef22019-05-24 20:41:55 +0200838" Adding a text property to a new buffer should not fail
839func Test_textprop_empty_buffer()
840 call prop_type_add('comment', {'highlight': 'Search'})
841 new
842 call prop_add(1, 1, {'type': 'comment'})
843 close
Bram Moolenaaradfde112019-05-25 22:11:45 +0200844 call prop_type_delete('comment')
845endfunc
846
Bram Moolenaard74af422019-06-28 21:38:00 +0200847" Adding a text property with invalid highlight should be ignored.
848func Test_textprop_invalid_highlight()
849 call assert_fails("call prop_type_add('dni', {'highlight': 'DoesNotExist'})", 'E970:')
850 new
851 call setline(1, ['asdf','asdf'])
852 call prop_add(1, 1, {'length': 4, 'type': 'dni'})
853 redraw
854 bwipe!
855 call prop_type_delete('dni')
856endfunc
857
Bram Moolenaaradfde112019-05-25 22:11:45 +0200858" Adding a text property to an empty buffer and then editing another
859func Test_textprop_empty_buffer_next()
860 call prop_type_add("xxx", {})
861 call prop_add(1, 1, {"type": "xxx"})
862 next X
863 call prop_type_delete('xxx')
Bram Moolenaard79eef22019-05-24 20:41:55 +0200864endfunc
Bram Moolenaarf0884c52019-05-24 21:22:29 +0200865
866func Test_textprop_remove_from_buf()
867 new
868 let buf = bufnr('')
869 call prop_type_add('one', {'bufnr': buf})
870 call prop_add(1, 1, {'type': 'one', 'id': 234})
871 file x
872 edit y
873 call prop_remove({'id': 234, 'bufnr': buf}, 1)
874 call prop_type_delete('one', {'bufnr': buf})
875 bwipe! x
876 close
877endfunc
Bram Moolenaar45311b52019-08-13 22:27:32 +0200878
879func Test_textprop_in_unloaded_buf()
880 edit Xaaa
881 call setline(1, 'aaa')
882 write
883 edit Xbbb
884 call setline(1, 'bbb')
885 write
886 let bnr = bufnr('')
887 edit Xaaa
888
889 call prop_type_add('ErrorMsg', #{highlight:'ErrorMsg'})
890 call assert_fails("call prop_add(1, 1, #{end_lnum: 1, endcol: 2, type: 'ErrorMsg', bufnr: bnr})", 'E275:')
891 exe 'buf ' .. bnr
892 call assert_equal('bbb', getline(1))
893 call assert_equal(0, prop_list(1)->len())
894
895 bwipe! Xaaa
896 bwipe! Xbbb
897 cal delete('Xaaa')
898 cal delete('Xbbb')
899endfunc
Bram Moolenaar1fd30d72019-10-25 22:13:29 +0200900
901func Test_proptype_substitute2()
902 new
903 " text_prop.vim
904 call setline(1, [
905 \ 'The num 123 is smaller than 4567.',
906 \ '123 The number 123 is smaller than 4567.',
907 \ '123 The number 123 is smaller than 4567.'])
908
909 call prop_type_add('number', {'highlight': 'ErrorMsg'})
910
911 call prop_add(1, 12, {'length': 3, 'type': 'number'})
912 call prop_add(2, 1, {'length': 3, 'type': 'number'})
913 call prop_add(3, 36, {'length': 4, 'type': 'number'})
914 set ul&
915 let expected = [{'id': 0, 'col': 13, 'end': 1, 'type': 'number', 'length': 3, 'start': 1},
916 \ {'id': 0, 'col': 1, 'end': 1, 'type': 'number', 'length': 3, 'start': 1},
917 \ {'id': 0, 'col': 50, 'end': 1, 'type': 'number', 'length': 4, 'start': 1}]
918 " Add some text in between
919 %s/\s\+/ /g
920 call assert_equal(expected, prop_list(1) + prop_list(2) + prop_list(3))
921
922 " remove some text
923 :1s/[a-z]\{3\}//g
924 let expected = [{'id': 0, 'col': 10, 'end': 1, 'type': 'number', 'length': 3, 'start': 1}]
925 call assert_equal(expected, prop_list(1))
926 bwipe!
927endfunc
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100928
Bram Moolenaarac15fd82020-01-09 21:35:48 +0100929func SaveOptions()
930 let d = #{tabstop: &tabstop,
931 \ softtabstop: &softtabstop,
932 \ shiftwidth: &shiftwidth,
933 \ expandtab: &expandtab,
934 \ foldmethod: '"' .. &foldmethod .. '"',
935 \ }
936 return d
937endfunc
938
939func RestoreOptions(dict)
940 for name in keys(a:dict)
941 exe 'let &' .. name .. ' = ' .. a:dict[name]
942 endfor
943endfunc
944
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100945func Test_textprop_noexpandtab()
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100946 new
Bram Moolenaarac15fd82020-01-09 21:35:48 +0100947 let save_dict = SaveOptions()
948
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100949 set tabstop=8
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100950 set softtabstop=4
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100951 set shiftwidth=4
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100952 set noexpandtab
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100953 set foldmethod=marker
Bram Moolenaarac15fd82020-01-09 21:35:48 +0100954
Bram Moolenaar5cb0b932020-01-03 21:25:59 +0100955 call feedkeys("\<esc>\<esc>0Ca\<cr>\<esc>\<up>", "tx")
956 call prop_type_add('test', {'highlight': 'ErrorMsg'})
957 call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
958 call feedkeys("0i\<tab>", "tx")
959 call prop_remove({'type': 'test'})
960 call prop_add(1, 2, {'end_col': 3, 'type': 'test'})
961 call feedkeys("A\<left>\<tab>", "tx")
962 call prop_remove({'type': 'test'})
963 try
964 " It is correct that this does not pass
965 call prop_add(1, 6, {'end_col': 7, 'type': 'test'})
966 " Has already collapsed here, start_col:6 does not result in an error
967 call feedkeys("A\<left>\<tab>", "tx")
968 catch /^Vim\%((\a\+)\)\=:E964/
969 endtry
970 call prop_remove({'type': 'test'})
Bram Moolenaarac15fd82020-01-09 21:35:48 +0100971 call prop_type_delete('test')
972
973 call RestoreOptions(save_dict)
974 bwipe!
975endfunc
976
977func Test_textprop_noexpandtab_redraw()
978 new
979 let save_dict = SaveOptions()
980
981 set tabstop=8
982 set softtabstop=4
983 set shiftwidth=4
984 set noexpandtab
985 set foldmethod=marker
986
987 call feedkeys("\<esc>\<esc>0Ca\<cr>\<space>\<esc>\<up>", "tx")
988 call prop_type_add('test', {'highlight': 'ErrorMsg'})
989 call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
990 call feedkeys("0i\<tab>", "tx")
991 " Internally broken at the next line
992 call feedkeys("A\<left>\<tab>", "tx")
993 redraw
994 " Index calculation failed internally on next line
995 call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
996 call prop_remove({'type': 'test', 'all': v:true})
997 call prop_type_delete('test')
998 call prop_type_delete('test')
999
1000 call RestoreOptions(save_dict)
1001 bwipe!
1002endfunc
1003
1004func Test_textprop_ins_str()
1005 new
1006 call setline(1, 'just some text')
1007 call prop_type_add('test', {'highlight': 'ErrorMsg'})
1008 call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
1009 call assert_equal([{'id': 0, 'col': 1, 'end': 1, 'type': 'test', 'length': 1, 'start': 1}], prop_list(1))
1010
1011 call feedkeys("foi\<F8>\<Esc>", "tx")
1012 call assert_equal('just s<F8>ome text', getline(1))
1013 call assert_equal([{'id': 0, 'col': 1, 'end': 1, 'type': 'test', 'length': 1, 'start': 1}], prop_list(1))
1014
1015 bwipe!
1016 call prop_remove({'type': 'test'})
1017 call prop_type_delete('test')
Bram Moolenaar5cb0b932020-01-03 21:25:59 +01001018endfunc