blob: 28b95ab69ac7d686429f82c593fd1d3f20fe286a [file] [log] [blame]
Bram Moolenaar04958cb2018-06-23 19:23:02 +02001" Test for variable tabstops
2
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003CheckFeature vartabs
Bram Moolenaar04958cb2018-06-23 19:23:02 +02004
Bram Moolenaar64f41072018-10-15 22:51:50 +02005func s:compare_lines(expect, actual)
Bram Moolenaara87b72c2018-06-25 21:24:51 +02006 call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
Bram Moolenaar64f41072018-10-15 22:51:50 +02007endfunc
Bram Moolenaara87b72c2018-06-25 21:24:51 +02008
Bram Moolenaar64f41072018-10-15 22:51:50 +02009func Test_vartabs()
Bram Moolenaar04958cb2018-06-23 19:23:02 +020010 new
11 %d
12
13 " Test normal operation of tabstops ...
14 set ts=4
15 call setline(1, join(split('aaaaa', '\zs'), "\t"))
16 retab 8
17 let expect = "a a\<tab>a a\<tab>a"
18 call assert_equal(expect, getline(1))
19
20 " ... and softtabstops
21 set ts=8 sts=6
22 exe "norm! Sb\<tab>b\<tab>b\<tab>b\<tab>b"
23 let expect = "b b\<tab> b\<tab> b\<tab>b"
24 call assert_equal(expect, getline(1))
25
26 " Test variable tabstops.
27 set sts=0 vts=4,8,4,8
28 exe "norm! Sc\<tab>c\<tab>c\<tab>c\<tab>c\<tab>c"
29 retab 8
30 let expect = "c c\<tab> c\<tab>c\<tab>c\<tab>c"
31 call assert_equal(expect, getline(1))
32
33 set et vts=4,8,4,8
34 exe "norm! Sd\<tab>d\<tab>d\<tab>d\<tab>d\<tab>d"
35 let expect = "d d d d d d"
36 call assert_equal(expect, getline(1))
37
38 " Changing ts should have no effect if vts is in use.
39 call cursor(1, 1)
40 set ts=6
41 exe "norm! Se\<tab>e\<tab>e\<tab>e\<tab>e\<tab>e"
42 let expect = "e e e e e e"
43 call assert_equal(expect, getline(1))
44
45 " Clearing vts should revert to using ts.
46 set vts=
47 exe "norm! Sf\<tab>f\<tab>f\<tab>f\<tab>f\<tab>f"
48 let expect = "f f f f f f"
49 call assert_equal(expect, getline(1))
50
51 " Test variable softtabstops.
52 set noet ts=8 vsts=12,2,6
53 exe "norm! Sg\<tab>g\<tab>g\<tab>g\<tab>g\<tab>g"
54 let expect = "g\<tab> g g\<tab> g\<tab> g\<tab>g"
55 call assert_equal(expect, getline(1))
56
57 " Variable tabstops and softtabstops combined.
58 set vsts=6,12,8 vts=4,6,8
59 exe "norm! Sh\<tab>h\<tab>h\<tab>h\<tab>h"
60 let expect = "h\<tab> h\<tab>\<tab>h\<tab>h\<tab>h"
61 call assert_equal(expect, getline(1))
62
63 " Retab with a single value, not using vts.
64 set ts=8 sts=0 vts= vsts=
65 exe "norm! Si\<tab>i\<tab>i\<tab>i\<tab>i"
66 retab 4
67 let expect = "i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i"
68 call assert_equal(expect, getline(1))
69
70 " Retab with a single value, using vts.
71 set ts=8 sts=0 vts=6 vsts=
72 exe "norm! Sj\<tab>j\<tab>j\<tab>j\<tab>j"
73 retab 4
74 let expect = "j\<tab> j\<tab>\<tab>j\<tab> j\<tab>\<tab>j"
75 call assert_equal(expect, getline(1))
76
77 " Retab with multiple values, not using vts.
78 set ts=6 sts=0 vts= vsts=
79 exe "norm! Sk\<tab>k\<tab>k\<tab>k\<tab>k\<tab>k"
80 retab 4,8
81 let expect = "k\<tab> k\<tab>k k\<tab> k\<tab> k"
82 call assert_equal(expect, getline(1))
83
84 " Retab with multiple values, using vts.
85 set ts=8 sts=0 vts=6 vsts=
86 exe "norm! Sl\<tab>l\<tab>l\<tab>l\<tab>l\<tab>l"
87 retab 4,8
88 let expect = "l\<tab> l\<tab>l l\<tab> l\<tab> l"
89 call assert_equal(expect, getline(1))
90
Bram Moolenaarbd7206e2020-03-06 20:36:04 +010091 " Test for 'retab' with vts
92 set ts=8 sts=0 vts=5,3,6,2 vsts=
93 exe "norm! S l"
94 .retab!
95 call assert_equal("\t\t\t\tl", getline(1))
96
Bram Moolenaar8e7d6222020-12-18 19:49:56 +010097 " Test for 'retab' with same values as vts
Bram Moolenaarbd7206e2020-03-06 20:36:04 +010098 set ts=8 sts=0 vts=5,3,6,2 vsts=
99 exe "norm! S l"
100 .retab! 5,3,6,2
101 call assert_equal("\t\t\t\tl", getline(1))
102
Bram Moolenaar04958cb2018-06-23 19:23:02 +0200103 " Check that global and local values are set.
104 set ts=4 vts=6 sts=8 vsts=10
105 call assert_equal(&ts, 4)
106 call assert_equal(&vts, '6')
107 call assert_equal(&sts, 8)
108 call assert_equal(&vsts, '10')
109 new
110 call assert_equal(&ts, 4)
111 call assert_equal(&vts, '6')
112 call assert_equal(&sts, 8)
113 call assert_equal(&vsts, '10')
114 bwipeout!
115
116 " Check that local values only are set.
117 setlocal ts=5 vts=7 sts=9 vsts=11
118 call assert_equal(&ts, 5)
119 call assert_equal(&vts, '7')
120 call assert_equal(&sts, 9)
121 call assert_equal(&vsts, '11')
122 new
123 call assert_equal(&ts, 4)
124 call assert_equal(&vts, '6')
125 call assert_equal(&sts, 8)
126 call assert_equal(&vsts, '10')
127 bwipeout!
128
129 " Check that global values only are set.
130 setglobal ts=6 vts=8 sts=10 vsts=12
131 call assert_equal(&ts, 5)
132 call assert_equal(&vts, '7')
133 call assert_equal(&sts, 9)
134 call assert_equal(&vsts, '11')
135 new
136 call assert_equal(&ts, 6)
137 call assert_equal(&vts, '8')
138 call assert_equal(&sts, 10)
139 call assert_equal(&vsts, '12')
140 bwipeout!
141
142 set ts& vts& sts& vsts& et&
143 bwipeout!
144endfunc
145
Bram Moolenaarfc88df42022-02-05 11:13:05 +0000146func Test_retab_invalid_arg()
147 new
148 call setline(1, "\ttext")
149 retab 0
150 call assert_fails("retab -8", 'E487: Argument must be positive')
151 call assert_fails("retab 10000", 'E475:')
152 call assert_fails("retab 720575940379279360", 'E475:')
153 bwipe!
154endfunc
155
Bram Moolenaar1e115362019-01-09 23:01:02 +0100156func Test_vartabs_breakindent()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200157 CheckOption breakindent
Bram Moolenaar04958cb2018-06-23 19:23:02 +0200158 new
159 %d
160
161 " Test normal operation of tabstops ...
162 set ts=4
163 call setline(1, join(split('aaaaa', '\zs'), "\t"))
164 retab 8
165 let expect = "a a\<tab>a a\<tab>a"
166 call assert_equal(expect, getline(1))
167
168 " ... and softtabstops
169 set ts=8 sts=6
170 exe "norm! Sb\<tab>b\<tab>b\<tab>b\<tab>b"
171 let expect = "b b\<tab> b\<tab> b\<tab>b"
172 call assert_equal(expect, getline(1))
173
174 " Test variable tabstops.
175 set sts=0 vts=4,8,4,8
176 exe "norm! Sc\<tab>c\<tab>c\<tab>c\<tab>c\<tab>c"
177 retab 8
178 let expect = "c c\<tab> c\<tab>c\<tab>c\<tab>c"
179 call assert_equal(expect, getline(1))
180
181 set et vts=4,8,4,8
182 exe "norm! Sd\<tab>d\<tab>d\<tab>d\<tab>d\<tab>d"
183 let expect = "d d d d d d"
184 call assert_equal(expect, getline(1))
185
186 " Changing ts should have no effect if vts is in use.
187 call cursor(1, 1)
188 set ts=6
189 exe "norm! Se\<tab>e\<tab>e\<tab>e\<tab>e\<tab>e"
190 let expect = "e e e e e e"
191 call assert_equal(expect, getline(1))
192
193 " Clearing vts should revert to using ts.
194 set vts=
195 exe "norm! Sf\<tab>f\<tab>f\<tab>f\<tab>f\<tab>f"
196 let expect = "f f f f f f"
197 call assert_equal(expect, getline(1))
198
199 " Test variable softtabstops.
200 set noet ts=8 vsts=12,2,6
201 exe "norm! Sg\<tab>g\<tab>g\<tab>g\<tab>g\<tab>g"
202 let expect = "g\<tab> g g\<tab> g\<tab> g\<tab>g"
203 call assert_equal(expect, getline(1))
204
205 " Variable tabstops and softtabstops combined.
206 set vsts=6,12,8 vts=4,6,8
207 exe "norm! Sh\<tab>h\<tab>h\<tab>h\<tab>h"
208 let expect = "h\<tab> h\<tab>\<tab>h\<tab>h\<tab>h"
209 call assert_equal(expect, getline(1))
210
211 " Retab with a single value, not using vts.
212 set ts=8 sts=0 vts= vsts=
213 exe "norm! Si\<tab>i\<tab>i\<tab>i\<tab>i"
214 retab 4
215 let expect = "i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i\<tab>\<tab>i"
216 call assert_equal(expect, getline(1))
217
218 " Retab with a single value, using vts.
219 set ts=8 sts=0 vts=6 vsts=
220 exe "norm! Sj\<tab>j\<tab>j\<tab>j\<tab>j"
221 retab 4
222 let expect = "j\<tab> j\<tab>\<tab>j\<tab> j\<tab>\<tab>j"
223 call assert_equal(expect, getline(1))
224
225 " Retab with multiple values, not using vts.
226 set ts=6 sts=0 vts= vsts=
227 exe "norm! Sk\<tab>k\<tab>k\<tab>k\<tab>k\<tab>k"
228 retab 4,8
229 let expect = "k\<tab> k\<tab>k k\<tab> k\<tab> k"
230 call assert_equal(expect, getline(1))
231
232 " Retab with multiple values, using vts.
233 set ts=8 sts=0 vts=6 vsts=
234 exe "norm! Sl\<tab>l\<tab>l\<tab>l\<tab>l\<tab>l"
235 retab 4,8
236 let expect = "l\<tab> l\<tab>l l\<tab> l\<tab> l"
237 call assert_equal(expect, getline(1))
238
239 " Check that global and local values are set.
240 set ts=4 vts=6 sts=8 vsts=10
241 call assert_equal(&ts, 4)
242 call assert_equal(&vts, '6')
243 call assert_equal(&sts, 8)
244 call assert_equal(&vsts, '10')
245 new
246 call assert_equal(&ts, 4)
247 call assert_equal(&vts, '6')
248 call assert_equal(&sts, 8)
249 call assert_equal(&vsts, '10')
250 bwipeout!
251
252 " Check that local values only are set.
253 setlocal ts=5 vts=7 sts=9 vsts=11
254 call assert_equal(&ts, 5)
255 call assert_equal(&vts, '7')
256 call assert_equal(&sts, 9)
257 call assert_equal(&vsts, '11')
258 new
259 call assert_equal(&ts, 4)
260 call assert_equal(&vts, '6')
261 call assert_equal(&sts, 8)
262 call assert_equal(&vsts, '10')
263 bwipeout!
264
265 " Check that global values only are set.
266 setglobal ts=6 vts=8 sts=10 vsts=12
267 call assert_equal(&ts, 5)
268 call assert_equal(&vts, '7')
269 call assert_equal(&sts, 9)
270 call assert_equal(&vsts, '11')
271 new
272 call assert_equal(&ts, 6)
273 call assert_equal(&vts, '8')
274 call assert_equal(&sts, 10)
275 call assert_equal(&vsts, '12')
276 bwipeout!
277
278 bwipeout!
279endfunc
Bram Moolenaara87b72c2018-06-25 21:24:51 +0200280
Bram Moolenaar64f41072018-10-15 22:51:50 +0200281func Test_vartabs_linebreak()
Bram Moolenaar307ac5c2018-06-28 22:23:00 +0200282 if winwidth(0) < 40
Bram Moolenaara87b72c2018-06-25 21:24:51 +0200283 return
284 endif
285 new
Bram Moolenaar307ac5c2018-06-28 22:23:00 +0200286 40vnew
Bram Moolenaara87b72c2018-06-25 21:24:51 +0200287 %d
Bram Moolenaar307ac5c2018-06-28 22:23:00 +0200288 setl linebreak vartabstop=10,20,30,40
Bram Moolenaara87b72c2018-06-25 21:24:51 +0200289 call setline(1, "\tx\tx\tx\tx")
290
Bram Moolenaar307ac5c2018-06-28 22:23:00 +0200291 let expect = [' x ',
292 \ 'x x ',
293 \ 'x ']
294 let lines = ScreenLines([1, 3], winwidth(0))
295 call s:compare_lines(expect, lines)
296 setl list listchars=tab:>-
297 let expect = ['>---------x>------------------ ',
298 \ 'x>------------------x>------------------',
299 \ 'x ']
300 let lines = ScreenLines([1, 3], winwidth(0))
301 call s:compare_lines(expect, lines)
302 setl linebreak vartabstop=40
303 let expect = ['>---------------------------------------',
304 \ 'x>--------------------------------------',
305 \ 'x>--------------------------------------',
306 \ 'x>--------------------------------------',
307 \ 'x ']
308 let lines = ScreenLines([1, 5], winwidth(0))
Bram Moolenaara87b72c2018-06-25 21:24:51 +0200309 call s:compare_lines(expect, lines)
310
311 " cleanup
312 bw!
313 bw!
Bram Moolenaar307ac5c2018-06-28 22:23:00 +0200314 set nolist listchars&vim
Bram Moolenaara87b72c2018-06-25 21:24:51 +0200315endfunc
Bram Moolenaar64f41072018-10-15 22:51:50 +0200316
Bram Moolenaarf9514162018-11-22 03:08:29 +0100317func Test_vartabs_shiftwidth()
318 "return
319 if winwidth(0) < 40
320 return
321 endif
322 new
323 40vnew
324 %d
325" setl varsofttabstop=10,20,30,40
326 setl shiftwidth=0 vartabstop=10,20,30,40
327 call setline(1, "x")
328
329 " Check without any change.
330 let expect = ['x ']
331 let lines = ScreenLines(1, winwidth(0))
332 call s:compare_lines(expect, lines)
333 " Test 1:
334 " shiftwidth depends on the indent, first check with cursor at the end of the
335 " line (which is the same as the start of the line, since there is only one
336 " character).
337 norm! $>>
338 let expect1 = [' x ']
339 let lines = ScreenLines(1, winwidth(0))
340 call s:compare_lines(expect1, lines)
341 call assert_equal(10, shiftwidth())
342 call assert_equal(10, shiftwidth(1))
343 call assert_equal(20, shiftwidth(virtcol('.')))
344 norm! $>>
345 let expect2 = [' x ', '~ ']
346 let lines = ScreenLines([1, 2], winwidth(0))
347 call s:compare_lines(expect2, lines)
348 call assert_equal(20, shiftwidth(virtcol('.')-2))
Bram Moolenaaraad222c2019-09-06 22:46:09 +0200349 call assert_equal(30, virtcol('.')->shiftwidth())
Bram Moolenaarf9514162018-11-22 03:08:29 +0100350 norm! $>>
351 let expect3 = [' ', ' x ', '~ ']
352 let lines = ScreenLines([1, 3], winwidth(0))
353 call s:compare_lines(expect3, lines)
354 call assert_equal(30, shiftwidth(virtcol('.')-2))
355 call assert_equal(40, shiftwidth(virtcol('.')))
356 norm! $>>
357 let expect4 = [' ', ' ', ' x ']
358 let lines = ScreenLines([1, 3], winwidth(0))
359 call assert_equal(40, shiftwidth(virtcol('.')))
360 call s:compare_lines(expect4, lines)
361
362 " Test 2: Put the cursor at the first column, result should be the same
363 call setline(1, "x")
364 norm! 0>>
365 let lines = ScreenLines(1, winwidth(0))
366 call s:compare_lines(expect1, lines)
367 norm! 0>>
368 let lines = ScreenLines([1, 2], winwidth(0))
369 call s:compare_lines(expect2, lines)
370 norm! 0>>
371 let lines = ScreenLines([1, 3], winwidth(0))
372 call s:compare_lines(expect3, lines)
373 norm! 0>>
374 let lines = ScreenLines([1, 3], winwidth(0))
375 call s:compare_lines(expect4, lines)
376
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100377 call assert_fails('call shiftwidth([])', 'E745:')
378
Bram Moolenaarf9514162018-11-22 03:08:29 +0100379 " cleanup
380 bw!
381 bw!
382endfunc
383
Bram Moolenaar64f41072018-10-15 22:51:50 +0200384func Test_vartabs_failures()
385 call assert_fails('set vts=8,')
386 call assert_fails('set vsts=8,')
387 call assert_fails('set vts=8,,8')
388 call assert_fails('set vsts=8,,8')
389 call assert_fails('set vts=8,,8,')
390 call assert_fails('set vsts=8,,8,')
391 call assert_fails('set vts=,8')
392 call assert_fails('set vsts=,8')
393endfunc
Bram Moolenaar037c54f2019-04-20 23:47:46 +0200394
395func Test_vartabs_reset()
396 set vts=8
397 set all&
398 call assert_equal('', &vts)
399endfunc
Bram Moolenaarbd7206e2020-03-06 20:36:04 +0100400
401func s:SaveCol(l)
402 call add(a:l, [col('.'), virtcol('.')])
403 return ''
404endfunc
405
406" Test for 'varsofttabstop'
407func Test_varsofttabstop()
408 new
409 inoremap <expr> <F2> s:SaveCol(g:cols)
410
411 set backspace=indent,eol,start
412 set varsofttabstop=6,2,5,3
413 let g:cols = []
414 call feedkeys("a\t\<F2>\t\<F2>\t\<F2>\t\<F2> ", 'xt')
415 call assert_equal("\t\t ", getline(1))
416 call assert_equal([[7, 7], [2, 9], [7, 14], [3, 17]], g:cols)
417
418 let g:cols = []
419 call feedkeys("a\<bs>\<F2>\<bs>\<F2>\<bs>\<F2>\<bs>\<F2>\<bs>\<F2>", 'xt')
420 call assert_equal('', getline(1))
421 call assert_equal([[3, 17], [7, 14], [2, 9], [7, 7], [1, 1]], g:cols)
422
423 set varsofttabstop&
424 set backspace&
425 iunmap <F2>
426 close!
427endfunc
428
Yegappan Lakshmanan59585492021-06-12 13:46:41 +0200429" Setting 'shiftwidth' to a negative value, should set it to either the value
430" of 'tabstop' (if 'vartabstop' is not set) or to the first value in
431" 'vartabstop'
432func Test_shiftwidth_vartabstop()
433 setlocal tabstop=7 vartabstop=
434 call assert_fails('set shiftwidth=-1', 'E487:')
435 call assert_equal(7, &shiftwidth)
436 setlocal tabstop=7 vartabstop=5,7,10
437 call assert_fails('set shiftwidth=-1', 'E487:')
438 call assert_equal(5, &shiftwidth)
439 setlocal shiftwidth& vartabstop& tabstop&
440endfunc
441
Bram Moolenaar4e889f92022-02-21 19:36:12 +0000442func Test_vartabstop_latin1()
443 let save_encoding = &encoding
444 new
K.Takata0f113e42022-02-22 11:04:50 +0000445 set encoding=iso8859-1
Bram Moolenaar2dada732022-02-23 10:52:41 +0000446 set compatible linebreak list revins smarttab
Bram Moolenaar4e889f92022-02-21 19:36:12 +0000447 set vartabstop=400
K.Takata0f113e42022-02-22 11:04:50 +0000448 exe "norm i00\t\<C-D>"
Bram Moolenaar4e889f92022-02-21 19:36:12 +0000449 bwipe!
450 let &encoding = save_encoding
Bram Moolenaar2dada732022-02-23 10:52:41 +0000451 set nocompatible linebreak& list& revins& smarttab& vartabstop&
Bram Moolenaar4e889f92022-02-21 19:36:12 +0000452endfunc
453
Gary Johnson88d4f252024-06-01 20:51:33 +0200454" Verify that right-shifting and left-shifting adjust lines to the proper
455" tabstops.
456func Test_vartabstop_shift_right_left()
457 new
458 set expandtab
459 set shiftwidth=0
460 set vartabstop=17,11,7
461 exe "norm! aword"
462 let expect = "word"
463 call assert_equal(expect, getline(1))
464
465 " Shift to first tabstop.
466 norm! >>
467 let expect = " word"
468 call assert_equal(expect, getline(1))
469
470 " Shift to second tabstop.
471 norm! >>
472 let expect = " word"
473 call assert_equal(expect, getline(1))
474
475 " Shift to third tabstop.
476 norm! >>
477 let expect = " word"
478 call assert_equal(expect, getline(1))
479
480 " Shift to fourth tabstop, repeating the third shift width.
481 norm! >>
482 let expect = " word"
483 call assert_equal(expect, getline(1))
484
485 " Shift back to the third tabstop.
486 norm! <<
487 let expect = " word"
488 call assert_equal(expect, getline(1))
489
490 " Shift back to the second tabstop.
491 norm! <<
492 let expect = " word"
493 call assert_equal(expect, getline(1))
494
495 " Shift back to the first tabstop.
496 norm! <<
497 let expect = " word"
498 call assert_equal(expect, getline(1))
499
500 " Shift back to the left margin.
501 norm! <<
502 let expect = "word"
503 call assert_equal(expect, getline(1))
504
505 " Shift again back to the left margin.
506 norm! <<
507 let expect = "word"
508 call assert_equal(expect, getline(1))
509
510 bwipeout!
511endfunc
512
Bram Moolenaar4e889f92022-02-21 19:36:12 +0000513
Bram Moolenaarbd7206e2020-03-06 20:36:04 +0100514" vim: shiftwidth=2 sts=2 expandtab