test_signs.vim 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077
  1. " Test for signs
  2. source check.vim
  3. CheckFeature signs
  4. source screendump.vim
  5. func Test_sign()
  6. new
  7. call setline(1, ['a', 'b', 'c', 'd'])
  8. " Define some signs.
  9. " We can specify icons even if not all versions of vim support icons as
  10. " icon is ignored when not supported. "(not supported)" is shown after
  11. " the icon name when listing signs.
  12. sign define Sign1 text=x
  13. call Sign_command_ignore_error('sign define Sign2 text=xy texthl=Title linehl=Error culhl=Search numhl=Number icon=../../pixmaps/stock_vim_find_help.png')
  14. " Test listing signs.
  15. let a=execute('sign list')
  16. call assert_match('^\nsign Sign1 text=x \nsign Sign2 ' .
  17. \ 'icon=../../pixmaps/stock_vim_find_help.png .*text=xy ' .
  18. \ 'linehl=Error texthl=Title culhl=Search numhl=Number$', a)
  19. let a=execute('sign list Sign1')
  20. call assert_equal("\nsign Sign1 text=x ", a)
  21. " Split the window to the bottom to verify sign jump will stay in the
  22. " current window if the buffer is displayed there.
  23. let bn = bufnr('%')
  24. let wn = winnr()
  25. exe 'sign place 41 line=3 name=Sign1 buffer=' . bn
  26. 1
  27. bot split
  28. exe 'sign jump 41 buffer=' . bufnr('%')
  29. call assert_equal('c', getline('.'))
  30. call assert_equal(3, winnr())
  31. call assert_equal(bn, bufnr('%'))
  32. call assert_notequal(wn, winnr())
  33. " Create a new buffer and check that ":sign jump" switches to the old buffer.
  34. 1
  35. new foo
  36. call assert_notequal(bn, bufnr('%'))
  37. exe 'sign jump 41 buffer=' . bn
  38. call assert_equal(bn, bufnr('%'))
  39. call assert_equal('c', getline('.'))
  40. " Redraw to make sure that screen redraw with sign gets exercised,
  41. " with and without 'rightleft'.
  42. if has('rightleft')
  43. set rightleft
  44. redraw
  45. set norightleft
  46. endif
  47. redraw
  48. " Check that we can't change sign.
  49. call assert_fails("sign place 40 name=Sign1 buffer=" . bufnr('%'), 'E885:')
  50. " Check placed signs
  51. let a=execute('sign place')
  52. call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
  53. \ " line=3 id=41 name=Sign1 priority=10\n", a)
  54. " Unplace the sign and try jumping to it again should fail.
  55. sign unplace 41
  56. 1
  57. call assert_fails("sign jump 41 buffer=" . bufnr('%'), 'E157:')
  58. call assert_equal('a', getline('.'))
  59. " Unplace sign on current line.
  60. exe 'sign place 42 line=4 name=Sign2 buffer=' . bufnr('%')
  61. 4
  62. sign unplace
  63. let a=execute('sign place')
  64. call assert_equal("\n--- Signs ---\n", a)
  65. " Try again to unplace sign on current line, it should fail this time.
  66. call assert_fails('sign unplace', 'E159:')
  67. " Unplace all signs.
  68. exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%')
  69. sign unplace *
  70. let a=execute('sign place')
  71. call assert_equal("\n--- Signs ---\n", a)
  72. " Place a sign without specifying the filename or buffer
  73. sign place 77 line=9 name=Sign2
  74. let a=execute('sign place')
  75. " Nvim: sign line clamped to buffer length
  76. call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
  77. \ " line=4 id=77 name=Sign2 priority=10\n", a)
  78. sign unplace *
  79. " Check :jump with file=...
  80. edit foo
  81. call setline(1, ['A', 'B', 'C', 'D'])
  82. call Sign_command_ignore_error('sign define Sign3 text=y texthl=DoesNotExist linehl=DoesNotExist icon=doesnotexist.xpm')
  83. let fn = expand('%:p')
  84. exe 'sign place 43 line=2 name=Sign3 file=' . fn
  85. edit bar
  86. call assert_notequal(fn, expand('%:p'))
  87. exe 'sign jump 43 file=' . fn
  88. call assert_equal('B', getline('.'))
  89. " Check for jumping to a sign in a hidden buffer
  90. enew! | only!
  91. edit foo
  92. call setline(1, ['A', 'B', 'C', 'D'])
  93. let fn = expand('%:p')
  94. exe 'sign place 21 line=3 name=Sign3 file=' . fn
  95. hide edit bar
  96. exe 'sign jump 21 file=' . fn
  97. call assert_equal('C', getline('.'))
  98. " can't define a sign with a non-printable character as text
  99. call assert_fails("sign define Sign4 text=\e linehl=Comment", 'E239:')
  100. call assert_fails("sign define Sign4 text=a\e linehl=Comment", 'E239:')
  101. call assert_fails("sign define Sign4 text=\ea linehl=Comment", 'E239:')
  102. " Only 0, 1 or 2 character text is allowed
  103. call assert_fails("sign define Sign4 text=abc linehl=Comment", 'E239:')
  104. " call assert_fails("sign define Sign4 text= linehl=Comment", 'E239:')
  105. call assert_fails("sign define Sign4 text=\\ ab linehl=Comment", 'E239:')
  106. " an empty highlight argument for an existing sign clears it
  107. sign define SignY texthl=TextHl culhl=CulHl linehl=LineHl numhl=NumHl
  108. let sl = sign_getdefined('SignY')[0]
  109. call assert_equal('TextHl', sl.texthl)
  110. call assert_equal('CulHl', sl.culhl)
  111. call assert_equal('LineHl', sl.linehl)
  112. call assert_equal('NumHl', sl.numhl)
  113. sign define SignY texthl= culhl=CulHl linehl=LineHl numhl=NumHl
  114. let sl = sign_getdefined('SignY')[0]
  115. call assert_false(has_key(sl, 'texthl'))
  116. call assert_equal('CulHl', sl.culhl)
  117. call assert_equal('LineHl', sl.linehl)
  118. call assert_equal('NumHl', sl.numhl)
  119. sign define SignY linehl=
  120. let sl = sign_getdefined('SignY')[0]
  121. call assert_false(has_key(sl, 'linehl'))
  122. call assert_equal('CulHl', sl.culhl)
  123. call assert_equal('NumHl', sl.numhl)
  124. sign define SignY culhl=
  125. let sl = sign_getdefined('SignY')[0]
  126. call assert_false(has_key(sl, 'culhl'))
  127. call assert_equal('NumHl', sl.numhl)
  128. sign define SignY numhl=
  129. let sl = sign_getdefined('SignY')[0]
  130. call assert_false(has_key(sl, 'numhl'))
  131. sign undefine SignY
  132. " define sign with whitespace
  133. sign define Sign4 text=\ X linehl=Comment
  134. sign undefine Sign4
  135. sign define Sign4 linehl=Comment text=\ X
  136. sign undefine Sign4
  137. sign define Sign5 text=X\ linehl=Comment
  138. sign undefine Sign5
  139. sign define Sign5 linehl=Comment text=X\
  140. sign undefine Sign5
  141. " define sign with backslash
  142. sign define Sign4 text=\\\\ linehl=Comment
  143. sign undefine Sign4
  144. sign define Sign4 text=\\ linehl=Comment
  145. sign undefine Sign4
  146. " define a sign with a leading 0 in the name
  147. sign unplace *
  148. sign define 004 text=#> linehl=Comment
  149. let a = execute('sign list 4')
  150. call assert_equal("\nsign 4 text=#> linehl=Comment", a)
  151. exe 'sign place 20 line=3 name=004 buffer=' . bufnr('')
  152. let a = execute('sign place')
  153. call assert_equal("\n--- Signs ---\nSigns for foo:\n" .
  154. \ " line=3 id=20 name=4 priority=10\n", a)
  155. exe 'sign unplace 20 buffer=' . bufnr('')
  156. sign undefine 004
  157. call assert_fails('sign list 4', 'E155:')
  158. " After undefining the sign, we should no longer be able to place it.
  159. sign undefine Sign1
  160. sign undefine Sign2
  161. sign undefine Sign3
  162. call assert_fails("sign place 41 line=3 name=Sign1 buffer=" .
  163. \ bufnr('%'), 'E155:')
  164. " Defining a sign without attributes is allowed.
  165. sign define Sign1
  166. call assert_equal([{'name': 'Sign1'}], sign_getdefined())
  167. sign undefine Sign1
  168. endfunc
  169. func Test_sign_many_bytes()
  170. new
  171. set signcolumn=number
  172. set number
  173. call setline(1, 'some text')
  174. " composing characters can use many bytes, check for overflow
  175. sign define manyBytes text=▶᷄᷅᷆◀᷄᷅᷆᷇
  176. sign place 17 line=1 name=manyBytes
  177. redraw
  178. bwipe!
  179. sign undefine manyBytes
  180. endfunc
  181. " Undefining placed sign is not recommended.
  182. " Quoting :help sign
  183. "
  184. " :sign undefine {name}
  185. " Deletes a previously defined sign. If signs with this {name}
  186. " are still placed this will cause trouble.
  187. func Test_sign_undefine_still_placed()
  188. new foobar
  189. sign define Sign text=x
  190. exe 'sign place 41 line=1 name=Sign buffer=' . bufnr('%')
  191. sign undefine Sign
  192. " Listing placed sign should show that sign is deleted.
  193. let a=execute('sign place')
  194. call assert_equal("\n--- Signs ---\nSigns for foobar:\n" .
  195. \ " line=1 id=41 name=[Deleted] priority=10\n", a)
  196. sign unplace 41
  197. let a=execute('sign place')
  198. call assert_equal("\n--- Signs ---\n", a)
  199. endfunc
  200. func Test_sign_completion()
  201. sign define Sign1 text=x
  202. sign define Sign2 text=y
  203. call feedkeys(":sign \<C-A>\<C-B>\"\<CR>", 'tx')
  204. call assert_equal('"sign define jump list place undefine unplace', @:)
  205. call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
  206. call assert_equal('"sign define Sign culhl= icon= linehl= numhl= priority= text= texthl=', @:)
  207. for hl in ['culhl', 'linehl', 'numhl', 'texthl']
  208. call feedkeys(":sign define Sign "..hl.."=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
  209. call assert_equal('"sign define Sign '..hl..'=SpellBad SpellCap ' .
  210. \ 'SpellLocal SpellRare', @:)
  211. endfor
  212. call writefile(repeat(["Sun is shining"], 30), "XsignOne", 'D')
  213. call writefile(repeat(["Sky is blue"], 30), "XsignTwo", 'D')
  214. call feedkeys(":sign define Sign icon=Xsig\<C-A>\<C-B>\"\<CR>", 'tx')
  215. call assert_equal('"sign define Sign icon=XsignOne XsignTwo', @:)
  216. " Test for completion of arguments to ':sign undefine'
  217. call feedkeys(":sign undefine \<C-A>\<C-B>\"\<CR>", 'tx')
  218. call assert_equal('"sign undefine Sign1 Sign2', @:)
  219. call feedkeys(":sign place 1 \<C-A>\<C-B>\"\<CR>", 'tx')
  220. call assert_equal('"sign place 1 buffer= file= group= line= name= priority=',
  221. \ @:)
  222. call feedkeys(":sign place 1 name=\<C-A>\<C-B>\"\<CR>", 'tx')
  223. call assert_equal('"sign place 1 name=Sign1 Sign2', @:)
  224. edit XsignOne
  225. sign place 1 name=Sign1 line=5
  226. sign place 1 name=Sign1 group=g1 line=10
  227. edit XsignTwo
  228. sign place 1 name=Sign2 group=g2 line=15
  229. " Test for completion of group= and file= arguments to ':sign place'
  230. call feedkeys(":sign place 1 name=Sign1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
  231. call assert_equal('"sign place 1 name=Sign1 file=XsignOne XsignTwo', @:)
  232. call feedkeys(":sign place 1 name=Sign1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
  233. call assert_equal('"sign place 1 name=Sign1 group=g1 g2', @:)
  234. " Test for completion of arguments to 'sign place' without sign identifier
  235. call feedkeys(":sign place \<C-A>\<C-B>\"\<CR>", 'tx')
  236. call assert_equal('"sign place buffer= file= group=', @:)
  237. call feedkeys(":sign place file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
  238. call assert_equal('"sign place file=XsignOne XsignTwo', @:)
  239. call feedkeys(":sign place group=\<C-A>\<C-B>\"\<CR>", 'tx')
  240. call assert_equal('"sign place group=g1 g2', @:)
  241. call feedkeys(":sign place group=g1 file=\<C-A>\<C-B>\"\<CR>", 'tx')
  242. call assert_equal('"sign place group=g1 file=XsignOne XsignTwo', @:)
  243. " Test for completion of arguments to ':sign unplace'
  244. call feedkeys(":sign unplace 1 \<C-A>\<C-B>\"\<CR>", 'tx')
  245. call assert_equal('"sign unplace 1 buffer= file= group=', @:)
  246. call feedkeys(":sign unplace 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
  247. call assert_equal('"sign unplace 1 file=XsignOne XsignTwo', @:)
  248. call feedkeys(":sign unplace 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
  249. call assert_equal('"sign unplace 1 group=g1 g2', @:)
  250. call feedkeys(":sign unplace 1 group=g2 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
  251. call assert_equal('"sign unplace 1 group=g2 file=XsignOne XsignTwo', @:)
  252. " Test for completion of arguments to ':sign list'
  253. call feedkeys(":sign list \<C-A>\<C-B>\"\<CR>", 'tx')
  254. call assert_equal('"sign list Sign1 Sign2', @:)
  255. " Test for completion of arguments to ':sign jump'
  256. call feedkeys(":sign jump 1 \<C-A>\<C-B>\"\<CR>", 'tx')
  257. call assert_equal('"sign jump 1 buffer= file= group=', @:)
  258. call feedkeys(":sign jump 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
  259. call assert_equal('"sign jump 1 file=XsignOne XsignTwo', @:)
  260. call feedkeys(":sign jump 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
  261. call assert_equal('"sign jump 1 group=g1 g2', @:)
  262. " Error cases
  263. call feedkeys(":sign here\<C-A>\<C-B>\"\<CR>", 'tx')
  264. call assert_equal('"sign here', @:)
  265. call feedkeys(":sign define Sign here=\<C-A>\<C-B>\"\<CR>", 'tx')
  266. call assert_equal("\"sign define Sign here=\<C-A>", @:)
  267. call feedkeys(":sign place 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
  268. call assert_equal("\"sign place 1 here=\<C-A>", @:)
  269. call feedkeys(":sign jump 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
  270. call assert_equal("\"sign jump 1 here=\<C-A>", @:)
  271. call feedkeys(":sign here there\<C-A>\<C-B>\"\<CR>", 'tx')
  272. call assert_equal("\"sign here there\<C-A>", @:)
  273. call feedkeys(":sign here there=\<C-A>\<C-B>\"\<CR>", 'tx')
  274. call assert_equal("\"sign here there=\<C-A>", @:)
  275. sign unplace * group=*
  276. sign undefine Sign1
  277. sign undefine Sign2
  278. enew
  279. endfunc
  280. func Test_sign_invalid_commands()
  281. sign define Sign1 text=x
  282. call assert_fails('sign', 'E471:')
  283. call assert_fails('sign jump', 'E471:')
  284. call assert_fails('sign xxx', 'E160:')
  285. call assert_fails('sign define', 'E156:')
  286. call assert_fails('sign define Sign1 xxx', 'E475:')
  287. call assert_fails('sign undefine', 'E156:')
  288. call assert_fails('sign list xxx', 'E155:')
  289. call assert_fails('sign place 1 buffer=999', 'E158:')
  290. call assert_fails('sign place 1 name=Sign1 buffer=999', 'E158:')
  291. call assert_fails('sign place buffer=999', 'E158:')
  292. call assert_fails('sign jump buffer=999', 'E158:')
  293. call assert_fails('sign jump 1 file=', 'E158:')
  294. call assert_fails('sign jump 1 group=', 'E474:')
  295. call assert_fails('sign jump 1 name=', 'E474:')
  296. call assert_fails('sign jump 1 name=Sign1', 'E474:')
  297. call assert_fails('sign jump 1 line=100', '474:')
  298. " call assert_fails('sign define Sign2 text=', 'E239:')
  299. " Non-numeric identifier for :sign place
  300. call assert_fails("sign place abc line=3 name=Sign1 buffer=" . bufnr(''),
  301. \ 'E474:')
  302. " Non-numeric identifier for :sign unplace
  303. call assert_fails("sign unplace abc name=Sign1 buffer=" . bufnr(''),
  304. \ 'E474:')
  305. " Number followed by an alphabet as sign identifier for :sign place
  306. call assert_fails("sign place 1abc line=3 name=Sign1 buffer=" . bufnr(''),
  307. \ 'E474:')
  308. " Number followed by an alphabet as sign identifier for :sign unplace
  309. call assert_fails("sign unplace 2abc name=Sign1 buffer=" . bufnr(''),
  310. \ 'E474:')
  311. " Sign identifier and '*' for :sign unplace
  312. call assert_fails("sign unplace 2 *", 'E474:')
  313. " Trailing characters after buffer number for :sign place
  314. call assert_fails("sign place 1 line=3 name=Sign1 buffer=" .
  315. \ bufnr('%') . 'xxx', 'E488:')
  316. " Trailing characters after buffer number for :sign unplace
  317. call assert_fails("sign unplace 1 buffer=" . bufnr('%') . 'xxx', 'E488:')
  318. call assert_fails("sign unplace * buffer=" . bufnr('%') . 'xxx', 'E488:')
  319. call assert_fails("sign unplace 1 xxx", 'E474:')
  320. call assert_fails("sign unplace * xxx", 'E474:')
  321. call assert_fails("sign unplace xxx", 'E474:')
  322. " Placing a sign without line number
  323. call assert_fails("sign place name=Sign1 buffer=" . bufnr('%'), 'E474:')
  324. " Placing a sign without sign name
  325. call assert_fails("sign place line=10 buffer=" . bufnr('%'), 'E474:')
  326. " Unplacing a sign with line number
  327. call assert_fails("sign unplace 2 line=10 buffer=" . bufnr('%'), 'E474:')
  328. " Unplacing a sign with sign name
  329. call assert_fails("sign unplace 2 name=Sign1 buffer=" . bufnr('%'), 'E474:')
  330. " Placing a sign without sign name
  331. call assert_fails("sign place 2 line=3 buffer=" . bufnr('%'), 'E474:')
  332. " Placing a sign with only sign identifier
  333. call assert_fails("sign place 2", 'E474:')
  334. " Placing a sign with only a name
  335. call assert_fails("sign place abc", 'E474:')
  336. " Placing a sign with only line number
  337. call assert_fails("sign place 5 line=3", 'E474:')
  338. " Placing a sign with only sign group
  339. call assert_fails("sign place 5 group=g1", 'E474:')
  340. call assert_fails("sign place 5 group=*", 'E474:')
  341. " Placing a sign with only sign priority
  342. call assert_fails("sign place 5 priority=10", 'E474:')
  343. sign undefine Sign1
  344. endfunc
  345. func Test_sign_delete_buffer()
  346. new
  347. sign define Sign text=x
  348. let bufnr = bufnr('%')
  349. new
  350. exe 'bd ' . bufnr
  351. exe 'sign place 61 line=3 name=Sign buffer=' . bufnr
  352. call assert_fails('sign jump 61 buffer=' . bufnr, 'E934:')
  353. sign unplace 61
  354. sign undefine Sign
  355. endfunc
  356. " Ignore error: E255: Couldn't read in sign data!
  357. " This error can happen when running in the GUI.
  358. " Some gui like Motif do not support the png icon format.
  359. func Sign_command_ignore_error(cmd)
  360. try
  361. exe a:cmd
  362. catch /E255:/
  363. endtry
  364. endfunc
  365. " ignore error: E255: Couldn't read in sign data!
  366. " This error can happen when running in gui.
  367. func Sign_define_ignore_error(name, attr)
  368. try
  369. call sign_define(a:name, a:attr)
  370. catch /E255:/
  371. endtry
  372. endfunc
  373. " Test for Vim script functions for managing signs
  374. func Test_sign_funcs()
  375. " Remove all the signs
  376. call sign_unplace('*')
  377. call sign_undefine()
  378. " Tests for sign_define()
  379. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error',
  380. \ 'culhl': 'Visual', 'numhl': 'Number'}
  381. call assert_equal(0, "sign1"->sign_define(attr))
  382. call assert_equal([{'name' : 'sign1', 'texthl' : 'Error', 'linehl' : 'Search',
  383. \ 'culhl' : 'Visual', 'numhl': 'Number', 'text' : '=>'}],
  384. \ sign_getdefined())
  385. " Define a new sign without attributes and then update it
  386. call sign_define("sign2")
  387. let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange',
  388. \ 'culhl': 'DiffDelete', 'numhl': 'Number', 'icon' : 'sign2.ico'}
  389. call Sign_define_ignore_error("sign2", attr)
  390. call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange',
  391. \ 'linehl' : 'DiffAdd', 'culhl' : 'DiffDelete', 'text' : '!!',
  392. \ 'numhl': 'Number', 'icon' : 'sign2.ico'}],
  393. \ "sign2"->sign_getdefined())
  394. " Test for a sign name with digits
  395. call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'}))
  396. call assert_equal([{'name' : '2', 'linehl' : 'StatusLine'}],
  397. \ sign_getdefined(0002))
  398. eval 0002->sign_undefine()
  399. " Tests for invalid arguments to sign_define()
  400. call assert_fails('call sign_define("sign4", {"text" : "===>"})', 'E239:')
  401. " call assert_fails('call sign_define("sign5", {"text" : ""})', 'E239:')
  402. call assert_fails('call sign_define({})', 'E731:')
  403. call assert_fails('call sign_define("sign6", [])', 'E1206:')
  404. " Tests for sign_getdefined()
  405. call assert_equal([], sign_getdefined("none"))
  406. call assert_fails('call sign_getdefined({})', 'E731:')
  407. " Tests for sign_place()
  408. call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
  409. edit Xsign
  410. call assert_equal(10, sign_place(10, '', 'sign1', 'Xsign',
  411. \ {'lnum' : 20}))
  412. call assert_equal([{'bufnr' : bufnr(''), 'signs' :
  413. \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
  414. \ 'priority' : 10}]}], sign_getplaced('Xsign'))
  415. call assert_equal([{'bufnr' : bufnr(''), 'signs' :
  416. \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
  417. \ 'priority' : 10}]}],
  418. \ '%'->sign_getplaced({'lnum' : 20}))
  419. call assert_equal([{'bufnr' : bufnr(''), 'signs' :
  420. \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
  421. \ 'priority' : 10}]}],
  422. \ sign_getplaced('', {'id' : 10}))
  423. " Tests for invalid arguments to sign_place()
  424. call assert_fails('call sign_place([], "", "mySign", 1)', 'E745:')
  425. call assert_fails('call sign_place(5, "", "mySign", -1)', 'E158:')
  426. call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])', 'E1206:')
  427. call assert_fails('call sign_place(-1, "", "sign1", "Xsign",
  428. \ {"lnum" : 30})', 'E474:')
  429. call assert_fails('call sign_place(10, "", "xsign1x", "Xsign",
  430. \ {"lnum" : 30})', 'E155:')
  431. call assert_fails('call sign_place(10, "", "", "Xsign",
  432. \ {"lnum" : 30})', 'E155:')
  433. call assert_fails('call sign_place(10, "", [], "Xsign",
  434. \ {"lnum" : 30})', 'E730:')
  435. call assert_fails('call sign_place(5, "", "sign1", "abcxyz.xxx",
  436. \ {"lnum" : 10})', 'E158:')
  437. call assert_fails('call sign_place(5, "", "sign1", "@", {"lnum" : 10})',
  438. \ 'E158:')
  439. call assert_fails('call sign_place(5, "", "sign1", [], {"lnum" : 10})',
  440. \ 'E730:')
  441. call assert_fails('call sign_place(21, "", "sign1", "Xsign",
  442. \ {"lnum" : -1})', 'E474:')
  443. call assert_fails('call sign_place(22, "", "sign1", "Xsign",
  444. \ {"lnum" : 0})', 'E474:')
  445. call assert_fails('call sign_place(22, "", "sign1", "Xsign",
  446. \ {"lnum" : []})', 'E745:')
  447. call assert_equal(-1, sign_place(1, "*", "sign1", "Xsign", {"lnum" : 10}))
  448. " Tests for sign_getplaced()
  449. call assert_equal([{'bufnr' : bufnr(''), 'signs' :
  450. \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
  451. \ 'priority' : 10}]}],
  452. \ sign_getplaced(bufnr('Xsign')))
  453. call assert_equal([{'bufnr' : bufnr(''), 'signs' :
  454. \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
  455. \ 'priority' : 10}]}],
  456. \ sign_getplaced())
  457. call assert_fails("call sign_getplaced('dummy.sign')", 'E158:')
  458. call assert_fails('call sign_getplaced("&")', 'E158:')
  459. call assert_fails('call sign_getplaced(-1)', 'E158:')
  460. call assert_fails('call sign_getplaced("Xsign", [])', 'E1206:')
  461. call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}],
  462. \ sign_getplaced('Xsign', {'lnum' : 1000000}))
  463. call assert_fails("call sign_getplaced('Xsign', {'lnum' : []})",
  464. \ 'E745:')
  465. call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}],
  466. \ sign_getplaced('Xsign', {'id' : 44}))
  467. call assert_fails("call sign_getplaced('Xsign', {'id' : []})",
  468. \ 'E745:')
  469. " Tests for sign_unplace()
  470. eval 20->sign_place('', 'sign2', 'Xsign', {"lnum" : 30})
  471. call assert_equal(0, sign_unplace('',
  472. \ {'id' : 20, 'buffer' : 'Xsign'}))
  473. call assert_equal(-1, ''->sign_unplace(
  474. \ {'id' : 30, 'buffer' : 'Xsign'}))
  475. call sign_place(20, '', 'sign2', 'Xsign', {"lnum" : 30})
  476. call assert_fails("call sign_unplace('',
  477. \ {'id' : 20, 'buffer' : 'buffer.c'})", 'E158:')
  478. call assert_fails("call sign_unplace('',
  479. \ {'id' : 20, 'buffer' : '&'})", 'E158:')
  480. call assert_fails("call sign_unplace('g1',
  481. \ {'id' : 20, 'buffer' : 200})", 'E158:')
  482. call assert_fails("call sign_unplace('g1', 'mySign')", 'E1206:')
  483. call sign_unplace('*')
  484. " Test for modifying a placed sign
  485. call assert_equal(15, sign_place(15, '', 'sign1', 'Xsign', {'lnum' : 20}))
  486. call assert_equal(15, sign_place(15, '', 'sign2', 'Xsign'))
  487. call assert_equal([{'bufnr' : bufnr(''), 'signs' :
  488. \ [{'id' : 15, 'group' : '', 'lnum' : 20, 'name' : 'sign2',
  489. \ 'priority' : 10}]}],
  490. \ sign_getplaced())
  491. " Tests for sign_undefine()
  492. call assert_equal(0, sign_undefine("sign1"))
  493. call assert_equal([], sign_getdefined("sign1"))
  494. call assert_fails('call sign_undefine("none")', 'E155:')
  495. call assert_fails('call sign_undefine({})', 'E731:')
  496. " Test for using '.' as the line number for sign_place()
  497. call Sign_define_ignore_error("sign1", attr)
  498. call cursor(22, 1)
  499. call assert_equal(15, sign_place(15, '', 'sign1', 'Xsign',
  500. \ {'lnum' : '.'}))
  501. call assert_equal([{'bufnr' : bufnr(''), 'signs' :
  502. \ [{'id' : 15, 'group' : '', 'lnum' : 22, 'name' : 'sign1',
  503. \ 'priority' : 10}]}],
  504. \ sign_getplaced('%', {'lnum' : 22}))
  505. call sign_unplace('*')
  506. call sign_undefine()
  507. enew | only
  508. endfunc
  509. " Tests for sign groups
  510. func Test_sign_group()
  511. enew | only
  512. " Remove all the signs
  513. call sign_unplace('*')
  514. call sign_undefine()
  515. call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
  516. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
  517. call assert_equal(0, sign_define("sign1", attr))
  518. edit Xsign
  519. let bnum = bufnr('%')
  520. " Error case
  521. call assert_fails("call sign_place(5, [], 'sign1', 'Xsign',
  522. \ {'lnum' : 30})", 'E730:')
  523. " place three signs with the same identifier. One in the global group and
  524. " others in the named groups
  525. call assert_equal(5, sign_place(5, '', 'sign1', 'Xsign',
  526. \ {'lnum' : 10}))
  527. call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 20}))
  528. call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 30}))
  529. " Test for sign_getplaced() with group
  530. let s = sign_getplaced('Xsign')
  531. call assert_equal(1, len(s[0].signs))
  532. call assert_equal(s[0].signs[0].group, '')
  533. let s = sign_getplaced(bnum, {'group' : ''})
  534. call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
  535. \ 'priority' : 10}], s[0].signs)
  536. call assert_equal(1, len(s[0].signs))
  537. let s = sign_getplaced(bnum, {'group' : 'g2'})
  538. call assert_equal('g2', s[0].signs[0].group)
  539. let s = sign_getplaced(bnum, {'group' : 'g3'})
  540. call assert_equal([], s[0].signs)
  541. let s = sign_getplaced(bnum, {'group' : '*'})
  542. call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
  543. \ 'priority' : 10},
  544. \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20,
  545. \ 'priority' : 10},
  546. \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30,
  547. \ 'priority' : 10}],
  548. \ s[0].signs)
  549. " Test for sign_getplaced() with id
  550. let s = sign_getplaced(bnum, {'id' : 5})
  551. call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
  552. \ 'priority' : 10}],
  553. \ s[0].signs)
  554. let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g2'})
  555. call assert_equal(
  556. \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
  557. \ 'priority' : 10}],
  558. \ s[0].signs)
  559. let s = sign_getplaced(bnum, {'id' : 5, 'group' : '*'})
  560. call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
  561. \ 'priority' : 10},
  562. \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20,
  563. \ 'priority' : 10},
  564. \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30,
  565. \ 'priority' : 10}],
  566. \ s[0].signs)
  567. let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g3'})
  568. call assert_equal([], s[0].signs)
  569. " Test for sign_getplaced() with lnum
  570. let s = sign_getplaced(bnum, {'lnum' : 20})
  571. call assert_equal([], s[0].signs)
  572. let s = sign_getplaced(bnum, {'lnum' : 20, 'group' : 'g1'})
  573. call assert_equal(
  574. \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1',
  575. \ 'priority' : 10}],
  576. \ s[0].signs)
  577. let s = sign_getplaced(bnum, {'lnum' : 30, 'group' : '*'})
  578. call assert_equal(
  579. \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
  580. \ 'priority' : 10}],
  581. \ s[0].signs)
  582. let s = sign_getplaced(bnum, {'lnum' : 40, 'group' : '*'})
  583. call assert_equal([], s[0].signs)
  584. " Error case
  585. call assert_fails("call sign_getplaced(bnum, {'group' : []})",
  586. \ 'E730:')
  587. " Clear the sign in global group
  588. call sign_unplace('', {'id' : 5, 'buffer' : bnum})
  589. let s = sign_getplaced(bnum, {'group' : '*'})
  590. call assert_equal([
  591. \ {'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1',
  592. \ 'priority' : 10},
  593. \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
  594. \ 'priority' : 10}],
  595. \ s[0].signs)
  596. " Clear the sign in one of the groups
  597. call sign_unplace('g1', {'buffer' : 'Xsign'})
  598. let s = sign_getplaced(bnum, {'group' : '*'})
  599. call assert_equal([
  600. \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
  601. \ 'priority' : 10}],
  602. \ s[0].signs)
  603. " Clear all the signs from the buffer
  604. call sign_unplace('*', {'buffer' : bnum})
  605. call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs)
  606. " Clear sign across groups using an identifier
  607. call sign_place(25, '', 'sign1', bnum, {'lnum' : 10})
  608. call sign_place(25, 'g1', 'sign1', bnum, {'lnum' : 11})
  609. call sign_place(25, 'g2', 'sign1', bnum, {'lnum' : 12})
  610. call assert_equal(0, sign_unplace('*', {'id' : 25}))
  611. call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs)
  612. " Error case
  613. call assert_fails("call sign_unplace({})", 'E1174:')
  614. " Place a sign in the global group and try to delete it using a group
  615. call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10}))
  616. call assert_equal(-1, sign_unplace('g1', {'id' : 5}))
  617. " Place signs in multiple groups and delete all the signs in one of the
  618. " group
  619. call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10}))
  620. call assert_equal(6, sign_place(6, '', 'sign1', bnum, {'lnum' : 11}))
  621. call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 10}))
  622. call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 10}))
  623. call assert_equal(6, sign_place(6, 'g1', 'sign1', bnum, {'lnum' : 11}))
  624. call assert_equal(6, sign_place(6, 'g2', 'sign1', bnum, {'lnum' : 11}))
  625. call assert_equal(0, sign_unplace('g1'))
  626. let s = sign_getplaced(bnum, {'group' : 'g1'})
  627. call assert_equal([], s[0].signs)
  628. let s = sign_getplaced(bnum)
  629. call assert_equal(2, len(s[0].signs))
  630. let s = sign_getplaced(bnum, {'group' : 'g2'})
  631. call assert_equal('g2', s[0].signs[0].group)
  632. call assert_equal(0, sign_unplace('', {'id' : 5}))
  633. call assert_equal(0, sign_unplace('', {'id' : 6}))
  634. let s = sign_getplaced(bnum, {'group' : 'g2'})
  635. call assert_equal('g2', s[0].signs[0].group)
  636. call assert_equal(0, sign_unplace('', {'buffer' : bnum}))
  637. call sign_unplace('*')
  638. " Test for :sign command and groups
  639. sign place 5 line=10 name=sign1 file=Xsign
  640. sign place 5 group=g1 line=10 name=sign1 file=Xsign
  641. sign place 5 group=g2 line=10 name=sign1 file=Xsign
  642. " Tests for the ':sign place' command
  643. " :sign place file={fname}
  644. let a = execute('sign place file=Xsign')
  645. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  646. \ " line=10 id=5 name=sign1 priority=10\n", a)
  647. " :sign place group={group} file={fname}
  648. let a = execute('sign place group=g2 file=Xsign')
  649. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  650. \ " line=10 id=5 group=g2 name=sign1 priority=10\n", a)
  651. " :sign place group=* file={fname}
  652. let a = execute('sign place group=* file=Xsign')
  653. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  654. \ " line=10 id=5 group=g2 name=sign1 priority=10\n" .
  655. \ " line=10 id=5 group=g1 name=sign1 priority=10\n" .
  656. \ " line=10 id=5 name=sign1 priority=10\n", a)
  657. " Error case: non-existing group
  658. let a = execute('sign place group=xyz file=Xsign')
  659. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
  660. call sign_unplace('*')
  661. let bnum = bufnr('Xsign')
  662. exe 'sign place 5 line=10 name=sign1 buffer=' . bnum
  663. exe 'sign place 5 group=g1 line=11 name=sign1 buffer=' . bnum
  664. exe 'sign place 5 group=g2 line=12 name=sign1 buffer=' . bnum
  665. " :sign place buffer={fname}
  666. let a = execute('sign place buffer=' . bnum)
  667. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  668. \ " line=10 id=5 name=sign1 priority=10\n", a)
  669. " :sign place group={group} buffer={fname}
  670. let a = execute('sign place group=g2 buffer=' . bnum)
  671. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  672. \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
  673. " :sign place group=* buffer={fname}
  674. let a = execute('sign place group=* buffer=' . bnum)
  675. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  676. \ " line=10 id=5 name=sign1 priority=10\n" .
  677. \ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
  678. \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
  679. " Error case: non-existing group
  680. let a = execute('sign place group=xyz buffer=' . bnum)
  681. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
  682. " :sign place
  683. let a = execute('sign place')
  684. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  685. \ " line=10 id=5 name=sign1 priority=10\n", a)
  686. " Place signs in more than one buffer and list the signs
  687. split foo
  688. set buftype=nofile
  689. sign place 25 line=76 name=sign1 priority=99 file=foo
  690. let a = execute('sign place')
  691. " Nvim: sign line clamped to buffer length
  692. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  693. \ " line=10 id=5 name=sign1 priority=10\n" .
  694. \ "Signs for foo:\n" .
  695. \ " line=1 id=25 name=sign1 priority=99\n", a)
  696. close
  697. bwipe foo
  698. " :sign place group={group}
  699. let a = execute('sign place group=g1')
  700. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  701. \ " line=11 id=5 group=g1 name=sign1 priority=10\n", a)
  702. " :sign place group=*
  703. let a = execute('sign place group=*')
  704. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  705. \ " line=10 id=5 name=sign1 priority=10\n" .
  706. \ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
  707. \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
  708. " Test for ':sign jump' command with groups
  709. sign jump 5 group=g1 file=Xsign
  710. call assert_equal(11, line('.'))
  711. call assert_equal('Xsign', bufname(''))
  712. sign jump 5 group=g2 file=Xsign
  713. call assert_equal(12, line('.'))
  714. " Test for :sign jump command without the filename or buffer
  715. sign jump 5
  716. call assert_equal(10, line('.'))
  717. sign jump 5 group=g1
  718. call assert_equal(11, line('.'))
  719. " Error cases
  720. call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:')
  721. call sign_unplace('*')
  722. call sign_undefine()
  723. enew | only
  724. endfunc
  725. " Place signs used for ":sign unplace" command test
  726. func Place_signs_for_test()
  727. call sign_unplace('*')
  728. sign place 3 line=10 name=sign1 file=Xsign1
  729. sign place 3 group=g1 line=11 name=sign1 file=Xsign1
  730. sign place 3 group=g2 line=12 name=sign1 file=Xsign1
  731. sign place 4 line=15 name=sign1 file=Xsign1
  732. sign place 4 group=g1 line=16 name=sign1 file=Xsign1
  733. sign place 4 group=g2 line=17 name=sign1 file=Xsign1
  734. sign place 5 line=20 name=sign1 file=Xsign2
  735. sign place 5 group=g1 line=21 name=sign1 file=Xsign2
  736. sign place 5 group=g2 line=22 name=sign1 file=Xsign2
  737. sign place 6 line=25 name=sign1 file=Xsign2
  738. sign place 6 group=g1 line=26 name=sign1 file=Xsign2
  739. sign place 6 group=g2 line=27 name=sign1 file=Xsign2
  740. endfunc
  741. " Place multiple signs in a single line for test
  742. func Place_signs_at_line_for_test()
  743. call sign_unplace('*')
  744. sign place 3 line=13 name=sign1 file=Xsign1
  745. sign place 3 group=g1 line=13 name=sign1 file=Xsign1
  746. sign place 3 group=g2 line=13 name=sign1 file=Xsign1
  747. sign place 4 line=13 name=sign1 file=Xsign1
  748. sign place 4 group=g1 line=13 name=sign1 file=Xsign1
  749. sign place 4 group=g2 line=13 name=sign1 file=Xsign1
  750. endfunc
  751. " Tests for the ':sign unplace' command
  752. func Test_sign_unplace()
  753. enew | only
  754. " Remove all the signs
  755. call sign_unplace('*')
  756. call sign_undefine()
  757. " Create two files and define signs
  758. call writefile(repeat(["Sun is shining"], 30), "Xsign1", 'D')
  759. call writefile(repeat(["It is beautiful"], 30), "Xsign2", 'D')
  760. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
  761. call sign_define("sign1", attr)
  762. edit Xsign1
  763. let bnum1 = bufnr('%')
  764. split Xsign2
  765. let bnum2 = bufnr('%')
  766. let signs1 = [{'id' : 3, 'name' : 'sign1', 'lnum' : 10, 'group' : '',
  767. \ 'priority' : 10},
  768. \ {'id' : 3, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1',
  769. \ 'priority' : 10},
  770. \ {'id' : 3, 'name' : 'sign1', 'lnum' : 12, 'group' : 'g2',
  771. \ 'priority' : 10},
  772. \ {'id' : 4, 'name' : 'sign1', 'lnum' : 15, 'group' : '',
  773. \ 'priority' : 10},
  774. \ {'id' : 4, 'name' : 'sign1', 'lnum' : 16, 'group' : 'g1',
  775. \ 'priority' : 10},
  776. \ {'id' : 4, 'name' : 'sign1', 'lnum' : 17, 'group' : 'g2',
  777. \ 'priority' : 10},]
  778. let signs2 = [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : '',
  779. \ 'priority' : 10},
  780. \ {'id' : 5, 'name' : 'sign1', 'lnum' : 21, 'group' : 'g1',
  781. \ 'priority' : 10},
  782. \ {'id' : 5, 'name' : 'sign1', 'lnum' : 22, 'group' : 'g2',
  783. \ 'priority' : 10},
  784. \ {'id' : 6, 'name' : 'sign1', 'lnum' : 25, 'group' : '',
  785. \ 'priority' : 10},
  786. \ {'id' : 6, 'name' : 'sign1', 'lnum' : 26, 'group' : 'g1',
  787. \ 'priority' : 10},
  788. \ {'id' : 6, 'name' : 'sign1', 'lnum' : 27, 'group' : 'g2',
  789. \ 'priority' : 10},]
  790. " Test for :sign unplace {id} file={fname}
  791. call Place_signs_for_test()
  792. sign unplace 3 file=Xsign1
  793. sign unplace 6 file=Xsign2
  794. call assert_equal(
  795. \ filter(copy(signs1),
  796. \ {idx, val -> val.id != 3 || val.group != ''}),
  797. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  798. call assert_equal(
  799. \ filter(copy(signs2),
  800. \ {idx, val -> val.id != 6 || val.group != ''}),
  801. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  802. " Test for :sign unplace {id} group={group} file={fname}
  803. call Place_signs_for_test()
  804. sign unplace 4 group=g1 file=Xsign1
  805. sign unplace 5 group=g2 file=Xsign2
  806. call assert_equal(
  807. \ filter(copy(signs1),
  808. \ {idx, val -> val.id != 4 || val.group != 'g1'}),
  809. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  810. call assert_equal(
  811. \ filter(copy(signs2),
  812. \ {idx, val -> val.id != 5 || val.group != 'g2'}),
  813. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  814. " Test for :sign unplace {id} group=* file={fname}
  815. call Place_signs_for_test()
  816. sign unplace 3 group=* file=Xsign1
  817. sign unplace 6 group=* file=Xsign2
  818. call assert_equal(
  819. \ filter(copy(signs1),
  820. \ {idx, val -> val.id != 3}),
  821. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  822. call assert_equal(
  823. \ filter(copy(signs2),
  824. \ {idx, val -> val.id != 6}),
  825. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  826. " Test for :sign unplace * file={fname}
  827. call Place_signs_for_test()
  828. sign unplace * file=Xsign1
  829. call assert_equal(
  830. \ filter(copy(signs1),
  831. \ {idx, val -> val.group != ''}),
  832. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  833. call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  834. " Test for :sign unplace * group={group} file={fname}
  835. call Place_signs_for_test()
  836. sign unplace * group=g1 file=Xsign1
  837. sign unplace * group=g2 file=Xsign2
  838. call assert_equal(
  839. \ filter(copy(signs1),
  840. \ {idx, val -> val.group != 'g1'}),
  841. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  842. call assert_equal(
  843. \ filter(copy(signs2),
  844. \ {idx, val -> val.group != 'g2'}),
  845. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  846. " Test for :sign unplace * group=* file={fname}
  847. call Place_signs_for_test()
  848. sign unplace * group=* file=Xsign2
  849. call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  850. call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  851. " Test for :sign unplace {id} buffer={nr}
  852. call Place_signs_for_test()
  853. exe 'sign unplace 3 buffer=' . bnum1
  854. exe 'sign unplace 6 buffer=' . bnum2
  855. call assert_equal(
  856. \ filter(copy(signs1),
  857. \ {idx, val -> val.id != 3 || val.group != ''}),
  858. \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
  859. call assert_equal(
  860. \ filter(copy(signs2),
  861. \ {idx, val -> val.id != 6 || val.group != ''}),
  862. \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
  863. " Test for :sign unplace {id} group={group} buffer={nr}
  864. call Place_signs_for_test()
  865. exe 'sign unplace 4 group=g1 buffer=' . bnum1
  866. exe 'sign unplace 5 group=g2 buffer=' . bnum2
  867. call assert_equal(
  868. \ filter(copy(signs1),
  869. \ {idx, val -> val.id != 4 || val.group != 'g1'}),
  870. \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
  871. call assert_equal(
  872. \ filter(copy(signs2),
  873. \ {idx, val -> val.id != 5 || val.group != 'g2'}),
  874. \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
  875. " Test for :sign unplace {id} group=* buffer={nr}
  876. call Place_signs_for_test()
  877. exe 'sign unplace 3 group=* buffer=' . bnum1
  878. exe 'sign unplace 6 group=* buffer=' . bnum2
  879. call assert_equal(
  880. \ filter(copy(signs1),
  881. \ {idx, val -> val.id != 3}),
  882. \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
  883. call assert_equal(
  884. \ filter(copy(signs2),
  885. \ {idx, val -> val.id != 6}),
  886. \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
  887. " Test for :sign unplace * buffer={nr}
  888. call Place_signs_for_test()
  889. exe 'sign unplace * buffer=' . bnum1
  890. call assert_equal(
  891. \ filter(copy(signs1),
  892. \ {idx, val -> val.group != ''}),
  893. \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
  894. call assert_equal(signs2, sign_getplaced(bnum2, {'group' : '*'})[0].signs)
  895. " Test for :sign unplace * group={group} buffer={nr}
  896. call Place_signs_for_test()
  897. exe 'sign unplace * group=g1 buffer=' . bnum1
  898. exe 'sign unplace * group=g2 buffer=' . bnum2
  899. call assert_equal(
  900. \ filter(copy(signs1),
  901. \ {idx, val -> val.group != 'g1'}),
  902. \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
  903. call assert_equal(
  904. \ filter(copy(signs2),
  905. \ {idx, val -> val.group != 'g2'}),
  906. \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
  907. " Test for :sign unplace * group=* buffer={nr}
  908. call Place_signs_for_test()
  909. exe 'sign unplace * group=* buffer=' . bnum2
  910. call assert_equal(signs1, sign_getplaced(bnum1, {'group' : '*'})[0].signs)
  911. call assert_equal([], sign_getplaced(bnum2, {'group' : '*'})[0].signs)
  912. " Test for :sign unplace {id}
  913. call Place_signs_for_test()
  914. sign unplace 4
  915. sign unplace 6
  916. call assert_equal(
  917. \ filter(copy(signs1),
  918. \ {idx, val -> val.id != 4 || val.group != ''}),
  919. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  920. call assert_equal(
  921. \ filter(copy(signs2),
  922. \ {idx, val -> val.id != 6 || val.group != ''}),
  923. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  924. " Test for :sign unplace {id} group={group}
  925. call Place_signs_for_test()
  926. sign unplace 4 group=g1
  927. sign unplace 6 group=g2
  928. call assert_equal(
  929. \ filter(copy(signs1),
  930. \ {idx, val -> val.id != 4 || val.group != 'g1'}),
  931. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  932. call assert_equal(
  933. \ filter(copy(signs2),
  934. \ {idx, val -> val.id != 6 || val.group != 'g2'}),
  935. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  936. " Test for :sign unplace {id} group=*
  937. call Place_signs_for_test()
  938. sign unplace 3 group=*
  939. sign unplace 5 group=*
  940. call assert_equal(
  941. \ filter(copy(signs1),
  942. \ {idx, val -> val.id != 3}),
  943. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  944. call assert_equal(
  945. \ filter(copy(signs2),
  946. \ {idx, val -> val.id != 5}),
  947. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  948. " Test for :sign unplace *
  949. call Place_signs_for_test()
  950. sign unplace *
  951. call assert_equal(
  952. \ filter(copy(signs1),
  953. \ {idx, val -> val.group != ''}),
  954. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  955. call assert_equal(
  956. \ filter(copy(signs2),
  957. \ {idx, val -> val.group != ''}),
  958. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  959. " Test for :sign unplace * group={group}
  960. call Place_signs_for_test()
  961. sign unplace * group=g1
  962. call assert_equal(
  963. \ filter(copy(signs1),
  964. \ {idx, val -> val.group != 'g1'}),
  965. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  966. call assert_equal(
  967. \ filter(copy(signs2),
  968. \ {idx, val -> val.group != 'g1'}),
  969. \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  970. " Test for :sign unplace * group=*
  971. call Place_signs_for_test()
  972. sign unplace * group=*
  973. call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  974. call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  975. " Negative test cases
  976. call Place_signs_for_test()
  977. sign unplace 3 group=xy file=Xsign1
  978. sign unplace * group=xy file=Xsign1
  979. silent! sign unplace * group=* file=FileNotPresent
  980. call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  981. call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
  982. " Tests for removing sign at the current cursor position
  983. " Test for ':sign unplace'
  984. let signs1 = [{'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
  985. \ 'priority' : 10},
  986. \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
  987. \ 'priority' : 10},
  988. \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
  989. \ 'priority' : 10},
  990. \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
  991. \ 'priority' : 10},
  992. \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
  993. \ 'priority' : 10},
  994. \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
  995. \ 'priority' : 10},]
  996. exe bufwinnr('Xsign1') . 'wincmd w'
  997. call cursor(13, 1)
  998. " Should remove only one sign in the global group
  999. call Place_signs_at_line_for_test()
  1000. sign unplace
  1001. call assert_equal(
  1002. \ filter(copy(signs1),
  1003. \ {idx, val -> val.id != 4 || val.group != ''}),
  1004. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  1005. " Should remove the second sign in the global group
  1006. sign unplace
  1007. call assert_equal(
  1008. \ filter(copy(signs1),
  1009. \ {idx, val -> val.group != ''}),
  1010. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  1011. " Test for ':sign unplace group={group}'
  1012. call Place_signs_at_line_for_test()
  1013. " Should remove only one sign in group g1
  1014. sign unplace group=g1
  1015. call assert_equal(
  1016. \ filter(copy(signs1),
  1017. \ {idx, val -> val.id != 4 || val.group != 'g1'}),
  1018. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  1019. sign unplace group=g2
  1020. call assert_equal(
  1021. \ filter(copy(signs1),
  1022. \ {idx, val -> val.id != 4 || val.group == ''}),
  1023. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  1024. " Test for ':sign unplace group=*'
  1025. call Place_signs_at_line_for_test()
  1026. sign unplace group=*
  1027. sign unplace group=*
  1028. sign unplace group=*
  1029. call assert_equal(
  1030. \ filter(copy(signs1),
  1031. \ {idx, val -> val.id != 4}),
  1032. \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  1033. sign unplace group=*
  1034. sign unplace group=*
  1035. sign unplace group=*
  1036. call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
  1037. call sign_unplace('*')
  1038. call sign_undefine()
  1039. enew | only
  1040. endfunc
  1041. " Tests for auto-generating the sign identifier.
  1042. func Test_aaa_sign_id_autogen()
  1043. enew | only
  1044. call sign_unplace('*')
  1045. call sign_undefine()
  1046. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
  1047. call assert_equal(0, sign_define("sign1", attr))
  1048. call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
  1049. edit Xsign
  1050. call assert_equal(1, sign_place(0, '', 'sign1', 'Xsign',
  1051. \ {'lnum' : 10}))
  1052. call assert_equal(2, sign_place(2, '', 'sign1', 'Xsign',
  1053. \ {'lnum' : 12}))
  1054. call assert_equal(3, sign_place(0, '', 'sign1', 'Xsign',
  1055. \ {'lnum' : 14}))
  1056. call sign_unplace('', {'buffer' : 'Xsign', 'id' : 2})
  1057. call assert_equal(4, sign_place(0, '', 'sign1', 'Xsign',
  1058. \ {'lnum' : 12}))
  1059. call assert_equal(1, sign_place(0, 'g1', 'sign1', 'Xsign',
  1060. \ {'lnum' : 11}))
  1061. " Check for the next generated sign id in this group
  1062. call assert_equal(2, sign_place(0, 'g1', 'sign1', 'Xsign',
  1063. \ {'lnum' : 12}))
  1064. call assert_equal(0, sign_unplace('g1', {'id' : 1}))
  1065. call assert_equal(10,
  1066. \ sign_getplaced('Xsign', {'id' : 1})[0].signs[0].lnum)
  1067. call sign_unplace('*')
  1068. call sign_undefine()
  1069. enew | only
  1070. endfunc
  1071. " Test for sign priority
  1072. func Test_sign_priority()
  1073. enew | only
  1074. call sign_unplace('*')
  1075. call sign_undefine()
  1076. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search'}
  1077. call sign_define("sign1", attr)
  1078. call sign_define("sign2", attr)
  1079. call sign_define("sign3", attr)
  1080. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search', 'priority': 60}
  1081. call sign_define("sign4", attr)
  1082. " Test for :sign list
  1083. let a = execute('sign list')
  1084. call assert_equal("\nsign sign1 text==> linehl=Search texthl=Search\n" .
  1085. \ "sign sign2 text==> linehl=Search texthl=Search\n" .
  1086. \ "sign sign3 text==> linehl=Search texthl=Search\n" .
  1087. \ "sign sign4 text==> priority=60 linehl=Search texthl=Search", a)
  1088. " Test for sign_getdefined()
  1089. let s = sign_getdefined()
  1090. call assert_equal([
  1091. \ {'name': 'sign1', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
  1092. \ {'name': 'sign2', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
  1093. \ {'name': 'sign3', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
  1094. \ {'name': 'sign4', 'priority': 60, 'texthl': 'Search', 'linehl': 'Search',
  1095. \ 'text': '=>'}],
  1096. \ s)
  1097. " Place three signs with different priority in the same line
  1098. call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
  1099. edit Xsign
  1100. call sign_place(1, 'g1', 'sign1', 'Xsign',
  1101. \ {'lnum' : 11, 'priority' : 50})
  1102. call sign_place(2, 'g2', 'sign2', 'Xsign',
  1103. \ {'lnum' : 11, 'priority' : 100})
  1104. call sign_place(3, '', 'sign3', 'Xsign', {'lnum' : 11})
  1105. let s = sign_getplaced('Xsign', {'group' : '*'})
  1106. call assert_equal([
  1107. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11, 'group' : 'g2',
  1108. \ 'priority' : 100},
  1109. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1',
  1110. \ 'priority' : 50},
  1111. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11, 'group' : '',
  1112. \ 'priority' : 10}],
  1113. \ s[0].signs)
  1114. call sign_unplace('*')
  1115. " Three signs on different lines with changing priorities
  1116. call sign_place(1, '', 'sign1', 'Xsign',
  1117. \ {'lnum' : 11, 'priority' : 50})
  1118. call sign_place(2, '', 'sign2', 'Xsign',
  1119. \ {'lnum' : 12, 'priority' : 60})
  1120. call sign_place(3, '', 'sign3', 'Xsign',
  1121. \ {'lnum' : 13, 'priority' : 70})
  1122. call sign_place(2, '', 'sign2', 'Xsign',
  1123. \ {'lnum' : 12, 'priority' : 40})
  1124. call sign_place(3, '', 'sign3', 'Xsign',
  1125. \ {'lnum' : 13, 'priority' : 30})
  1126. call sign_place(1, '', 'sign1', 'Xsign',
  1127. \ {'lnum' : 11, 'priority' : 50})
  1128. let s = sign_getplaced('Xsign', {'group' : '*'})
  1129. call assert_equal([
  1130. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : '',
  1131. \ 'priority' : 50},
  1132. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 12, 'group' : '',
  1133. \ 'priority' : 40},
  1134. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 13, 'group' : '',
  1135. \ 'priority' : 30}],
  1136. \ s[0].signs)
  1137. call sign_unplace('*')
  1138. " Two signs on the same line with changing priorities
  1139. call sign_place(1, '', 'sign1', 'Xsign',
  1140. \ {'lnum' : 4, 'priority' : 20})
  1141. call sign_place(2, '', 'sign2', 'Xsign',
  1142. \ {'lnum' : 4, 'priority' : 30})
  1143. let s = sign_getplaced('Xsign', {'group' : '*'})
  1144. call assert_equal([
  1145. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1146. \ 'priority' : 30},
  1147. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1148. \ 'priority' : 20}],
  1149. \ s[0].signs)
  1150. " Change the priority of the last sign to highest
  1151. call sign_place(1, '', 'sign1', 'Xsign',
  1152. \ {'lnum' : 4, 'priority' : 40})
  1153. let s = sign_getplaced('Xsign', {'group' : '*'})
  1154. call assert_equal([
  1155. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1156. \ 'priority' : 40},
  1157. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1158. \ 'priority' : 30}],
  1159. \ s[0].signs)
  1160. " Change the priority of the first sign to lowest
  1161. call sign_place(1, '', 'sign1', 'Xsign',
  1162. \ {'lnum' : 4, 'priority' : 25})
  1163. let s = sign_getplaced('Xsign', {'group' : '*'})
  1164. call assert_equal([
  1165. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1166. \ 'priority' : 30},
  1167. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1168. \ 'priority' : 25}],
  1169. \ s[0].signs)
  1170. call sign_place(1, '', 'sign1', 'Xsign',
  1171. \ {'lnum' : 4, 'priority' : 45})
  1172. call sign_place(2, '', 'sign2', 'Xsign',
  1173. \ {'lnum' : 4, 'priority' : 55})
  1174. let s = sign_getplaced('Xsign', {'group' : '*'})
  1175. call assert_equal([
  1176. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1177. \ 'priority' : 55},
  1178. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1179. \ 'priority' : 45}],
  1180. \ s[0].signs)
  1181. call sign_unplace('*')
  1182. " Three signs on the same line with changing priorities
  1183. call sign_place(1, '', 'sign1', 'Xsign',
  1184. \ {'lnum' : 4, 'priority' : 40})
  1185. call sign_place(2, '', 'sign2', 'Xsign',
  1186. \ {'lnum' : 4, 'priority' : 30})
  1187. call sign_place(3, '', 'sign3', 'Xsign',
  1188. \ {'lnum' : 4, 'priority' : 20})
  1189. let s = sign_getplaced('Xsign', {'group' : '*'})
  1190. call assert_equal([
  1191. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1192. \ 'priority' : 40},
  1193. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1194. \ 'priority' : 30},
  1195. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1196. \ 'priority' : 20}],
  1197. \ s[0].signs)
  1198. " Change the priority of the middle sign to the highest
  1199. call sign_place(2, '', 'sign2', 'Xsign',
  1200. \ {'lnum' : 4, 'priority' : 50})
  1201. let s = sign_getplaced('Xsign', {'group' : '*'})
  1202. call assert_equal([
  1203. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1204. \ 'priority' : 50},
  1205. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1206. \ 'priority' : 40},
  1207. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1208. \ 'priority' : 20}],
  1209. \ s[0].signs)
  1210. " Change the priority of the middle sign to the lowest
  1211. call sign_place(1, '', 'sign1', 'Xsign',
  1212. \ {'lnum' : 4, 'priority' : 15})
  1213. let s = sign_getplaced('Xsign', {'group' : '*'})
  1214. call assert_equal([
  1215. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1216. \ 'priority' : 50},
  1217. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1218. \ 'priority' : 20},
  1219. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1220. \ 'priority' : 15}],
  1221. \ s[0].signs)
  1222. " Change the priority of the last sign to the highest
  1223. call sign_place(1, '', 'sign1', 'Xsign',
  1224. \ {'lnum' : 4, 'priority' : 55})
  1225. let s = sign_getplaced('Xsign', {'group' : '*'})
  1226. call assert_equal([
  1227. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1228. \ 'priority' : 55},
  1229. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1230. \ 'priority' : 50},
  1231. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1232. \ 'priority' : 20}],
  1233. \ s[0].signs)
  1234. " Change the priority of the first sign to the lowest
  1235. call sign_place(1, '', 'sign1', 'Xsign',
  1236. \ {'lnum' : 4, 'priority' : 15})
  1237. let s = sign_getplaced('Xsign', {'group' : '*'})
  1238. call assert_equal([
  1239. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1240. \ 'priority' : 50},
  1241. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1242. \ 'priority' : 20},
  1243. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1244. \ 'priority' : 15}],
  1245. \ s[0].signs)
  1246. call sign_unplace('*')
  1247. " Three signs on the same line with changing priorities along with other
  1248. " signs
  1249. call sign_place(1, '', 'sign1', 'Xsign',
  1250. \ {'lnum' : 2, 'priority' : 10})
  1251. call sign_place(2, '', 'sign1', 'Xsign',
  1252. \ {'lnum' : 4, 'priority' : 30})
  1253. call sign_place(3, '', 'sign2', 'Xsign',
  1254. \ {'lnum' : 4, 'priority' : 20})
  1255. call sign_place(4, '', 'sign3', 'Xsign',
  1256. \ {'lnum' : 4, 'priority' : 25})
  1257. call sign_place(5, '', 'sign2', 'Xsign',
  1258. \ {'lnum' : 6, 'priority' : 80})
  1259. let s = sign_getplaced('Xsign', {'group' : '*'})
  1260. call assert_equal([
  1261. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
  1262. \ 'priority' : 10},
  1263. \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1264. \ 'priority' : 30},
  1265. \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1266. \ 'priority' : 25},
  1267. \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1268. \ 'priority' : 20},
  1269. \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
  1270. \ 'priority' : 80}],
  1271. \ s[0].signs)
  1272. " Change the priority of the first sign to lowest
  1273. call sign_place(2, '', 'sign1', 'Xsign',
  1274. \ {'lnum' : 4, 'priority' : 15})
  1275. let s = sign_getplaced('Xsign', {'group' : '*'})
  1276. call assert_equal([
  1277. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
  1278. \ 'priority' : 10},
  1279. \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1280. \ 'priority' : 25},
  1281. \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1282. \ 'priority' : 20},
  1283. \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1284. \ 'priority' : 15},
  1285. \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
  1286. \ 'priority' : 80}],
  1287. \ s[0].signs)
  1288. " Change the priority of the last sign to highest
  1289. call sign_place(2, '', 'sign1', 'Xsign',
  1290. \ {'lnum' : 4, 'priority' : 30})
  1291. let s = sign_getplaced('Xsign', {'group' : '*'})
  1292. call assert_equal([
  1293. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
  1294. \ 'priority' : 10},
  1295. \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1296. \ 'priority' : 30},
  1297. \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1298. \ 'priority' : 25},
  1299. \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1300. \ 'priority' : 20},
  1301. \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
  1302. \ 'priority' : 80}],
  1303. \ s[0].signs)
  1304. " Change the priority of the middle sign to lowest
  1305. call sign_place(4, '', 'sign3', 'Xsign',
  1306. \ {'lnum' : 4, 'priority' : 15})
  1307. let s = sign_getplaced('Xsign', {'group' : '*'})
  1308. call assert_equal([
  1309. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
  1310. \ 'priority' : 10},
  1311. \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1312. \ 'priority' : 30},
  1313. \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1314. \ 'priority' : 20},
  1315. \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1316. \ 'priority' : 15},
  1317. \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
  1318. \ 'priority' : 80}],
  1319. \ s[0].signs)
  1320. " Change the priority of the middle sign to highest
  1321. call sign_place(3, '', 'sign2', 'Xsign',
  1322. \ {'lnum' : 4, 'priority' : 35})
  1323. let s = sign_getplaced('Xsign', {'group' : '*'})
  1324. call assert_equal([
  1325. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
  1326. \ 'priority' : 10},
  1327. \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1328. \ 'priority' : 35},
  1329. \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1330. \ 'priority' : 30},
  1331. \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1332. \ 'priority' : 15},
  1333. \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
  1334. \ 'priority' : 80}],
  1335. \ s[0].signs)
  1336. call sign_unplace('*')
  1337. " Multiple signs with the same priority on the same line
  1338. call sign_place(1, '', 'sign1', 'Xsign',
  1339. \ {'lnum' : 4, 'priority' : 20})
  1340. call sign_place(2, '', 'sign2', 'Xsign',
  1341. \ {'lnum' : 4, 'priority' : 20})
  1342. call sign_place(3, '', 'sign3', 'Xsign',
  1343. \ {'lnum' : 4, 'priority' : 20})
  1344. let s = sign_getplaced('Xsign', {'group' : '*'})
  1345. let se = [
  1346. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
  1347. \ 'priority' : 20},
  1348. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
  1349. \ 'priority' : 20},
  1350. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
  1351. \ 'priority' : 20}]
  1352. call assert_equal(se, s[0].signs)
  1353. " Nvim: signs are always sorted lnum->priority->sign_id->last_modified
  1354. " Last modified does not take precedence over sign_id here.
  1355. " Place the last sign again with the same priority
  1356. call sign_place(1, '', 'sign1', 'Xsign',
  1357. \ {'lnum' : 4, 'priority' : 20})
  1358. let s = sign_getplaced('Xsign', {'group' : '*'})
  1359. call assert_equal(se, s[0].signs)
  1360. " Place the first sign again with the same priority
  1361. call sign_place(1, '', 'sign1', 'Xsign',
  1362. \ {'lnum' : 4, 'priority' : 20})
  1363. let s = sign_getplaced('Xsign', {'group' : '*'})
  1364. call assert_equal(se, s[0].signs)
  1365. " Place the middle sign again with the same priority
  1366. call sign_place(3, '', 'sign3', 'Xsign',
  1367. \ {'lnum' : 4, 'priority' : 20})
  1368. let s = sign_getplaced('Xsign', {'group' : '*'})
  1369. call assert_equal(se, s[0].signs)
  1370. call sign_unplace('*')
  1371. " Place multiple signs with same id on a line with different priority
  1372. call sign_place(1, '', 'sign1', 'Xsign',
  1373. \ {'lnum' : 5, 'priority' : 20})
  1374. call sign_place(1, '', 'sign2', 'Xsign',
  1375. \ {'lnum' : 5, 'priority' : 10})
  1376. let s = sign_getplaced('Xsign', {'lnum' : 5})
  1377. call assert_equal([
  1378. \ {'id' : 1, 'name' : 'sign2', 'lnum' : 5, 'group' : '',
  1379. \ 'priority' : 10}],
  1380. \ s[0].signs)
  1381. call sign_place(1, '', 'sign2', 'Xsign',
  1382. \ {'lnum' : 5, 'priority' : 5})
  1383. let s = sign_getplaced('Xsign', {'lnum' : 5})
  1384. call assert_equal([
  1385. \ {'id' : 1, 'name' : 'sign2', 'lnum' : 5, 'group' : '',
  1386. \ 'priority' : 5}],
  1387. \ s[0].signs)
  1388. " Error case
  1389. call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', [])", 'E1206:')
  1390. call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign',
  1391. \ {'priority' : []})", 'E745:')
  1392. call sign_unplace('*')
  1393. " Tests for the :sign place command with priority
  1394. sign place 5 line=10 name=sign1 priority=30 file=Xsign
  1395. sign place 5 group=g1 line=10 name=sign1 priority=20 file=Xsign
  1396. sign place 5 group=g2 line=10 name=sign1 priority=25 file=Xsign
  1397. let a = execute('sign place group=*')
  1398. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  1399. \ " line=10 id=5 name=sign1 priority=30\n" .
  1400. \ " line=10 id=5 group=g2 name=sign1 priority=25\n" .
  1401. \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
  1402. " Test for :sign place group={group}
  1403. let a = execute('sign place group=g1')
  1404. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  1405. \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
  1406. call sign_unplace('*')
  1407. " Test for sign with default priority.
  1408. call sign_place(1, 'g1', 'sign4', 'Xsign', {'lnum' : 3})
  1409. sign place 2 line=5 name=sign4 group=g1 file=Xsign
  1410. let s = sign_getplaced('Xsign', {'group' : '*'})
  1411. call assert_equal([
  1412. \ {'id' : 1, 'name' : 'sign4', 'lnum' : 3, 'group' : 'g1',
  1413. \ 'priority' : 60},
  1414. \ {'id' : 2, 'name' : 'sign4', 'lnum' : 5, 'group' : 'g1',
  1415. \ 'priority' : 60}],
  1416. \ s[0].signs)
  1417. let a = execute('sign place group=g1')
  1418. call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
  1419. \ " line=3 id=1 group=g1 name=sign4 priority=60\n" .
  1420. \ " line=5 id=2 group=g1 name=sign4 priority=60\n", a)
  1421. call sign_unplace('*')
  1422. call sign_undefine()
  1423. enew | only
  1424. endfunc
  1425. " Tests for memory allocation failures in sign functions
  1426. func Test_sign_memfailures()
  1427. CheckFunction test_alloc_fail
  1428. call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
  1429. edit Xsign
  1430. call test_alloc_fail(GetAllocId('sign_getdefined'), 0, 0)
  1431. call assert_fails('call sign_getdefined("sign1")', 'E342:')
  1432. call test_alloc_fail(GetAllocId('sign_getplaced'), 0, 0)
  1433. call assert_fails('call sign_getplaced("Xsign")', 'E342:')
  1434. call test_alloc_fail(GetAllocId('sign_define_by_name'), 0, 0)
  1435. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
  1436. call assert_fails('call sign_define("sign1", attr)', 'E342:')
  1437. let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
  1438. call sign_define("sign1", attr)
  1439. call test_alloc_fail(GetAllocId('sign_getlist'), 0, 0)
  1440. call assert_fails('call sign_getdefined("sign1")', 'E342:')
  1441. call sign_place(3, 'g1', 'sign1', 'Xsign', {'lnum' : 10})
  1442. call test_alloc_fail(GetAllocId('sign_getplaced_dict'), 0, 0)
  1443. call assert_fails('call sign_getplaced("Xsign")', 'E342:')
  1444. call test_alloc_fail(GetAllocId('sign_getplaced_list'), 0, 0)
  1445. call assert_fails('call sign_getplaced("Xsign")', 'E342:')
  1446. call test_alloc_fail(GetAllocId('insert_sign'), 0, 0)
  1447. call assert_fails('call sign_place(4, "g1", "sign1", "Xsign", {"lnum" : 11})',
  1448. \ 'E342:')
  1449. call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0)
  1450. call assert_fails('call getbufinfo()', 'E342:')
  1451. call sign_place(4, 'g1', 'sign1', 'Xsign', {'lnum' : 11})
  1452. call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0)
  1453. call assert_fails('let binfo=getbufinfo("Xsign")', 'E342:')
  1454. call assert_equal([{'lnum': 11, 'id': 4, 'name': 'sign1',
  1455. \ 'priority': 10, 'group': 'g1'}], binfo[0].signs)
  1456. call sign_unplace('*')
  1457. call sign_undefine()
  1458. enew | only
  1459. endfunc
  1460. " Test for auto-adjusting the line number of a placed sign.
  1461. func Test_sign_lnum_adjust()
  1462. enew! | only!
  1463. sign define sign1 text=#> linehl=Comment
  1464. call setline(1, ['A', 'B', 'C', 'D', 'E'])
  1465. exe 'sign place 5 line=3 name=sign1 buffer=' . bufnr('')
  1466. let l = sign_getplaced(bufnr(''))
  1467. call assert_equal(3, l[0].signs[0].lnum)
  1468. " Add some lines before the sign and check the sign line number
  1469. call append(2, ['BA', 'BB', 'BC'])
  1470. let l = sign_getplaced(bufnr(''))
  1471. call assert_equal(6, l[0].signs[0].lnum)
  1472. " Delete some lines before the sign and check the sign line number
  1473. call deletebufline('%', 1, 2)
  1474. let l = sign_getplaced(bufnr(''))
  1475. call assert_equal(4, l[0].signs[0].lnum)
  1476. " Insert some lines after the sign and check the sign line number
  1477. call append(5, ['DA', 'DB'])
  1478. let l = sign_getplaced(bufnr(''))
  1479. call assert_equal(4, l[0].signs[0].lnum)
  1480. " Delete some lines after the sign and check the sign line number
  1481. call deletebufline('', 6, 7)
  1482. let l = sign_getplaced(bufnr(''))
  1483. call assert_equal(4, l[0].signs[0].lnum)
  1484. " Break the undo. Otherwise the undo operation below will undo all the
  1485. " changes made by this function.
  1486. let &g:undolevels=&g:undolevels
  1487. " Nvim: deleting a line removes the signs along with it.
  1488. " " Delete the line with the sign
  1489. " call deletebufline('', 4)
  1490. " let l = sign_getplaced(bufnr(''))
  1491. " call assert_equal(4, l[0].signs[0].lnum)
  1492. " " Undo the delete operation
  1493. " undo
  1494. " let l = sign_getplaced(bufnr(''))
  1495. " call assert_equal(5, l[0].signs[0].lnum)
  1496. " " Break the undo
  1497. " let &g:undolevels=&g:undolevels
  1498. " " Delete few lines at the end of the buffer including the line with the sign
  1499. " " Sign line number should not change (as it is placed outside of the buffer)
  1500. " call deletebufline('', 3, 6)
  1501. " let l = sign_getplaced(bufnr(''))
  1502. " call assert_equal(5, l[0].signs[0].lnum)
  1503. " " Undo the delete operation. Sign should be restored to the previous line
  1504. " undo
  1505. " let l = sign_getplaced(bufnr(''))
  1506. " call assert_equal(5, l[0].signs[0].lnum)
  1507. " set signcolumn&
  1508. sign unplace * group=*
  1509. sign undefine sign1
  1510. enew!
  1511. endfunc
  1512. " Test for changing the type of a placed sign
  1513. func Test_sign_change_type()
  1514. enew! | only!
  1515. sign define sign1 text=#> linehl=Comment
  1516. sign define sign2 text=@@ linehl=Comment
  1517. call setline(1, ['A', 'B', 'C', 'D'])
  1518. exe 'sign place 4 line=3 name=sign1 buffer=' . bufnr('')
  1519. let l = sign_getplaced(bufnr(''))
  1520. call assert_equal('sign1', l[0].signs[0].name)
  1521. exe 'sign place 4 name=sign2 buffer=' . bufnr('')
  1522. let l = sign_getplaced(bufnr(''))
  1523. call assert_equal('sign2', l[0].signs[0].name)
  1524. call sign_place(4, '', 'sign1', '')
  1525. let l = sign_getplaced(bufnr(''))
  1526. call assert_equal('sign1', l[0].signs[0].name)
  1527. exe 'sign place 4 group=g1 line=4 name=sign1 buffer=' . bufnr('')
  1528. let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
  1529. call assert_equal('sign1', l[0].signs[0].name)
  1530. exe 'sign place 4 group=g1 name=sign2 buffer=' . bufnr('')
  1531. let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
  1532. call assert_equal('sign2', l[0].signs[0].name)
  1533. call sign_place(4, 'g1', 'sign1', '')
  1534. let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
  1535. call assert_equal('sign1', l[0].signs[0].name)
  1536. sign unplace * group=*
  1537. sign undefine sign1
  1538. sign undefine sign2
  1539. enew!
  1540. endfunc
  1541. " Test for the sign_jump() function
  1542. func Test_sign_jump_func()
  1543. enew! | only!
  1544. sign define sign1 text=#> linehl=Comment
  1545. edit foo
  1546. set buftype=nofile
  1547. call setline(1, ['A', 'B', 'C', 'D', 'E'])
  1548. call sign_place(5, '', 'sign1', '', {'lnum' : 2})
  1549. call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
  1550. call sign_place(6, '', 'sign1', '', {'lnum' : 4})
  1551. call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
  1552. split bar
  1553. set buftype=nofile
  1554. call setline(1, ['P', 'Q', 'R', 'S', 'T'])
  1555. call sign_place(5, '', 'sign1', '', {'lnum' : 2})
  1556. call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
  1557. call sign_place(6, '', 'sign1', '', {'lnum' : 4})
  1558. call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
  1559. let r = sign_jump(5, '', 'foo')
  1560. call assert_equal(2, r)
  1561. call assert_equal(2, line('.'))
  1562. let r = 6->sign_jump('g1', 'foo')
  1563. call assert_equal(5, r)
  1564. call assert_equal(5, line('.'))
  1565. let r = sign_jump(5, '', 'bar')
  1566. call assert_equal(2, r)
  1567. call assert_equal(2, line('.'))
  1568. " Error cases
  1569. call assert_fails("call sign_jump(99, '', 'bar')", 'E157:')
  1570. call assert_fails("call sign_jump(0, '', 'foo')", 'E474:')
  1571. call assert_fails("call sign_jump(5, 'g5', 'foo')", 'E157:')
  1572. call assert_fails('call sign_jump([], "", "foo")', 'E745:')
  1573. call assert_fails('call sign_jump(2, [], "foo")', 'E730:')
  1574. call assert_fails('call sign_jump(2, "", {})', 'E731:')
  1575. call assert_fails('call sign_jump(2, "", "baz")', 'E158:')
  1576. sign unplace * group=*
  1577. sign undefine sign1
  1578. enew! | only!
  1579. endfunc
  1580. " Test for correct cursor position after the sign column appears or disappears.
  1581. func Test_sign_cursor_position()
  1582. CheckRunVimInTerminal
  1583. let lines =<< trim END
  1584. call setline(1, [repeat('x', 75), 'mmmm', 'yyyy'])
  1585. call cursor(2,1)
  1586. sign define s1 texthl=Search text==>
  1587. sign define s2 linehl=Pmenu
  1588. redraw
  1589. sign place 10 line=2 name=s1
  1590. END
  1591. call writefile(lines, 'XtestSigncolumn', 'D')
  1592. let buf = RunVimInTerminal('-S XtestSigncolumn', {'rows': 6})
  1593. call VerifyScreenDump(buf, 'Test_sign_cursor_1', {})
  1594. " Change the sign text
  1595. call term_sendkeys(buf, ":sign define s1 text=-)\<CR>")
  1596. call VerifyScreenDump(buf, 'Test_sign_cursor_2', {})
  1597. " Also place a line HL sign
  1598. call term_sendkeys(buf, ":sign place 11 line=2 name=s2\<CR>")
  1599. call VerifyScreenDump(buf, 'Test_sign_cursor_3', {})
  1600. " update cursor position calculation
  1601. call term_sendkeys(buf, "lh")
  1602. call term_sendkeys(buf, ":sign unplace 11\<CR>")
  1603. call term_sendkeys(buf, ":sign unplace 10\<CR>")
  1604. call VerifyScreenDump(buf, 'Test_sign_cursor_4', {})
  1605. " clean up
  1606. call StopVimInTerminal(buf)
  1607. endfunc
  1608. " Return the 'len' characters in screen starting from (row,col)
  1609. func s:ScreenLine(row, col, len)
  1610. let s = ''
  1611. for i in range(a:len)
  1612. let s .= nr2char(screenchar(a:row, a:col + i))
  1613. endfor
  1614. return s
  1615. endfunc
  1616. " Test for 'signcolumn' set to 'number'.
  1617. func Test_sign_numcol()
  1618. new
  1619. call append(0, "01234")
  1620. " With 'signcolumn' set to 'number', make sure sign is displayed in the
  1621. " number column and line number is not displayed.
  1622. set numberwidth=2
  1623. set number
  1624. set signcolumn=number
  1625. sign define sign1 text==>
  1626. sign define sign2 text=V
  1627. sign place 10 line=1 name=sign1
  1628. redraw!
  1629. call assert_equal("=> 01234", s:ScreenLine(1, 1, 8))
  1630. " With 'signcolumn' set to 'number', when there is no sign, make sure line
  1631. " number is displayed in the number column
  1632. sign unplace 10
  1633. redraw!
  1634. call assert_equal("1 01234", s:ScreenLine(1, 1, 7))
  1635. " Disable number column. Check whether sign is displayed in the sign column
  1636. set numberwidth=4
  1637. set nonumber
  1638. sign place 10 line=1 name=sign1
  1639. redraw!
  1640. call assert_equal("=>01234", s:ScreenLine(1, 1, 7))
  1641. " Enable number column. Check whether sign is displayed in the number column
  1642. set number
  1643. redraw!
  1644. call assert_equal(" => 01234", s:ScreenLine(1, 1, 9))
  1645. " Disable sign column. Make sure line number is displayed
  1646. set signcolumn=no
  1647. redraw!
  1648. call assert_equal(" 1 01234", s:ScreenLine(1, 1, 9))
  1649. " Enable auto sign column. Make sure both sign and line number are displayed
  1650. set signcolumn=auto
  1651. redraw!
  1652. call assert_equal("=> 1 01234", s:ScreenLine(1, 1, 11))
  1653. " Test displaying signs in the number column with width 1
  1654. call sign_unplace('*')
  1655. call append(1, "abcde")
  1656. call append(2, "01234")
  1657. " Enable number column with width 1
  1658. set number numberwidth=1 signcolumn=auto
  1659. redraw!
  1660. call assert_equal("3 01234", s:ScreenLine(3, 1, 7))
  1661. " Place a sign and make sure number column width remains the same
  1662. sign place 20 line=2 name=sign1
  1663. redraw!
  1664. call assert_equal("=>2 abcde", s:ScreenLine(2, 1, 9))
  1665. call assert_equal(" 3 01234", s:ScreenLine(3, 1, 9))
  1666. " Set 'signcolumn' to 'number', make sure the number column width increases
  1667. set signcolumn=number
  1668. redraw!
  1669. call assert_equal("=> abcde", s:ScreenLine(2, 1, 8))
  1670. call assert_equal(" 3 01234", s:ScreenLine(3, 1, 8))
  1671. " Set 'signcolumn' to 'auto', make sure the number column width is 1.
  1672. set signcolumn=auto
  1673. redraw!
  1674. call assert_equal("=>2 abcde", s:ScreenLine(2, 1, 9))
  1675. call assert_equal(" 3 01234", s:ScreenLine(3, 1, 9))
  1676. " Set 'signcolumn' to 'number', make sure the number column width is 2.
  1677. set signcolumn=number
  1678. redraw!
  1679. call assert_equal("=> abcde", s:ScreenLine(2, 1, 8))
  1680. call assert_equal(" 3 01234", s:ScreenLine(3, 1, 8))
  1681. " Disable 'number' column
  1682. set nonumber
  1683. redraw!
  1684. call assert_equal("=>abcde", s:ScreenLine(2, 1, 7))
  1685. call assert_equal(" 01234", s:ScreenLine(3, 1, 7))
  1686. " Enable 'number' column
  1687. set number
  1688. redraw!
  1689. call assert_equal("=> abcde", s:ScreenLine(2, 1, 8))
  1690. call assert_equal(" 3 01234", s:ScreenLine(3, 1, 8))
  1691. " Remove the sign and make sure the width of the number column is 1.
  1692. call sign_unplace('', {'id' : 20})
  1693. redraw!
  1694. call assert_equal("3 01234", s:ScreenLine(3, 1, 7))
  1695. " When the first sign is placed with 'signcolumn' set to number, verify that
  1696. " the number column width increases
  1697. sign place 30 line=1 name=sign1
  1698. redraw!
  1699. call assert_equal("=> 01234", s:ScreenLine(1, 1, 8))
  1700. call assert_equal(" 2 abcde", s:ScreenLine(2, 1, 8))
  1701. " Add sign with multi-byte text
  1702. set numberwidth=4
  1703. sign place 40 line=2 name=sign2
  1704. redraw!
  1705. call assert_equal(" => 01234", s:ScreenLine(1, 1, 9))
  1706. call assert_equal(" V abcde", s:ScreenLine(2, 1, 9))
  1707. sign unplace * group=*
  1708. sign undefine sign1
  1709. set signcolumn&
  1710. set number&
  1711. enew! | close
  1712. endfunc
  1713. " Test for managing multiple signs using the sign functions
  1714. func Test_sign_funcs_multi()
  1715. call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
  1716. edit Xsign
  1717. let bnum = bufnr('')
  1718. " Define multiple signs at once
  1719. call assert_equal([0, 0, 0, 0], sign_define([
  1720. \ {'name' : 'sign1', 'text' : '=>', 'linehl' : 'Search',
  1721. \ 'texthl' : 'Search'},
  1722. \ {'name' : 'sign2', 'text' : '=>', 'linehl' : 'Search',
  1723. \ 'texthl' : 'Search'},
  1724. \ {'name' : 'sign3', 'text' : '=>', 'linehl' : 'Search',
  1725. \ 'texthl' : 'Search'},
  1726. \ {'name' : 'sign4', 'text' : '=>', 'linehl' : 'Search',
  1727. \ 'texthl' : 'Search'}]))
  1728. " Negative cases for sign_define()
  1729. call assert_equal([], sign_define([]))
  1730. call assert_equal([-1], sign_define([{}]))
  1731. call assert_fails('call sign_define([6])', 'E715:')
  1732. call assert_fails('call sign_define(["abc"])', 'E715:')
  1733. call assert_fails('call sign_define([[]])', 'E715:')
  1734. " Place multiple signs at once with specific sign identifier
  1735. let l = sign_placelist([{'id' : 1, 'group' : 'g1', 'name' : 'sign1',
  1736. \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 50},
  1737. \ {'id' : 2, 'group' : 'g2', 'name' : 'sign2',
  1738. \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 100},
  1739. \ {'id' : 3, 'group' : '', 'name' : 'sign3',
  1740. \ 'buffer' : 'Xsign', 'lnum' : 11}])
  1741. call assert_equal([1, 2, 3], l)
  1742. let s = sign_getplaced('Xsign', {'group' : '*'})
  1743. call assert_equal([
  1744. \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11,
  1745. \ 'group' : 'g2', 'priority' : 100},
  1746. \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11,
  1747. \ 'group' : 'g1', 'priority' : 50},
  1748. \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11,
  1749. \ 'group' : '', 'priority' : 10}], s[0].signs)
  1750. call sign_unplace('*')
  1751. " Place multiple signs at once with auto-generated sign identifier
  1752. " Nvim: next sign id is not reset and is always incremented
  1753. call assert_equal([2, 3, 4], sign_placelist([
  1754. \ {'group' : 'g1', 'name' : 'sign1',
  1755. \ 'buffer' : 'Xsign', 'lnum' : 11},
  1756. \ {'group' : 'g2', 'name' : 'sign2',
  1757. \ 'buffer' : 'Xsign', 'lnum' : 11},
  1758. \ {'group' : '', 'name' : 'sign3',
  1759. \ 'buffer' : 'Xsign', 'lnum' : 11}]))
  1760. let s = sign_getplaced('Xsign', {'group' : '*'})
  1761. call assert_equal([
  1762. \ {'id' : 4, 'name' : 'sign3', 'lnum' : 11,
  1763. \ 'group' : '', 'priority' : 10},
  1764. \ {'id' : 3, 'name' : 'sign2', 'lnum' : 11,
  1765. \ 'group' : 'g2', 'priority' : 10},
  1766. \ {'id' : 2, 'name' : 'sign1', 'lnum' : 11,
  1767. \ 'group' : 'g1', 'priority' : 10}], s[0].signs)
  1768. " Change an existing sign without specifying the group
  1769. call assert_equal([4], [{'id' : 4, 'name' : 'sign1', 'buffer' : 'Xsign'}]->sign_placelist())
  1770. let s = sign_getplaced('Xsign', {'id' : 4, 'group' : ''})
  1771. call assert_equal([{'id' : 4, 'name' : 'sign1', 'lnum' : 11,
  1772. \ 'group' : '', 'priority' : 10}], s[0].signs)
  1773. " Place a sign using '.' as the line number
  1774. call cursor(23, 1)
  1775. call assert_equal([7], sign_placelist([
  1776. \ {'id' : 7, 'name' : 'sign1', 'buffer' : '%', 'lnum' : '.'}]))
  1777. let s = sign_getplaced('%', {'lnum' : '.'})
  1778. call assert_equal([{'id' : 7, 'name' : 'sign1', 'lnum' : 23,
  1779. \ 'group' : '', 'priority' : 10}], s[0].signs)
  1780. " Place sign without a sign name
  1781. call assert_equal([-1], sign_placelist([{'id' : 10, 'buffer' : 'Xsign',
  1782. \ 'lnum' : 12, 'group' : ''}]))
  1783. " Place sign without a buffer
  1784. call assert_equal([-1], sign_placelist([{'id' : 10, 'name' : 'sign1',
  1785. \ 'lnum' : 12, 'group' : ''}]))
  1786. " Invalid arguments
  1787. call assert_equal([], sign_placelist([]))
  1788. call assert_fails('call sign_placelist({})', "E714:")
  1789. call assert_fails('call sign_placelist([[]])', "E715:")
  1790. call assert_fails('call sign_placelist(["abc"])', "E715:")
  1791. call assert_fails('call sign_placelist([100])', "E715:")
  1792. " Unplace multiple signs
  1793. call assert_equal([0, 0, 0], sign_unplacelist([{'id' : 4},
  1794. \ {'id' : 2, 'group' : 'g1'}, {'id' : 3, 'group' : 'g2'}]))
  1795. " Invalid arguments
  1796. call assert_equal([], []->sign_unplacelist())
  1797. call assert_fails('call sign_unplacelist({})', "E714:")
  1798. call assert_fails('call sign_unplacelist([[]])', "E715:")
  1799. call assert_fails('call sign_unplacelist(["abc"])', "E715:")
  1800. call assert_fails('call sign_unplacelist([100])', "E715:")
  1801. call assert_fails("call sign_unplacelist([{'id' : -1}])", 'E474')
  1802. call assert_equal([0, 0, 0, 0],
  1803. \ sign_undefine(['sign1', 'sign2', 'sign3', 'sign4']))
  1804. call assert_equal([], sign_getdefined())
  1805. " Invalid arguments
  1806. call assert_equal([], sign_undefine([]))
  1807. call assert_fails('call sign_undefine([[]])', 'E730:')
  1808. call assert_fails('call sign_undefine([{}])', 'E731:')
  1809. call assert_fails('call sign_undefine(["1abc2"])', 'E155:')
  1810. call sign_unplace('*')
  1811. call sign_undefine()
  1812. enew!
  1813. endfunc
  1814. func Test_sign_null_list()
  1815. eval v:_null_list->sign_define()
  1816. eval v:_null_list->sign_placelist()
  1817. eval v:_null_list->sign_undefine()
  1818. eval v:_null_list->sign_unplacelist()
  1819. endfunc
  1820. " vim: shiftwidth=2 sts=2 expandtab