test_listlbr_utf8.vim 11 KB

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