blob: bd0578eff98e6b543931629c4e059fdd53c915e3 [file] [log] [blame]
Bram Moolenaar544d3bc2017-02-05 21:14:50 +01001" Test for linebreak and list option in utf-8 mode
2
3set encoding=utf-8
4scriptencoding utf-8
5
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02006source check.vim
7CheckOption linebreak
8CheckFeature conceal
9CheckFeature signs
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010010
11source view_util.vim
zeertzjqdf23d7f2024-02-09 18:14:12 +010012source screendump.vim
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010013
Bram Moolenaar1e115362019-01-09 23:01:02 +010014func s:screen_lines(lnum, width) abort
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010015 return ScreenLines(a:lnum, a:width)
Bram Moolenaar1e115362019-01-09 23:01:02 +010016endfunc
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010017
Bram Moolenaar1e115362019-01-09 23:01:02 +010018func s:compare_lines(expect, actual)
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010019 call assert_equal(a:expect, a:actual)
Bram Moolenaar1e115362019-01-09 23:01:02 +010020endfunc
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010021
Bram Moolenaar1e115362019-01-09 23:01:02 +010022func s:screen_attr(lnum, chars, ...) abort
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010023 let line = getline(a:lnum)
24 let attr = []
25 let prefix = get(a:000, 0, 0)
26 for i in range(a:chars[0], a:chars[1])
27 let scol = strdisplaywidth(strcharpart(line, 0, i-1)) + 1
28 let attr += [screenattr(a:lnum, scol + prefix)]
29 endfor
30 return attr
Bram Moolenaar1e115362019-01-09 23:01:02 +010031endfunc
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010032
Bram Moolenaar1e115362019-01-09 23:01:02 +010033func s:test_windows(...)
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010034 call NewWindow(10, 20)
35 setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap
36 exe get(a:000, 0, '')
Bram Moolenaar1e115362019-01-09 23:01:02 +010037endfunc
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010038
Bram Moolenaar1e115362019-01-09 23:01:02 +010039func s:close_windows(...)
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010040 call CloseWindow()
41 exe get(a:000, 0, '')
Bram Moolenaar1e115362019-01-09 23:01:02 +010042endfunc
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010043
44func Test_linebreak_with_fancy_listchars()
45 call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
46 call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
47 redraw!
48 let lines = s:screen_lines([1, 4], winwidth(0))
49 let expect = [
50\ "▕———abcdef ",
51\ "+hijklmn▕——— ",
52\ "+pqrstuvwxyz1060ABC",
53\ "+DEFGHIJKLMNOPˑ¶ ",
54\ ]
55 call s:compare_lines(expect, lines)
56 call s:close_windows()
57endfunc
58
59func Test_nolinebreak_with_list()
60 call s:test_windows("setl nolinebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
61 call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
62 redraw!
63 let lines = s:screen_lines([1, 4], winwidth(0))
64 let expect = [
65\ "▕———abcdef hijklmn▕—",
66\ "+pqrstuvwxyz1060ABC",
67\ "+DEFGHIJKLMNOPˑ¶ ",
68\ "~ ",
69\ ]
70 call s:compare_lines(expect, lines)
71 call s:close_windows()
72endfunc
73
Bram Moolenaar89a54b42021-09-07 20:45:31 +020074" this was causing a crash
75func Test_linebreak_with_list_and_tabs()
76 set linebreak list listchars=tab:⇤\ tabstop=100
77 new
78 call setline(1, "\t\t\ttext")
79 redraw
80 bwipe!
81 set nolinebreak nolist listchars&vim tabstop=8
82endfunc
83
Bram Moolenaar544d3bc2017-02-05 21:14:50 +010084func Test_linebreak_with_nolist()
85 call s:test_windows('setl nolist')
86 call setline(1, "\t*mask = nil;")
87 redraw!
88 let lines = s:screen_lines([1, 4], winwidth(0))
89 let expect = [
90\ " *mask = nil; ",
91\ "~ ",
92\ "~ ",
93\ "~ ",
94\ ]
95 call s:compare_lines(expect, lines)
96 call s:close_windows()
97endfunc
98
99func Test_list_and_concealing1()
100 call s:test_windows('setl list listchars=tab:>- cole=1')
101 call setline(1, [
102\ "#define ABCDE\t\t1",
103\ "#define ABCDEF\t\t1",
104\ "#define ABCDEFG\t\t1",
105\ "#define ABCDEFGH\t1",
106\ "#define MSG_MODE_FILE\t\t\t1",
107\ "#define MSG_MODE_CONSOLE\t\t2",
108\ "#define MSG_MODE_FILE_AND_CONSOLE\t3",
109\ "#define MSG_MODE_FILE_THEN_CONSOLE\t4",
110\ ])
111 vert resize 40
112 syn match Conceal conceal cchar=>'AB\|MSG_MODE'
113 redraw!
114 let lines = s:screen_lines([1, 7], winwidth(0))
115 let expect = [
116\ "#define ABCDE>-->---1 ",
117\ "#define >CDEF>-->---1 ",
118\ "#define >CDEFG>->---1 ",
119\ "#define >CDEFGH>----1 ",
120\ "#define >_FILE>--------->--->---1 ",
121\ "#define >_CONSOLE>---------->---2 ",
122\ "#define >_FILE_AND_CONSOLE>---------3 ",
123\ ]
124 call s:compare_lines(expect, lines)
125 call s:close_windows()
126endfunc
127
128func Test_list_and_concealing2()
129 call s:test_windows('setl nowrap ts=2 list listchars=tab:>- cole=2 concealcursor=n')
130 call setline(1, "bbeeeeee\t\t;\tsome text")
131 vert resize 40
132 syn clear
133 syn match meaning /;\s*\zs.*/
134 syn match hasword /^\x\{8}/ contains=word
135 syn match word /\<\x\{8}\>/ contains=beginword,endword contained
136 syn match beginword /\<\x\x/ contained conceal
137 syn match endword /\x\{6}\>/ contained
138 hi meaning guibg=blue
139 hi beginword guibg=green
140 hi endword guibg=red
141 redraw!
142 let lines = s:screen_lines([1, 1], winwidth(0))
143 let expect = [
144\ "eeeeee>--->-;>some text ",
145\ ]
146 call s:compare_lines(expect, lines)
147 call s:close_windows()
148endfunc
149
150func Test_screenattr_for_comment()
151 call s:test_windows("setl ft=c ts=7 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
152 call setline(1, " /*\t\t and some more */")
153 norm! gg0
154 syntax on
155 hi SpecialKey term=underline ctermfg=red guifg=red
156 redraw!
157 let line = getline(1)
158 let attr = s:screen_attr(1, [1, 6])
159 call assert_notequal(attr[0], attr[1])
160 call assert_notequal(attr[1], attr[3])
161 call assert_notequal(attr[3], attr[5])
162 call s:close_windows()
163endfunc
164
165func Test_visual_block_and_selection_exclusive()
166 call s:test_windows('setl selection=exclusive')
167 call setline(1, "long line: " . repeat("foobar ", 40) . "TARGETÃ' at end")
168 exe "norm! $3B\<C-v>eAx\<Esc>"
169 let lines = s:screen_lines([1, 10], winwidth(0))
170 let expect = [
Bram Moolenaar0937b9f2022-10-06 21:24:34 +0100171\ "+foobar foobar ",
Bram Moolenaar544d3bc2017-02-05 21:14:50 +0100172\ "+foobar foobar ",
173\ "+foobar foobar ",
174\ "+foobar foobar ",
175\ "+foobar foobar ",
176\ "+foobar foobar ",
177\ "+foobar foobar ",
178\ "+foobar foobar ",
179\ "+foobar foobar ",
180\ "+foobar TARGETÃx' ",
181\ ]
182 call s:compare_lines(expect, lines)
183 call s:close_windows()
184endfunc
185
186func Test_multibyte_sign_and_colorcolumn()
187 call s:test_windows("setl nolinebreak cc=3 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
188 call setline(1, ["", "a b c", "a b c"])
189 exe "sign define foo text=\uff0b"
190 exe "sign place 1 name=foo line=2 buffer=" . bufnr('%')
191 redraw!
192 norm! ggj0
193 let signwidth = strdisplaywidth("\uff0b")
194 let attr1 = s:screen_attr(2, [1, 3], signwidth)
195 let attr2 = s:screen_attr(3, [1, 3], signwidth)
196 call assert_equal(attr1[0], attr2[0])
197 call assert_equal(attr1[1], attr2[1])
198 call assert_equal(attr1[2], attr2[2])
199 let lines = s:screen_lines([1, 3], winwidth(0))
200 let expect = [
201\ " ¶ ",
202\ "+a b c¶ ",
203\ " a b c¶ ",
204\ ]
205 call s:compare_lines(expect, lines)
206 call s:close_windows()
207endfunc
Bram Moolenaar38632fa2017-02-26 19:40:59 +0100208
Bram Moolenaar774e5a92017-06-25 18:03:37 +0200209func Test_colorcolumn_priority()
210 call s:test_windows('setl cc=4 cuc hls')
211 call setline(1, ["xxyy", ""])
212 norm! gg
213 exe "normal! /xxyy\<CR>"
214 norm! G
215 redraw!
216 let line_attr = s:screen_attr(1, [1, &cc])
217 " Search wins over CursorColumn
218 call assert_equal(line_attr[1], line_attr[0])
219 " Search wins over Colorcolumn
220 call assert_equal(line_attr[2], line_attr[3])
221 call s:close_windows('setl hls&vim')
222endfunc
223
Bram Moolenaar38632fa2017-02-26 19:40:59 +0100224func Test_illegal_byte_and_breakat()
225 call s:test_windows("setl sbr= brk+=<")
226 vert resize 18
227 call setline(1, repeat("\x80", 6))
228 redraw!
229 let lines = s:screen_lines([1, 2], winwidth(0))
230 let expect = [
231\ "<80><80><80><80><8",
232\ "0><80> ",
233\ ]
234 call s:compare_lines(expect, lines)
235 call s:close_windows('setl brk&vim')
236endfunc
237
238func Test_multibyte_wrap_and_breakat()
239 call s:test_windows("setl sbr= brk+=>")
240 call setline(1, repeat('a', 17) . repeat('あ', 2))
241 redraw!
242 let lines = s:screen_lines([1, 2], winwidth(0))
243 let expect = [
244\ "aaaaaaaaaaaaaaaaaあ>",
245\ "あ ",
246\ ]
247 call s:compare_lines(expect, lines)
248 call s:close_windows('setl brk&vim')
249endfunc
Bram Moolenaarabc39ab2017-03-01 18:04:05 +0100250
251func Test_chinese_char_on_wrap_column()
252 call s:test_windows("setl nolbr wrap sbr=")
Bram Moolenaarabc39ab2017-03-01 18:04:05 +0100253 call setline(1, [
254\ 'aaaaaaaaaaaaaaaaaaa中'.
255\ 'aaaaaaaaaaaaaaaaa中'.
256\ 'aaaaaaaaaaaaaaaaa中'.
257\ 'aaaaaaaaaaaaaaaaa中'.
258\ 'aaaaaaaaaaaaaaaaa中'.
259\ 'aaaaaaaaaaaaaaaaa中'.
260\ 'aaaaaaaaaaaaaaaaa中'.
261\ 'aaaaaaaaaaaaaaaaa中'.
262\ 'aaaaaaaaaaaaaaaaa中'.
263\ 'aaaaaaaaaaaaaaaaa中'.
264\ 'hello'])
265 call cursor(1,1)
266 norm! $
267 redraw!
268 let expect=[
Bram Moolenaar0466d392022-10-03 17:07:34 +0100269\ '<<<aaaaaaaaaaaaaaaa>',
Bram Moolenaarabc39ab2017-03-01 18:04:05 +0100270\ '中aaaaaaaaaaaaaaaaa>',
271\ '中aaaaaaaaaaaaaaaaa>',
272\ '中aaaaaaaaaaaaaaaaa>',
273\ '中aaaaaaaaaaaaaaaaa>',
274\ '中aaaaaaaaaaaaaaaaa>',
275\ '中aaaaaaaaaaaaaaaaa>',
276\ '中aaaaaaaaaaaaaaaaa>',
277\ '中aaaaaaaaaaaaaaaaa>',
278\ '中hello ']
279 let lines = s:screen_lines([1, 10], winwidth(0))
280 call s:compare_lines(expect, lines)
zeertzjqb557f482023-08-22 22:07:34 +0200281 call assert_equal(len(expect), winline())
282 call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
zeertzjqb5d6b5c2024-07-18 21:13:31 +0200283 norm! g0
284 call assert_equal(len(expect), winline())
285 call assert_equal(1, wincol())
zeertzjqb557f482023-08-22 22:07:34 +0200286 call s:close_windows()
287endfunc
288
289func Test_chinese_char_on_wrap_column_sbr()
290 call s:test_windows("setl nolbr wrap sbr=!!!")
291 call setline(1, [
292\ 'aaaaaaaaaaaaaaaaaaa中'.
293\ 'aaaaaaaaaaaaaa中'.
294\ 'aaaaaaaaaaaaaa中'.
295\ 'aaaaaaaaaaaaaa中'.
296\ 'aaaaaaaaaaaaaa中'.
297\ 'aaaaaaaaaaaaaa中'.
298\ 'aaaaaaaaaaaaaa中'.
299\ 'aaaaaaaaaaaaaa中'.
300\ 'aaaaaaaaaaaaaa中'.
301\ 'aaaaaaaaaaaaaa中'.
302\ 'hello'])
303 call cursor(1,1)
304 norm! $
305 redraw!
306 let expect=[
307\ '!!!中aaaaaaaaaaaaaa>',
308\ '!!!中aaaaaaaaaaaaaa>',
309\ '!!!中aaaaaaaaaaaaaa>',
310\ '!!!中aaaaaaaaaaaaaa>',
311\ '!!!中aaaaaaaaaaaaaa>',
312\ '!!!中aaaaaaaaaaaaaa>',
313\ '!!!中aaaaaaaaaaaaaa>',
314\ '!!!中aaaaaaaaaaaaaa>',
315\ '!!!中aaaaaaaaaaaaaa>',
316\ '!!!中hello ']
317 let lines = s:screen_lines([1, 10], winwidth(0))
318 call s:compare_lines(expect, lines)
319 call assert_equal(len(expect), winline())
320 call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
zeertzjqb5d6b5c2024-07-18 21:13:31 +0200321 norm! g0
322 call assert_equal(len(expect), winline())
323 call assert_equal(4, wincol())
zeertzjqb557f482023-08-22 22:07:34 +0200324 call s:close_windows()
325endfunc
326
327func Test_unprintable_char_on_wrap_column()
328 call s:test_windows("setl nolbr wrap sbr=")
329 call setline(1, 'aaa' .. repeat("\uFEFF", 50) .. 'bbb')
330 call cursor(1,1)
331 norm! $
332 redraw!
333 let expect=[
334\ '<<<<feff><feff><feff',
335\ '><feff><feff><feff><',
336\ 'feff><feff><feff><fe',
337\ 'ff><feff><feff><feff',
338\ '><feff><feff><feff><',
339\ 'feff><feff><feff><fe',
340\ 'ff><feff><feff><feff',
341\ '><feff><feff><feff><',
342\ 'feff><feff><feff><fe',
343\ 'ff>bbb ']
344 let lines = s:screen_lines([1, 10], winwidth(0))
345 call s:compare_lines(expect, lines)
346 call assert_equal(len(expect), winline())
347 call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
348 setl sbr=!!
349 redraw!
350 let expect=[
351\ '!!><feff><feff><feff',
352\ '!!><feff><feff><feff',
353\ '!!><feff><feff><feff',
354\ '!!><feff><feff><feff',
355\ '!!><feff><feff><feff',
356\ '!!><feff><feff><feff',
357\ '!!><feff><feff><feff',
358\ '!!><feff><feff><feff',
359\ '!!><feff><feff><feff',
360\ '!!><feff><feff>bbb ']
361 let lines = s:screen_lines([1, 10], winwidth(0))
362 call s:compare_lines(expect, lines)
363 call assert_equal(len(expect), winline())
364 call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
Bram Moolenaarabc39ab2017-03-01 18:04:05 +0100365 call s:close_windows()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200366endfunc
367
zeertzjqdf23d7f2024-02-09 18:14:12 +0100368" Test that Visual selection is drawn correctly when 'linebreak' is set and
369" selection ends before multibyte 'showbreak'.
370func Test_visual_ends_before_showbreak()
371 CheckScreendump
372
Yee Cheng Chine70587d2025-02-13 20:55:45 +0100373 " Redraw at the end is necessary due to https://github.com/vim/vim/issues/16620
zeertzjqdf23d7f2024-02-09 18:14:12 +0100374 let lines =<< trim END
375 vim9script
376 &wrap = true
377 &linebreak = true
378 &showbreak = '↪ '
379 ['xxxxx ' .. 'y'->repeat(&columns - 6) .. ' zzzz']->setline(1)
380 normal! wvel
Yee Cheng Chine70587d2025-02-13 20:55:45 +0100381 redraw
zeertzjqdf23d7f2024-02-09 18:14:12 +0100382 END
383 call writefile(lines, 'XvisualEndsBeforeShowbreak', 'D')
384 let buf = RunVimInTerminal('-S XvisualEndsBeforeShowbreak', #{rows: 6})
385 call VerifyScreenDump(buf, 'Test_visual_ends_before_showbreak', {})
386
387 call StopVimInTerminal(buf)
388endfunc
389
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200390" vim: shiftwidth=2 sts=2 expandtab