blob: 426998d6d7af378ee2d4e85bd0c4d9d06521f30a [file] [log] [blame]
Bram Moolenaar09de1752016-08-08 22:26:48 +02001" Test for signs
2
3if !has('signs')
4 finish
5endif
6
7func Test_sign()
8 new
9 call setline(1, ['a', 'b', 'c', 'd'])
10
Bram Moolenaar446a9732016-08-10 21:36:23 +020011 " Define some signs.
12 " We can specify icons even if not all versions of vim support icons as
13 " icon is ignored when not supported. "(not supported)" is shown after
14 " the icon name when listing signs.
Bram Moolenaar09de1752016-08-08 22:26:48 +020015 sign define Sign1 text=x
Bram Moolenaar446a9732016-08-10 21:36:23 +020016 try
Bram Moolenaarb328cca2019-01-06 16:24:01 +010017 sign define Sign2 text=xy texthl=Title linehl=Error
18 \ icon=../../pixmaps/stock_vim_find_help.png
Bram Moolenaar446a9732016-08-10 21:36:23 +020019 catch /E255:/
Bram Moolenaar162b7142018-12-21 15:17:36 +010020 " Ignore error: E255: Couldn't read in sign data!
21 " This error can happen when running in the GUI.
Bram Moolenaar446a9732016-08-10 21:36:23 +020022 " Some gui like Motif do not support the png icon format.
23 endtry
Bram Moolenaar09de1752016-08-08 22:26:48 +020024
25 " Test listing signs.
26 let a=execute('sign list')
Bram Moolenaarb328cca2019-01-06 16:24:01 +010027 call assert_match('^\nsign Sign1 text=x \nsign Sign2 ' .
28 \ 'icon=../../pixmaps/stock_vim_find_help.png .*text=xy ' .
29 \ 'linehl=Error texthl=Title$', a)
Bram Moolenaar09de1752016-08-08 22:26:48 +020030
31 let a=execute('sign list Sign1')
32 call assert_equal("\nsign Sign1 text=x ", a)
33
Bram Moolenaar7d83bf42018-12-29 18:53:55 +010034 " Split the window to the bottom to verify sign jump will stay in the
35 " current window if the buffer is displayed there.
Bram Moolenaar446a9732016-08-10 21:36:23 +020036 let bn = bufnr('%')
37 let wn = winnr()
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +010038 exe 'sign place 41 line=3 name=Sign1 buffer=' . bn
Bram Moolenaar09de1752016-08-08 22:26:48 +020039 1
Bram Moolenaar446a9732016-08-10 21:36:23 +020040 bot split
41 exe 'sign jump 41 buffer=' . bufnr('%')
42 call assert_equal('c', getline('.'))
43 call assert_equal(3, winnr())
44 call assert_equal(bn, bufnr('%'))
45 call assert_notequal(wn, winnr())
46
47 " Create a new buffer and check that ":sign jump" switches to the old buffer.
48 1
49 new foo
50 call assert_notequal(bn, bufnr('%'))
51 exe 'sign jump 41 buffer=' . bn
52 call assert_equal(bn, bufnr('%'))
Bram Moolenaar09de1752016-08-08 22:26:48 +020053 call assert_equal('c', getline('.'))
54
Bram Moolenaar446a9732016-08-10 21:36:23 +020055 " Redraw to make sure that screen redraw with sign gets exercised,
56 " with and without 'rightleft'.
57 if has('rightleft')
58 set rightleft
59 redraw
60 set norightleft
61 endif
62 redraw
Bram Moolenaar09de1752016-08-08 22:26:48 +020063
Bram Moolenaar446a9732016-08-10 21:36:23 +020064 " Check that we can't change sign.
Bram Moolenaar7a2d9892018-12-24 20:23:49 +010065 call assert_fails("sign place 40 name=Sign1 buffer=" . bufnr('%'), 'E885:')
Bram Moolenaar446a9732016-08-10 21:36:23 +020066
67 " Check placed signs
Bram Moolenaar09de1752016-08-08 22:26:48 +020068 let a=execute('sign place')
Bram Moolenaarb328cca2019-01-06 16:24:01 +010069 call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +010070 \ " line=3 id=41 name=Sign1 priority=10\n", a)
Bram Moolenaar09de1752016-08-08 22:26:48 +020071
Bram Moolenaar446a9732016-08-10 21:36:23 +020072 " Unplace the sign and try jumping to it again should fail.
73 sign unplace 41
Bram Moolenaar09de1752016-08-08 22:26:48 +020074 1
Bram Moolenaar7a2d9892018-12-24 20:23:49 +010075 call assert_fails("sign jump 41 buffer=" . bufnr('%'), 'E157:')
Bram Moolenaar09de1752016-08-08 22:26:48 +020076 call assert_equal('a', getline('.'))
77
78 " Unplace sign on current line.
Bram Moolenaar446a9732016-08-10 21:36:23 +020079 exe 'sign place 42 line=4 name=Sign2 buffer=' . bufnr('%')
Bram Moolenaar09de1752016-08-08 22:26:48 +020080 4
81 sign unplace
82 let a=execute('sign place')
83 call assert_equal("\n--- Signs ---\n", a)
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +010084
Bram Moolenaar09de1752016-08-08 22:26:48 +020085 " Try again to unplace sign on current line, it should fail this time.
86 call assert_fails('sign unplace', 'E159:')
87
88 " Unplace all signs.
Bram Moolenaar446a9732016-08-10 21:36:23 +020089 exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%')
Bram Moolenaar09de1752016-08-08 22:26:48 +020090 sign unplace *
91 let a=execute('sign place')
92 call assert_equal("\n--- Signs ---\n", a)
93
Bram Moolenaarb328cca2019-01-06 16:24:01 +010094 " Place a sign without specifying the filename or buffer
95 sign place 77 line=9 name=Sign2
96 let a=execute('sign place')
97 call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +010098 \ " line=9 id=77 name=Sign2 priority=10\n", a)
Bram Moolenaarb328cca2019-01-06 16:24:01 +010099 sign unplace *
100
Bram Moolenaar446a9732016-08-10 21:36:23 +0200101 " Check :jump with file=...
102 edit foo
103 call setline(1, ['A', 'B', 'C', 'D'])
104
105 try
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100106 sign define Sign3 text=y texthl=DoesNotExist linehl=DoesNotExist
107 \ icon=doesnotexist.xpm
Bram Moolenaar446a9732016-08-10 21:36:23 +0200108 catch /E255:/
109 " ignore error: E255: it can happens for guis.
110 endtry
111
112 let fn = expand('%:p')
113 exe 'sign place 43 line=2 name=Sign3 file=' . fn
114 edit bar
115 call assert_notequal(fn, expand('%:p'))
116 exe 'sign jump 43 file=' . fn
117 call assert_equal('B', getline('.'))
118
Bram Moolenaara3556522018-12-31 22:02:29 +0100119 " Check for jumping to a sign in a hidden buffer
120 enew! | only!
121 edit foo
122 call setline(1, ['A', 'B', 'C', 'D'])
123 let fn = expand('%:p')
124 exe 'sign place 21 line=3 name=Sign3 file=' . fn
125 hide edit bar
126 exe 'sign jump 21 file=' . fn
127 call assert_equal('C', getline('.'))
128
Bram Moolenaar06b056e2018-12-14 19:37:08 +0100129 " can't define a sign with a non-printable character as text
130 call assert_fails("sign define Sign4 text=\e linehl=Comment", 'E239:')
131 call assert_fails("sign define Sign4 text=a\e linehl=Comment", 'E239:')
132 call assert_fails("sign define Sign4 text=\ea linehl=Comment", 'E239:')
133
134 " Only 1 or 2 character text is allowed
135 call assert_fails("sign define Sign4 text=abc linehl=Comment", 'E239:')
136 call assert_fails("sign define Sign4 text= linehl=Comment", 'E239:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100137 call assert_fails("sign define Sign4 text=\\ ab linehl=Comment", 'E239:')
Bram Moolenaar06b056e2018-12-14 19:37:08 +0100138
139 " define sign with whitespace
140 sign define Sign4 text=\ X linehl=Comment
141 sign undefine Sign4
142 sign define Sign4 linehl=Comment text=\ X
143 sign undefine Sign4
144
145 sign define Sign5 text=X\ linehl=Comment
146 sign undefine Sign5
147 sign define Sign5 linehl=Comment text=X\
148 sign undefine Sign5
149
150 " define sign with backslash
151 sign define Sign4 text=\\\\ linehl=Comment
152 sign undefine Sign4
153 sign define Sign4 text=\\ linehl=Comment
154 sign undefine Sign4
155
Bram Moolenaara3556522018-12-31 22:02:29 +0100156 " define a sign with a leading 0 in the name
157 sign unplace *
158 sign define 004 text=#> linehl=Comment
159 let a = execute('sign list 4')
160 call assert_equal("\nsign 4 text=#> linehl=Comment", a)
161 exe 'sign place 20 line=3 name=004 buffer=' . bufnr('')
162 let a = execute('sign place')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100163 call assert_equal("\n--- Signs ---\nSigns for foo:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100164 \ " line=3 id=20 name=4 priority=10\n", a)
Bram Moolenaara3556522018-12-31 22:02:29 +0100165 exe 'sign unplace 20 buffer=' . bufnr('')
166 sign undefine 004
167 call assert_fails('sign list 4', 'E155:')
168
Bram Moolenaar09de1752016-08-08 22:26:48 +0200169 " After undefining the sign, we should no longer be able to place it.
170 sign undefine Sign1
171 sign undefine Sign2
Bram Moolenaar446a9732016-08-10 21:36:23 +0200172 sign undefine Sign3
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100173 call assert_fails("sign place 41 line=3 name=Sign1 buffer=" .
174 \ bufnr('%'), 'E155:')
Bram Moolenaar446a9732016-08-10 21:36:23 +0200175endfunc
Bram Moolenaar09de1752016-08-08 22:26:48 +0200176
Bram Moolenaar446a9732016-08-10 21:36:23 +0200177" Undefining placed sign is not recommended.
178" Quoting :help sign
179"
180" :sign undefine {name}
181" Deletes a previously defined sign. If signs with this {name}
182" are still placed this will cause trouble.
183func Test_sign_undefine_still_placed()
184 new foobar
185 sign define Sign text=x
186 exe 'sign place 41 line=1 name=Sign buffer=' . bufnr('%')
187 sign undefine Sign
188
189 " Listing placed sign should show that sign is deleted.
190 let a=execute('sign place')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100191 call assert_equal("\n--- Signs ---\nSigns for foobar:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100192 \ " line=1 id=41 name=[Deleted] priority=10\n", a)
Bram Moolenaar446a9732016-08-10 21:36:23 +0200193
194 sign unplace 41
195 let a=execute('sign place')
196 call assert_equal("\n--- Signs ---\n", a)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200197endfunc
198
199func Test_sign_completion()
200 sign define Sign1 text=x
201 sign define Sign2 text=y
202
203 call feedkeys(":sign \<C-A>\<C-B>\"\<CR>", 'tx')
204 call assert_equal('"sign define jump list place undefine unplace', @:)
205
206 call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
207 call assert_equal('"sign define Sign icon= linehl= text= texthl=', @:)
208
209 call feedkeys(":sign define Sign linehl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100210 call assert_equal('"sign define Sign linehl=SpellBad SpellCap ' .
211 \ 'SpellLocal SpellRare', @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200212
Bram Moolenaar3678f652019-02-17 14:50:25 +0100213 call feedkeys(":sign define Sign texthl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
214 call assert_equal('"sign define Sign texthl=SpellBad SpellCap ' .
215 \ 'SpellLocal SpellRare', @:)
216
217 call writefile(repeat(["Sun is shining"], 30), "XsignOne")
218 call writefile(repeat(["Sky is blue"], 30), "XsignTwo")
Bram Moolenaar64cefed2016-08-29 23:06:28 +0200219 call feedkeys(":sign define Sign icon=Xsig\<C-A>\<C-B>\"\<CR>", 'tx')
220 call assert_equal('"sign define Sign icon=XsignOne XsignTwo', @:)
Bram Moolenaar446a9732016-08-10 21:36:23 +0200221
Bram Moolenaar3678f652019-02-17 14:50:25 +0100222 " Test for completion of arguments to ':sign undefine'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200223 call feedkeys(":sign undefine \<C-A>\<C-B>\"\<CR>", 'tx')
224 call assert_equal('"sign undefine Sign1 Sign2', @:)
225
226 call feedkeys(":sign place 1 \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100227 call assert_equal('"sign place 1 buffer= file= group= line= name= priority=',
228 \ @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200229
230 call feedkeys(":sign place 1 name=\<C-A>\<C-B>\"\<CR>", 'tx')
231 call assert_equal('"sign place 1 name=Sign1 Sign2', @:)
232
Bram Moolenaar3678f652019-02-17 14:50:25 +0100233 edit XsignOne
234 sign place 1 name=Sign1 line=5
235 sign place 1 name=Sign1 group=g1 line=10
236 edit XsignTwo
237 sign place 1 name=Sign2 group=g2 line=15
238
239 " Test for completion of group= and file= arguments to ':sign place'
240 call feedkeys(":sign place 1 name=Sign1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
241 call assert_equal('"sign place 1 name=Sign1 file=XsignOne XsignTwo', @:)
242 call feedkeys(":sign place 1 name=Sign1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
243 call assert_equal('"sign place 1 name=Sign1 group=g1 g2', @:)
244
245 " Test for completion of arguments to 'sign place' without sign identifier
246 call feedkeys(":sign place \<C-A>\<C-B>\"\<CR>", 'tx')
247 call assert_equal('"sign place buffer= file= group=', @:)
248 call feedkeys(":sign place file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
249 call assert_equal('"sign place file=XsignOne XsignTwo', @:)
250 call feedkeys(":sign place group=\<C-A>\<C-B>\"\<CR>", 'tx')
251 call assert_equal('"sign place group=g1 g2', @:)
252 call feedkeys(":sign place group=g1 file=\<C-A>\<C-B>\"\<CR>", 'tx')
253 call assert_equal('"sign place group=g1 file=XsignOne XsignTwo', @:)
254
255 " Test for completion of arguments to ':sign unplace'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200256 call feedkeys(":sign unplace 1 \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100257 call assert_equal('"sign unplace 1 buffer= file= group=', @:)
Bram Moolenaar3678f652019-02-17 14:50:25 +0100258 call feedkeys(":sign unplace 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
259 call assert_equal('"sign unplace 1 file=XsignOne XsignTwo', @:)
260 call feedkeys(":sign unplace 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
261 call assert_equal('"sign unplace 1 group=g1 g2', @:)
262 call feedkeys(":sign unplace 1 group=g2 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
263 call assert_equal('"sign unplace 1 group=g2 file=XsignOne XsignTwo', @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200264
Bram Moolenaar3678f652019-02-17 14:50:25 +0100265 " Test for completion of arguments to ':sign list'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200266 call feedkeys(":sign list \<C-A>\<C-B>\"\<CR>", 'tx')
267 call assert_equal('"sign list Sign1 Sign2', @:)
268
Bram Moolenaar3678f652019-02-17 14:50:25 +0100269 " Test for completion of arguments to ':sign jump'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200270 call feedkeys(":sign jump 1 \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100271 call assert_equal('"sign jump 1 buffer= file= group=', @:)
Bram Moolenaar3678f652019-02-17 14:50:25 +0100272 call feedkeys(":sign jump 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
273 call assert_equal('"sign jump 1 file=XsignOne XsignTwo', @:)
274 call feedkeys(":sign jump 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
275 call assert_equal('"sign jump 1 group=g1 g2', @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200276
Bram Moolenaar3678f652019-02-17 14:50:25 +0100277 " Error cases
278 call feedkeys(":sign here\<C-A>\<C-B>\"\<CR>", 'tx')
279 call assert_equal('"sign here', @:)
280 call feedkeys(":sign define Sign here=\<C-A>\<C-B>\"\<CR>", 'tx')
281 call assert_equal("\"sign define Sign here=\<C-A>", @:)
282 call feedkeys(":sign place 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
283 call assert_equal("\"sign place 1 here=\<C-A>", @:)
284 call feedkeys(":sign jump 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
285 call assert_equal("\"sign jump 1 here=\<C-A>", @:)
286 call feedkeys(":sign here there\<C-A>\<C-B>\"\<CR>", 'tx')
287 call assert_equal("\"sign here there\<C-A>", @:)
288 call feedkeys(":sign here there=\<C-A>\<C-B>\"\<CR>", 'tx')
289 call assert_equal("\"sign here there=\<C-A>", @:)
290
291 sign unplace * group=*
Bram Moolenaar09de1752016-08-08 22:26:48 +0200292 sign undefine Sign1
293 sign undefine Sign2
Bram Moolenaar3678f652019-02-17 14:50:25 +0100294 enew
295 call delete('XsignOne')
296 call delete('XsignTwo')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200297endfunc
298
299func Test_sign_invalid_commands()
Bram Moolenaar162b7142018-12-21 15:17:36 +0100300 sign define Sign1 text=x
301
Bram Moolenaar09de1752016-08-08 22:26:48 +0200302 call assert_fails('sign', 'E471:')
Bram Moolenaar446a9732016-08-10 21:36:23 +0200303 call assert_fails('sign jump', 'E471:')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200304 call assert_fails('sign xxx', 'E160:')
305 call assert_fails('sign define', 'E156:')
Bram Moolenaar446a9732016-08-10 21:36:23 +0200306 call assert_fails('sign define Sign1 xxx', 'E475:')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200307 call assert_fails('sign undefine', 'E156:')
308 call assert_fails('sign list xxx', 'E155:')
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200309 call assert_fails('sign place 1 buffer=999', 'E158:')
Bram Moolenaara3556522018-12-31 22:02:29 +0100310 call assert_fails('sign place 1 name=Sign1 buffer=999', 'E158:')
311 call assert_fails('sign place buffer=999', 'E158:')
312 call assert_fails('sign jump buffer=999', 'E158:')
313 call assert_fails('sign jump 1 file=', 'E158:')
314 call assert_fails('sign jump 1 group=', 'E474:')
315 call assert_fails('sign jump 1 name=', 'E474:')
316 call assert_fails('sign jump 1 name=Sign1', 'E474:')
317 call assert_fails('sign jump 1 line=100', '474:')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200318 call assert_fails('sign define Sign2 text=', 'E239:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100319 " Non-numeric identifier for :sign place
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100320 call assert_fails("sign place abc line=3 name=Sign1 buffer=" . bufnr(''),
321 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100322 " Non-numeric identifier for :sign unplace
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100323 call assert_fails("sign unplace abc name=Sign1 buffer=" . bufnr(''),
324 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100325 " Number followed by an alphabet as sign identifier for :sign place
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100326 call assert_fails("sign place 1abc line=3 name=Sign1 buffer=" . bufnr(''),
327 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100328 " Number followed by an alphabet as sign identifier for :sign unplace
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100329 call assert_fails("sign unplace 2abc name=Sign1 buffer=" . bufnr(''),
330 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100331 " Sign identifier and '*' for :sign unplace
332 call assert_fails("sign unplace 2 *", 'E474:')
333 " Trailing characters after buffer number for :sign place
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100334 call assert_fails("sign place 1 line=3 name=Sign1 buffer=" .
335 \ bufnr('%') . 'xxx', 'E488:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100336 " Trailing characters after buffer number for :sign unplace
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100337 call assert_fails("sign unplace 1 buffer=" . bufnr('%') . 'xxx', 'E488:')
338 call assert_fails("sign unplace * buffer=" . bufnr('%') . 'xxx', 'E488:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100339 call assert_fails("sign unplace 1 xxx", 'E474:')
340 call assert_fails("sign unplace * xxx", 'E474:')
341 call assert_fails("sign unplace xxx", 'E474:')
342 " Placing a sign without line number
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100343 call assert_fails("sign place name=Sign1 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100344 " Placing a sign without sign name
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100345 call assert_fails("sign place line=10 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100346 " Unplacing a sign with line number
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100347 call assert_fails("sign unplace 2 line=10 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100348 " Unplacing a sign with sign name
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100349 call assert_fails("sign unplace 2 name=Sign1 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100350 " Placing a sign without sign name
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100351 call assert_fails("sign place 2 line=3 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100352 " Placing a sign with only sign identifier
353 call assert_fails("sign place 2", 'E474:')
354 " Placing a sign with only a name
355 call assert_fails("sign place abc", 'E474:')
356 " Placing a sign with only line number
357 call assert_fails("sign place 5 line=3", 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100358 " Placing a sign with only sign group
359 call assert_fails("sign place 5 group=g1", 'E474:')
360 call assert_fails("sign place 5 group=*", 'E474:')
361 " Placing a sign with only sign priority
362 call assert_fails("sign place 5 priority=10", 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100363
364 sign undefine Sign1
Bram Moolenaar09de1752016-08-08 22:26:48 +0200365endfunc
Bram Moolenaarbfd096d2016-08-17 22:29:09 +0200366
367func Test_sign_delete_buffer()
368 new
369 sign define Sign text=x
370 let bufnr = bufnr('%')
371 new
372 exe 'bd ' . bufnr
373 exe 'sign place 61 line=3 name=Sign buffer=' . bufnr
374 call assert_fails('sign jump 61 buffer=' . bufnr, 'E934:')
375 sign unplace 61
376 sign undefine Sign
377endfunc
Bram Moolenaar162b7142018-12-21 15:17:36 +0100378
Bram Moolenaar6436cd82018-12-27 00:28:33 +0100379" Test for Vim script functions for managing signs
Bram Moolenaar162b7142018-12-21 15:17:36 +0100380func Test_sign_funcs()
381 " Remove all the signs
382 call sign_unplace('*')
383 call sign_undefine()
384
385 " Tests for sign_define()
386 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
387 call assert_equal(0, sign_define("sign1", attr))
388 call assert_equal([{'name' : 'sign1', 'texthl' : 'Error',
389 \ 'linehl' : 'Search', 'text' : '=>'}], sign_getdefined())
390
391 " Define a new sign without attributes and then update it
392 call sign_define("sign2")
393 let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange',
394 \ 'icon' : 'sign2.ico'}
395 try
396 call sign_define("sign2", attr)
397 catch /E255:/
398 " ignore error: E255: Couldn't read in sign data!
399 " This error can happen when running in gui.
400 endtry
401 call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange',
402 \ 'linehl' : 'DiffAdd', 'text' : '!!', 'icon' : 'sign2.ico'}],
403 \ sign_getdefined("sign2"))
404
405 " Test for a sign name with digits
406 call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'}))
407 call assert_equal([{'name' : '2', 'linehl' : 'StatusLine'}],
408 \ sign_getdefined(0002))
409 call sign_undefine(0002)
410
411 " Tests for invalid arguments to sign_define()
412 call assert_fails('call sign_define("sign4", {"text" : "===>"})', 'E239:')
413 call assert_fails('call sign_define("sign5", {"text" : ""})', 'E239:')
414 call assert_fails('call sign_define([])', 'E730:')
415 call assert_fails('call sign_define("sign6", [])', 'E715:')
416
417 " Tests for sign_getdefined()
418 call assert_equal([], sign_getdefined("none"))
419 call assert_fails('call sign_getdefined({})', 'E731:')
420
421 " Tests for sign_place()
422 call writefile(repeat(["Sun is shining"], 30), "Xsign")
423 edit Xsign
424
425 call assert_equal(10, sign_place(10, '', 'sign1', 'Xsign',
426 \ {'lnum' : 20}))
427 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
428 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
429 \ 'priority' : 10}]}], sign_getplaced('Xsign'))
430 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
431 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
432 \ 'priority' : 10}]}],
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100433 \ sign_getplaced('%', {'lnum' : 20}))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100434 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
435 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
436 \ 'priority' : 10}]}],
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100437 \ sign_getplaced('', {'id' : 10}))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100438
439 " Tests for invalid arguments to sign_place()
440 call assert_fails('call sign_place([], "", "mySign", 1)', 'E745:')
441 call assert_fails('call sign_place(5, "", "mySign", -1)', 'E158:')
442 call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])',
443 \ 'E474:')
444 call assert_fails('call sign_place(-1, "", "sign1", "Xsign",
445 \ {"lnum" : 30})', 'E474:')
446 call assert_fails('call sign_place(10, "", "xsign1x", "Xsign",
447 \ {"lnum" : 30})', 'E155:')
448 call assert_fails('call sign_place(10, "", "", "Xsign",
449 \ {"lnum" : 30})', 'E155:')
450 call assert_fails('call sign_place(10, "", [], "Xsign",
451 \ {"lnum" : 30})', 'E730:')
452 call assert_fails('call sign_place(5, "", "sign1", "abcxyz.xxx",
453 \ {"lnum" : 10})', 'E158:')
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100454 call assert_fails('call sign_place(5, "", "sign1", "@", {"lnum" : 10})',
Bram Moolenaar162b7142018-12-21 15:17:36 +0100455 \ 'E158:')
456 call assert_fails('call sign_place(5, "", "sign1", [], {"lnum" : 10})',
457 \ 'E158:')
458 call assert_fails('call sign_place(21, "", "sign1", "Xsign",
459 \ {"lnum" : -1})', 'E885:')
460 call assert_fails('call sign_place(22, "", "sign1", "Xsign",
461 \ {"lnum" : 0})', 'E885:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100462 call assert_fails('call sign_place(22, "", "sign1", "Xsign",
463 \ {"lnum" : []})', 'E745:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100464 call assert_equal(-1, sign_place(1, "*", "sign1", "Xsign", {"lnum" : 10}))
465
466 " Tests for sign_getplaced()
467 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
468 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
469 \ 'priority' : 10}]}],
470 \ sign_getplaced(bufnr('Xsign')))
471 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
472 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
473 \ 'priority' : 10}]}],
474 \ sign_getplaced())
475 call assert_fails("call sign_getplaced('dummy.sign')", 'E158:')
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100476 call assert_fails('call sign_getplaced("&")', 'E158:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100477 call assert_fails('call sign_getplaced(-1)', 'E158:')
478 call assert_fails('call sign_getplaced("Xsign", [])', 'E715:')
479 call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}],
480 \ sign_getplaced('Xsign', {'lnum' : 1000000}))
481 call assert_fails("call sign_getplaced('Xsign', {'lnum' : []})",
482 \ 'E745:')
483 call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}],
484 \ sign_getplaced('Xsign', {'id' : 44}))
485 call assert_fails("call sign_getplaced('Xsign', {'id' : []})",
486 \ 'E745:')
487
488 " Tests for sign_unplace()
489 call sign_place(20, '', 'sign2', 'Xsign', {"lnum" : 30})
490 call assert_equal(0, sign_unplace('',
491 \ {'id' : 20, 'buffer' : 'Xsign'}))
492 call assert_equal(-1, sign_unplace('',
493 \ {'id' : 30, 'buffer' : 'Xsign'}))
494 call sign_place(20, '', 'sign2', 'Xsign', {"lnum" : 30})
495 call assert_fails("call sign_unplace('',
496 \ {'id' : 20, 'buffer' : 'buffer.c'})", 'E158:')
497 call assert_fails("call sign_unplace('',
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100498 \ {'id' : 20, 'buffer' : '&'})", 'E158:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100499 call assert_fails("call sign_unplace('g1',
Bram Moolenaar162b7142018-12-21 15:17:36 +0100500 \ {'id' : 20, 'buffer' : 200})", 'E158:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100501 call assert_fails("call sign_unplace('g1', 'mySign')", 'E715:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100502
503 " Tests for sign_undefine()
504 call assert_equal(0, sign_undefine("sign1"))
505 call assert_equal([], sign_getdefined("sign1"))
506 call assert_fails('call sign_undefine("none")', 'E155:')
507 call assert_fails('call sign_undefine([])', 'E730:')
508
509 call delete("Xsign")
510 call sign_unplace('*')
511 call sign_undefine()
512 enew | only
513endfunc
514
515" Tests for sign groups
516func Test_sign_group()
517 enew | only
518 " Remove all the signs
519 call sign_unplace('*')
520 call sign_undefine()
521
522 call writefile(repeat(["Sun is shining"], 30), "Xsign")
523
524 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
525 call assert_equal(0, sign_define("sign1", attr))
526
527 edit Xsign
528 let bnum = bufnr('%')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100529
530 " Error case
531 call assert_fails("call sign_place(5, [], 'sign1', 'Xsign',
532 \ {'lnum' : 30})", 'E730:')
533
534 " place three signs with the same identifier. One in the global group and
535 " others in the named groups
536 call assert_equal(5, sign_place(5, '', 'sign1', 'Xsign',
537 \ {'lnum' : 10}))
538 call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 20}))
539 call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 30}))
540
541 " Test for sign_getplaced() with group
542 let s = sign_getplaced('Xsign')
543 call assert_equal(1, len(s[0].signs))
544 call assert_equal(s[0].signs[0].group, '')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100545 let s = sign_getplaced(bnum, {'group' : ''})
546 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
547 \ 'priority' : 10}], s[0].signs)
548 call assert_equal(1, len(s[0].signs))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100549 let s = sign_getplaced(bnum, {'group' : 'g2'})
550 call assert_equal('g2', s[0].signs[0].group)
551 let s = sign_getplaced(bnum, {'group' : 'g3'})
552 call assert_equal([], s[0].signs)
553 let s = sign_getplaced(bnum, {'group' : '*'})
554 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
555 \ 'priority' : 10},
556 \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20,
557 \ 'priority' : 10},
558 \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30,
559 \ 'priority' : 10}],
560 \ s[0].signs)
561
562 " Test for sign_getplaced() with id
563 let s = sign_getplaced(bnum, {'id' : 5})
564 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
565 \ 'priority' : 10}],
566 \ s[0].signs)
567 let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g2'})
568 call assert_equal(
569 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
570 \ 'priority' : 10}],
571 \ s[0].signs)
572 let s = sign_getplaced(bnum, {'id' : 5, 'group' : '*'})
573 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
574 \ 'priority' : 10},
575 \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20,
576 \ 'priority' : 10},
577 \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30,
578 \ 'priority' : 10}],
579 \ s[0].signs)
580 let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g3'})
581 call assert_equal([], s[0].signs)
582
583 " Test for sign_getplaced() with lnum
584 let s = sign_getplaced(bnum, {'lnum' : 20})
585 call assert_equal([], s[0].signs)
586 let s = sign_getplaced(bnum, {'lnum' : 20, 'group' : 'g1'})
587 call assert_equal(
588 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1',
589 \ 'priority' : 10}],
590 \ s[0].signs)
591 let s = sign_getplaced(bnum, {'lnum' : 30, 'group' : '*'})
592 call assert_equal(
593 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
594 \ 'priority' : 10}],
595 \ s[0].signs)
596 let s = sign_getplaced(bnum, {'lnum' : 40, 'group' : '*'})
597 call assert_equal([], s[0].signs)
598
599 " Error case
600 call assert_fails("call sign_getplaced(bnum, {'group' : []})",
601 \ 'E730:')
602
603 " Clear the sign in global group
604 call sign_unplace('', {'id' : 5, 'buffer' : bnum})
605 let s = sign_getplaced(bnum, {'group' : '*'})
606 call assert_equal([
607 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1',
608 \ 'priority' : 10},
609 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
610 \ 'priority' : 10}],
611 \ s[0].signs)
612
613 " Clear the sign in one of the groups
614 call sign_unplace('g1', {'buffer' : 'Xsign'})
615 let s = sign_getplaced(bnum, {'group' : '*'})
616 call assert_equal([
617 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
618 \ 'priority' : 10}],
619 \ s[0].signs)
620
621 " Clear all the signs from the buffer
622 call sign_unplace('*', {'buffer' : bnum})
623 call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs)
624
625 " Clear sign across groups using an identifier
626 call sign_place(25, '', 'sign1', bnum, {'lnum' : 10})
627 call sign_place(25, 'g1', 'sign1', bnum, {'lnum' : 11})
628 call sign_place(25, 'g2', 'sign1', bnum, {'lnum' : 12})
629 call assert_equal(0, sign_unplace('*', {'id' : 25}))
630 call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs)
631
632 " Error case
633 call assert_fails("call sign_unplace([])", 'E474:')
634
635 " Place a sign in the global group and try to delete it using a group
636 call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10}))
637 call assert_equal(-1, sign_unplace('g1', {'id' : 5}))
638
639 " Place signs in multiple groups and delete all the signs in one of the
640 " group
641 call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10}))
642 call assert_equal(6, sign_place(6, '', 'sign1', bnum, {'lnum' : 11}))
643 call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 10}))
644 call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 10}))
645 call assert_equal(6, sign_place(6, 'g1', 'sign1', bnum, {'lnum' : 11}))
646 call assert_equal(6, sign_place(6, 'g2', 'sign1', bnum, {'lnum' : 11}))
647 call assert_equal(0, sign_unplace('g1'))
648 let s = sign_getplaced(bnum, {'group' : 'g1'})
649 call assert_equal([], s[0].signs)
650 let s = sign_getplaced(bnum)
651 call assert_equal(2, len(s[0].signs))
652 let s = sign_getplaced(bnum, {'group' : 'g2'})
653 call assert_equal('g2', s[0].signs[0].group)
654 call assert_equal(0, sign_unplace('', {'id' : 5}))
655 call assert_equal(0, sign_unplace('', {'id' : 6}))
656 let s = sign_getplaced(bnum, {'group' : 'g2'})
657 call assert_equal('g2', s[0].signs[0].group)
658 call assert_equal(0, sign_unplace('', {'buffer' : bnum}))
659
660 call sign_unplace('*')
661
662 " Test for :sign command and groups
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100663 sign place 5 line=10 name=sign1 file=Xsign
664 sign place 5 group=g1 line=10 name=sign1 file=Xsign
665 sign place 5 group=g2 line=10 name=sign1 file=Xsign
Bram Moolenaar162b7142018-12-21 15:17:36 +0100666
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100667 " Tests for the ':sign place' command
668
669 " :sign place file={fname}
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100670 let a = execute('sign place file=Xsign')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100671 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100672 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100673
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100674 " :sign place group={group} file={fname}
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100675 let a = execute('sign place group=g2 file=Xsign')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100676 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100677 \ " line=10 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100678
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100679 " :sign place group=* file={fname}
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100680 let a = execute('sign place group=* file=Xsign')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100681 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100682 \ " line=10 id=5 group=g2 name=sign1 priority=10\n" .
683 \ " line=10 id=5 group=g1 name=sign1 priority=10\n" .
684 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100685
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100686 " Error case: non-existing group
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100687 let a = execute('sign place group=xyz file=Xsign')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100688 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
689
690 call sign_unplace('*')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100691 let bnum = bufnr('Xsign')
692 exe 'sign place 5 line=10 name=sign1 buffer=' . bnum
693 exe 'sign place 5 group=g1 line=11 name=sign1 buffer=' . bnum
694 exe 'sign place 5 group=g2 line=12 name=sign1 buffer=' . bnum
695
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100696 " :sign place buffer={fname}
Bram Moolenaar162b7142018-12-21 15:17:36 +0100697 let a = execute('sign place buffer=' . bnum)
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100698 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100699 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100700
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100701 " :sign place group={group} buffer={fname}
Bram Moolenaar162b7142018-12-21 15:17:36 +0100702 let a = execute('sign place group=g2 buffer=' . bnum)
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100703 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100704 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100705
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100706 " :sign place group=* buffer={fname}
Bram Moolenaar162b7142018-12-21 15:17:36 +0100707 let a = execute('sign place group=* buffer=' . bnum)
708 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100709 \ " line=10 id=5 name=sign1 priority=10\n" .
710 \ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
711 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100712
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100713 " Error case: non-existing group
Bram Moolenaar162b7142018-12-21 15:17:36 +0100714 let a = execute('sign place group=xyz buffer=' . bnum)
715 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
716
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100717 " :sign place
718 let a = execute('sign place')
719 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100720 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100721
Bram Moolenaarb589f952019-01-07 22:10:00 +0100722 " Place signs in more than one buffer and list the signs
723 split foo
724 set buftype=nofile
725 sign place 25 line=76 name=sign1 priority=99 file=foo
726 let a = execute('sign place')
727 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
728 \ " line=10 id=5 name=sign1 priority=10\n" .
729 \ "Signs for foo:\n" .
730 \ " line=76 id=25 name=sign1 priority=99\n", a)
731 close
732 bwipe foo
733
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100734 " :sign place group={group}
735 let a = execute('sign place group=g1')
736 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100737 \ " line=11 id=5 group=g1 name=sign1 priority=10\n", a)
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100738
739 " :sign place group=*
Bram Moolenaar162b7142018-12-21 15:17:36 +0100740 let a = execute('sign place group=*')
741 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100742 \ " line=10 id=5 name=sign1 priority=10\n" .
743 \ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
744 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100745
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100746 " Test for ':sign jump' command with groups
747 sign jump 5 group=g1 file=Xsign
748 call assert_equal(11, line('.'))
749 call assert_equal('Xsign', bufname(''))
750 sign jump 5 group=g2 file=Xsign
751 call assert_equal(12, line('.'))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100752
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100753 " Test for :sign jump command without the filename or buffer
754 sign jump 5
755 call assert_equal(10, line('.'))
756 sign jump 5 group=g1
757 call assert_equal(11, line('.'))
758
Bram Moolenaar162b7142018-12-21 15:17:36 +0100759 " Error cases
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100760 call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100761
762 call delete("Xsign")
763 call sign_unplace('*')
764 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100765 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +0100766endfunc
767
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100768" Place signs used for ":sign unplace" command test
769func Place_signs_for_test()
770 call sign_unplace('*')
771
772 sign place 3 line=10 name=sign1 file=Xsign1
773 sign place 3 group=g1 line=11 name=sign1 file=Xsign1
774 sign place 3 group=g2 line=12 name=sign1 file=Xsign1
775 sign place 4 line=15 name=sign1 file=Xsign1
776 sign place 4 group=g1 line=16 name=sign1 file=Xsign1
777 sign place 4 group=g2 line=17 name=sign1 file=Xsign1
778 sign place 5 line=20 name=sign1 file=Xsign2
779 sign place 5 group=g1 line=21 name=sign1 file=Xsign2
780 sign place 5 group=g2 line=22 name=sign1 file=Xsign2
781 sign place 6 line=25 name=sign1 file=Xsign2
782 sign place 6 group=g1 line=26 name=sign1 file=Xsign2
783 sign place 6 group=g2 line=27 name=sign1 file=Xsign2
784endfunc
785
786" Place multiple signs in a single line for test
787func Place_signs_at_line_for_test()
788 call sign_unplace('*')
789 sign place 3 line=13 name=sign1 file=Xsign1
790 sign place 3 group=g1 line=13 name=sign1 file=Xsign1
791 sign place 3 group=g2 line=13 name=sign1 file=Xsign1
792 sign place 4 line=13 name=sign1 file=Xsign1
793 sign place 4 group=g1 line=13 name=sign1 file=Xsign1
794 sign place 4 group=g2 line=13 name=sign1 file=Xsign1
795endfunc
796
797" Tests for the ':sign unplace' command
798func Test_sign_unplace()
799 enew | only
800 " Remove all the signs
801 call sign_unplace('*')
802 call sign_undefine()
803
804 " Create two files and define signs
805 call writefile(repeat(["Sun is shining"], 30), "Xsign1")
806 call writefile(repeat(["It is beautiful"], 30), "Xsign2")
807
808 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
809 call sign_define("sign1", attr)
810
811 edit Xsign1
812 let bnum1 = bufnr('%')
813 split Xsign2
814 let bnum2 = bufnr('%')
815
816 let signs1 = [{'id' : 3, 'name' : 'sign1', 'lnum' : 10, 'group' : '',
817 \ 'priority' : 10},
818 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1',
819 \ 'priority' : 10},
820 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 12, 'group' : 'g2',
821 \ 'priority' : 10},
822 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 15, 'group' : '',
823 \ 'priority' : 10},
824 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 16, 'group' : 'g1',
825 \ 'priority' : 10},
826 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 17, 'group' : 'g2',
827 \ 'priority' : 10},]
828 let signs2 = [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : '',
829 \ 'priority' : 10},
830 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 21, 'group' : 'g1',
831 \ 'priority' : 10},
832 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 22, 'group' : 'g2',
833 \ 'priority' : 10},
834 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 25, 'group' : '',
835 \ 'priority' : 10},
836 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 26, 'group' : 'g1',
837 \ 'priority' : 10},
838 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 27, 'group' : 'g2',
839 \ 'priority' : 10},]
840
841 " Test for :sign unplace {id} file={fname}
842 call Place_signs_for_test()
843 sign unplace 3 file=Xsign1
844 sign unplace 6 file=Xsign2
845 call assert_equal(
846 \ filter(copy(signs1),
847 \ {idx, val -> val.id != 3 || val.group != ''}),
848 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
849 call assert_equal(
850 \ filter(copy(signs2),
851 \ {idx, val -> val.id != 6 || val.group != ''}),
852 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
853
854 " Test for :sign unplace {id} group={group} file={fname}
855 call Place_signs_for_test()
856 sign unplace 4 group=g1 file=Xsign1
857 sign unplace 5 group=g2 file=Xsign2
858 call assert_equal(
859 \ filter(copy(signs1),
860 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
861 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
862 call assert_equal(
863 \ filter(copy(signs2),
864 \ {idx, val -> val.id != 5 || val.group != 'g2'}),
865 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
866
867 " Test for :sign unplace {id} group=* file={fname}
868 call Place_signs_for_test()
869 sign unplace 3 group=* file=Xsign1
870 sign unplace 6 group=* file=Xsign2
871 call assert_equal(
872 \ filter(copy(signs1),
873 \ {idx, val -> val.id != 3}),
874 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
875 call assert_equal(
876 \ filter(copy(signs2),
877 \ {idx, val -> val.id != 6}),
878 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
879
880 " Test for :sign unplace * file={fname}
881 call Place_signs_for_test()
882 sign unplace * file=Xsign1
883 call assert_equal(
884 \ filter(copy(signs1),
885 \ {idx, val -> val.group != ''}),
886 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
887 call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
888
889 " Test for :sign unplace * group={group} file={fname}
890 call Place_signs_for_test()
891 sign unplace * group=g1 file=Xsign1
892 sign unplace * group=g2 file=Xsign2
893 call assert_equal(
894 \ filter(copy(signs1),
895 \ {idx, val -> val.group != 'g1'}),
896 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
897 call assert_equal(
898 \ filter(copy(signs2),
899 \ {idx, val -> val.group != 'g2'}),
900 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
901
902 " Test for :sign unplace * group=* file={fname}
903 call Place_signs_for_test()
904 sign unplace * group=* file=Xsign2
905 call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
906 call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
907
908 " Test for :sign unplace {id} buffer={nr}
909 call Place_signs_for_test()
910 exe 'sign unplace 3 buffer=' . bnum1
911 exe 'sign unplace 6 buffer=' . bnum2
912 call assert_equal(
913 \ filter(copy(signs1),
914 \ {idx, val -> val.id != 3 || val.group != ''}),
915 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
916 call assert_equal(
917 \ filter(copy(signs2),
918 \ {idx, val -> val.id != 6 || val.group != ''}),
919 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
920
921 " Test for :sign unplace {id} group={group} buffer={nr}
922 call Place_signs_for_test()
923 exe 'sign unplace 4 group=g1 buffer=' . bnum1
924 exe 'sign unplace 5 group=g2 buffer=' . bnum2
925 call assert_equal(
926 \ filter(copy(signs1),
927 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
928 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
929 call assert_equal(
930 \ filter(copy(signs2),
931 \ {idx, val -> val.id != 5 || val.group != 'g2'}),
932 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
933
934 " Test for :sign unplace {id} group=* buffer={nr}
935 call Place_signs_for_test()
936 exe 'sign unplace 3 group=* buffer=' . bnum1
937 exe 'sign unplace 6 group=* buffer=' . bnum2
938 call assert_equal(
939 \ filter(copy(signs1),
940 \ {idx, val -> val.id != 3}),
941 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
942 call assert_equal(
943 \ filter(copy(signs2),
944 \ {idx, val -> val.id != 6}),
945 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
946
947 " Test for :sign unplace * buffer={nr}
948 call Place_signs_for_test()
949 exe 'sign unplace * buffer=' . bnum1
950 call assert_equal(
951 \ filter(copy(signs1),
952 \ {idx, val -> val.group != ''}),
953 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
954 call assert_equal(signs2, sign_getplaced(bnum2, {'group' : '*'})[0].signs)
955
956 " Test for :sign unplace * group={group} buffer={nr}
957 call Place_signs_for_test()
958 exe 'sign unplace * group=g1 buffer=' . bnum1
959 exe 'sign unplace * group=g2 buffer=' . bnum2
960 call assert_equal(
961 \ filter(copy(signs1),
962 \ {idx, val -> val.group != 'g1'}),
963 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
964 call assert_equal(
965 \ filter(copy(signs2),
966 \ {idx, val -> val.group != 'g2'}),
967 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
968
969 " Test for :sign unplace * group=* buffer={nr}
970 call Place_signs_for_test()
971 exe 'sign unplace * group=* buffer=' . bnum2
972 call assert_equal(signs1, sign_getplaced(bnum1, {'group' : '*'})[0].signs)
973 call assert_equal([], sign_getplaced(bnum2, {'group' : '*'})[0].signs)
974
975 " Test for :sign unplace {id}
976 call Place_signs_for_test()
977 sign unplace 4
978 sign unplace 6
979 call assert_equal(
980 \ filter(copy(signs1),
981 \ {idx, val -> val.id != 4 || val.group != ''}),
982 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
983 call assert_equal(
984 \ filter(copy(signs2),
985 \ {idx, val -> val.id != 6 || val.group != ''}),
986 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
987
988 " Test for :sign unplace {id} group={group}
989 call Place_signs_for_test()
990 sign unplace 4 group=g1
991 sign unplace 6 group=g2
992 call assert_equal(
993 \ filter(copy(signs1),
994 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
995 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
996 call assert_equal(
997 \ filter(copy(signs2),
998 \ {idx, val -> val.id != 6 || val.group != 'g2'}),
999 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1000
1001 " Test for :sign unplace {id} group=*
1002 call Place_signs_for_test()
1003 sign unplace 3 group=*
1004 sign unplace 5 group=*
1005 call assert_equal(
1006 \ filter(copy(signs1),
1007 \ {idx, val -> val.id != 3}),
1008 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1009 call assert_equal(
1010 \ filter(copy(signs2),
1011 \ {idx, val -> val.id != 5}),
1012 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1013
1014 " Test for :sign unplace *
1015 call Place_signs_for_test()
1016 sign unplace *
1017 call assert_equal(
1018 \ filter(copy(signs1),
1019 \ {idx, val -> val.group != ''}),
1020 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1021 call assert_equal(
1022 \ filter(copy(signs2),
1023 \ {idx, val -> val.group != ''}),
1024 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1025
1026 " Test for :sign unplace * group={group}
1027 call Place_signs_for_test()
1028 sign unplace * group=g1
1029 call assert_equal(
1030 \ filter(copy(signs1),
1031 \ {idx, val -> val.group != 'g1'}),
1032 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1033 call assert_equal(
1034 \ filter(copy(signs2),
1035 \ {idx, val -> val.group != 'g1'}),
1036 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1037
1038 " Test for :sign unplace * group=*
1039 call Place_signs_for_test()
1040 sign unplace * group=*
1041 call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1042 call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1043
1044 " Negative test cases
1045 call Place_signs_for_test()
1046 sign unplace 3 group=xy file=Xsign1
1047 sign unplace * group=xy file=Xsign1
1048 silent! sign unplace * group=* file=FileNotPresent
1049 call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1050 call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1051
1052 " Tests for removing sign at the current cursor position
1053
1054 " Test for ':sign unplace'
1055 let signs1 = [{'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
1056 \ 'priority' : 10},
1057 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
1058 \ 'priority' : 10},
1059 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
1060 \ 'priority' : 10},
1061 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
1062 \ 'priority' : 10},
1063 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
1064 \ 'priority' : 10},
1065 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
1066 \ 'priority' : 10},]
1067 exe bufwinnr('Xsign1') . 'wincmd w'
1068 call cursor(13, 1)
1069
1070 " Should remove only one sign in the global group
1071 call Place_signs_at_line_for_test()
1072 sign unplace
1073 call assert_equal(
1074 \ filter(copy(signs1),
1075 \ {idx, val -> val.id != 4 || val.group != ''}),
1076 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1077 " Should remove the second sign in the global group
1078 sign unplace
1079 call assert_equal(
1080 \ filter(copy(signs1),
1081 \ {idx, val -> val.group != ''}),
1082 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1083
1084 " Test for ':sign unplace group={group}'
1085 call Place_signs_at_line_for_test()
1086 " Should remove only one sign in group g1
1087 sign unplace group=g1
1088 call assert_equal(
1089 \ filter(copy(signs1),
1090 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
1091 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1092 sign unplace group=g2
1093 call assert_equal(
1094 \ filter(copy(signs1),
1095 \ {idx, val -> val.id != 4 || val.group == ''}),
1096 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1097
1098 " Test for ':sign unplace group=*'
1099 call Place_signs_at_line_for_test()
1100 sign unplace group=*
1101 sign unplace group=*
1102 sign unplace group=*
1103 call assert_equal(
1104 \ filter(copy(signs1),
1105 \ {idx, val -> val.id != 4}),
1106 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1107 sign unplace group=*
1108 sign unplace group=*
1109 sign unplace group=*
1110 call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1111
1112 call sign_unplace('*')
1113 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001114 enew | only
Bram Moolenaar7d83bf42018-12-29 18:53:55 +01001115 call delete("Xsign1")
1116 call delete("Xsign2")
1117endfunc
1118
Bram Moolenaar162b7142018-12-21 15:17:36 +01001119" Tests for auto-generating the sign identifier
1120func Test_sign_id_autogen()
1121 enew | only
1122 call sign_unplace('*')
1123 call sign_undefine()
1124
1125 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
1126 call assert_equal(0, sign_define("sign1", attr))
1127
1128 call writefile(repeat(["Sun is shining"], 30), "Xsign")
1129 edit Xsign
1130
1131 call assert_equal(1, sign_place(0, '', 'sign1', 'Xsign',
1132 \ {'lnum' : 10}))
1133 call assert_equal(2, sign_place(2, '', 'sign1', 'Xsign',
1134 \ {'lnum' : 12}))
1135 call assert_equal(3, sign_place(0, '', 'sign1', 'Xsign',
1136 \ {'lnum' : 14}))
1137 call sign_unplace('', {'buffer' : 'Xsign', 'id' : 2})
Bram Moolenaar6436cd82018-12-27 00:28:33 +01001138 call assert_equal(4, sign_place(0, '', 'sign1', 'Xsign',
Bram Moolenaar162b7142018-12-21 15:17:36 +01001139 \ {'lnum' : 12}))
1140
1141 call assert_equal(1, sign_place(0, 'g1', 'sign1', 'Xsign',
1142 \ {'lnum' : 11}))
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001143 " Check for the next generated sign id in this group
1144 call assert_equal(2, sign_place(0, 'g1', 'sign1', 'Xsign',
1145 \ {'lnum' : 12}))
Bram Moolenaar162b7142018-12-21 15:17:36 +01001146 call assert_equal(0, sign_unplace('g1', {'id' : 1}))
1147 call assert_equal(10,
1148 \ sign_getplaced('Xsign', {'id' : 1})[0].signs[0].lnum)
1149
1150 call delete("Xsign")
1151 call sign_unplace('*')
1152 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001153 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +01001154endfunc
1155
1156" Test for sign priority
1157func Test_sign_priority()
1158 enew | only
1159 call sign_unplace('*')
1160 call sign_undefine()
1161
1162 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search'}
1163 call sign_define("sign1", attr)
1164 call sign_define("sign2", attr)
1165 call sign_define("sign3", attr)
1166
1167 " Place three signs with different priority in the same line
1168 call writefile(repeat(["Sun is shining"], 30), "Xsign")
1169 edit Xsign
Bram Moolenaar162b7142018-12-21 15:17:36 +01001170
1171 call sign_place(1, 'g1', 'sign1', 'Xsign',
1172 \ {'lnum' : 11, 'priority' : 50})
1173 call sign_place(2, 'g2', 'sign2', 'Xsign',
1174 \ {'lnum' : 11, 'priority' : 100})
1175 call sign_place(3, '', 'sign3', 'Xsign', {'lnum' : 11})
1176 let s = sign_getplaced('Xsign', {'group' : '*'})
1177 call assert_equal([
1178 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11, 'group' : 'g2',
1179 \ 'priority' : 100},
1180 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1',
1181 \ 'priority' : 50},
1182 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11, 'group' : '',
1183 \ 'priority' : 10}],
1184 \ s[0].signs)
1185
1186 " Error case
1187 call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign',
1188 \ [])", 'E715:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001189 call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign',
1190 \ {'priority' : []})", 'E745:')
Bram Moolenaar162b7142018-12-21 15:17:36 +01001191 call sign_unplace('*')
1192
1193 " Tests for the :sign place command with priority
1194 sign place 5 line=10 name=sign1 priority=30 file=Xsign
1195 sign place 5 group=g1 line=10 name=sign1 priority=20 file=Xsign
1196 sign place 5 group=g2 line=10 name=sign1 priority=25 file=Xsign
1197 let a = execute('sign place group=*')
1198 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +01001199 \ " line=10 id=5 name=sign1 priority=30\n" .
1200 \ " line=10 id=5 group=g2 name=sign1 priority=25\n" .
1201 \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +01001202
1203 " Test for :sign place group={group}
1204 let a = execute('sign place group=g1')
1205 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +01001206 \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +01001207
1208 call sign_unplace('*')
1209 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001210 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +01001211 call delete("Xsign")
1212endfunc
1213
1214" Tests for memory allocation failures in sign functions
1215func Test_sign_memfailures()
1216 call writefile(repeat(["Sun is shining"], 30), "Xsign")
1217 edit Xsign
1218
1219 call test_alloc_fail(GetAllocId('sign_getdefined'), 0, 0)
1220 call assert_fails('call sign_getdefined("sign1")', 'E342:')
1221 call test_alloc_fail(GetAllocId('sign_getplaced'), 0, 0)
1222 call assert_fails('call sign_getplaced("Xsign")', 'E342:')
1223 call test_alloc_fail(GetAllocId('sign_define_by_name'), 0, 0)
1224 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
1225 call assert_fails('call sign_define("sign1", attr)', 'E342:')
1226
1227 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
1228 call sign_define("sign1", attr)
1229 call test_alloc_fail(GetAllocId('sign_getlist'), 0, 0)
1230 call assert_fails('call sign_getdefined("sign1")', 'E342:')
1231
1232 call sign_place(3, 'g1', 'sign1', 'Xsign', {'lnum' : 10})
1233 call test_alloc_fail(GetAllocId('sign_getplaced_dict'), 0, 0)
1234 call assert_fails('call sign_getplaced("Xsign")', 'E342:')
1235 call test_alloc_fail(GetAllocId('sign_getplaced_list'), 0, 0)
1236 call assert_fails('call sign_getplaced("Xsign")', 'E342:')
1237
1238 call test_alloc_fail(GetAllocId('insert_sign'), 0, 0)
1239 call assert_fails('call sign_place(4, "g1", "sign1", "Xsign", {"lnum" : 11})',
1240 \ 'E342:')
1241
1242 call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0)
1243 call assert_fails('call getbufinfo()', 'E342:')
1244 call sign_place(4, 'g1', 'sign1', 'Xsign', {'lnum' : 11})
1245 call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0)
1246 call assert_fails('let binfo=getbufinfo("Xsign")', 'E342:')
1247 call assert_equal([{'lnum': 11, 'id': 4, 'name': 'sign1',
1248 \ 'priority': 10, 'group': 'g1'}], binfo[0].signs)
1249
1250 call sign_unplace('*')
1251 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001252 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +01001253 call delete("Xsign")
1254endfunc
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001255
1256" Test for auto-adjusting the line number of a placed sign.
1257func Test_sign_lnum_adjust()
1258 enew! | only!
1259
1260 sign define sign1 text=#> linehl=Comment
Bram Moolenaarc771bf92019-01-17 17:36:45 +01001261 call setline(1, ['A', 'B', 'C', 'D', 'E'])
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001262 exe 'sign place 5 line=3 name=sign1 buffer=' . bufnr('')
1263 let l = sign_getplaced(bufnr(''))
1264 call assert_equal(3, l[0].signs[0].lnum)
1265
1266 " Add some lines before the sign and check the sign line number
Bram Moolenaarc771bf92019-01-17 17:36:45 +01001267 call append(2, ['BA', 'BB', 'BC'])
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001268 let l = sign_getplaced(bufnr(''))
1269 call assert_equal(6, l[0].signs[0].lnum)
1270
1271 " Delete some lines before the sign and check the sign line number
1272 call deletebufline('%', 1, 2)
1273 let l = sign_getplaced(bufnr(''))
1274 call assert_equal(4, l[0].signs[0].lnum)
1275
Bram Moolenaarc771bf92019-01-17 17:36:45 +01001276 " Insert some lines after the sign and check the sign line number
1277 call append(5, ['DA', 'DB'])
1278 let l = sign_getplaced(bufnr(''))
1279 call assert_equal(4, l[0].signs[0].lnum)
1280
1281 " Delete some lines after the sign and check the sign line number
1282 call deletebufline('', 6, 7)
1283 let l = sign_getplaced(bufnr(''))
1284 call assert_equal(4, l[0].signs[0].lnum)
1285
1286 " Break the undo. Otherwise the undo operation below will undo all the
1287 " changes made by this function.
1288 let &undolevels=&undolevels
1289
1290 " Delete the line with the sign
1291 call deletebufline('', 4)
1292 let l = sign_getplaced(bufnr(''))
1293 call assert_equal(4, l[0].signs[0].lnum)
1294
1295 " Undo the delete operation
1296 undo
1297 let l = sign_getplaced(bufnr(''))
1298 call assert_equal(5, l[0].signs[0].lnum)
1299
1300 " Break the undo
1301 let &undolevels=&undolevels
1302
1303 " Delete few lines at the end of the buffer including the line with the sign
1304 " Sign line number should not change (as it is placed outside of the buffer)
1305 call deletebufline('', 3, 6)
1306 let l = sign_getplaced(bufnr(''))
1307 call assert_equal(5, l[0].signs[0].lnum)
1308
1309 " Undo the delete operation. Sign should be restored to the previous line
1310 undo
1311 let l = sign_getplaced(bufnr(''))
1312 call assert_equal(5, l[0].signs[0].lnum)
1313
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001314 sign unplace * group=*
1315 sign undefine sign1
1316 enew!
1317endfunc
1318
1319" Test for changing the type of a placed sign
1320func Test_sign_change_type()
1321 enew! | only!
1322
1323 sign define sign1 text=#> linehl=Comment
1324 sign define sign2 text=@@ linehl=Comment
1325
1326 call setline(1, ['A', 'B', 'C', 'D'])
1327 exe 'sign place 4 line=3 name=sign1 buffer=' . bufnr('')
1328 let l = sign_getplaced(bufnr(''))
1329 call assert_equal('sign1', l[0].signs[0].name)
1330 exe 'sign place 4 name=sign2 buffer=' . bufnr('')
1331 let l = sign_getplaced(bufnr(''))
1332 call assert_equal('sign2', l[0].signs[0].name)
1333 call sign_place(4, '', 'sign1', '')
1334 let l = sign_getplaced(bufnr(''))
1335 call assert_equal('sign1', l[0].signs[0].name)
1336
1337 exe 'sign place 4 group=g1 line=4 name=sign1 buffer=' . bufnr('')
1338 let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
1339 call assert_equal('sign1', l[0].signs[0].name)
1340 exe 'sign place 4 group=g1 name=sign2 buffer=' . bufnr('')
1341 let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
1342 call assert_equal('sign2', l[0].signs[0].name)
1343 call sign_place(4, 'g1', 'sign1', '')
1344 let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
1345 call assert_equal('sign1', l[0].signs[0].name)
1346
1347 sign unplace * group=*
1348 sign undefine sign1
1349 sign undefine sign2
1350 enew!
1351endfunc
Bram Moolenaar6b7b7192019-01-11 13:42:41 +01001352
1353" Test for the sign_jump() function
1354func Test_sign_jump_func()
1355 enew! | only!
1356
1357 sign define sign1 text=#> linehl=Comment
1358
1359 edit foo
1360 set buftype=nofile
1361 call setline(1, ['A', 'B', 'C', 'D', 'E'])
1362 call sign_place(5, '', 'sign1', '', {'lnum' : 2})
1363 call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
1364 call sign_place(6, '', 'sign1', '', {'lnum' : 4})
1365 call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
1366 split bar
1367 set buftype=nofile
1368 call setline(1, ['P', 'Q', 'R', 'S', 'T'])
1369 call sign_place(5, '', 'sign1', '', {'lnum' : 2})
1370 call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
1371 call sign_place(6, '', 'sign1', '', {'lnum' : 4})
1372 call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
1373
1374 let r = sign_jump(5, '', 'foo')
1375 call assert_equal(2, r)
1376 call assert_equal(2, line('.'))
1377 let r = sign_jump(6, 'g1', 'foo')
1378 call assert_equal(5, r)
1379 call assert_equal(5, line('.'))
1380 let r = sign_jump(5, '', 'bar')
1381 call assert_equal(2, r)
1382 call assert_equal(2, line('.'))
1383
1384 " Error cases
1385 call assert_fails("call sign_jump(99, '', 'bar')", 'E157:')
1386 call assert_fails("call sign_jump(0, '', 'foo')", 'E474:')
1387 call assert_fails("call sign_jump(5, 'g5', 'foo')", 'E157:')
1388 call assert_fails('call sign_jump([], "", "foo")', 'E745:')
1389 call assert_fails('call sign_jump(2, [], "foo")', 'E730:')
1390 call assert_fails('call sign_jump(2, "", {})', 'E158:')
1391 call assert_fails('call sign_jump(2, "", "baz")', 'E158:')
1392
1393 sign unplace * group=*
1394 sign undefine sign1
1395 enew! | only!
1396endfunc