statuscolumn_spec.lua 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local Screen = require('test.functional.ui.screen')
  4. local clear = n.clear
  5. local command = n.command
  6. local eq = t.eq
  7. local exec = n.exec
  8. local eval = n.eval
  9. local exec_lua = n.exec_lua
  10. local feed = n.feed
  11. local api = n.api
  12. local pcall_err = t.pcall_err
  13. local assert_alive = n.assert_alive
  14. local mousemodels = { 'extend', 'popup', 'popup_setpos' }
  15. describe('statuscolumn', function()
  16. local screen
  17. before_each(function()
  18. clear('--cmd', 'set number nuw=1 | call setline(1, repeat(["aaaaa"], 16)) | norm GM')
  19. screen = Screen.new()
  20. exec_lua('ns = vim.api.nvim_create_namespace("")')
  21. end)
  22. it("fails with invalid 'statuscolumn'", function()
  23. command(
  24. [[set stc=%{v:relnum?v:relnum:(v:lnum==5?'truncate':v:lnum)}%{!v:relnum&&v:lnum==5?invalid:''}\ ]]
  25. )
  26. screen:expect([[
  27. {8:4 }aaaaa |
  28. {8:3 }aaaaa |
  29. {8:2 }aaaaa |
  30. {8:1 }aaaaa |
  31. {8:8 }^aaaaa |
  32. {8:1 }aaaaa |
  33. {8:2 }aaaaa |
  34. {8:3 }aaaaa |
  35. {8:4 }aaaaa |
  36. {8:5 }aaaaa |
  37. {8:6 }aaaaa |
  38. {8:7 }aaaaa |
  39. {8:8 }aaaaa |
  40. |
  41. ]])
  42. command('norm 5G')
  43. eq('Vim(redraw):E121: Undefined variable: invalid', pcall_err(command, 'redraw!'))
  44. eq('', eval('&statuscolumn'))
  45. screen:expect([[
  46. {8: 4 }aaaaa |
  47. {8: 5 }^aaaaa |
  48. {8: 6 }aaaaa |
  49. {8: 7 }aaaaa |
  50. {8: 8 }aaaaa |
  51. {8: 9 }aaaaa |
  52. {8:10 }aaaaa |
  53. {8:11 }aaaaa |
  54. {8:12 }aaaaa |
  55. {8:13 }aaaaa |
  56. {8:14 }aaaaa |
  57. {8:15 }aaaaa |
  58. {8:16 }aaaaa |
  59. |
  60. ]])
  61. end)
  62. it("widens with irregular 'statuscolumn' width", function()
  63. screen:try_resize(screen._width, 4)
  64. command([=[
  65. set stc=%{v:relnum?v:relnum:(v:lnum==5?'bbbbb':v:lnum)}
  66. let ns = nvim_create_namespace('')
  67. call nvim_buf_set_extmark(0, ns, 3, 0, {'virt_text':[['virt_text']]})
  68. norm 5G | redraw!
  69. ]=])
  70. screen:expect([[
  71. {8:1 }aaaaa virt_text |
  72. {8:bbbbb}a^eaaa |
  73. {8:1 }aaaaa |
  74. |
  75. ]])
  76. -- Doesn't crash when trying to fill click defs that do not fit (#26845)
  77. command('norm gg')
  78. command([=[
  79. set stc=%@Click@%{v:relnum?v:relnum:(v:lnum==5?'bbbbb':v:lnum)}%T
  80. norm 5Gzt | redraw!
  81. ]=])
  82. screen:expect([[
  83. {8:bbbbb}a^eaaa |
  84. {8:1 }aaaaa |
  85. {8:2 }aaaaa |
  86. |
  87. ]])
  88. -- Doesn't crash when clicking inside padded area without click_defs
  89. command('set numberwidth=10')
  90. api.nvim_input_mouse('left', 'press', '', 0, 0, 5)
  91. assert_alive()
  92. end)
  93. it("works with 'number' and 'relativenumber'", function()
  94. screen:expect([[
  95. {8: 4 }aaaaa |
  96. {8: 5 }aaaaa |
  97. {8: 6 }aaaaa |
  98. {8: 7 }aaaaa |
  99. {8: 8 }^aaaaa |
  100. {8: 9 }aaaaa |
  101. {8:10 }aaaaa |
  102. {8:11 }aaaaa |
  103. {8:12 }aaaaa |
  104. {8:13 }aaaaa |
  105. {8:14 }aaaaa |
  106. {8:15 }aaaaa |
  107. {8:16 }aaaaa |
  108. |
  109. ]])
  110. command([[set stc=%l\ ]])
  111. screen:expect_unchanged()
  112. command('set relativenumber')
  113. screen:expect([[
  114. {8: 4 }aaaaa |
  115. {8: 3 }aaaaa |
  116. {8: 2 }aaaaa |
  117. {8: 1 }aaaaa |
  118. {8:8 }^aaaaa |
  119. {8: 1 }aaaaa |
  120. {8: 2 }aaaaa |
  121. {8: 3 }aaaaa |
  122. {8: 4 }aaaaa |
  123. {8: 5 }aaaaa |
  124. {8: 6 }aaaaa |
  125. {8: 7 }aaaaa |
  126. {8: 8 }aaaaa |
  127. |
  128. ]])
  129. command('set stc=')
  130. screen:expect_unchanged()
  131. command([[set nonu stc=%l\ ]])
  132. screen:expect([[
  133. {8: 4 }aaaaa |
  134. {8: 3 }aaaaa |
  135. {8: 2 }aaaaa |
  136. {8: 1 }aaaaa |
  137. {8: 0 }^aaaaa |
  138. {8: 1 }aaaaa |
  139. {8: 2 }aaaaa |
  140. {8: 3 }aaaaa |
  141. {8: 4 }aaaaa |
  142. {8: 5 }aaaaa |
  143. {8: 6 }aaaaa |
  144. {8: 7 }aaaaa |
  145. {8: 8 }aaaaa |
  146. |
  147. ]])
  148. command('set nuw=1 stc=')
  149. screen:expect_unchanged()
  150. -- Correct alignment with items before and after number column
  151. command([[set nu stc=foo\ %l\ bar]])
  152. screen:expect([[
  153. {8:foo 4 bar}aaaaa |
  154. {8:foo 3 bar}aaaaa |
  155. {8:foo 2 bar}aaaaa |
  156. {8:foo 1 bar}aaaaa |
  157. {8:foo 8 bar}^aaaaa |
  158. {8:foo 1 bar}aaaaa |
  159. {8:foo 2 bar}aaaaa |
  160. {8:foo 3 bar}aaaaa |
  161. {8:foo 4 bar}aaaaa |
  162. {8:foo 5 bar}aaaaa |
  163. {8:foo 6 bar}aaaaa |
  164. {8:foo 7 bar}aaaaa |
  165. {8:foo 8 bar}aaaaa |
  166. |
  167. ]])
  168. end)
  169. it("works with highlighted 'statuscolumn'", function()
  170. command(
  171. [[set stc=%#NonText#%{&nu?v:lnum:''}]]
  172. .. [[%=%{&rnu&&(v:lnum%2)?'\ '.v:relnum:''}]]
  173. .. [[%#LineNr#%{&rnu&&!(v:lnum%2)?'\ '.v:relnum:''}│]]
  174. )
  175. screen:expect([[
  176. {1:4 }{8:│}aaaaa |
  177. {1:5 }{8:│}aaaaa |
  178. {1:6 }{8:│}aaaaa |
  179. {1:7 }{8:│}aaaaa |
  180. {1:8 }{8:│}^aaaaa |
  181. {1:9 }{8:│}aaaaa |
  182. {1:10}{8:│}aaaaa |
  183. {1:11}{8:│}aaaaa |
  184. {1:12}{8:│}aaaaa |
  185. {1:13}{8:│}aaaaa |
  186. {1:14}{8:│}aaaaa |
  187. {1:15}{8:│}aaaaa |
  188. {1:16}{8:│}aaaaa |
  189. |
  190. ]])
  191. command('set relativenumber')
  192. screen:expect([[
  193. {1:4 }{8: 4│}aaaaa |
  194. {1:5 3}{8:│}aaaaa |
  195. {1:6 }{8: 2│}aaaaa |
  196. {1:7 1}{8:│}aaaaa |
  197. {1:8 }{8: 0│}^aaaaa |
  198. {1:9 1}{8:│}aaaaa |
  199. {1:10 }{8: 2│}aaaaa |
  200. {1:11 3}{8:│}aaaaa |
  201. {1:12 }{8: 4│}aaaaa |
  202. {1:13 5}{8:│}aaaaa |
  203. {1:14 }{8: 6│}aaaaa |
  204. {1:15 7}{8:│}aaaaa |
  205. {1:16 }{8: 8│}aaaaa |
  206. |
  207. ]])
  208. command('set nonumber')
  209. screen:expect([[
  210. {1: }{8:4│}aaaaa |
  211. {1: 3}{8:│}aaaaa |
  212. {1: }{8:2│}aaaaa |
  213. {1: 1}{8:│}aaaaa |
  214. {1: }{8:0│}^aaaaa |
  215. {1: 1}{8:│}aaaaa |
  216. {1: }{8:2│}aaaaa |
  217. {1: 3}{8:│}aaaaa |
  218. {1: }{8:4│}aaaaa |
  219. {1: 5}{8:│}aaaaa |
  220. {1: }{8:6│}aaaaa |
  221. {1: 7}{8:│}aaaaa |
  222. {1: }{8:8│}aaaaa |
  223. |
  224. ]])
  225. end)
  226. it('works with wrapped lines, signs and folds', function()
  227. command([[set stc=%C%s%=%{v:virtnum?'':v:lnum}│\ ]])
  228. command("call setline(1,repeat([repeat('aaaaa',10)],16))")
  229. screen:add_extra_attr_ids {
  230. [100] = { foreground = Screen.colors.Red, background = Screen.colors.LightGray },
  231. [101] = {
  232. bold = true,
  233. background = Screen.colors.WebGray,
  234. foreground = Screen.colors.DarkBlue,
  235. },
  236. }
  237. command('hi! CursorLine guifg=Red guibg=NONE')
  238. screen:expect([[
  239. {8: 4│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  240. {8: │ }a |
  241. {8: 5│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  242. {8: │ }a |
  243. {8: 6│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  244. {8: │ }a |
  245. {8: 7│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  246. {8: │ }a |
  247. {8: 8│ }^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  248. {8: │ }a |
  249. {8: 9│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  250. {8: │ }a |
  251. {8:10│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{1:@@@}|
  252. |
  253. ]])
  254. command([[set stc=%C%s%=%l│\ ]])
  255. screen:expect_unchanged()
  256. command('set signcolumn=auto:2 foldcolumn=auto')
  257. command('sign define piet1 text=>> texthl=LineNr')
  258. command('sign define piet2 text=>! texthl=NonText')
  259. command('sign place 1 line=4 name=piet1 buffer=1')
  260. command('sign place 2 line=5 name=piet2 buffer=1')
  261. command('sign place 3 line=6 name=piet1 buffer=1')
  262. command('sign place 4 line=6 name=piet2 buffer=1')
  263. screen:expect([[
  264. {8:>>}{7: }{8: 4│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  265. {7: }{8: │ }aaaaa |
  266. {1:>!}{7: }{8: 5│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  267. {7: }{8: │ }aaaaa |
  268. {1:>!}{8:>> 6│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  269. {7: }{8: │ }aaaaa |
  270. {7: }{8: 7│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  271. {7: }{8: │ }aaaaa |
  272. {7: }{8: 8│ }^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  273. {7: }{8: │ }aaaaa |
  274. {7: }{8: 9│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  275. {7: }{8: │ }aaaaa |
  276. {7: }{8:10│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{1:@@@}|
  277. |
  278. ]])
  279. command('norm zf$')
  280. -- Check that alignment works properly with signs after %=
  281. command([[set stc=%C%=%{v:virtnum?'':v:lnum}│%s\ ]])
  282. screen:expect([[
  283. {7: }{8: 4│>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  284. {7: }{8: │}{7: }{8: }aaaaaa |
  285. {7: }{8: 5│}{1:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  286. {7: }{8: │}{7: }{8: }aaaaaa |
  287. {7: }{8: 6│}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  288. {7: }{8: │}{7: }{8: }aaaaaa |
  289. {7: }{8: 7│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  290. {7: }{8: │}{7: }{8: }aaaaaa |
  291. {7:+}{8: 8│}{7: }{8: }{13:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  292. {7: }{8: 9│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  293. {7: }{8: │}{7: }{8: }aaaaaa |
  294. {7: }{8:10│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  295. {7: }{8: │}{7: }{8: }aaaaaa |
  296. |
  297. ]])
  298. command('set cursorline')
  299. screen:expect([[
  300. {7: }{8: 4│>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  301. {7: }{8: │}{7: }{8: }aaaaaa |
  302. {7: }{8: 5│}{1:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  303. {7: }{8: │}{7: }{8: }aaaaaa |
  304. {7: }{8: 6│}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  305. {7: }{8: │}{7: }{8: }aaaaaa |
  306. {7: }{8: 7│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  307. {7: }{8: │}{7: }{8: }aaaaaa |
  308. {101:+}{15: 8│}{101: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  309. {7: }{8: 9│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  310. {7: }{8: │}{7: }{8: }aaaaaa |
  311. {7: }{8:10│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  312. {7: }{8: │}{7: }{8: }aaaaaa |
  313. |
  314. ]])
  315. -- v:lnum is the same value on wrapped lines
  316. command([[set stc=%C%=%{v:lnum}│%s\ ]])
  317. screen:expect([[
  318. {7: }{8: 4│>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  319. {7: }{8: 4│}{7: }{8: }aaaaaa |
  320. {7: }{8: 5│}{1:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  321. {7: }{8: 5│}{7: }{8: }aaaaaa |
  322. {7: }{8: 6│}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  323. {7: }{8: 6│}{7: }{8: }aaaaaa |
  324. {7: }{8: 7│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  325. {7: }{8: 7│}{7: }{8: }aaaaaa |
  326. {101:+}{15: 8│}{101: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  327. {7: }{8: 9│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  328. {7: }{8: 9│}{7: }{8: }aaaaaa |
  329. {7: }{8:10│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  330. {7: }{8:10│}{7: }{8: }aaaaaa |
  331. |
  332. ]])
  333. -- v:relnum is the same value on wrapped lines
  334. command([[set stc=%C%=\ %{v:relnum}│%s\ ]])
  335. screen:expect([[
  336. {7: }{8: 4│>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  337. {7: }{8: 4│}{7: }{8: }aaaaaaa |
  338. {7: }{8: 3│}{1:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  339. {7: }{8: 3│}{7: }{8: }aaaaaaa |
  340. {7: }{8: 2│}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  341. {7: }{8: 2│}{7: }{8: }aaaaaaa |
  342. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  343. {7: }{8: 1│}{7: }{8: }aaaaaaa |
  344. {101:+}{15: 0│}{101: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  345. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  346. {7: }{8: 1│}{7: }{8: }aaaaaaa |
  347. {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  348. {7: }{8: 2│}{7: }{8: }aaaaaaa |
  349. |
  350. ]])
  351. command([[set stc=%C%=\ %{v:virtnum?'':v:relnum}│%s\ ]])
  352. screen:expect([[
  353. {7: }{8: 4│>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  354. {7: }{8: │}{7: }{8: }aaaaaaa |
  355. {7: }{8: 3│}{1:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  356. {7: }{8: │}{7: }{8: }aaaaaaa |
  357. {7: }{8: 2│}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  358. {7: }{8: │}{7: }{8: }aaaaaaa |
  359. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  360. {7: }{8: │}{7: }{8: }aaaaaaa |
  361. {101:+}{15: 0│}{101: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  362. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  363. {7: }{8: │}{7: }{8: }aaaaaaa |
  364. {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  365. {7: }{8: │}{7: }{8: }aaaaaaa |
  366. |
  367. ]])
  368. -- Up to 9 signs in a line
  369. command('set signcolumn=auto:9 foldcolumn=auto')
  370. command('sign place 5 line=6 name=piet1 buffer=1')
  371. command('sign place 6 line=6 name=piet2 buffer=1')
  372. command('sign place 7 line=6 name=piet1 buffer=1')
  373. command('sign place 8 line=6 name=piet2 buffer=1')
  374. command('sign place 9 line=6 name=piet1 buffer=1')
  375. command('sign place 10 line=6 name=piet2 buffer=1')
  376. command('sign place 11 line=6 name=piet1 buffer=1')
  377. screen:expect([[
  378. {7: }{8: 4│>>}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  379. {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa |
  380. {7: }{8: 3│}{1:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  381. {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa |
  382. {7: }{8: 2│>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  383. {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa |
  384. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  385. {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa |
  386. {101:+}{15: 0│}{101: }{15: }{100:^+-- 1 line: aaaaaaaaaaaaaaaa}|
  387. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  388. {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa |
  389. {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  390. {7: }{8: │}{7: }{8: }aaaaaaaaaaaaaaaaaaaaa |
  391. |
  392. ]])
  393. -- Also test fold and sign column when 'cpoptions' includes "n"
  394. command('set cpoptions+=n')
  395. feed('Hgjg0')
  396. screen:expect([[
  397. {101: }{15: 0│>>}{101: }{15: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  398. {7: }{19:^aaaaaaaaaaaaaaaaaaaaa }|
  399. {7: }{8: 3│}{1:>!}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  400. {7: }aaaaaaaaaaaaaaaaaaaaa |
  401. {7: }{8: 2│>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  402. {7: }aaaaaaaaaaaaaaaaaaaaa |
  403. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  404. {7: }aaaaaaaaaaaaaaaaaaaaa |
  405. {7:+}{8: 4│}{7: }{8: }{13:+-- 1 line: aaaaaaaaaaaaaaaa}|
  406. {7: }{8: 1│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  407. {7: }aaaaaaaaaaaaaaaaaaaaa |
  408. {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  409. {7: }aaaaaaaaaaaaaaaaaaaaa |
  410. |
  411. ]])
  412. command('set breakindent')
  413. command('sign unplace 2')
  414. feed('J2gjg0')
  415. screen:expect([[
  416. {101: }{15: 0│>>}{101: }{15: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  417. {7: } {19:aaaaaaaaaaaaaaaaaaaaa aaaaaaa}|
  418. {7: } {19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  419. {7: } {19:^aaaaaaaaaaaaaa }|
  420. {7: }{8: 1│>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  421. {7: } aaaaaaaaaaaaaaaaaaaaa |
  422. {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  423. {7: } aaaaaaaaaaaaaaaaaaaaa |
  424. {7:+}{8: 3│}{7: }{8: }{13:+-- 1 line: aaaaaaaaaaaaaaaa}|
  425. {7: }{8: 4│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  426. {7: } aaaaaaaaaaaaaaaaaaaaa |
  427. {7: }{8: 5│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  428. {7: } aaaaaaaaaaaaaaaaaaaaa |
  429. |
  430. ]])
  431. command('set nobreakindent')
  432. feed('$g0')
  433. screen:expect([[
  434. {101: }{15: 0│>>}{101: }{15: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  435. {7: }{19:aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa}|
  436. {7: }{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  437. {7: }{19:^aaaa }|
  438. {7: }{8: 1│>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>>}{1:>!}{8:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  439. {7: }aaaaaaaaaaaaaaaaaaaaa |
  440. {7: }{8: 2│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  441. {7: }aaaaaaaaaaaaaaaaaaaaa |
  442. {7:+}{8: 3│}{7: }{8: }{13:+-- 1 line: aaaaaaaaaaaaaaaa}|
  443. {7: }{8: 4│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  444. {7: }aaaaaaaaaaaaaaaaaaaaa |
  445. {7: }{8: 5│}{7: }{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  446. {7: }aaaaaaaaaaaaaaaaaaaaa |
  447. |
  448. ]])
  449. command('silent undo')
  450. feed('8gg')
  451. command('set cpoptions-=n')
  452. -- Status column is re-evaluated for virt_lines, buffer line, and wrapped line
  453. exec_lua([[
  454. vim.api.nvim_buf_set_extmark(0, ns, 5, 0, {
  455. virt_lines_above = true, virt_lines = {{{"virt_line above", ""}}} })
  456. vim.api.nvim_buf_set_extmark(0, ns, 4, 0, { virt_lines = {{{"virt_line", ""}}} })
  457. ]])
  458. command('set foldcolumn=0 signcolumn=number stc=%l')
  459. screen:expect([[
  460. {8:>>}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  461. {8: 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  462. {8: }virt_line |
  463. {8: }virt_line above |
  464. {8:>>}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  465. {8: 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  466. {15: 8}{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  467. {8: 9}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  468. {8:10}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  469. {8:11}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  470. {8:12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  471. {8:13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  472. {8:14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
  473. |
  474. ]])
  475. command(
  476. [[set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum}]]
  477. )
  478. screen:expect([[
  479. {8:buffer 0 4}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  480. {8:wrapped 1 4}aaaaaaaa |
  481. {8:buffer 0 5}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  482. {8:wrapped 1 5}aaaaaaaa |
  483. {8:virtual-2 5}virt_line |
  484. {8:virtual-1 5}virt_line above |
  485. {8:buffer 0 6}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  486. {8:wrapped 1 6}aaaaaaaa |
  487. {8:buffer 0 7}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  488. {8:wrapped 1 7}aaaaaaaa |
  489. {15:buffer 0 8}{100:^+-- 1 line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  490. {8:buffer 0 9}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  491. {8:wrapped 1 9}aaaaaaaa |
  492. |
  493. ]])
  494. -- Also test virt_lines at the end of buffer
  495. exec_lua([[
  496. vim.api.nvim_buf_set_extmark(0, ns, 15, 0, { virt_lines = {{{"END", ""}}} })
  497. ]])
  498. feed('GkJzz')
  499. screen:expect([[
  500. {8:buffer 0 12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  501. {8:wrapped 1 12}aaaaaaaaa |
  502. {8:buffer 0 13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  503. {8:wrapped 1 13}aaaaaaaaa |
  504. {8:buffer 0 14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  505. {8:wrapped 1 14}aaaaaaaaa |
  506. {15:buffer 0 15}{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  507. {15:wrapped 1 15}{19:aaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  508. {15:wrapped 2 15}{19:aaaaaaaaaaaaaaaaaaa }|
  509. {8:virtual-1 15}END |
  510. {1:~ }|*3
  511. |
  512. ]])
  513. -- Also test virt_lines when 'cpoptions' includes "n"
  514. exec_lua([[
  515. vim.opt.cpoptions:append("n")
  516. vim.api.nvim_buf_set_extmark(0, ns, 14, 0, { virt_lines = {{{"virt_line1", ""}}} })
  517. vim.api.nvim_buf_set_extmark(0, ns, 14, 0, { virt_lines = {{{"virt_line2", ""}}} })
  518. ]])
  519. screen:expect([[
  520. {8:buffer 0 12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  521. aaaaaaaaa |
  522. {8:buffer 0 13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  523. aaaaaaaaa |
  524. {8:buffer 0 14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  525. aaaaaaaaa |
  526. {15:buffer 0 15}{19:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  527. {19:aaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
  528. {19:aaaaaaa }|
  529. {8:virtual-3 15}virt_line1 |
  530. {8:virtual-2 15}virt_line2 |
  531. {8:virtual-1 15}END |
  532. {1:~ }|
  533. |
  534. ]])
  535. -- Also test "col_rows" code path for 'relativenumber' cursor movement
  536. command([[
  537. set cpoptions-=n nocursorline relativenumber
  538. set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum.'\ '.v:relnum}
  539. ]])
  540. screen:expect([[
  541. {8:buffer 0 12 3}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  542. {8:wrapped 1 12 3}aaaaaaaaaaa |
  543. {8:buffer 0 13 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  544. {8:wrapped 1 13 2}aaaaaaaaaaa |
  545. {8:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  546. {8:wrapped 1 14 1}aaaaaaaaaaa |
  547. {8:buffer 0 15 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  548. {8:wrapped 1 15 0}aaaaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaa|
  549. {8:wrapped 2 15 0}aaaaaaaaaaaaaaaaaaaaaaa |
  550. {8:virtual-3 15 0}virt_line1 |
  551. {8:virtual-2 15 0}virt_line2 |
  552. {8:virtual-1 15 0}END |
  553. {1:~ }|
  554. |
  555. ]])
  556. feed('kk')
  557. screen:expect([[
  558. {8:buffer 0 12 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  559. {8:wrapped 1 12 1}aaaaaaaaaaa |
  560. {8:buffer 0 13 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  561. {8:wrapped 1 13 0}aaaaaaaaaa^a |
  562. {8:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  563. {8:wrapped 1 14 1}aaaaaaaaaaa |
  564. {8:buffer 0 15 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
  565. {8:wrapped 1 15 2}aaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaa|
  566. {8:wrapped 2 15 2}aaaaaaaaaaaaaaaaaaaaaaa |
  567. {8:virtual-3 15 2}virt_line1 |
  568. {8:virtual-2 15 2}virt_line2 |
  569. {8:virtual-1 15 2}END |
  570. {1:~ }|
  571. |
  572. ]])
  573. end)
  574. it('does not corrupt the screen with minwid sign item', function()
  575. screen:try_resize(screen._width, 3)
  576. command([[set stc=%6s\ %l]])
  577. exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 7, 0, {sign_text = "𒀀"})')
  578. screen:expect([[
  579. {8: 𒀀 8}^aaaaa |
  580. {8: }{7: }{8: 9}aaaaa |
  581. |
  582. ]])
  583. end)
  584. for _, model in ipairs(mousemodels) do
  585. describe('with mousemodel=' .. model, function()
  586. before_each(function()
  587. command('set mousemodel=' .. model)
  588. exec([[
  589. function! MyClickFunc(minwid, clicks, button, mods)
  590. let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line)
  591. if a:mods !=# ' '
  592. let g:testvar ..= '(' .. a:mods .. ')'
  593. endif
  594. endfunction
  595. let g:testvar = ''
  596. ]])
  597. end)
  598. it('clicks work with mousemodel=' .. model, function()
  599. api.nvim_set_option_value('statuscolumn', '%0@MyClickFunc@%=%l%T', {})
  600. api.nvim_input_mouse('left', 'press', '', 0, 0, 0)
  601. eq('0 1 l 4', eval('g:testvar'))
  602. api.nvim_input_mouse('left', 'press', '', 0, 0, 0)
  603. eq('0 2 l 4', eval('g:testvar'))
  604. api.nvim_input_mouse('left', 'press', '', 0, 0, 0)
  605. eq('0 3 l 4', eval('g:testvar'))
  606. api.nvim_input_mouse('left', 'press', '', 0, 0, 0)
  607. eq('0 4 l 4', eval('g:testvar'))
  608. api.nvim_input_mouse('right', 'press', '', 0, 3, 0)
  609. eq('0 1 r 7', eval('g:testvar'))
  610. api.nvim_input_mouse('right', 'press', '', 0, 3, 0)
  611. eq('0 2 r 7', eval('g:testvar'))
  612. api.nvim_input_mouse('right', 'press', '', 0, 3, 0)
  613. eq('0 3 r 7', eval('g:testvar'))
  614. api.nvim_input_mouse('right', 'press', '', 0, 3, 0)
  615. eq('0 4 r 7', eval('g:testvar'))
  616. command('rightbelow vsplit')
  617. api.nvim_input_mouse('left', 'press', '', 0, 0, 27)
  618. eq('0 1 l 4', eval('g:testvar'))
  619. api.nvim_input_mouse('right', 'press', '', 0, 3, 27)
  620. eq('0 1 r 7', eval('g:testvar'))
  621. command('setlocal rightleft')
  622. api.nvim_input_mouse('left', 'press', '', 0, 0, 52)
  623. eq('0 1 l 4', eval('g:testvar'))
  624. api.nvim_input_mouse('right', 'press', '', 0, 3, 52)
  625. eq('0 1 r 7', eval('g:testvar'))
  626. command('wincmd H')
  627. api.nvim_input_mouse('left', 'press', '', 0, 0, 25)
  628. eq('0 1 l 4', eval('g:testvar'))
  629. api.nvim_input_mouse('right', 'press', '', 0, 3, 25)
  630. eq('0 1 r 7', eval('g:testvar'))
  631. command('close')
  632. command('set laststatus=2 winbar=%f')
  633. command('let g:testvar = ""')
  634. -- Check that winbar click doesn't register as statuscolumn click
  635. api.nvim_input_mouse('right', 'press', '', 0, 0, 0)
  636. eq('', eval('g:testvar'))
  637. -- Check that statusline click doesn't register as statuscolumn click
  638. api.nvim_input_mouse('right', 'press', '', 0, 12, 0)
  639. eq('', eval('g:testvar'))
  640. end)
  641. it('clicks and highlights work with control characters', function()
  642. api.nvim_set_option_value('statuscolumn', '\t%#NonText#\1%0@MyClickFunc@\t\1%T\t%##\1', {})
  643. screen:expect {
  644. grid = [[
  645. {1:^I}{0:^A^I^A^I}{1:^A}aaaaa |*4
  646. {1:^I}{0:^A^I^A^I}{1:^A}^aaaaa |
  647. {1:^I}{0:^A^I^A^I}{1:^A}aaaaa |*8
  648. |
  649. ]],
  650. attr_ids = {
  651. [0] = { foreground = Screen.colors.Blue, bold = true }, -- NonText
  652. [1] = { foreground = Screen.colors.Brown }, -- LineNr
  653. },
  654. }
  655. api.nvim_input_mouse('right', 'press', '', 0, 4, 3)
  656. eq('', eval('g:testvar'))
  657. api.nvim_input_mouse('left', 'press', '', 0, 5, 8)
  658. eq('', eval('g:testvar'))
  659. api.nvim_input_mouse('right', 'press', '', 0, 6, 4)
  660. eq('0 1 r 10', eval('g:testvar'))
  661. api.nvim_input_mouse('left', 'press', '', 0, 7, 7)
  662. eq('0 1 l 11', eval('g:testvar'))
  663. end)
  664. it('popupmenu callback does not drag mouse on close', function()
  665. screen:try_resize(screen._width, 2)
  666. api.nvim_set_option_value('statuscolumn', '%0@MyClickFunc@%l%T', {})
  667. exec([[
  668. function! MyClickFunc(minwid, clicks, button, mods)
  669. let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line)
  670. menu PopupStc.Echo <cmd>echo g:testvar<CR>
  671. popup PopupStc
  672. endfunction
  673. ]])
  674. -- clicking an item does not drag mouse
  675. api.nvim_input_mouse('left', 'press', '', 0, 0, 0)
  676. screen:expect([[
  677. {8: 8}^aaaaa |
  678. {4: Echo } |
  679. ]])
  680. api.nvim_input_mouse('left', 'press', '', 0, 1, 5)
  681. api.nvim_input_mouse('left', 'release', '', 0, 1, 5)
  682. screen:expect([[
  683. {8: 8}^aaaaa |
  684. 0 1 l 8 |
  685. ]])
  686. command('echo')
  687. -- clicking outside to close the menu does not drag mouse
  688. api.nvim_input_mouse('left', 'press', '', 0, 0, 0)
  689. screen:expect([[
  690. {8: 8}^aaaaa |
  691. {4: Echo } |
  692. ]])
  693. api.nvim_input_mouse('left', 'press', '', 0, 0, 10)
  694. api.nvim_input_mouse('left', 'release', '', 0, 0, 10)
  695. screen:expect([[
  696. {8: 8}^aaaaa |
  697. |
  698. ]])
  699. end)
  700. end)
  701. end
  702. it('click labels do not leak memory #21878', function()
  703. exec([[
  704. set laststatus=2
  705. setlocal statuscolumn=%0@MyClickFunc@abcd%T
  706. 4vsplit
  707. setlocal statusline=abcd
  708. redrawstatus
  709. setlocal statusline=
  710. only
  711. redraw
  712. ]])
  713. end)
  714. it('click labels do not crash when initial width is 0 #24428', function()
  715. exec([[
  716. set nonumber
  717. bwipe!
  718. setlocal statuscolumn=abcd
  719. redraw
  720. setlocal statuscolumn=%0@MyClickFunc@abcd%T
  721. redraw
  722. ]])
  723. assert_alive()
  724. end)
  725. it('works with foldcolumn', function()
  726. -- Fits maximum multibyte foldcolumn #21759
  727. command([[set stc=%C%=%l\ fdc=9 fillchars=foldsep:𒀀]])
  728. for _ = 0, 8 do
  729. command('norm zfjzo')
  730. end
  731. -- 'statuscolumn' is not drawn for `virt_lines_leftcol` lines
  732. exec_lua([[
  733. vim.api.nvim_buf_set_extmark(0, ns, 6, 0, {
  734. virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} })
  735. vim.api.nvim_buf_set_extmark(0, ns, 7, 0, {
  736. virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} })
  737. ]])
  738. screen:expect([[
  739. {7: }{8: 4 }aaaaa |
  740. {7: }{8: 5 }aaaaa |
  741. {7: }{8: 6 }aaaaa |
  742. {7: }{8: 7 }aaaaa |
  743. virt |
  744. {7:---------}{8: 8 }^aaaaa |
  745. virt |
  746. {7:𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀𒀀}{8: 9 }aaaaa |
  747. {7: }{8:10 }aaaaa |
  748. {7: }{8:11 }aaaaa |
  749. {7: }{8:12 }aaaaa |
  750. {7: }{8:13 }aaaaa |
  751. {7: }{8:14 }aaaaa |
  752. |
  753. ]])
  754. command('set stc=') -- also for the default fold column
  755. screen:expect_unchanged()
  756. -- 'statuscolumn' is not too wide with custom (bogus) fold column
  757. command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]])
  758. feed('Gd10Ggg<C-l>')
  759. screen:expect([[
  760. {8: 1 }^aaaaa |
  761. {8: 2 }aaaaa |
  762. {8: 3 }aaaaa |
  763. {8: 4 }aaaaa |
  764. {8: 5 }aaaaa |
  765. {8: 6 }aaaaa |
  766. {8: 7 }aaaaa |
  767. virt |
  768. {8:---------8 }aaaaa |
  769. virt |
  770. {8:---------9 }aaaaa |
  771. {1:~ }|*2
  772. |
  773. ]])
  774. end)
  775. it('works with cmdwin', function()
  776. feed(':set stc=%l<CR>q:k$')
  777. screen:expect([[
  778. {8: 7}aaaaa |
  779. {8: 8}aaaaa |
  780. {8: 9}aaaaa |
  781. {8:10}aaaaa |
  782. {2:[No Name] [+] }|
  783. {1::}{8:1}set stc=%^l |
  784. {1::}{8:2} |
  785. {1:~ }|*5
  786. {3:[Command Line] }|
  787. : |
  788. ]])
  789. end)
  790. it("has correct width when toggling '(relative)number'", function()
  791. screen:try_resize(screen._width, 6)
  792. command('call setline(1, repeat(["aaaaa"], 100))')
  793. command('set relativenumber')
  794. command([[set stc=%{!&nu&&!&rnu?'':&rnu?v:relnum?v:relnum:&nu?v:lnum:'0':v:lnum}]])
  795. screen:expect([[
  796. {8:1 }aaaaa |
  797. {8:8 }^aaaaa |
  798. {8:1 }aaaaa |
  799. {8:2 }aaaaa |
  800. {8:3 }aaaaa |
  801. |
  802. ]])
  803. -- width correctly estimated with "w_nrwidth_line_count" when setting 'stc'
  804. command([[set stc=%{!&nu&&!&rnu?'':&rnu?v:relnum?v:relnum:&nu?v:lnum:'0':v:lnum}]])
  805. screen:expect_unchanged()
  806. -- zero width when disabling 'number'
  807. command('set norelativenumber nonumber')
  808. screen:expect([[
  809. aaaaa |
  810. ^aaaaa |
  811. aaaaa |*3
  812. |
  813. ]])
  814. -- width correctly estimated with "w_nrwidth_line_count" when setting 'nu'
  815. command('set number')
  816. screen:expect([[
  817. {8:7 }aaaaa |
  818. {8:8 }^aaaaa |
  819. {8:9 }aaaaa |
  820. {8:10 }aaaaa |
  821. {8:11 }aaaaa |
  822. |
  823. ]])
  824. end)
  825. it('has correct width with custom sign column when (un)placing signs', function()
  826. screen:try_resize(screen._width, 3)
  827. exec_lua([[
  828. vim.cmd.norm('gg')
  829. vim.o.signcolumn = 'no'
  830. vim.fn.sign_define('sign', { text = 'ss' })
  831. _G.StatusCol = function()
  832. local s = vim.fn.sign_getplaced(1)[1].signs
  833. local es = vim.api.nvim_buf_get_extmarks(0, ns, 0, -1, {type = "sign"})
  834. local sign = ''
  835. local signs = #s + #es
  836. if signs > 0 then
  837. sign = (vim.v.lnum == 2 and 'ss' or ' '):rep(signs)
  838. end
  839. return vim.v.lnum .. '%=' .. sign
  840. end
  841. vim.o.number = true
  842. vim.o.numberwidth = 2
  843. vim.o.statuscolumn = "%!v:lua.StatusCol()"
  844. ]])
  845. command('sign place 1 line=2 name=sign')
  846. screen:expect([[
  847. {8:1 }^aaaaa |
  848. {8:2 ss}aaaaa |
  849. |
  850. ]])
  851. command('sign place 2 line=2 name=sign')
  852. screen:expect([[
  853. {8:1 }^aaaaa |
  854. {8:2 ssss}aaaaa |
  855. |
  856. ]])
  857. command('sign unplace 2')
  858. screen:expect([[
  859. {8:1 }^aaaaa |
  860. {8:2 ss}aaaaa |
  861. |
  862. ]])
  863. command('sign unplace 1')
  864. screen:expect([[
  865. {8:1 }^aaaaa |
  866. {8:2 }aaaaa |
  867. |
  868. ]])
  869. -- Also for extmark signs
  870. exec_lua('id1 = vim.api.nvim_buf_set_extmark(0, ns, 1, 0, {sign_text = "ss"})')
  871. screen:expect([[
  872. {8:1 }^aaaaa |
  873. {8:2 ss}aaaaa |
  874. |
  875. ]])
  876. exec_lua('id2 = vim.api.nvim_buf_set_extmark(0, ns, 1, 0, {sign_text = "ss"})')
  877. screen:expect([[
  878. {8:1 }^aaaaa |
  879. {8:2 ssss}aaaaa |
  880. |
  881. ]])
  882. exec_lua('vim.api.nvim_buf_del_extmark(0, ns, id1)')
  883. screen:expect([[
  884. {8:1 }^aaaaa |
  885. {8:2 ss}aaaaa |
  886. |
  887. ]])
  888. exec_lua('vim.api.nvim_buf_del_extmark(0, ns, id2)')
  889. screen:expect([[
  890. {8:1 }^aaaaa |
  891. {8:2 }aaaaa |
  892. |
  893. ]])
  894. -- In all windows
  895. command('wincmd v | set ls=0')
  896. command('sign place 1 line=2 name=sign')
  897. screen:expect([[
  898. {8:1 }^aaaaa │{8:1 }aaaaa |
  899. {8:2 ss}aaaaa │{8:2 ss}aaaaa |
  900. |
  901. ]])
  902. end)
  903. it('is only evaluated twice, once to estimate and once to draw', function()
  904. command([[
  905. let g:stcnr = 0
  906. func! Stc()
  907. let g:stcnr += 1
  908. return '12345'
  909. endfunc
  910. set stc=%!Stc()
  911. norm ggdG
  912. ]])
  913. eq(2, eval('g:stcnr'))
  914. end)
  915. it('does not wrap multibyte characters at the end of a line', function()
  916. screen:try_resize(33, 4)
  917. screen:add_extra_attr_ids {
  918. [100] = { undercurl = true, special = Screen.colors.Red },
  919. }
  920. command([[set spell stc=%l\ ]])
  921. command('call setline(8, "This is a line that contains ᶏ multibyte character.")')
  922. screen:expect([[
  923. {8: 8 }^This is a line that contains {100:ᶏ}|
  924. {8: } {100:multibyte} character. |
  925. {8: 9 }{100:aaaaa} |
  926. |
  927. ]])
  928. end)
  929. it('line increase properly redraws buffer text with relativenumber #27709', function()
  930. screen:try_resize(33, 4)
  931. command([[set rnu nuw=3 stc=%{v:lnum}\ ]])
  932. command('call setline(1, range(1, 99))')
  933. feed('Gyyp')
  934. screen:expect([[
  935. {8:98 }98 |
  936. {8:99 }99 |
  937. {8:100 }^99 |
  938. |
  939. ]])
  940. end)
  941. it('forces a rebuild with nvim__redraw', function()
  942. screen:try_resize(40, 4)
  943. -- Current window
  944. command([[
  945. let g:insert = v:false
  946. set nonu stc=%{g:insert?'insert':''}
  947. vsplit
  948. au InsertEnter * let g:insert = v:true | call nvim__redraw(#{statuscolumn:1, win:0})
  949. au InsertLeave * let g:insert = v:false | call nvim__redraw(#{statuscolumn:1, win:0})
  950. ]])
  951. feed('i')
  952. screen:expect({
  953. grid = [[
  954. {8:insert}^aaaaa │aaaaa |
  955. {8:insert}aaaaa │aaaaa |
  956. {3:[No Name] [+] }{2:[No Name] [+] }|
  957. {5:-- INSERT --} |
  958. ]],
  959. })
  960. feed('<esc>')
  961. screen:expect({
  962. grid = [[
  963. ^aaaaa │aaaaa |
  964. aaaaa │aaaaa |
  965. {3:[No Name] [+] }{2:[No Name] [+] }|
  966. |
  967. ]],
  968. })
  969. -- All windows
  970. command([[
  971. au! InsertEnter * let g:insert = v:true | call nvim__redraw(#{statuscolumn:1})
  972. au! InsertLeave * let g:insert = v:false | call nvim__redraw(#{statuscolumn:1})
  973. ]])
  974. feed('i')
  975. screen:expect({
  976. grid = [[
  977. {8:insert}^aaaaa │{8:insert}aaaaa |
  978. {8:insert}aaaaa │{8:insert}aaaaa |
  979. {3:[No Name] [+] }{2:[No Name] [+] }|
  980. {5:-- INSERT --} |
  981. ]],
  982. })
  983. feed('<esc>')
  984. screen:expect({
  985. grid = [[
  986. ^aaaaa │aaaaa |
  987. aaaaa │aaaaa |
  988. {3:[No Name] [+] }{2:[No Name] [+] }|
  989. |
  990. ]],
  991. })
  992. end)
  993. end)