test_listchars.vim 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. " Tests for 'listchars' display with 'list' and :list
  2. source check.vim
  3. source view_util.vim
  4. source screendump.vim
  5. func Check_listchars(expected, end_lnum, end_scol = -1, leftcol = 0)
  6. if a:leftcol > 0
  7. let save_wrap = &wrap
  8. set nowrap
  9. call cursor(1, 1)
  10. exe 'normal! ' .. a:leftcol .. 'zl'
  11. endif
  12. redraw!
  13. for i in range(1, a:end_lnum)
  14. if a:leftcol > 0
  15. let col = virtcol2col(0, i, a:leftcol)
  16. let col += getline(i)->strpart(col - 1, 1, v:true)->len()
  17. call cursor(i, col)
  18. redraw
  19. call assert_equal(a:leftcol, winsaveview().leftcol)
  20. else
  21. call cursor(i, 1)
  22. end
  23. let end_scol = a:end_scol < 0 ? '$'->virtcol() - a:leftcol : a:end_scol
  24. call assert_equal([a:expected[i - 1]->strcharpart(a:leftcol)],
  25. \ ScreenLines(i, end_scol))
  26. endfor
  27. if a:leftcol > 0
  28. let &wrap = save_wrap
  29. endif
  30. endfunc
  31. func Test_listchars()
  32. enew!
  33. set ff=unix
  34. set list
  35. set listchars+=tab:>-,space:.,trail:<
  36. call append(0, [
  37. \ ' aa ',
  38. \ ' bb ',
  39. \ ' cccc ',
  40. \ 'dd ee ',
  41. \ ' '
  42. \ ])
  43. let expected = [
  44. \ '>-------aa>-----$',
  45. \ '..bb>---<<$',
  46. \ '...cccc><$',
  47. \ 'dd........ee<<>-$',
  48. \ '<$'
  49. \ ]
  50. call Check_listchars(expected, 5)
  51. call Check_listchars(expected, 4, -1, 5)
  52. set listchars-=trail:<
  53. let expected = [
  54. \ '>-------aa>-----$',
  55. \ '..bb>---..$',
  56. \ '...cccc>.$',
  57. \ 'dd........ee..>-$',
  58. \ '.$'
  59. \ ]
  60. call Check_listchars(expected, 5)
  61. call Check_listchars(expected, 4, -1, 5)
  62. " tab with 3rd character.
  63. set listchars-=tab:>-
  64. set listchars+=tab:<=>,trail:-
  65. let expected = [
  66. \ '<======>aa<====>$',
  67. \ '..bb<==>--$',
  68. \ '...cccc>-$',
  69. \ 'dd........ee--<>$',
  70. \ '-$'
  71. \ ]
  72. call Check_listchars(expected, 5)
  73. call Check_listchars(expected, 4, -1, 5)
  74. " tab with 3rd character and linebreak set
  75. set listchars-=tab:<=>
  76. set listchars+=tab:<·>
  77. set linebreak
  78. let expected = [
  79. \ '<······>aa<····>$',
  80. \ '..bb<··>--$',
  81. \ '...cccc>-$',
  82. \ 'dd........ee--<>$',
  83. \ '-$'
  84. \ ]
  85. call Check_listchars(expected, 5)
  86. set nolinebreak
  87. set listchars-=tab:<·>
  88. set listchars+=tab:<=>
  89. set listchars-=trail:-
  90. let expected = [
  91. \ '<======>aa<====>$',
  92. \ '..bb<==>..$',
  93. \ '...cccc>.$',
  94. \ 'dd........ee..<>$',
  95. \ '.$'
  96. \ ]
  97. call Check_listchars(expected, 5)
  98. call Check_listchars(expected, 4, -1, 5)
  99. set listchars-=tab:<=>
  100. set listchars+=tab:>-
  101. set listchars+=trail:<
  102. set nolist
  103. normal ggdG
  104. call append(0, [
  105. \ ' fff ',
  106. \ ' gg ',
  107. \ ' h ',
  108. \ 'iii ',
  109. \ ])
  110. let l = split(execute("%list"), "\n")
  111. call assert_equal([
  112. \ '..fff>--<<$',
  113. \ '>-------gg>-----$',
  114. \ '.....h>-$',
  115. \ 'iii<<<<><<$',
  116. \ '$'], l)
  117. " Test lead and trail
  118. normal ggdG
  119. set listchars=eol:$ " Accommodate Nvim default
  120. set listchars+=lead:>,trail:<,space:x
  121. set list
  122. call append(0, [
  123. \ ' ffff ',
  124. \ ' gg',
  125. \ 'h ',
  126. \ ' ',
  127. \ ' 0 0 ',
  128. \ ])
  129. let expected = [
  130. \ '>>>>ffff<<<<$',
  131. \ '>>>>>>>>>>gg$',
  132. \ 'h<<<<<<<<<<<$',
  133. \ '<<<<<<<<<<<<$',
  134. \ '>>>>0xx0<<<<$',
  135. \ '$'
  136. \ ]
  137. call Check_listchars(expected, 6)
  138. call Check_listchars(expected, 5, -1, 6)
  139. call assert_equal(expected, split(execute("%list"), "\n"))
  140. " Test multispace
  141. normal ggdG
  142. set listchars=eol:$ " Accommodate Nvim default
  143. set listchars+=multispace:yYzZ
  144. set list
  145. call append(0, [
  146. \ ' ffff ',
  147. \ ' i i gg',
  148. \ ' h ',
  149. \ ' j ',
  150. \ ' 0 0 ',
  151. \ ])
  152. let expected = [
  153. \ 'yYzZffffyYzZ$',
  154. \ 'yYi iyYzZygg$',
  155. \ ' hyYzZyYzZyY$',
  156. \ 'yYzZyYzZyYj $',
  157. \ 'yYzZ0yY0yYzZ$',
  158. \ '$'
  159. \ ]
  160. call Check_listchars(expected, 6)
  161. call Check_listchars(expected, 5, -1, 6)
  162. call assert_equal(expected, split(execute("%list"), "\n"))
  163. " Test leadmultispace + multispace
  164. normal ggdG
  165. set listchars=eol:$,multispace:yYzZ,nbsp:S
  166. set listchars+=leadmultispace:.-+*
  167. set list
  168. call append(0, [
  169. \ ' ffff ',
  170. \ ' i i  gg',
  171. \ ' h ',
  172. \ ' j ',
  173. \ ' 0 0 ',
  174. \ ])
  175. let expected = [
  176. \ '.-+*ffffyYzZ$',
  177. \ '.-i iSyYzZgg$',
  178. \ ' hyYzZyYzZyY$',
  179. \ '.-+*.-+*.-j $',
  180. \ '.-+*0yY0yYzZ$',
  181. \ '$'
  182. \ ]
  183. call assert_equal('eol:$,multispace:yYzZ,nbsp:S,leadmultispace:.-+*', &listchars)
  184. call Check_listchars(expected, 6)
  185. call Check_listchars(expected, 5, -1, 1)
  186. call Check_listchars(expected, 5, -1, 2)
  187. call Check_listchars(expected, 5, -1, 3)
  188. call Check_listchars(expected, 5, -1, 6)
  189. call assert_equal(expected, split(execute("%list"), "\n"))
  190. " Test leadmultispace without multispace
  191. normal ggdG
  192. set listchars-=multispace:yYzZ
  193. set listchars+=space:+,trail:>,eol:$
  194. set list
  195. call append(0, [
  196. \ ' ffff ',
  197. \ ' i i gg',
  198. \ ' h ',
  199. \ ' j ',
  200. \ ' 0 0 ',
  201. \ ])
  202. let expected = [
  203. \ '.-+*ffff>>>>$',
  204. \ '.-i+i+++++gg$',
  205. \ '+h>>>>>>>>>>$',
  206. \ '.-+*.-+*.-j>$',
  207. \ '.-+*0++0>>>>$',
  208. \ '$'
  209. \ ]
  210. call assert_equal('eol:$,nbsp:S,leadmultispace:.-+*,space:+,trail:>,eol:$', &listchars)
  211. call Check_listchars(expected, 6)
  212. call Check_listchars(expected, 5, -1, 1)
  213. call Check_listchars(expected, 5, -1, 2)
  214. call Check_listchars(expected, 5, -1, 3)
  215. call Check_listchars(expected, 5, -1, 6)
  216. call assert_equal(expected, split(execute("%list"), "\n"))
  217. " Test leadmultispace only
  218. normal ggdG
  219. set listchars=eol:$ " Accommodate Nvim default
  220. set listchars=leadmultispace:.-+*
  221. set list
  222. call append(0, [
  223. \ ' ffff ',
  224. \ ' i i gg',
  225. \ ' h ',
  226. \ ' j ',
  227. \ ' 0 0 ',
  228. \ ])
  229. let expected = [
  230. \ '.-+*ffff ',
  231. \ '.-i i gg',
  232. \ ' h ',
  233. \ '.-+*.-+*.-j ',
  234. \ '.-+*0 0 ',
  235. \ ' '
  236. \ ]
  237. call assert_equal('leadmultispace:.-+*', &listchars)
  238. call Check_listchars(expected, 5, 12)
  239. call assert_equal(expected, split(execute("%list"), "\n"))
  240. " Changing the value of 'ambiwidth' twice shouldn't cause double-free when
  241. " "leadmultispace" is specified.
  242. set ambiwidth=double
  243. set ambiwidth&
  244. " Test leadmultispace and lead and space
  245. normal ggdG
  246. set listchars=eol:$ " Accommodate Nvim default
  247. set listchars+=lead:<,space:-
  248. set listchars+=leadmultispace:.-+*
  249. set list
  250. call append(0, [
  251. \ ' ffff ',
  252. \ ' i i gg',
  253. \ ' h ',
  254. \ ' j ',
  255. \ ' 0 0 ',
  256. \ ])
  257. let expected = [
  258. \ '.-+*ffff----$',
  259. \ '.-i-i-----gg$',
  260. \ '<h----------$',
  261. \ '.-+*.-+*.-j-$',
  262. \ '.-+*0--0----$',
  263. \ '$'
  264. \ ]
  265. call assert_equal('eol:$,lead:<,space:-,leadmultispace:.-+*', &listchars)
  266. call Check_listchars(expected, 6)
  267. call Check_listchars(expected, 5, -1, 1)
  268. call Check_listchars(expected, 5, -1, 2)
  269. call Check_listchars(expected, 5, -1, 3)
  270. call Check_listchars(expected, 5, -1, 6)
  271. call assert_equal(expected, split(execute("%list"), "\n"))
  272. " the last occurrence of 'multispace:' is used
  273. set listchars=eol:$ " Accommodate Nvim default
  274. set listchars+=multispace:yYzZ
  275. set listchars+=space:x,multispace:XyY
  276. let expected = [
  277. \ 'XyYXffffXyYX$',
  278. \ 'XyixiXyYXygg$',
  279. \ 'xhXyYXyYXyYX$',
  280. \ 'XyYXyYXyYXjx$',
  281. \ 'XyYX0Xy0XyYX$',
  282. \ '$'
  283. \ ]
  284. call assert_equal('eol:$,multispace:yYzZ,space:x,multispace:XyY', &listchars)
  285. call Check_listchars(expected, 6)
  286. call Check_listchars(expected, 5, -1, 6)
  287. call assert_equal(expected, split(execute("%list"), "\n"))
  288. set listchars+=lead:>,trail:<
  289. let expected = [
  290. \ '>>>>ffff<<<<$',
  291. \ '>>ixiXyYXygg$',
  292. \ '>h<<<<<<<<<<$',
  293. \ '>>>>>>>>>>j<$',
  294. \ '>>>>0Xy0<<<<$',
  295. \ '$'
  296. \ ]
  297. call Check_listchars(expected, 6)
  298. call Check_listchars(expected, 5, -1, 6)
  299. call assert_equal(expected, split(execute("%list"), "\n"))
  300. " removing 'multispace:'
  301. set listchars-=multispace:XyY
  302. set listchars-=multispace:yYzZ
  303. let expected = [
  304. \ '>>>>ffff<<<<$',
  305. \ '>>ixixxxxxgg$',
  306. \ '>h<<<<<<<<<<$',
  307. \ '>>>>>>>>>>j<$',
  308. \ '>>>>0xx0<<<<$',
  309. \ '$'
  310. \ ]
  311. call Check_listchars(expected, 6)
  312. call Check_listchars(expected, 5, -1, 6)
  313. call assert_equal(expected, split(execute("%list"), "\n"))
  314. " test nbsp
  315. normal ggdG
  316. set listchars=nbsp:X,trail:Y
  317. set list
  318. " Non-breaking space
  319. let nbsp = nr2char(0xa0)
  320. call append(0, [ ">" .. nbsp .. "<" ])
  321. let expected = '>X< '
  322. call Check_listchars([expected], 1)
  323. set listchars=nbsp:X
  324. call Check_listchars([expected], 1)
  325. " test extends
  326. normal ggdG
  327. set listchars=extends:Z
  328. set nowrap
  329. set nolist
  330. call append(0, [ repeat('A', &columns + 1) ])
  331. let expected = repeat('A', &columns)
  332. call Check_listchars([expected], 1, &columns)
  333. set list
  334. let expected = expected[:-2] . 'Z'
  335. call Check_listchars([expected], 1, &columns)
  336. enew!
  337. set listchars& ff&
  338. endfunc
  339. " Test that unicode listchars characters get properly inserted
  340. func Test_listchars_unicode()
  341. enew!
  342. let oldencoding=&encoding
  343. set encoding=utf-8
  344. set ff=unix
  345. set listchars=eol:⇔,space:␣,multispace:≡≢≣,nbsp:≠,tab:←↔→
  346. set list
  347. let nbsp = nr2char(0xa0)
  348. call append(0, [" a\tb c" .. nbsp .. "d "])
  349. let expected = ['≡≢≣≡≢≣≡≢a←↔↔↔↔↔→b␣c≠d≡≢⇔']
  350. call Check_listchars(expected, 1)
  351. call Check_listchars(expected, 1, -1, 3)
  352. call Check_listchars(expected, 1, -1, 13)
  353. set listchars=eol:\\u21d4,space:\\u2423,multispace:≡\\u2262\\U00002263,nbsp:\\U00002260,tab:←↔\\u2192
  354. call Check_listchars(expected, 1)
  355. call Check_listchars(expected, 1, -1, 3)
  356. call Check_listchars(expected, 1, -1, 13)
  357. set listchars+=lead:⇨,trail:
  358. let expected = ['⇨⇨⇨⇨⇨⇨⇨⇨a←↔↔↔↔↔→b␣c≠d⇦⇦⇔']
  359. call Check_listchars(expected, 1)
  360. call Check_listchars(expected, 1, -1, 3)
  361. call Check_listchars(expected, 1, -1, 13)
  362. let &encoding=oldencoding
  363. enew!
  364. set listchars& ff&
  365. endfunction
  366. func Test_listchars_invalid()
  367. enew!
  368. set ff=unix
  369. set listchars=eol:$ " Accommodate Nvim default
  370. set list
  371. set ambiwidth=double
  372. " No colon
  373. call assert_fails('set listchars=x', 'E474:')
  374. call assert_fails('set listchars=x', 'E474:')
  375. call assert_fails('set listchars=multispace', 'E474:')
  376. call assert_fails('set listchars=leadmultispace', 'E474:')
  377. " Too short
  378. call assert_fails('set listchars=space:', 'E1511:')
  379. call assert_fails('set listchars=tab:x', 'E1511:')
  380. call assert_fails('set listchars=multispace:', 'E1511:')
  381. call assert_fails('set listchars=leadmultispace:', 'E1511:')
  382. " One occurrence too short
  383. call assert_fails('set listchars=space:x,space:', 'E1511:')
  384. call assert_fails('set listchars=space:,space:x', 'E1511:')
  385. call assert_fails('set listchars=tab:xx,tab:x', 'E1511:')
  386. call assert_fails('set listchars=tab:x,tab:xx', 'E1511:')
  387. call assert_fails('set listchars=multispace:,multispace:x', 'E1511:')
  388. call assert_fails('set listchars=multispace:x,multispace:', 'E1511:')
  389. call assert_fails('set listchars=leadmultispace:,leadmultispace:x', 'E1511:')
  390. call assert_fails('set listchars=leadmultispace:x,leadmultispace:', 'E1511:')
  391. " Too long
  392. call assert_fails('set listchars=space:xx', 'E1511:')
  393. call assert_fails('set listchars=tab:xxxx', 'E1511:')
  394. " Has double-width character
  395. call assert_fails('set listchars=space:·', 'E1512:')
  396. call assert_fails('set listchars=tab:·x', 'E1512:')
  397. call assert_fails('set listchars=tab:x·', 'E1512:')
  398. call assert_fails('set listchars=tab:xx·', 'E1512:')
  399. call assert_fails('set listchars=multispace:·', 'E1512:')
  400. call assert_fails('set listchars=multispace:xxx·', 'E1512:')
  401. call assert_fails('set listchars=leadmultispace:·', 'E1512:')
  402. call assert_fails('set listchars=leadmultispace:xxx·', 'E1512:')
  403. " Has control character
  404. call assert_fails("set listchars=space:\x01", 'E1512:')
  405. call assert_fails("set listchars=tab:\x01x", 'E1512:')
  406. call assert_fails("set listchars=tab:x\x01", 'E1512:')
  407. call assert_fails("set listchars=tab:xx\x01", 'E1512:')
  408. call assert_fails("set listchars=multispace:\x01", 'E1512:')
  409. call assert_fails("set listchars=multispace:xxx\x01", 'E1512:')
  410. call assert_fails('set listchars=space:\\x01', 'E1512:')
  411. call assert_fails('set listchars=tab:\\x01x', 'E1512:')
  412. call assert_fails('set listchars=tab:x\\x01', 'E1512:')
  413. call assert_fails('set listchars=tab:xx\\x01', 'E1512:')
  414. call assert_fails('set listchars=multispace:\\x01', 'E1512:')
  415. call assert_fails('set listchars=multispace:xxx\\x01', 'E1512:')
  416. call assert_fails("set listchars=leadmultispace:\x01", 'E1512:')
  417. call assert_fails('set listchars=leadmultispace:\\x01', 'E1512:')
  418. call assert_fails("set listchars=leadmultispace:xxx\x01", 'E1512:')
  419. call assert_fails('set listchars=leadmultispace:xxx\\x01', 'E1512:')
  420. enew!
  421. set ambiwidth& listchars& ff&
  422. endfunction
  423. " Tests that space characters following composing character won't get replaced
  424. " by listchars.
  425. func Test_listchars_composing()
  426. enew!
  427. let oldencoding=&encoding
  428. set encoding=utf-8
  429. set ff=unix
  430. set list
  431. set listchars=eol:$,space:_,nbsp:=
  432. let nbsp1 = nr2char(0xa0)
  433. let nbsp2 = nr2char(0x202f)
  434. call append(0, [
  435. \ " \u3099\t \u309A" .. nbsp1 .. nbsp1 .. "\u0302" .. nbsp2 .. nbsp2 .. "\u0302",
  436. \ ])
  437. let expected = [
  438. \ "_ \u3099^I \u309A=" .. nbsp1 .. "\u0302=" .. nbsp2 .. "\u0302$"
  439. \ ]
  440. call Check_listchars(expected, 1)
  441. let &encoding=oldencoding
  442. enew!
  443. set listchars& ff&
  444. endfunction
  445. " Check for the value of the 'listchars' option
  446. func s:CheckListCharsValue(expected)
  447. call assert_equal(a:expected, &listchars)
  448. call assert_equal(a:expected, getwinvar(0, '&listchars'))
  449. endfunc
  450. " Test for using a window local value for 'listchars'
  451. func Test_listchars_window_local()
  452. %bw!
  453. set list listchars&
  454. let nvim_default = &listchars " Accommodate Nvim default
  455. new
  456. " set a local value for 'listchars'
  457. setlocal listchars=tab:+-,eol:#
  458. call s:CheckListCharsValue('tab:+-,eol:#')
  459. " When local value is reset, global value should be used
  460. setlocal listchars=
  461. call s:CheckListCharsValue(nvim_default)
  462. " Use 'setlocal <' to copy global value
  463. setlocal listchars=space:.,extends:>
  464. setlocal listchars<
  465. call s:CheckListCharsValue(nvim_default)
  466. " Use 'set <' to copy global value
  467. setlocal listchars=space:.,extends:>
  468. set listchars<
  469. call s:CheckListCharsValue(nvim_default)
  470. " Changing global setting should not change the local setting
  471. setlocal listchars=space:.,extends:>
  472. setglobal listchars=tab:+-,eol:#
  473. call s:CheckListCharsValue('space:.,extends:>')
  474. " when split opening a new window, local value should be copied
  475. split
  476. call s:CheckListCharsValue('space:.,extends:>')
  477. " clearing local value in one window should not change the other window
  478. set listchars&
  479. call s:CheckListCharsValue(nvim_default)
  480. close
  481. call s:CheckListCharsValue('space:.,extends:>')
  482. " use different values for 'listchars' items in two different windows
  483. call setline(1, ["\t one two "])
  484. setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
  485. split
  486. setlocal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
  487. split
  488. set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
  489. call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
  490. close
  491. call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
  492. close
  493. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  494. " changing the global setting should not change the local value
  495. setglobal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
  496. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  497. set listchars<
  498. call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
  499. " Using setglobal in a window with local setting should not affect the
  500. " window. But should impact other windows using the global setting.
  501. enew! | only
  502. call setline(1, ["\t one two "])
  503. set listchars=tab:[.],lead:#,space:_,trail:.,eol:&
  504. split
  505. setlocal listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
  506. split
  507. setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
  508. setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$
  509. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  510. close
  511. call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
  512. close
  513. call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
  514. " Setting the global setting to the default value should not impact a window
  515. " using a local setting.
  516. split
  517. setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
  518. setglobal listchars=eol:$ " Accommodate Nvim default
  519. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  520. close
  521. call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$')))
  522. " Setting the local setting to the default value should not impact a window
  523. " using a global setting.
  524. set listchars=tab:{.},lead:-,space:=,trail:#,eol:$
  525. split
  526. setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
  527. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  528. setlocal listchars=eol:$ " Accommodate Nvim default
  529. call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$')))
  530. close
  531. call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
  532. " Using set in a window with a local setting should change it to use the
  533. " global setting and also impact other windows using the global setting.
  534. split
  535. setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
  536. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  537. set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
  538. call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
  539. close
  540. call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
  541. " Setting invalid value for a local setting should not impact the local and
  542. " global settings.
  543. split
  544. setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
  545. let cmd = 'setlocal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x'
  546. call assert_fails(cmd, 'E474:')
  547. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  548. close
  549. call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
  550. " Setting invalid value for a global setting should not impact the local and
  551. " global settings.
  552. split
  553. setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
  554. let cmd = 'setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x'
  555. call assert_fails(cmd, 'E474:')
  556. call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
  557. close
  558. call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
  559. " Closing window with local lcs-multispace should not cause a memory leak.
  560. setlocal listchars=multispace:---+
  561. split
  562. call s:CheckListCharsValue('multispace:---+')
  563. close
  564. %bw!
  565. set list& listchars&
  566. endfunc
  567. func Test_listchars_foldcolumn()
  568. CheckScreendump
  569. let lines =<< trim END
  570. call setline(1, ['aaa', '', 'a', 'aaaaaa'])
  571. vsplit
  572. vsplit
  573. windo set signcolumn=yes foldcolumn=1 winminwidth=0 nowrap list listchars=extends:>,precedes:<
  574. END
  575. call writefile(lines, 'XTest_listchars', 'D')
  576. let buf = RunVimInTerminal('-S XTest_listchars', {'rows': 10, 'cols': 60})
  577. call term_sendkeys(buf, "13\<C-W>>")
  578. call VerifyScreenDump(buf, 'Test_listchars_01', {})
  579. call term_sendkeys(buf, "\<C-W>>")
  580. call VerifyScreenDump(buf, 'Test_listchars_02', {})
  581. call term_sendkeys(buf, "\<C-W>>")
  582. call VerifyScreenDump(buf, 'Test_listchars_03', {})
  583. call term_sendkeys(buf, "\<C-W>>")
  584. call VerifyScreenDump(buf, 'Test_listchars_04', {})
  585. call term_sendkeys(buf, "\<C-W>>")
  586. call VerifyScreenDump(buf, 'Test_listchars_05', {})
  587. call term_sendkeys(buf, "\<C-W>h")
  588. call term_sendkeys(buf, ":set nowrap foldcolumn=4\<CR>")
  589. call term_sendkeys(buf, "15\<C-W><")
  590. call VerifyScreenDump(buf, 'Test_listchars_06', {})
  591. call term_sendkeys(buf, "4\<C-W><")
  592. call VerifyScreenDump(buf, 'Test_listchars_07', {})
  593. " clean up
  594. call StopVimInTerminal(buf)
  595. endfunc
  596. func Test_listchars_precedes_with_wide_char()
  597. new
  598. setlocal nowrap list listchars=eol:$,precedes:!
  599. call setline(1, '123口456')
  600. call assert_equal(['123口456$ '], ScreenLines(1, 10))
  601. let attr = screenattr(1, 9)
  602. normal! zl
  603. call assert_equal(['!3口456$ '], ScreenLines(1, 10))
  604. call assert_equal(attr, screenattr(1, 1))
  605. normal! zl
  606. call assert_equal(['!口456$ '], ScreenLines(1, 10))
  607. call assert_equal(attr, screenattr(1, 1))
  608. normal! zl
  609. call assert_equal(['!<456$ '], ScreenLines(1, 10))
  610. call assert_equal(attr, screenattr(1, 1))
  611. call assert_equal(attr, screenattr(1, 2))
  612. normal! zl
  613. call assert_equal(['!456$ '], ScreenLines(1, 10))
  614. call assert_equal(attr, screenattr(1, 1))
  615. normal! zl
  616. call assert_equal(['!56$ '], ScreenLines(1, 10))
  617. call assert_equal(attr, screenattr(1, 1))
  618. normal! zl
  619. call assert_equal(['!6$ '], ScreenLines(1, 10))
  620. call assert_equal(attr, screenattr(1, 1))
  621. bw!
  622. endfunc
  623. func Test_listchars_precedes_with_tab()
  624. new
  625. setlocal nowrap list listchars=eol:$,precedes:!,tab:<->
  626. call setline(1, "1234\t56")
  627. let expected_line = '1234<-->56$ '
  628. call assert_equal([expected_line], ScreenLines(1, 12))
  629. let expected_attrs = mapnew(range(1, 12), 'screenattr(1, v:val)')
  630. let attr = expected_attrs[-2]
  631. for i in range(8)
  632. normal! zl
  633. let expected_line = '!' .. expected_line[2:] .. ' '
  634. let expected_attrs = [attr] + expected_attrs[2:] + expected_attrs[-1:]
  635. call assert_equal([expected_line], ScreenLines(1, 12))
  636. let attrs = mapnew(range(1, 12), 'screenattr(1, v:val)')
  637. call assert_equal(expected_attrs, attrs)
  638. endfor
  639. bw!
  640. endfunc
  641. " vim: shiftwidth=2 sts=2 expandtab