1" Test for linebreak and list option in utf-8 mode
2
3set encoding=utf-8
4scriptencoding utf-8
5
6if !exists("+linebreak") || !has("conceal") || !has("signs")
7  finish
8endif
9
10source view_util.vim
11
12function s:screen_lines(lnum, width) abort
13  return ScreenLines(a:lnum, a:width)
14endfunction
15
16function! s:compare_lines(expect, actual)
17  call assert_equal(a:expect, a:actual)
18endfunction
19
20function s:screen_attr(lnum, chars, ...) abort
21  let line = getline(a:lnum)
22  let attr = []
23  let prefix = get(a:000, 0, 0)
24  for i in range(a:chars[0], a:chars[1])
25    let scol = strdisplaywidth(strcharpart(line, 0, i-1)) + 1
26    let attr += [screenattr(a:lnum, scol + prefix)]
27  endfor
28  return attr
29endfunction
30
31function s:test_windows(...)
32  call NewWindow(10, 20)
33  setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap
34  exe get(a:000, 0, '')
35endfunction
36
37function s:close_windows(...)
38  call CloseWindow()
39  exe get(a:000, 0, '')
40endfunction
41
42func Test_linebreak_with_fancy_listchars()
43  call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
44  call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
45  redraw!
46  let lines = s:screen_lines([1, 4], winwidth(0))
47  let expect = [
48\ "▕———abcdef          ",
49\ "+hijklmn▕———        ",
50\ "+pqrstuvwxyz␣1060ABC",
51\ "+DEFGHIJKLMNOPˑ¶    ",
52\ ]
53  call s:compare_lines(expect, lines)
54  call s:close_windows()
55endfunc
56
57func Test_nolinebreak_with_list()
58  call s:test_windows("setl nolinebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
59  call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
60  redraw!
61  let lines = s:screen_lines([1, 4], winwidth(0))
62  let expect = [
63\ "▕———abcdef hijklmn▕—",
64\ "+pqrstuvwxyz␣1060ABC",
65\ "+DEFGHIJKLMNOPˑ¶    ",
66\ "~                   ",
67\ ]
68  call s:compare_lines(expect, lines)
69  call s:close_windows()
70endfunc
71
72func Test_linebreak_with_nolist()
73  call s:test_windows('setl nolist')
74  call setline(1, "\t*mask = nil;")
75  redraw!
76  let lines = s:screen_lines([1, 4], winwidth(0))
77  let expect = [
78\ "    *mask = nil;    ",
79\ "~                   ",
80\ "~                   ",
81\ "~                   ",
82\ ]
83  call s:compare_lines(expect, lines)
84  call s:close_windows()
85endfunc
86
87func Test_list_and_concealing1()
88  call s:test_windows('setl list listchars=tab:>- cole=1')
89  call setline(1, [
90\ "#define ABCDE\t\t1",
91\ "#define ABCDEF\t\t1",
92\ "#define ABCDEFG\t\t1",
93\ "#define ABCDEFGH\t1",
94\ "#define MSG_MODE_FILE\t\t\t1",
95\ "#define MSG_MODE_CONSOLE\t\t2",
96\ "#define MSG_MODE_FILE_AND_CONSOLE\t3",
97\ "#define MSG_MODE_FILE_THEN_CONSOLE\t4",
98\ ])
99  vert resize 40
100  syn match Conceal conceal cchar=>'AB\|MSG_MODE'
101  redraw!
102  let lines = s:screen_lines([1, 7], winwidth(0))
103  let expect = [
104\ "#define ABCDE>-->---1                   ",
105\ "#define >CDEF>-->---1                   ",
106\ "#define >CDEFG>->---1                   ",
107\ "#define >CDEFGH>----1                   ",
108\ "#define >_FILE>--------->--->---1       ",
109\ "#define >_CONSOLE>---------->---2       ",
110\ "#define >_FILE_AND_CONSOLE>---------3   ",
111\ ]
112  call s:compare_lines(expect, lines)
113  call s:close_windows()
114endfunc
115
116func Test_list_and_concealing2()
117  call s:test_windows('setl nowrap ts=2 list listchars=tab:>- cole=2 concealcursor=n')
118  call setline(1, "bbeeeeee\t\t;\tsome text")
119  vert resize 40
120  syn clear
121  syn match meaning    /;\s*\zs.*/
122  syn match hasword    /^\x\{8}/    contains=word
123  syn match word       /\<\x\{8}\>/ contains=beginword,endword contained
124  syn match beginword  /\<\x\x/     contained conceal
125  syn match endword    /\x\{6}\>/   contained
126  hi meaning   guibg=blue
127  hi beginword guibg=green
128  hi endword   guibg=red
129  redraw!
130  let lines = s:screen_lines([1, 1], winwidth(0))
131  let expect = [
132\ "eeeeee>--->-;>some text                 ",
133\ ]
134  call s:compare_lines(expect, lines)
135  call s:close_windows()
136endfunc
137
138func Test_screenattr_for_comment()
139  call s:test_windows("setl ft=c ts=7 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
140  call setline(1, " /*\t\t and some more */")
141  norm! gg0
142  syntax on
143  hi SpecialKey term=underline ctermfg=red guifg=red
144  redraw!
145  let line = getline(1)
146  let attr = s:screen_attr(1, [1, 6])
147  call assert_notequal(attr[0], attr[1])
148  call assert_notequal(attr[1], attr[3])
149  call assert_notequal(attr[3], attr[5])
150  call s:close_windows()
151endfunc
152
153func Test_visual_block_and_selection_exclusive()
154  call s:test_windows('setl selection=exclusive')
155  call setline(1, "long line: " . repeat("foobar ", 40) . "TARGETÃ' at end")
156  exe "norm! $3B\<C-v>eAx\<Esc>"
157  let lines = s:screen_lines([1, 10], winwidth(0))
158  let expect = [
159\ "+foobar foobar      ",
160\ "+foobar foobar      ",
161\ "+foobar foobar      ",
162\ "+foobar foobar      ",
163\ "+foobar foobar      ",
164\ "+foobar foobar      ",
165\ "+foobar foobar      ",
166\ "+foobar foobar      ",
167\ "+foobar foobar      ",
168\ "+foobar TARGETÃx'   ",
169\ ]
170  call s:compare_lines(expect, lines)
171  call s:close_windows()
172endfunc
173
174func Test_multibyte_sign_and_colorcolumn()
175  call s:test_windows("setl nolinebreak cc=3 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
176  call setline(1, ["", "a b c", "a b c"])
177  exe "sign define foo text=\uff0b"
178  exe "sign place 1 name=foo line=2 buffer=" . bufnr('%')
179  redraw!
180  norm! ggj0
181  let signwidth = strdisplaywidth("\uff0b")
182  let attr1 = s:screen_attr(2, [1, 3], signwidth)
183  let attr2 = s:screen_attr(3, [1, 3], signwidth)
184  call assert_equal(attr1[0], attr2[0])
185  call assert_equal(attr1[1], attr2[1])
186  call assert_equal(attr1[2], attr2[2])
187  let lines = s:screen_lines([1, 3], winwidth(0))
188  let expect = [
189\ "  ¶                 ",
190\ "+a b c¶            ",
191\ "  a b c¶            ",
192\ ]
193  call s:compare_lines(expect, lines)
194  call s:close_windows()
195endfunc
196
197func Test_colorcolumn_priority()
198  call s:test_windows('setl cc=4 cuc hls')
199  call setline(1, ["xxyy", ""])
200  norm! gg
201  exe "normal! /xxyy\<CR>"
202  norm! G
203  redraw!
204  let line_attr = s:screen_attr(1, [1, &cc])
205  " Search wins over CursorColumn
206  call assert_equal(line_attr[1], line_attr[0])
207  " Search wins over Colorcolumn
208  call assert_equal(line_attr[2], line_attr[3])
209  call s:close_windows('setl hls&vim')
210endfunc
211
212func Test_illegal_byte_and_breakat()
213  call s:test_windows("setl sbr= brk+=<")
214  vert resize 18
215  call setline(1, repeat("\x80", 6))
216  redraw!
217  let lines = s:screen_lines([1, 2], winwidth(0))
218  let expect = [
219\ "<80><80><80><80><8",
220\ "0><80>            ",
221\ ]
222  call s:compare_lines(expect, lines)
223  call s:close_windows('setl brk&vim')
224endfunc
225
226func Test_multibyte_wrap_and_breakat()
227  call s:test_windows("setl sbr= brk+=>")
228  call setline(1, repeat('a', 17) . repeat('あ', 2))
229  redraw!
230  let lines = s:screen_lines([1, 2], winwidth(0))
231  let expect = [
232\ "aaaaaaaaaaaaaaaaaあ>",
233\ "あ                  ",
234\ ]
235  call s:compare_lines(expect, lines)
236  call s:close_windows('setl brk&vim')
237endfunc
238
239func Test_chinese_char_on_wrap_column()
240  call s:test_windows("setl nolbr wrap sbr=")
241  syntax off
242  call setline(1, [
243\ 'aaaaaaaaaaaaaaaaaaa中'.
244\ 'aaaaaaaaaaaaaaaaa中'.
245\ 'aaaaaaaaaaaaaaaaa中'.
246\ 'aaaaaaaaaaaaaaaaa中'.
247\ 'aaaaaaaaaaaaaaaaa中'.
248\ 'aaaaaaaaaaaaaaaaa中'.
249\ 'aaaaaaaaaaaaaaaaa中'.
250\ 'aaaaaaaaaaaaaaaaa中'.
251\ 'aaaaaaaaaaaaaaaaa中'.
252\ 'aaaaaaaaaaaaaaaaa中'.
253\ 'hello'])
254  call cursor(1,1)
255  norm! $
256  redraw!
257  let expect=[
258\ '中aaaaaaaaaaaaaaaaa>',
259\ '中aaaaaaaaaaaaaaaaa>',
260\ '中aaaaaaaaaaaaaaaaa>',
261\ '中aaaaaaaaaaaaaaaaa>',
262\ '中aaaaaaaaaaaaaaaaa>',
263\ '中aaaaaaaaaaaaaaaaa>',
264\ '中aaaaaaaaaaaaaaaaa>',
265\ '中aaaaaaaaaaaaaaaaa>',
266\ '中aaaaaaaaaaaaaaaaa>',
267\ '中hello             ']
268  let lines = s:screen_lines([1, 10], winwidth(0))
269  call s:compare_lines(expect, lines)
270  call s:close_windows()
271endfu
272