1" Test for breakindent
2"
3" Note: if you get strange failures when adding new tests, it might be that
4" while the test is run, the breakindent cacheing gets in its way.
5" It helps to change the tabastop setting and force a redraw (e.g. see
6" Test_breakindent08())
7if !exists('+breakindent')
8  finish
9endif
10
11let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
12
13function s:screenline(lnum, width) abort
14  " always get 4 screen lines
15  redraw!
16  let line = []
17  for j in range(3)
18    for c in range(1, a:width)
19  call add(line, nr2char(screenchar(a:lnum+j, c)))
20    endfor
21    call add(line, "\n")
22  endfor
23  return join(line, '')
24endfunction
25
26function s:testwindows(...)
27  10new
28  vsp
29  vert resize 20
30  setl ts=4 sw=4 sts=4 breakindent
31  put =s:input
32  if a:0
33    exe a:1
34  endif
35endfunction
36
37function s:close_windows(...)
38  bw!
39  if a:0
40    exe a:1
41  endif
42  unlet! g:line g:expect
43endfunction
44
45function Test_breakindent01()
46  " simple breakindent test
47  call s:testwindows('setl briopt=min:0')
48  let g:line=s:screenline(line('.'),8)
49  let g:expect="    abcd\n    qrst\n    GHIJ\n"
50  call assert_equal(g:expect, g:line)
51  call s:close_windows()
52endfunction
53
54function Test_breakindent02()
55  " simple breakindent test with showbreak set
56  call s:testwindows('setl briopt=min:0 sbr=>>')
57  let g:line=s:screenline(line('.'),8)
58  let g:expect="    abcd\n    >>qr\n    >>EF\n"
59  call assert_equal(g:expect, g:line)
60  call s:close_windows('set sbr=')
61endfunction
62
63function Test_breakindent03()
64  " simple breakindent test with showbreak set and briopt including sbr
65  call s:testwindows('setl briopt=sbr,min:0 sbr=++')
66  let g:line=s:screenline(line('.'),8)
67  let g:expect="    abcd\n++  qrst\n++  GHIJ\n"
68  call assert_equal(g:expect, g:line)
69  " clean up
70  call s:close_windows('set sbr=')
71endfunction
72
73function Test_breakindent04()
74  " breakindent set with min width 18
75  call s:testwindows('setl sbr= briopt=min:18')
76  let g:line=s:screenline(line('.'),8)
77  let g:expect="    abcd\n  qrstuv\n  IJKLMN\n"
78  call assert_equal(g:expect, g:line)
79  " clean up
80  call s:close_windows('set sbr=')
81endfunction
82
83function Test_breakindent05()
84  " breakindent set and shift by 2
85  call s:testwindows('setl briopt=shift:2,min:0')
86  let g:line=s:screenline(line('.'),8)
87  let g:expect="    abcd\n      qr\n      EF\n"
88  call assert_equal(g:expect, g:line)
89  call s:close_windows()
90endfunction
91
92function Test_breakindent06()
93  " breakindent set and shift by -1
94  call s:testwindows('setl briopt=shift:-1,min:0')
95  let g:line=s:screenline(line('.'),8)
96  let g:expect="    abcd\n   qrstu\n   HIJKL\n"
97  call assert_equal(g:expect, g:line)
98  call s:close_windows()
99endfunction
100
101function Test_breakindent07()
102  " breakindent set and shift by 1, Number  set sbr=? and briopt:sbr
103  call s:testwindows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n')
104  let g:line=s:screenline(line('.'),10)
105  let g:expect="  2     ab\n?        m\n?        x\n"
106  call assert_equal(g:expect, g:line)
107  " clean up
108  call s:close_windows('set sbr= cpo-=n')
109endfunction
110
111function Test_breakindent07a()
112  " breakindent set and shift by 1, Number  set sbr=? and briopt:sbr
113  call s:testwindows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4')
114  let g:line=s:screenline(line('.'),10)
115  let g:expect="  2     ab\n    ?    m\n    ?    x\n"
116  call assert_equal(g:expect, g:line)
117  " clean up
118  call s:close_windows('set sbr=')
119endfunction
120
121function Test_breakindent08()
122  " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
123  call s:testwindows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4')
124  " make sure, cache is invalidated!
125  set ts=8
126  redraw!
127  set ts=4
128  redraw!
129  let g:line=s:screenline(line('.'),10)
130  let g:expect="  2 ^Iabcd\n#      opq\n#      BCD\n"
131  call assert_equal(g:expect, g:line)
132  call s:close_windows('set sbr= cpo-=n')
133endfunction
134
135function Test_breakindent08a()
136  " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
137  call s:testwindows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list')
138  let g:line=s:screenline(line('.'),10)
139  let g:expect="  2 ^Iabcd\n    #  opq\n    #  BCD\n"
140  call assert_equal(g:expect, g:line)
141  call s:close_windows('set sbr=')
142endfunction
143
144function Test_breakindent09()
145  " breakindent set and shift by 1, Number and list set sbr=#
146  call s:testwindows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list')
147  let g:line=s:screenline(line('.'),10)
148  let g:expect="  2 ^Iabcd\n       #op\n       #AB\n"
149  call assert_equal(g:expect, g:line)
150  call s:close_windows('set sbr=')
151endfunction
152
153function Test_breakindent10()
154  " breakindent set, Number set sbr=~
155  call s:testwindows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0')
156  " make sure, cache is invalidated!
157  set ts=8
158  redraw!
159  set ts=4
160  redraw!
161  let g:line=s:screenline(line('.'),10)
162  let g:expect="  2     ab\n~       mn\n~       yz\n"
163  call assert_equal(g:expect, g:line)
164  call s:close_windows('set sbr= cpo-=n')
165endfunction
166
167function Test_breakindent11()
168  " test strdisplaywidth()
169  call s:testwindows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4')
170  let text=getline(2)
171  let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
172  call assert_equal(width, strdisplaywidth(text))
173  call s:close_windows('set sbr=')
174endfunction
175
176function Test_breakindent12()
177  " test breakindent with long indent
178  let s:input="\t\t\t\t\t{"
179  call s:testwindows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-')
180  let g:line=s:screenline(2,16)
181  let g:expect=" 2 >--->--->--->\n          ---{  \n~               \n"
182  call assert_equal(g:expect, g:line)
183  call s:close_windows('set nuw=4 listchars=')
184endfunction
185
186function Test_breakindent13()
187  let s:input=""
188  call s:testwindows('setl breakindent briopt=min:10 ts=8')
189  vert resize 20
190  call setline(1, ["    a\tb\tc\td\te", "    z   y       x       w       v"])
191  1
192  norm! fbgj"ayl
193  2
194  norm! fygj"byl
195  call assert_equal('d', @a)
196  call assert_equal('w', @b)
197  call s:close_windows()
198endfunction
199
200function Test_breakindent14()
201  let s:input=""
202  call s:testwindows('setl breakindent briopt= ts=8')
203  vert resize 30
204  norm! 3a1234567890
205  norm! a    abcde
206  exec "norm! 0\<C-V>tex"
207  let g:line=s:screenline(line('.'),8)
208  let g:expect="e       \n~       \n~       \n"
209  call assert_equal(g:expect, g:line)
210  call s:close_windows()
211endfunction
212
213function Test_breakindent15()
214  let s:input=""
215  call s:testwindows('setl breakindent briopt= ts=8 sw=8')
216  vert resize 30
217  norm! 4a1234567890
218  exe "normal! >>\<C-V>3f0x"
219  let g:line=s:screenline(line('.'),20)
220  let g:expect="        1234567890  \n~                   \n~                   \n"
221  call assert_equal(g:expect, g:line)
222  call s:close_windows()
223endfunction
224
225function Test_breakindent16()
226  " Check that overlong lines are indented correctly.
227  " TODO: currently it does not fail even when the bug is not fixed.
228  let s:input=""
229  call s:testwindows('setl breakindent briopt=min:0 ts=4')
230  call setline(1, "\t".repeat("1234567890", 10))
231  resize 6
232  norm! 1gg$
233  redraw!
234  let g:line=s:screenline(1,10)
235  let g:expect="    123456\n    789012\n    345678\n"
236  call assert_equal(g:expect, g:line)
237  let g:line=s:screenline(4,10)
238  let g:expect="    901234\n    567890\n    123456\n"
239  call assert_equal(g:expect, g:line)
240  call s:close_windows()
241endfunction
242