blob: 3d885d6428f931f0d3737a7be2a7c447b093d4a8 [file] [log] [blame]
Bram Moolenaar09de1752016-08-08 22:26:48 +02001" Test for signs
2
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
4CheckFeature signs
Bram Moolenaar09de1752016-08-08 22:26:48 +02005
Bram Moolenaarf85e40a2019-06-16 13:55:40 +02006source screendump.vim
7
Bram Moolenaar09de1752016-08-08 22:26:48 +02008func Test_sign()
9 new
10 call setline(1, ['a', 'b', 'c', 'd'])
11
Bram Moolenaar446a9732016-08-10 21:36:23 +020012 " Define some signs.
13 " We can specify icons even if not all versions of vim support icons as
14 " icon is ignored when not supported. "(not supported)" is shown after
15 " the icon name when listing signs.
Bram Moolenaar09de1752016-08-08 22:26:48 +020016 sign define Sign1 text=x
Bram Moolenaar446a9732016-08-10 21:36:23 +020017 try
Bram Moolenaarb328cca2019-01-06 16:24:01 +010018 sign define Sign2 text=xy texthl=Title linehl=Error
19 \ icon=../../pixmaps/stock_vim_find_help.png
Bram Moolenaar446a9732016-08-10 21:36:23 +020020 catch /E255:/
Bram Moolenaar162b7142018-12-21 15:17:36 +010021 " Ignore error: E255: Couldn't read in sign data!
22 " This error can happen when running in the GUI.
Bram Moolenaar446a9732016-08-10 21:36:23 +020023 " Some gui like Motif do not support the png icon format.
24 endtry
Bram Moolenaar09de1752016-08-08 22:26:48 +020025
26 " Test listing signs.
27 let a=execute('sign list')
Bram Moolenaarb328cca2019-01-06 16:24:01 +010028 call assert_match('^\nsign Sign1 text=x \nsign Sign2 ' .
29 \ 'icon=../../pixmaps/stock_vim_find_help.png .*text=xy ' .
30 \ 'linehl=Error texthl=Title$', a)
Bram Moolenaar09de1752016-08-08 22:26:48 +020031
32 let a=execute('sign list Sign1')
33 call assert_equal("\nsign Sign1 text=x ", a)
34
Bram Moolenaar7d83bf42018-12-29 18:53:55 +010035 " Split the window to the bottom to verify sign jump will stay in the
36 " current window if the buffer is displayed there.
Bram Moolenaar446a9732016-08-10 21:36:23 +020037 let bn = bufnr('%')
38 let wn = winnr()
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +010039 exe 'sign place 41 line=3 name=Sign1 buffer=' . bn
Bram Moolenaar09de1752016-08-08 22:26:48 +020040 1
Bram Moolenaar446a9732016-08-10 21:36:23 +020041 bot split
42 exe 'sign jump 41 buffer=' . bufnr('%')
43 call assert_equal('c', getline('.'))
44 call assert_equal(3, winnr())
45 call assert_equal(bn, bufnr('%'))
46 call assert_notequal(wn, winnr())
47
48 " Create a new buffer and check that ":sign jump" switches to the old buffer.
49 1
50 new foo
51 call assert_notequal(bn, bufnr('%'))
52 exe 'sign jump 41 buffer=' . bn
53 call assert_equal(bn, bufnr('%'))
Bram Moolenaar09de1752016-08-08 22:26:48 +020054 call assert_equal('c', getline('.'))
55
Bram Moolenaar446a9732016-08-10 21:36:23 +020056 " Redraw to make sure that screen redraw with sign gets exercised,
57 " with and without 'rightleft'.
58 if has('rightleft')
59 set rightleft
60 redraw
61 set norightleft
62 endif
63 redraw
Bram Moolenaar09de1752016-08-08 22:26:48 +020064
Bram Moolenaar446a9732016-08-10 21:36:23 +020065 " Check that we can't change sign.
Bram Moolenaar7a2d9892018-12-24 20:23:49 +010066 call assert_fails("sign place 40 name=Sign1 buffer=" . bufnr('%'), 'E885:')
Bram Moolenaar446a9732016-08-10 21:36:23 +020067
68 " Check placed signs
Bram Moolenaar09de1752016-08-08 22:26:48 +020069 let a=execute('sign place')
Bram Moolenaarb328cca2019-01-06 16:24:01 +010070 call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +010071 \ " line=3 id=41 name=Sign1 priority=10\n", a)
Bram Moolenaar09de1752016-08-08 22:26:48 +020072
Bram Moolenaar446a9732016-08-10 21:36:23 +020073 " Unplace the sign and try jumping to it again should fail.
74 sign unplace 41
Bram Moolenaar09de1752016-08-08 22:26:48 +020075 1
Bram Moolenaar7a2d9892018-12-24 20:23:49 +010076 call assert_fails("sign jump 41 buffer=" . bufnr('%'), 'E157:')
Bram Moolenaar09de1752016-08-08 22:26:48 +020077 call assert_equal('a', getline('.'))
78
79 " Unplace sign on current line.
Bram Moolenaar446a9732016-08-10 21:36:23 +020080 exe 'sign place 42 line=4 name=Sign2 buffer=' . bufnr('%')
Bram Moolenaar09de1752016-08-08 22:26:48 +020081 4
82 sign unplace
83 let a=execute('sign place')
84 call assert_equal("\n--- Signs ---\n", a)
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +010085
Bram Moolenaar09de1752016-08-08 22:26:48 +020086 " Try again to unplace sign on current line, it should fail this time.
87 call assert_fails('sign unplace', 'E159:')
88
89 " Unplace all signs.
Bram Moolenaar446a9732016-08-10 21:36:23 +020090 exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%')
Bram Moolenaar09de1752016-08-08 22:26:48 +020091 sign unplace *
92 let a=execute('sign place')
93 call assert_equal("\n--- Signs ---\n", a)
94
Bram Moolenaarb328cca2019-01-06 16:24:01 +010095 " Place a sign without specifying the filename or buffer
96 sign place 77 line=9 name=Sign2
97 let a=execute('sign place')
98 call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +010099 \ " line=9 id=77 name=Sign2 priority=10\n", a)
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100100 sign unplace *
101
Bram Moolenaar446a9732016-08-10 21:36:23 +0200102 " Check :jump with file=...
103 edit foo
104 call setline(1, ['A', 'B', 'C', 'D'])
105
106 try
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100107 sign define Sign3 text=y texthl=DoesNotExist linehl=DoesNotExist
108 \ icon=doesnotexist.xpm
Bram Moolenaar446a9732016-08-10 21:36:23 +0200109 catch /E255:/
110 " ignore error: E255: it can happens for guis.
111 endtry
112
113 let fn = expand('%:p')
114 exe 'sign place 43 line=2 name=Sign3 file=' . fn
115 edit bar
116 call assert_notequal(fn, expand('%:p'))
117 exe 'sign jump 43 file=' . fn
118 call assert_equal('B', getline('.'))
119
Bram Moolenaara3556522018-12-31 22:02:29 +0100120 " Check for jumping to a sign in a hidden buffer
121 enew! | only!
122 edit foo
123 call setline(1, ['A', 'B', 'C', 'D'])
124 let fn = expand('%:p')
125 exe 'sign place 21 line=3 name=Sign3 file=' . fn
126 hide edit bar
127 exe 'sign jump 21 file=' . fn
128 call assert_equal('C', getline('.'))
129
Bram Moolenaar06b056e2018-12-14 19:37:08 +0100130 " can't define a sign with a non-printable character as text
131 call assert_fails("sign define Sign4 text=\e linehl=Comment", 'E239:')
132 call assert_fails("sign define Sign4 text=a\e linehl=Comment", 'E239:')
133 call assert_fails("sign define Sign4 text=\ea linehl=Comment", 'E239:')
134
135 " Only 1 or 2 character text is allowed
136 call assert_fails("sign define Sign4 text=abc linehl=Comment", 'E239:')
137 call assert_fails("sign define Sign4 text= linehl=Comment", 'E239:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100138 call assert_fails("sign define Sign4 text=\\ ab linehl=Comment", 'E239:')
Bram Moolenaar06b056e2018-12-14 19:37:08 +0100139
140 " define sign with whitespace
141 sign define Sign4 text=\ X linehl=Comment
142 sign undefine Sign4
143 sign define Sign4 linehl=Comment text=\ X
144 sign undefine Sign4
145
146 sign define Sign5 text=X\ linehl=Comment
147 sign undefine Sign5
148 sign define Sign5 linehl=Comment text=X\
149 sign undefine Sign5
150
151 " define sign with backslash
152 sign define Sign4 text=\\\\ linehl=Comment
153 sign undefine Sign4
154 sign define Sign4 text=\\ linehl=Comment
155 sign undefine Sign4
156
Bram Moolenaara3556522018-12-31 22:02:29 +0100157 " define a sign with a leading 0 in the name
158 sign unplace *
159 sign define 004 text=#> linehl=Comment
160 let a = execute('sign list 4')
161 call assert_equal("\nsign 4 text=#> linehl=Comment", a)
162 exe 'sign place 20 line=3 name=004 buffer=' . bufnr('')
163 let a = execute('sign place')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100164 call assert_equal("\n--- Signs ---\nSigns for foo:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100165 \ " line=3 id=20 name=4 priority=10\n", a)
Bram Moolenaara3556522018-12-31 22:02:29 +0100166 exe 'sign unplace 20 buffer=' . bufnr('')
167 sign undefine 004
168 call assert_fails('sign list 4', 'E155:')
169
Bram Moolenaar09de1752016-08-08 22:26:48 +0200170 " After undefining the sign, we should no longer be able to place it.
171 sign undefine Sign1
172 sign undefine Sign2
Bram Moolenaar446a9732016-08-10 21:36:23 +0200173 sign undefine Sign3
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100174 call assert_fails("sign place 41 line=3 name=Sign1 buffer=" .
175 \ bufnr('%'), 'E155:')
Bram Moolenaar446a9732016-08-10 21:36:23 +0200176endfunc
Bram Moolenaar09de1752016-08-08 22:26:48 +0200177
Bram Moolenaar446a9732016-08-10 21:36:23 +0200178" Undefining placed sign is not recommended.
179" Quoting :help sign
180"
181" :sign undefine {name}
182" Deletes a previously defined sign. If signs with this {name}
183" are still placed this will cause trouble.
184func Test_sign_undefine_still_placed()
185 new foobar
186 sign define Sign text=x
187 exe 'sign place 41 line=1 name=Sign buffer=' . bufnr('%')
188 sign undefine Sign
189
190 " Listing placed sign should show that sign is deleted.
191 let a=execute('sign place')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100192 call assert_equal("\n--- Signs ---\nSigns for foobar:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100193 \ " line=1 id=41 name=[Deleted] priority=10\n", a)
Bram Moolenaar446a9732016-08-10 21:36:23 +0200194
195 sign unplace 41
196 let a=execute('sign place')
197 call assert_equal("\n--- Signs ---\n", a)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200198endfunc
199
200func Test_sign_completion()
201 sign define Sign1 text=x
202 sign define Sign2 text=y
203
204 call feedkeys(":sign \<C-A>\<C-B>\"\<CR>", 'tx')
205 call assert_equal('"sign define jump list place undefine unplace', @:)
206
207 call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
208 call assert_equal('"sign define Sign icon= linehl= text= texthl=', @:)
209
210 call feedkeys(":sign define Sign linehl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100211 call assert_equal('"sign define Sign linehl=SpellBad SpellCap ' .
212 \ 'SpellLocal SpellRare', @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200213
Bram Moolenaar3678f652019-02-17 14:50:25 +0100214 call feedkeys(":sign define Sign texthl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
215 call assert_equal('"sign define Sign texthl=SpellBad SpellCap ' .
216 \ 'SpellLocal SpellRare', @:)
217
218 call writefile(repeat(["Sun is shining"], 30), "XsignOne")
219 call writefile(repeat(["Sky is blue"], 30), "XsignTwo")
Bram Moolenaar64cefed2016-08-29 23:06:28 +0200220 call feedkeys(":sign define Sign icon=Xsig\<C-A>\<C-B>\"\<CR>", 'tx')
221 call assert_equal('"sign define Sign icon=XsignOne XsignTwo', @:)
Bram Moolenaar446a9732016-08-10 21:36:23 +0200222
Bram Moolenaar3678f652019-02-17 14:50:25 +0100223 " Test for completion of arguments to ':sign undefine'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200224 call feedkeys(":sign undefine \<C-A>\<C-B>\"\<CR>", 'tx')
225 call assert_equal('"sign undefine Sign1 Sign2', @:)
226
227 call feedkeys(":sign place 1 \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100228 call assert_equal('"sign place 1 buffer= file= group= line= name= priority=',
229 \ @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200230
231 call feedkeys(":sign place 1 name=\<C-A>\<C-B>\"\<CR>", 'tx')
232 call assert_equal('"sign place 1 name=Sign1 Sign2', @:)
233
Bram Moolenaar3678f652019-02-17 14:50:25 +0100234 edit XsignOne
235 sign place 1 name=Sign1 line=5
236 sign place 1 name=Sign1 group=g1 line=10
237 edit XsignTwo
238 sign place 1 name=Sign2 group=g2 line=15
239
240 " Test for completion of group= and file= arguments to ':sign place'
241 call feedkeys(":sign place 1 name=Sign1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
242 call assert_equal('"sign place 1 name=Sign1 file=XsignOne XsignTwo', @:)
243 call feedkeys(":sign place 1 name=Sign1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
244 call assert_equal('"sign place 1 name=Sign1 group=g1 g2', @:)
245
246 " Test for completion of arguments to 'sign place' without sign identifier
247 call feedkeys(":sign place \<C-A>\<C-B>\"\<CR>", 'tx')
248 call assert_equal('"sign place buffer= file= group=', @:)
249 call feedkeys(":sign place file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
250 call assert_equal('"sign place file=XsignOne XsignTwo', @:)
251 call feedkeys(":sign place group=\<C-A>\<C-B>\"\<CR>", 'tx')
252 call assert_equal('"sign place group=g1 g2', @:)
253 call feedkeys(":sign place group=g1 file=\<C-A>\<C-B>\"\<CR>", 'tx')
254 call assert_equal('"sign place group=g1 file=XsignOne XsignTwo', @:)
255
256 " Test for completion of arguments to ':sign unplace'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200257 call feedkeys(":sign unplace 1 \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100258 call assert_equal('"sign unplace 1 buffer= file= group=', @:)
Bram Moolenaar3678f652019-02-17 14:50:25 +0100259 call feedkeys(":sign unplace 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
260 call assert_equal('"sign unplace 1 file=XsignOne XsignTwo', @:)
261 call feedkeys(":sign unplace 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
262 call assert_equal('"sign unplace 1 group=g1 g2', @:)
263 call feedkeys(":sign unplace 1 group=g2 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
264 call assert_equal('"sign unplace 1 group=g2 file=XsignOne XsignTwo', @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200265
Bram Moolenaar3678f652019-02-17 14:50:25 +0100266 " Test for completion of arguments to ':sign list'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200267 call feedkeys(":sign list \<C-A>\<C-B>\"\<CR>", 'tx')
268 call assert_equal('"sign list Sign1 Sign2', @:)
269
Bram Moolenaar3678f652019-02-17 14:50:25 +0100270 " Test for completion of arguments to ':sign jump'
Bram Moolenaar09de1752016-08-08 22:26:48 +0200271 call feedkeys(":sign jump 1 \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100272 call assert_equal('"sign jump 1 buffer= file= group=', @:)
Bram Moolenaar3678f652019-02-17 14:50:25 +0100273 call feedkeys(":sign jump 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
274 call assert_equal('"sign jump 1 file=XsignOne XsignTwo', @:)
275 call feedkeys(":sign jump 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
276 call assert_equal('"sign jump 1 group=g1 g2', @:)
Bram Moolenaar09de1752016-08-08 22:26:48 +0200277
Bram Moolenaar3678f652019-02-17 14:50:25 +0100278 " Error cases
279 call feedkeys(":sign here\<C-A>\<C-B>\"\<CR>", 'tx')
280 call assert_equal('"sign here', @:)
281 call feedkeys(":sign define Sign here=\<C-A>\<C-B>\"\<CR>", 'tx')
282 call assert_equal("\"sign define Sign here=\<C-A>", @:)
283 call feedkeys(":sign place 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
284 call assert_equal("\"sign place 1 here=\<C-A>", @:)
285 call feedkeys(":sign jump 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
286 call assert_equal("\"sign jump 1 here=\<C-A>", @:)
287 call feedkeys(":sign here there\<C-A>\<C-B>\"\<CR>", 'tx')
288 call assert_equal("\"sign here there\<C-A>", @:)
289 call feedkeys(":sign here there=\<C-A>\<C-B>\"\<CR>", 'tx')
290 call assert_equal("\"sign here there=\<C-A>", @:)
291
292 sign unplace * group=*
Bram Moolenaar09de1752016-08-08 22:26:48 +0200293 sign undefine Sign1
294 sign undefine Sign2
Bram Moolenaar3678f652019-02-17 14:50:25 +0100295 enew
296 call delete('XsignOne')
297 call delete('XsignTwo')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200298endfunc
299
300func Test_sign_invalid_commands()
Bram Moolenaar162b7142018-12-21 15:17:36 +0100301 sign define Sign1 text=x
302
Bram Moolenaar09de1752016-08-08 22:26:48 +0200303 call assert_fails('sign', 'E471:')
Bram Moolenaar446a9732016-08-10 21:36:23 +0200304 call assert_fails('sign jump', 'E471:')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200305 call assert_fails('sign xxx', 'E160:')
306 call assert_fails('sign define', 'E156:')
Bram Moolenaar446a9732016-08-10 21:36:23 +0200307 call assert_fails('sign define Sign1 xxx', 'E475:')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200308 call assert_fails('sign undefine', 'E156:')
309 call assert_fails('sign list xxx', 'E155:')
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200310 call assert_fails('sign place 1 buffer=999', 'E158:')
Bram Moolenaara3556522018-12-31 22:02:29 +0100311 call assert_fails('sign place 1 name=Sign1 buffer=999', 'E158:')
312 call assert_fails('sign place buffer=999', 'E158:')
313 call assert_fails('sign jump buffer=999', 'E158:')
314 call assert_fails('sign jump 1 file=', 'E158:')
315 call assert_fails('sign jump 1 group=', 'E474:')
316 call assert_fails('sign jump 1 name=', 'E474:')
317 call assert_fails('sign jump 1 name=Sign1', 'E474:')
318 call assert_fails('sign jump 1 line=100', '474:')
Bram Moolenaar09de1752016-08-08 22:26:48 +0200319 call assert_fails('sign define Sign2 text=', 'E239:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100320 " Non-numeric identifier for :sign place
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100321 call assert_fails("sign place abc line=3 name=Sign1 buffer=" . bufnr(''),
322 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100323 " Non-numeric identifier for :sign unplace
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100324 call assert_fails("sign unplace abc name=Sign1 buffer=" . bufnr(''),
325 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100326 " Number followed by an alphabet as sign identifier for :sign place
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100327 call assert_fails("sign place 1abc line=3 name=Sign1 buffer=" . bufnr(''),
328 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100329 " Number followed by an alphabet as sign identifier for :sign unplace
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100330 call assert_fails("sign unplace 2abc name=Sign1 buffer=" . bufnr(''),
331 \ 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100332 " Sign identifier and '*' for :sign unplace
333 call assert_fails("sign unplace 2 *", 'E474:')
334 " Trailing characters after buffer number for :sign place
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100335 call assert_fails("sign place 1 line=3 name=Sign1 buffer=" .
336 \ bufnr('%') . 'xxx', 'E488:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100337 " Trailing characters after buffer number for :sign unplace
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100338 call assert_fails("sign unplace 1 buffer=" . bufnr('%') . 'xxx', 'E488:')
339 call assert_fails("sign unplace * buffer=" . bufnr('%') . 'xxx', 'E488:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100340 call assert_fails("sign unplace 1 xxx", 'E474:')
341 call assert_fails("sign unplace * xxx", 'E474:')
342 call assert_fails("sign unplace xxx", 'E474:')
343 " Placing a sign without line number
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100344 call assert_fails("sign place name=Sign1 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100345 " Placing a sign without sign name
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100346 call assert_fails("sign place line=10 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100347 " Unplacing a sign with line number
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100348 call assert_fails("sign unplace 2 line=10 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100349 " Unplacing a sign with sign name
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100350 call assert_fails("sign unplace 2 name=Sign1 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100351 " Placing a sign without sign name
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100352 call assert_fails("sign place 2 line=3 buffer=" . bufnr('%'), 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100353 " Placing a sign with only sign identifier
354 call assert_fails("sign place 2", 'E474:')
355 " Placing a sign with only a name
356 call assert_fails("sign place abc", 'E474:')
357 " Placing a sign with only line number
358 call assert_fails("sign place 5 line=3", 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100359 " Placing a sign with only sign group
360 call assert_fails("sign place 5 group=g1", 'E474:')
361 call assert_fails("sign place 5 group=*", 'E474:')
362 " Placing a sign with only sign priority
363 call assert_fails("sign place 5 priority=10", 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100364
365 sign undefine Sign1
Bram Moolenaar09de1752016-08-08 22:26:48 +0200366endfunc
Bram Moolenaarbfd096d2016-08-17 22:29:09 +0200367
368func Test_sign_delete_buffer()
369 new
370 sign define Sign text=x
371 let bufnr = bufnr('%')
372 new
373 exe 'bd ' . bufnr
374 exe 'sign place 61 line=3 name=Sign buffer=' . bufnr
375 call assert_fails('sign jump 61 buffer=' . bufnr, 'E934:')
376 sign unplace 61
377 sign undefine Sign
378endfunc
Bram Moolenaar162b7142018-12-21 15:17:36 +0100379
Bram Moolenaar6436cd82018-12-27 00:28:33 +0100380" Test for Vim script functions for managing signs
Bram Moolenaar162b7142018-12-21 15:17:36 +0100381func Test_sign_funcs()
382 " Remove all the signs
383 call sign_unplace('*')
384 call sign_undefine()
385
386 " Tests for sign_define()
387 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
388 call assert_equal(0, sign_define("sign1", attr))
389 call assert_equal([{'name' : 'sign1', 'texthl' : 'Error',
390 \ 'linehl' : 'Search', 'text' : '=>'}], sign_getdefined())
391
392 " Define a new sign without attributes and then update it
393 call sign_define("sign2")
394 let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange',
395 \ 'icon' : 'sign2.ico'}
396 try
397 call sign_define("sign2", attr)
398 catch /E255:/
399 " ignore error: E255: Couldn't read in sign data!
400 " This error can happen when running in gui.
401 endtry
402 call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange',
403 \ 'linehl' : 'DiffAdd', 'text' : '!!', 'icon' : 'sign2.ico'}],
404 \ sign_getdefined("sign2"))
405
406 " Test for a sign name with digits
407 call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'}))
408 call assert_equal([{'name' : '2', 'linehl' : 'StatusLine'}],
409 \ sign_getdefined(0002))
410 call sign_undefine(0002)
411
412 " Tests for invalid arguments to sign_define()
413 call assert_fails('call sign_define("sign4", {"text" : "===>"})', 'E239:')
414 call assert_fails('call sign_define("sign5", {"text" : ""})', 'E239:')
Bram Moolenaar809ce4d2019-07-13 21:21:40 +0200415 call assert_fails('call sign_define({})', 'E731:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100416 call assert_fails('call sign_define("sign6", [])', 'E715:')
417
418 " Tests for sign_getdefined()
419 call assert_equal([], sign_getdefined("none"))
420 call assert_fails('call sign_getdefined({})', 'E731:')
421
422 " Tests for sign_place()
423 call writefile(repeat(["Sun is shining"], 30), "Xsign")
424 edit Xsign
425
426 call assert_equal(10, sign_place(10, '', 'sign1', 'Xsign',
427 \ {'lnum' : 20}))
428 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
429 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
430 \ 'priority' : 10}]}], sign_getplaced('Xsign'))
431 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
432 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
433 \ 'priority' : 10}]}],
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100434 \ sign_getplaced('%', {'lnum' : 20}))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100435 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
436 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
437 \ 'priority' : 10}]}],
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100438 \ sign_getplaced('', {'id' : 10}))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100439
440 " Tests for invalid arguments to sign_place()
441 call assert_fails('call sign_place([], "", "mySign", 1)', 'E745:')
442 call assert_fails('call sign_place(5, "", "mySign", -1)', 'E158:')
443 call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])',
Bram Moolenaar809ce4d2019-07-13 21:21:40 +0200444 \ 'E715:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100445 call assert_fails('call sign_place(-1, "", "sign1", "Xsign",
446 \ {"lnum" : 30})', 'E474:')
447 call assert_fails('call sign_place(10, "", "xsign1x", "Xsign",
448 \ {"lnum" : 30})', 'E155:')
449 call assert_fails('call sign_place(10, "", "", "Xsign",
450 \ {"lnum" : 30})', 'E155:')
451 call assert_fails('call sign_place(10, "", [], "Xsign",
452 \ {"lnum" : 30})', 'E730:')
453 call assert_fails('call sign_place(5, "", "sign1", "abcxyz.xxx",
454 \ {"lnum" : 10})', 'E158:')
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100455 call assert_fails('call sign_place(5, "", "sign1", "@", {"lnum" : 10})',
Bram Moolenaar162b7142018-12-21 15:17:36 +0100456 \ 'E158:')
457 call assert_fails('call sign_place(5, "", "sign1", [], {"lnum" : 10})',
458 \ 'E158:')
459 call assert_fails('call sign_place(21, "", "sign1", "Xsign",
460 \ {"lnum" : -1})', 'E885:')
461 call assert_fails('call sign_place(22, "", "sign1", "Xsign",
462 \ {"lnum" : 0})', 'E885:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100463 call assert_fails('call sign_place(22, "", "sign1", "Xsign",
464 \ {"lnum" : []})', 'E745:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100465 call assert_equal(-1, sign_place(1, "*", "sign1", "Xsign", {"lnum" : 10}))
466
467 " Tests for sign_getplaced()
468 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
469 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
470 \ 'priority' : 10}]}],
471 \ sign_getplaced(bufnr('Xsign')))
472 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
473 \ [{'id' : 10, 'group' : '', 'lnum' : 20, 'name' : 'sign1',
474 \ 'priority' : 10}]}],
475 \ sign_getplaced())
476 call assert_fails("call sign_getplaced('dummy.sign')", 'E158:')
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100477 call assert_fails('call sign_getplaced("&")', 'E158:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100478 call assert_fails('call sign_getplaced(-1)', 'E158:')
479 call assert_fails('call sign_getplaced("Xsign", [])', 'E715:')
480 call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}],
481 \ sign_getplaced('Xsign', {'lnum' : 1000000}))
482 call assert_fails("call sign_getplaced('Xsign', {'lnum' : []})",
483 \ 'E745:')
484 call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}],
485 \ sign_getplaced('Xsign', {'id' : 44}))
486 call assert_fails("call sign_getplaced('Xsign', {'id' : []})",
487 \ 'E745:')
488
489 " Tests for sign_unplace()
490 call sign_place(20, '', 'sign2', 'Xsign', {"lnum" : 30})
491 call assert_equal(0, sign_unplace('',
492 \ {'id' : 20, 'buffer' : 'Xsign'}))
493 call assert_equal(-1, sign_unplace('',
494 \ {'id' : 30, 'buffer' : 'Xsign'}))
495 call sign_place(20, '', 'sign2', 'Xsign', {"lnum" : 30})
496 call assert_fails("call sign_unplace('',
497 \ {'id' : 20, 'buffer' : 'buffer.c'})", 'E158:')
498 call assert_fails("call sign_unplace('',
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +0100499 \ {'id' : 20, 'buffer' : '&'})", 'E158:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100500 call assert_fails("call sign_unplace('g1',
Bram Moolenaar162b7142018-12-21 15:17:36 +0100501 \ {'id' : 20, 'buffer' : 200})", 'E158:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100502 call assert_fails("call sign_unplace('g1', 'mySign')", 'E715:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100503
Bram Moolenaar809ce4d2019-07-13 21:21:40 +0200504 call sign_unplace('*')
505
506 " Test for modifying a placed sign
507 call assert_equal(15, sign_place(15, '', 'sign1', 'Xsign', {'lnum' : 20}))
508 call assert_equal(15, sign_place(15, '', 'sign2', 'Xsign'))
509 call assert_equal([{'bufnr' : bufnr(''), 'signs' :
510 \ [{'id' : 15, 'group' : '', 'lnum' : 20, 'name' : 'sign2',
511 \ 'priority' : 10}]}],
512 \ sign_getplaced())
513
Bram Moolenaar162b7142018-12-21 15:17:36 +0100514 " Tests for sign_undefine()
515 call assert_equal(0, sign_undefine("sign1"))
516 call assert_equal([], sign_getdefined("sign1"))
517 call assert_fails('call sign_undefine("none")', 'E155:')
Bram Moolenaar809ce4d2019-07-13 21:21:40 +0200518 call assert_fails('call sign_undefine({})', 'E731:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100519
520 call delete("Xsign")
521 call sign_unplace('*')
522 call sign_undefine()
523 enew | only
524endfunc
525
526" Tests for sign groups
527func Test_sign_group()
528 enew | only
529 " Remove all the signs
530 call sign_unplace('*')
531 call sign_undefine()
532
533 call writefile(repeat(["Sun is shining"], 30), "Xsign")
534
535 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
536 call assert_equal(0, sign_define("sign1", attr))
537
538 edit Xsign
539 let bnum = bufnr('%')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100540
541 " Error case
542 call assert_fails("call sign_place(5, [], 'sign1', 'Xsign',
543 \ {'lnum' : 30})", 'E730:')
544
545 " place three signs with the same identifier. One in the global group and
546 " others in the named groups
547 call assert_equal(5, sign_place(5, '', 'sign1', 'Xsign',
548 \ {'lnum' : 10}))
549 call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 20}))
550 call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 30}))
551
552 " Test for sign_getplaced() with group
553 let s = sign_getplaced('Xsign')
554 call assert_equal(1, len(s[0].signs))
555 call assert_equal(s[0].signs[0].group, '')
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100556 let s = sign_getplaced(bnum, {'group' : ''})
557 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
558 \ 'priority' : 10}], s[0].signs)
559 call assert_equal(1, len(s[0].signs))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100560 let s = sign_getplaced(bnum, {'group' : 'g2'})
561 call assert_equal('g2', s[0].signs[0].group)
562 let s = sign_getplaced(bnum, {'group' : 'g3'})
563 call assert_equal([], s[0].signs)
564 let s = sign_getplaced(bnum, {'group' : '*'})
565 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
566 \ 'priority' : 10},
567 \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20,
568 \ 'priority' : 10},
569 \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30,
570 \ 'priority' : 10}],
571 \ s[0].signs)
572
573 " Test for sign_getplaced() with id
574 let s = sign_getplaced(bnum, {'id' : 5})
575 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
576 \ 'priority' : 10}],
577 \ s[0].signs)
578 let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g2'})
579 call assert_equal(
580 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
581 \ 'priority' : 10}],
582 \ s[0].signs)
583 let s = sign_getplaced(bnum, {'id' : 5, 'group' : '*'})
584 call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
585 \ 'priority' : 10},
586 \ {'id' : 5, 'group' : 'g1', 'name' : 'sign1', 'lnum' : 20,
587 \ 'priority' : 10},
588 \ {'id' : 5, 'group' : 'g2', 'name' : 'sign1', 'lnum' : 30,
589 \ 'priority' : 10}],
590 \ s[0].signs)
591 let s = sign_getplaced(bnum, {'id' : 5, 'group' : 'g3'})
592 call assert_equal([], s[0].signs)
593
594 " Test for sign_getplaced() with lnum
595 let s = sign_getplaced(bnum, {'lnum' : 20})
596 call assert_equal([], s[0].signs)
597 let s = sign_getplaced(bnum, {'lnum' : 20, 'group' : 'g1'})
598 call assert_equal(
599 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1',
600 \ 'priority' : 10}],
601 \ s[0].signs)
602 let s = sign_getplaced(bnum, {'lnum' : 30, 'group' : '*'})
603 call assert_equal(
604 \ [{'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
605 \ 'priority' : 10}],
606 \ s[0].signs)
607 let s = sign_getplaced(bnum, {'lnum' : 40, 'group' : '*'})
608 call assert_equal([], s[0].signs)
609
610 " Error case
611 call assert_fails("call sign_getplaced(bnum, {'group' : []})",
612 \ 'E730:')
613
614 " Clear the sign in global group
615 call sign_unplace('', {'id' : 5, 'buffer' : bnum})
616 let s = sign_getplaced(bnum, {'group' : '*'})
617 call assert_equal([
618 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : 'g1',
619 \ 'priority' : 10},
620 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
621 \ 'priority' : 10}],
622 \ s[0].signs)
623
624 " Clear the sign in one of the groups
625 call sign_unplace('g1', {'buffer' : 'Xsign'})
626 let s = sign_getplaced(bnum, {'group' : '*'})
627 call assert_equal([
628 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 30, 'group' : 'g2',
629 \ 'priority' : 10}],
630 \ s[0].signs)
631
632 " Clear all the signs from the buffer
633 call sign_unplace('*', {'buffer' : bnum})
634 call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs)
635
636 " Clear sign across groups using an identifier
637 call sign_place(25, '', 'sign1', bnum, {'lnum' : 10})
638 call sign_place(25, 'g1', 'sign1', bnum, {'lnum' : 11})
639 call sign_place(25, 'g2', 'sign1', bnum, {'lnum' : 12})
640 call assert_equal(0, sign_unplace('*', {'id' : 25}))
641 call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs)
642
643 " Error case
Bram Moolenaar809ce4d2019-07-13 21:21:40 +0200644 call assert_fails("call sign_unplace({})", 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100645
646 " Place a sign in the global group and try to delete it using a group
647 call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10}))
648 call assert_equal(-1, sign_unplace('g1', {'id' : 5}))
649
650 " Place signs in multiple groups and delete all the signs in one of the
651 " group
652 call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10}))
653 call assert_equal(6, sign_place(6, '', 'sign1', bnum, {'lnum' : 11}))
654 call assert_equal(5, sign_place(5, 'g1', 'sign1', bnum, {'lnum' : 10}))
655 call assert_equal(5, sign_place(5, 'g2', 'sign1', bnum, {'lnum' : 10}))
656 call assert_equal(6, sign_place(6, 'g1', 'sign1', bnum, {'lnum' : 11}))
657 call assert_equal(6, sign_place(6, 'g2', 'sign1', bnum, {'lnum' : 11}))
658 call assert_equal(0, sign_unplace('g1'))
659 let s = sign_getplaced(bnum, {'group' : 'g1'})
660 call assert_equal([], s[0].signs)
661 let s = sign_getplaced(bnum)
662 call assert_equal(2, len(s[0].signs))
663 let s = sign_getplaced(bnum, {'group' : 'g2'})
664 call assert_equal('g2', s[0].signs[0].group)
665 call assert_equal(0, sign_unplace('', {'id' : 5}))
666 call assert_equal(0, sign_unplace('', {'id' : 6}))
667 let s = sign_getplaced(bnum, {'group' : 'g2'})
668 call assert_equal('g2', s[0].signs[0].group)
669 call assert_equal(0, sign_unplace('', {'buffer' : bnum}))
670
671 call sign_unplace('*')
672
673 " Test for :sign command and groups
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100674 sign place 5 line=10 name=sign1 file=Xsign
675 sign place 5 group=g1 line=10 name=sign1 file=Xsign
676 sign place 5 group=g2 line=10 name=sign1 file=Xsign
Bram Moolenaar162b7142018-12-21 15:17:36 +0100677
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100678 " Tests for the ':sign place' command
679
680 " :sign place file={fname}
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100681 let a = execute('sign place file=Xsign')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100682 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100683 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100684
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100685 " :sign place group={group} file={fname}
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100686 let a = execute('sign place group=g2 file=Xsign')
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100687 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100688 \ " line=10 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100689
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100690 " :sign place group=* file={fname}
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100691 let a = execute('sign place group=* file=Xsign')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100692 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100693 \ " line=10 id=5 group=g2 name=sign1 priority=10\n" .
694 \ " line=10 id=5 group=g1 name=sign1 priority=10\n" .
695 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100696
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100697 " Error case: non-existing group
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100698 let a = execute('sign place group=xyz file=Xsign')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100699 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
700
701 call sign_unplace('*')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100702 let bnum = bufnr('Xsign')
703 exe 'sign place 5 line=10 name=sign1 buffer=' . bnum
704 exe 'sign place 5 group=g1 line=11 name=sign1 buffer=' . bnum
705 exe 'sign place 5 group=g2 line=12 name=sign1 buffer=' . bnum
706
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100707 " :sign place buffer={fname}
Bram Moolenaar162b7142018-12-21 15:17:36 +0100708 let a = execute('sign place buffer=' . bnum)
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100709 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100710 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100711
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100712 " :sign place group={group} buffer={fname}
Bram Moolenaar162b7142018-12-21 15:17:36 +0100713 let a = execute('sign place group=g2 buffer=' . bnum)
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100714 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100715 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100716
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100717 " :sign place group=* buffer={fname}
Bram Moolenaar162b7142018-12-21 15:17:36 +0100718 let a = execute('sign place group=* buffer=' . bnum)
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" .
721 \ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
722 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100723
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100724 " Error case: non-existing group
Bram Moolenaar162b7142018-12-21 15:17:36 +0100725 let a = execute('sign place group=xyz buffer=' . bnum)
726 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
727
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100728 " :sign place
729 let a = execute('sign place')
730 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100731 \ " line=10 id=5 name=sign1 priority=10\n", a)
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100732
Bram Moolenaarb589f952019-01-07 22:10:00 +0100733 " Place signs in more than one buffer and list the signs
734 split foo
735 set buftype=nofile
736 sign place 25 line=76 name=sign1 priority=99 file=foo
737 let a = execute('sign place')
738 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
739 \ " line=10 id=5 name=sign1 priority=10\n" .
740 \ "Signs for foo:\n" .
741 \ " line=76 id=25 name=sign1 priority=99\n", a)
742 close
743 bwipe foo
744
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100745 " :sign place group={group}
746 let a = execute('sign place group=g1')
747 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100748 \ " line=11 id=5 group=g1 name=sign1 priority=10\n", a)
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100749
750 " :sign place group=*
Bram Moolenaar162b7142018-12-21 15:17:36 +0100751 let a = execute('sign place group=*')
752 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +0100753 \ " line=10 id=5 name=sign1 priority=10\n" .
754 \ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
755 \ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +0100756
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100757 " Test for ':sign jump' command with groups
758 sign jump 5 group=g1 file=Xsign
759 call assert_equal(11, line('.'))
760 call assert_equal('Xsign', bufname(''))
761 sign jump 5 group=g2 file=Xsign
762 call assert_equal(12, line('.'))
Bram Moolenaar162b7142018-12-21 15:17:36 +0100763
Bram Moolenaarb328cca2019-01-06 16:24:01 +0100764 " Test for :sign jump command without the filename or buffer
765 sign jump 5
766 call assert_equal(10, line('.'))
767 sign jump 5 group=g1
768 call assert_equal(11, line('.'))
769
Bram Moolenaar162b7142018-12-21 15:17:36 +0100770 " Error cases
Bram Moolenaar7a2d9892018-12-24 20:23:49 +0100771 call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:')
Bram Moolenaar162b7142018-12-21 15:17:36 +0100772
773 call delete("Xsign")
774 call sign_unplace('*')
775 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +0100776 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +0100777endfunc
778
Bram Moolenaar7d83bf42018-12-29 18:53:55 +0100779" Place signs used for ":sign unplace" command test
780func Place_signs_for_test()
781 call sign_unplace('*')
782
783 sign place 3 line=10 name=sign1 file=Xsign1
784 sign place 3 group=g1 line=11 name=sign1 file=Xsign1
785 sign place 3 group=g2 line=12 name=sign1 file=Xsign1
786 sign place 4 line=15 name=sign1 file=Xsign1
787 sign place 4 group=g1 line=16 name=sign1 file=Xsign1
788 sign place 4 group=g2 line=17 name=sign1 file=Xsign1
789 sign place 5 line=20 name=sign1 file=Xsign2
790 sign place 5 group=g1 line=21 name=sign1 file=Xsign2
791 sign place 5 group=g2 line=22 name=sign1 file=Xsign2
792 sign place 6 line=25 name=sign1 file=Xsign2
793 sign place 6 group=g1 line=26 name=sign1 file=Xsign2
794 sign place 6 group=g2 line=27 name=sign1 file=Xsign2
795endfunc
796
797" Place multiple signs in a single line for test
798func Place_signs_at_line_for_test()
799 call sign_unplace('*')
800 sign place 3 line=13 name=sign1 file=Xsign1
801 sign place 3 group=g1 line=13 name=sign1 file=Xsign1
802 sign place 3 group=g2 line=13 name=sign1 file=Xsign1
803 sign place 4 line=13 name=sign1 file=Xsign1
804 sign place 4 group=g1 line=13 name=sign1 file=Xsign1
805 sign place 4 group=g2 line=13 name=sign1 file=Xsign1
806endfunc
807
808" Tests for the ':sign unplace' command
809func Test_sign_unplace()
810 enew | only
811 " Remove all the signs
812 call sign_unplace('*')
813 call sign_undefine()
814
815 " Create two files and define signs
816 call writefile(repeat(["Sun is shining"], 30), "Xsign1")
817 call writefile(repeat(["It is beautiful"], 30), "Xsign2")
818
819 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
820 call sign_define("sign1", attr)
821
822 edit Xsign1
823 let bnum1 = bufnr('%')
824 split Xsign2
825 let bnum2 = bufnr('%')
826
827 let signs1 = [{'id' : 3, 'name' : 'sign1', 'lnum' : 10, 'group' : '',
828 \ 'priority' : 10},
829 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1',
830 \ 'priority' : 10},
831 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 12, 'group' : 'g2',
832 \ 'priority' : 10},
833 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 15, 'group' : '',
834 \ 'priority' : 10},
835 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 16, 'group' : 'g1',
836 \ 'priority' : 10},
837 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 17, 'group' : 'g2',
838 \ 'priority' : 10},]
839 let signs2 = [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : '',
840 \ 'priority' : 10},
841 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 21, 'group' : 'g1',
842 \ 'priority' : 10},
843 \ {'id' : 5, 'name' : 'sign1', 'lnum' : 22, 'group' : 'g2',
844 \ 'priority' : 10},
845 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 25, 'group' : '',
846 \ 'priority' : 10},
847 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 26, 'group' : 'g1',
848 \ 'priority' : 10},
849 \ {'id' : 6, 'name' : 'sign1', 'lnum' : 27, 'group' : 'g2',
850 \ 'priority' : 10},]
851
852 " Test for :sign unplace {id} file={fname}
853 call Place_signs_for_test()
854 sign unplace 3 file=Xsign1
855 sign unplace 6 file=Xsign2
856 call assert_equal(
857 \ filter(copy(signs1),
858 \ {idx, val -> val.id != 3 || val.group != ''}),
859 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
860 call assert_equal(
861 \ filter(copy(signs2),
862 \ {idx, val -> val.id != 6 || val.group != ''}),
863 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
864
865 " Test for :sign unplace {id} group={group} file={fname}
866 call Place_signs_for_test()
867 sign unplace 4 group=g1 file=Xsign1
868 sign unplace 5 group=g2 file=Xsign2
869 call assert_equal(
870 \ filter(copy(signs1),
871 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
872 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
873 call assert_equal(
874 \ filter(copy(signs2),
875 \ {idx, val -> val.id != 5 || val.group != 'g2'}),
876 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
877
878 " Test for :sign unplace {id} group=* file={fname}
879 call Place_signs_for_test()
880 sign unplace 3 group=* file=Xsign1
881 sign unplace 6 group=* file=Xsign2
882 call assert_equal(
883 \ filter(copy(signs1),
884 \ {idx, val -> val.id != 3}),
885 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
886 call assert_equal(
887 \ filter(copy(signs2),
888 \ {idx, val -> val.id != 6}),
889 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
890
891 " Test for :sign unplace * file={fname}
892 call Place_signs_for_test()
893 sign unplace * file=Xsign1
894 call assert_equal(
895 \ filter(copy(signs1),
896 \ {idx, val -> val.group != ''}),
897 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
898 call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
899
900 " Test for :sign unplace * group={group} file={fname}
901 call Place_signs_for_test()
902 sign unplace * group=g1 file=Xsign1
903 sign unplace * group=g2 file=Xsign2
904 call assert_equal(
905 \ filter(copy(signs1),
906 \ {idx, val -> val.group != 'g1'}),
907 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
908 call assert_equal(
909 \ filter(copy(signs2),
910 \ {idx, val -> val.group != 'g2'}),
911 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
912
913 " Test for :sign unplace * group=* file={fname}
914 call Place_signs_for_test()
915 sign unplace * group=* file=Xsign2
916 call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
917 call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
918
919 " Test for :sign unplace {id} buffer={nr}
920 call Place_signs_for_test()
921 exe 'sign unplace 3 buffer=' . bnum1
922 exe 'sign unplace 6 buffer=' . bnum2
923 call assert_equal(
924 \ filter(copy(signs1),
925 \ {idx, val -> val.id != 3 || val.group != ''}),
926 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
927 call assert_equal(
928 \ filter(copy(signs2),
929 \ {idx, val -> val.id != 6 || val.group != ''}),
930 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
931
932 " Test for :sign unplace {id} group={group} buffer={nr}
933 call Place_signs_for_test()
934 exe 'sign unplace 4 group=g1 buffer=' . bnum1
935 exe 'sign unplace 5 group=g2 buffer=' . bnum2
936 call assert_equal(
937 \ filter(copy(signs1),
938 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
939 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
940 call assert_equal(
941 \ filter(copy(signs2),
942 \ {idx, val -> val.id != 5 || val.group != 'g2'}),
943 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
944
945 " Test for :sign unplace {id} group=* buffer={nr}
946 call Place_signs_for_test()
947 exe 'sign unplace 3 group=* buffer=' . bnum1
948 exe 'sign unplace 6 group=* buffer=' . bnum2
949 call assert_equal(
950 \ filter(copy(signs1),
951 \ {idx, val -> val.id != 3}),
952 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
953 call assert_equal(
954 \ filter(copy(signs2),
955 \ {idx, val -> val.id != 6}),
956 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
957
958 " Test for :sign unplace * buffer={nr}
959 call Place_signs_for_test()
960 exe 'sign unplace * buffer=' . bnum1
961 call assert_equal(
962 \ filter(copy(signs1),
963 \ {idx, val -> val.group != ''}),
964 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
965 call assert_equal(signs2, sign_getplaced(bnum2, {'group' : '*'})[0].signs)
966
967 " Test for :sign unplace * group={group} buffer={nr}
968 call Place_signs_for_test()
969 exe 'sign unplace * group=g1 buffer=' . bnum1
970 exe 'sign unplace * group=g2 buffer=' . bnum2
971 call assert_equal(
972 \ filter(copy(signs1),
973 \ {idx, val -> val.group != 'g1'}),
974 \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
975 call assert_equal(
976 \ filter(copy(signs2),
977 \ {idx, val -> val.group != 'g2'}),
978 \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
979
980 " Test for :sign unplace * group=* buffer={nr}
981 call Place_signs_for_test()
982 exe 'sign unplace * group=* buffer=' . bnum2
983 call assert_equal(signs1, sign_getplaced(bnum1, {'group' : '*'})[0].signs)
984 call assert_equal([], sign_getplaced(bnum2, {'group' : '*'})[0].signs)
985
986 " Test for :sign unplace {id}
987 call Place_signs_for_test()
988 sign unplace 4
989 sign unplace 6
990 call assert_equal(
991 \ filter(copy(signs1),
992 \ {idx, val -> val.id != 4 || val.group != ''}),
993 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
994 call assert_equal(
995 \ filter(copy(signs2),
996 \ {idx, val -> val.id != 6 || val.group != ''}),
997 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
998
999 " Test for :sign unplace {id} group={group}
1000 call Place_signs_for_test()
1001 sign unplace 4 group=g1
1002 sign unplace 6 group=g2
1003 call assert_equal(
1004 \ filter(copy(signs1),
1005 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
1006 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1007 call assert_equal(
1008 \ filter(copy(signs2),
1009 \ {idx, val -> val.id != 6 || val.group != 'g2'}),
1010 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1011
1012 " Test for :sign unplace {id} group=*
1013 call Place_signs_for_test()
1014 sign unplace 3 group=*
1015 sign unplace 5 group=*
1016 call assert_equal(
1017 \ filter(copy(signs1),
1018 \ {idx, val -> val.id != 3}),
1019 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1020 call assert_equal(
1021 \ filter(copy(signs2),
1022 \ {idx, val -> val.id != 5}),
1023 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1024
1025 " Test for :sign unplace *
1026 call Place_signs_for_test()
1027 sign unplace *
1028 call assert_equal(
1029 \ filter(copy(signs1),
1030 \ {idx, val -> val.group != ''}),
1031 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1032 call assert_equal(
1033 \ filter(copy(signs2),
1034 \ {idx, val -> val.group != ''}),
1035 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1036
1037 " Test for :sign unplace * group={group}
1038 call Place_signs_for_test()
1039 sign unplace * group=g1
1040 call assert_equal(
1041 \ filter(copy(signs1),
1042 \ {idx, val -> val.group != 'g1'}),
1043 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1044 call assert_equal(
1045 \ filter(copy(signs2),
1046 \ {idx, val -> val.group != 'g1'}),
1047 \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1048
1049 " Test for :sign unplace * group=*
1050 call Place_signs_for_test()
1051 sign unplace * group=*
1052 call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1053 call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1054
1055 " Negative test cases
1056 call Place_signs_for_test()
1057 sign unplace 3 group=xy file=Xsign1
1058 sign unplace * group=xy file=Xsign1
1059 silent! sign unplace * group=* file=FileNotPresent
1060 call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1061 call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
1062
1063 " Tests for removing sign at the current cursor position
1064
1065 " Test for ':sign unplace'
1066 let signs1 = [{'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
1067 \ 'priority' : 10},
1068 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
1069 \ 'priority' : 10},
1070 \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
1071 \ 'priority' : 10},
1072 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
1073 \ 'priority' : 10},
1074 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
1075 \ 'priority' : 10},
1076 \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
1077 \ 'priority' : 10},]
1078 exe bufwinnr('Xsign1') . 'wincmd w'
1079 call cursor(13, 1)
1080
1081 " Should remove only one sign in the global group
1082 call Place_signs_at_line_for_test()
1083 sign unplace
1084 call assert_equal(
1085 \ filter(copy(signs1),
1086 \ {idx, val -> val.id != 4 || val.group != ''}),
1087 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1088 " Should remove the second sign in the global group
1089 sign unplace
1090 call assert_equal(
1091 \ filter(copy(signs1),
1092 \ {idx, val -> val.group != ''}),
1093 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1094
1095 " Test for ':sign unplace group={group}'
1096 call Place_signs_at_line_for_test()
1097 " Should remove only one sign in group g1
1098 sign unplace group=g1
1099 call assert_equal(
1100 \ filter(copy(signs1),
1101 \ {idx, val -> val.id != 4 || val.group != 'g1'}),
1102 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1103 sign unplace group=g2
1104 call assert_equal(
1105 \ filter(copy(signs1),
1106 \ {idx, val -> val.id != 4 || val.group == ''}),
1107 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1108
1109 " Test for ':sign unplace group=*'
1110 call Place_signs_at_line_for_test()
1111 sign unplace group=*
1112 sign unplace group=*
1113 sign unplace group=*
1114 call assert_equal(
1115 \ filter(copy(signs1),
1116 \ {idx, val -> val.id != 4}),
1117 \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1118 sign unplace group=*
1119 sign unplace group=*
1120 sign unplace group=*
1121 call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
1122
1123 call sign_unplace('*')
1124 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001125 enew | only
Bram Moolenaar7d83bf42018-12-29 18:53:55 +01001126 call delete("Xsign1")
1127 call delete("Xsign2")
1128endfunc
1129
Bram Moolenaar809ce4d2019-07-13 21:21:40 +02001130" Tests for auto-generating the sign identifier.
1131func Test_aaa_sign_id_autogen()
Bram Moolenaar162b7142018-12-21 15:17:36 +01001132 enew | only
1133 call sign_unplace('*')
1134 call sign_undefine()
1135
1136 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
1137 call assert_equal(0, sign_define("sign1", attr))
1138
1139 call writefile(repeat(["Sun is shining"], 30), "Xsign")
1140 edit Xsign
1141
1142 call assert_equal(1, sign_place(0, '', 'sign1', 'Xsign',
1143 \ {'lnum' : 10}))
1144 call assert_equal(2, sign_place(2, '', 'sign1', 'Xsign',
1145 \ {'lnum' : 12}))
1146 call assert_equal(3, sign_place(0, '', 'sign1', 'Xsign',
1147 \ {'lnum' : 14}))
1148 call sign_unplace('', {'buffer' : 'Xsign', 'id' : 2})
Bram Moolenaar6436cd82018-12-27 00:28:33 +01001149 call assert_equal(4, sign_place(0, '', 'sign1', 'Xsign',
Bram Moolenaar162b7142018-12-21 15:17:36 +01001150 \ {'lnum' : 12}))
1151
1152 call assert_equal(1, sign_place(0, 'g1', 'sign1', 'Xsign',
1153 \ {'lnum' : 11}))
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001154 " Check for the next generated sign id in this group
1155 call assert_equal(2, sign_place(0, 'g1', 'sign1', 'Xsign',
1156 \ {'lnum' : 12}))
Bram Moolenaar162b7142018-12-21 15:17:36 +01001157 call assert_equal(0, sign_unplace('g1', {'id' : 1}))
1158 call assert_equal(10,
1159 \ sign_getplaced('Xsign', {'id' : 1})[0].signs[0].lnum)
1160
1161 call delete("Xsign")
1162 call sign_unplace('*')
1163 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001164 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +01001165endfunc
1166
1167" Test for sign priority
1168func Test_sign_priority()
1169 enew | only
1170 call sign_unplace('*')
1171 call sign_undefine()
1172
1173 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search'}
1174 call sign_define("sign1", attr)
1175 call sign_define("sign2", attr)
1176 call sign_define("sign3", attr)
1177
1178 " Place three signs with different priority in the same line
1179 call writefile(repeat(["Sun is shining"], 30), "Xsign")
1180 edit Xsign
Bram Moolenaar162b7142018-12-21 15:17:36 +01001181
1182 call sign_place(1, 'g1', 'sign1', 'Xsign',
1183 \ {'lnum' : 11, 'priority' : 50})
1184 call sign_place(2, 'g2', 'sign2', 'Xsign',
1185 \ {'lnum' : 11, 'priority' : 100})
1186 call sign_place(3, '', 'sign3', 'Xsign', {'lnum' : 11})
1187 let s = sign_getplaced('Xsign', {'group' : '*'})
1188 call assert_equal([
1189 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11, 'group' : 'g2',
1190 \ 'priority' : 100},
1191 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1',
1192 \ 'priority' : 50},
1193 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11, 'group' : '',
1194 \ 'priority' : 10}],
1195 \ s[0].signs)
1196
Bram Moolenaar64416122019-06-07 21:37:13 +02001197 call sign_unplace('*')
1198
1199 " Three signs on different lines with changing priorities
1200 call sign_place(1, '', 'sign1', 'Xsign',
1201 \ {'lnum' : 11, 'priority' : 50})
1202 call sign_place(2, '', 'sign2', 'Xsign',
1203 \ {'lnum' : 12, 'priority' : 60})
1204 call sign_place(3, '', 'sign3', 'Xsign',
1205 \ {'lnum' : 13, 'priority' : 70})
1206 call sign_place(2, '', 'sign2', 'Xsign',
1207 \ {'lnum' : 12, 'priority' : 40})
1208 call sign_place(3, '', 'sign3', 'Xsign',
1209 \ {'lnum' : 13, 'priority' : 30})
1210 call sign_place(1, '', 'sign1', 'Xsign',
1211 \ {'lnum' : 11, 'priority' : 50})
1212 let s = sign_getplaced('Xsign', {'group' : '*'})
1213 call assert_equal([
1214 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : '',
1215 \ 'priority' : 50},
1216 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 12, 'group' : '',
1217 \ 'priority' : 40},
1218 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 13, 'group' : '',
1219 \ 'priority' : 30}],
1220 \ s[0].signs)
1221
1222 call sign_unplace('*')
1223
1224 " Two signs on the same line with changing priorities
1225 call sign_place(1, '', 'sign1', 'Xsign',
1226 \ {'lnum' : 4, 'priority' : 20})
1227 call sign_place(2, '', 'sign2', 'Xsign',
1228 \ {'lnum' : 4, 'priority' : 30})
1229 let s = sign_getplaced('Xsign', {'group' : '*'})
1230 call assert_equal([
1231 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1232 \ 'priority' : 30},
1233 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1234 \ 'priority' : 20}],
1235 \ s[0].signs)
1236 " Change the priority of the last sign to highest
1237 call sign_place(1, '', 'sign1', 'Xsign',
1238 \ {'lnum' : 4, 'priority' : 40})
1239 let s = sign_getplaced('Xsign', {'group' : '*'})
1240 call assert_equal([
1241 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1242 \ 'priority' : 40},
1243 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1244 \ 'priority' : 30}],
1245 \ s[0].signs)
1246 " Change the priority of the first sign to lowest
1247 call sign_place(1, '', 'sign1', 'Xsign',
1248 \ {'lnum' : 4, 'priority' : 25})
1249 let s = sign_getplaced('Xsign', {'group' : '*'})
1250 call assert_equal([
1251 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1252 \ 'priority' : 30},
1253 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1254 \ 'priority' : 25}],
1255 \ s[0].signs)
1256 call sign_place(1, '', 'sign1', 'Xsign',
1257 \ {'lnum' : 4, 'priority' : 45})
1258 call sign_place(2, '', 'sign2', 'Xsign',
1259 \ {'lnum' : 4, 'priority' : 55})
1260 let s = sign_getplaced('Xsign', {'group' : '*'})
1261 call assert_equal([
1262 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1263 \ 'priority' : 55},
1264 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1265 \ 'priority' : 45}],
1266 \ s[0].signs)
1267
1268 call sign_unplace('*')
1269
1270 " Three signs on the same line with changing priorities
1271 call sign_place(1, '', 'sign1', 'Xsign',
1272 \ {'lnum' : 4, 'priority' : 40})
1273 call sign_place(2, '', 'sign2', 'Xsign',
1274 \ {'lnum' : 4, 'priority' : 30})
1275 call sign_place(3, '', 'sign3', 'Xsign',
1276 \ {'lnum' : 4, 'priority' : 20})
1277 let s = sign_getplaced('Xsign', {'group' : '*'})
1278 call assert_equal([
1279 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1280 \ 'priority' : 40},
1281 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1282 \ 'priority' : 30},
1283 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1284 \ 'priority' : 20}],
1285 \ s[0].signs)
1286
1287 " Change the priority of the middle sign to the highest
1288 call sign_place(2, '', 'sign2', 'Xsign',
1289 \ {'lnum' : 4, 'priority' : 50})
1290 let s = sign_getplaced('Xsign', {'group' : '*'})
1291 call assert_equal([
1292 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1293 \ 'priority' : 50},
1294 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1295 \ 'priority' : 40},
1296 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1297 \ 'priority' : 20}],
1298 \ s[0].signs)
1299
1300 " Change the priority of the middle sign to the lowest
1301 call sign_place(1, '', 'sign1', 'Xsign',
1302 \ {'lnum' : 4, 'priority' : 15})
1303 let s = sign_getplaced('Xsign', {'group' : '*'})
1304 call assert_equal([
1305 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1306 \ 'priority' : 50},
1307 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1308 \ 'priority' : 20},
1309 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1310 \ 'priority' : 15}],
1311 \ s[0].signs)
1312
1313 " Change the priority of the last sign to the highest
1314 call sign_place(1, '', 'sign1', 'Xsign',
1315 \ {'lnum' : 4, 'priority' : 55})
1316 let s = sign_getplaced('Xsign', {'group' : '*'})
1317 call assert_equal([
1318 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1319 \ 'priority' : 55},
1320 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1321 \ 'priority' : 50},
1322 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1323 \ 'priority' : 20}],
1324 \ s[0].signs)
1325
1326 " Change the priority of the first sign to the lowest
1327 call sign_place(1, '', 'sign1', 'Xsign',
1328 \ {'lnum' : 4, 'priority' : 15})
1329 let s = sign_getplaced('Xsign', {'group' : '*'})
1330 call assert_equal([
1331 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1332 \ 'priority' : 50},
1333 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1334 \ 'priority' : 20},
1335 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1336 \ 'priority' : 15}],
1337 \ s[0].signs)
1338
1339 call sign_unplace('*')
1340
1341 " Three signs on the same line with changing priorities along with other
1342 " signs
1343 call sign_place(1, '', 'sign1', 'Xsign',
1344 \ {'lnum' : 2, 'priority' : 10})
1345 call sign_place(2, '', 'sign1', 'Xsign',
1346 \ {'lnum' : 4, 'priority' : 30})
1347 call sign_place(3, '', 'sign2', 'Xsign',
1348 \ {'lnum' : 4, 'priority' : 20})
1349 call sign_place(4, '', 'sign3', 'Xsign',
1350 \ {'lnum' : 4, 'priority' : 25})
1351 call sign_place(5, '', 'sign2', 'Xsign',
1352 \ {'lnum' : 6, 'priority' : 80})
1353 let s = sign_getplaced('Xsign', {'group' : '*'})
1354 call assert_equal([
1355 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
1356 \ 'priority' : 10},
1357 \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1358 \ 'priority' : 30},
1359 \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1360 \ 'priority' : 25},
1361 \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1362 \ 'priority' : 20},
1363 \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
1364 \ 'priority' : 80}],
1365 \ s[0].signs)
1366
1367 " Change the priority of the first sign to lowest
1368 call sign_place(2, '', 'sign1', 'Xsign',
1369 \ {'lnum' : 4, 'priority' : 15})
1370 let s = sign_getplaced('Xsign', {'group' : '*'})
1371 call assert_equal([
1372 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
1373 \ 'priority' : 10},
1374 \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1375 \ 'priority' : 25},
1376 \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1377 \ 'priority' : 20},
1378 \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1379 \ 'priority' : 15},
1380 \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
1381 \ 'priority' : 80}],
1382 \ s[0].signs)
1383
1384 " Change the priority of the last sign to highest
1385 call sign_place(2, '', 'sign1', 'Xsign',
1386 \ {'lnum' : 4, 'priority' : 30})
1387 let s = sign_getplaced('Xsign', {'group' : '*'})
1388 call assert_equal([
1389 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
1390 \ 'priority' : 10},
1391 \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1392 \ 'priority' : 30},
1393 \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1394 \ 'priority' : 25},
1395 \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1396 \ 'priority' : 20},
1397 \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
1398 \ 'priority' : 80}],
1399 \ s[0].signs)
1400
1401 " Change the priority of the middle sign to lowest
1402 call sign_place(4, '', 'sign3', 'Xsign',
1403 \ {'lnum' : 4, 'priority' : 15})
1404 let s = sign_getplaced('Xsign', {'group' : '*'})
1405 call assert_equal([
1406 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
1407 \ 'priority' : 10},
1408 \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1409 \ 'priority' : 30},
1410 \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1411 \ 'priority' : 20},
1412 \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1413 \ 'priority' : 15},
1414 \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
1415 \ 'priority' : 80}],
1416 \ s[0].signs)
1417
1418 " Change the priority of the middle sign to highest
1419 call sign_place(3, '', 'sign2', 'Xsign',
1420 \ {'lnum' : 4, 'priority' : 35})
1421 let s = sign_getplaced('Xsign', {'group' : '*'})
1422 call assert_equal([
1423 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
1424 \ 'priority' : 10},
1425 \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1426 \ 'priority' : 35},
1427 \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1428 \ 'priority' : 30},
1429 \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1430 \ 'priority' : 15},
1431 \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
1432 \ 'priority' : 80}],
1433 \ s[0].signs)
1434
1435 call sign_unplace('*')
1436
1437 " Multiple signs with the same priority on the same line
1438 call sign_place(1, '', 'sign1', 'Xsign',
1439 \ {'lnum' : 4, 'priority' : 20})
1440 call sign_place(2, '', 'sign2', 'Xsign',
1441 \ {'lnum' : 4, 'priority' : 20})
1442 call sign_place(3, '', 'sign3', 'Xsign',
1443 \ {'lnum' : 4, 'priority' : 20})
1444 let s = sign_getplaced('Xsign', {'group' : '*'})
1445 call assert_equal([
1446 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1447 \ 'priority' : 20},
1448 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1449 \ 'priority' : 20},
1450 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1451 \ 'priority' : 20}],
1452 \ s[0].signs)
1453 " Place the last sign again with the same priority
1454 call sign_place(1, '', 'sign1', 'Xsign',
1455 \ {'lnum' : 4, 'priority' : 20})
1456 let s = sign_getplaced('Xsign', {'group' : '*'})
1457 call assert_equal([
1458 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1459 \ 'priority' : 20},
1460 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1461 \ 'priority' : 20},
1462 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1463 \ 'priority' : 20}],
1464 \ s[0].signs)
1465 " Place the first sign again with the same priority
1466 call sign_place(1, '', 'sign1', 'Xsign',
1467 \ {'lnum' : 4, 'priority' : 20})
1468 let s = sign_getplaced('Xsign', {'group' : '*'})
1469 call assert_equal([
1470 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1471 \ 'priority' : 20},
1472 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1473 \ 'priority' : 20},
1474 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1475 \ 'priority' : 20}],
1476 \ s[0].signs)
1477 " Place the middle sign again with the same priority
1478 call sign_place(3, '', 'sign3', 'Xsign',
1479 \ {'lnum' : 4, 'priority' : 20})
1480 let s = sign_getplaced('Xsign', {'group' : '*'})
1481 call assert_equal([
1482 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
1483 \ 'priority' : 20},
1484 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
1485 \ 'priority' : 20},
1486 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
1487 \ 'priority' : 20}],
1488 \ s[0].signs)
1489
1490 call sign_unplace('*')
1491
Bram Moolenaar58a7f872019-06-04 22:48:15 +02001492 " Place multiple signs with same id on a line with different priority
1493 call sign_place(1, '', 'sign1', 'Xsign',
1494 \ {'lnum' : 5, 'priority' : 20})
1495 call sign_place(1, '', 'sign2', 'Xsign',
1496 \ {'lnum' : 5, 'priority' : 10})
1497 let s = sign_getplaced('Xsign', {'lnum' : 5})
1498 call assert_equal([
1499 \ {'id' : 1, 'name' : 'sign2', 'lnum' : 5, 'group' : '',
1500 \ 'priority' : 10}],
1501 \ s[0].signs)
1502 call sign_place(1, '', 'sign2', 'Xsign',
1503 \ {'lnum' : 5, 'priority' : 5})
1504 let s = sign_getplaced('Xsign', {'lnum' : 5})
1505 call assert_equal([
1506 \ {'id' : 1, 'name' : 'sign2', 'lnum' : 5, 'group' : '',
1507 \ 'priority' : 5}],
1508 \ s[0].signs)
1509
Bram Moolenaar162b7142018-12-21 15:17:36 +01001510 " Error case
1511 call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign',
1512 \ [])", 'E715:')
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001513 call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign',
1514 \ {'priority' : []})", 'E745:')
Bram Moolenaar162b7142018-12-21 15:17:36 +01001515 call sign_unplace('*')
1516
1517 " Tests for the :sign place command with priority
1518 sign place 5 line=10 name=sign1 priority=30 file=Xsign
1519 sign place 5 group=g1 line=10 name=sign1 priority=20 file=Xsign
1520 sign place 5 group=g2 line=10 name=sign1 priority=25 file=Xsign
1521 let a = execute('sign place group=*')
1522 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +01001523 \ " line=10 id=5 name=sign1 priority=30\n" .
1524 \ " line=10 id=5 group=g2 name=sign1 priority=25\n" .
1525 \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +01001526
1527 " Test for :sign place group={group}
1528 let a = execute('sign place group=g1')
1529 call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
Bram Moolenaard730c8e2019-01-07 21:16:53 +01001530 \ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
Bram Moolenaar162b7142018-12-21 15:17:36 +01001531
1532 call sign_unplace('*')
1533 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001534 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +01001535 call delete("Xsign")
1536endfunc
1537
1538" Tests for memory allocation failures in sign functions
1539func Test_sign_memfailures()
1540 call writefile(repeat(["Sun is shining"], 30), "Xsign")
1541 edit Xsign
1542
1543 call test_alloc_fail(GetAllocId('sign_getdefined'), 0, 0)
1544 call assert_fails('call sign_getdefined("sign1")', 'E342:')
1545 call test_alloc_fail(GetAllocId('sign_getplaced'), 0, 0)
1546 call assert_fails('call sign_getplaced("Xsign")', 'E342:')
1547 call test_alloc_fail(GetAllocId('sign_define_by_name'), 0, 0)
1548 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
1549 call assert_fails('call sign_define("sign1", attr)', 'E342:')
1550
1551 let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
1552 call sign_define("sign1", attr)
1553 call test_alloc_fail(GetAllocId('sign_getlist'), 0, 0)
1554 call assert_fails('call sign_getdefined("sign1")', 'E342:')
1555
1556 call sign_place(3, 'g1', 'sign1', 'Xsign', {'lnum' : 10})
1557 call test_alloc_fail(GetAllocId('sign_getplaced_dict'), 0, 0)
1558 call assert_fails('call sign_getplaced("Xsign")', 'E342:')
1559 call test_alloc_fail(GetAllocId('sign_getplaced_list'), 0, 0)
1560 call assert_fails('call sign_getplaced("Xsign")', 'E342:')
1561
1562 call test_alloc_fail(GetAllocId('insert_sign'), 0, 0)
1563 call assert_fails('call sign_place(4, "g1", "sign1", "Xsign", {"lnum" : 11})',
1564 \ 'E342:')
1565
1566 call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0)
1567 call assert_fails('call getbufinfo()', 'E342:')
1568 call sign_place(4, 'g1', 'sign1', 'Xsign', {'lnum' : 11})
1569 call test_alloc_fail(GetAllocId('sign_getinfo'), 0, 0)
1570 call assert_fails('let binfo=getbufinfo("Xsign")', 'E342:')
1571 call assert_equal([{'lnum': 11, 'id': 4, 'name': 'sign1',
1572 \ 'priority': 10, 'group': 'g1'}], binfo[0].signs)
1573
1574 call sign_unplace('*')
1575 call sign_undefine()
Bram Moolenaar1ea88a32018-12-29 21:00:27 +01001576 enew | only
Bram Moolenaar162b7142018-12-21 15:17:36 +01001577 call delete("Xsign")
1578endfunc
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001579
1580" Test for auto-adjusting the line number of a placed sign.
1581func Test_sign_lnum_adjust()
1582 enew! | only!
1583
1584 sign define sign1 text=#> linehl=Comment
Bram Moolenaarc771bf92019-01-17 17:36:45 +01001585 call setline(1, ['A', 'B', 'C', 'D', 'E'])
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001586 exe 'sign place 5 line=3 name=sign1 buffer=' . bufnr('')
1587 let l = sign_getplaced(bufnr(''))
1588 call assert_equal(3, l[0].signs[0].lnum)
1589
1590 " Add some lines before the sign and check the sign line number
Bram Moolenaarc771bf92019-01-17 17:36:45 +01001591 call append(2, ['BA', 'BB', 'BC'])
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001592 let l = sign_getplaced(bufnr(''))
1593 call assert_equal(6, l[0].signs[0].lnum)
1594
1595 " Delete some lines before the sign and check the sign line number
1596 call deletebufline('%', 1, 2)
1597 let l = sign_getplaced(bufnr(''))
1598 call assert_equal(4, l[0].signs[0].lnum)
1599
Bram Moolenaarc771bf92019-01-17 17:36:45 +01001600 " Insert some lines after the sign and check the sign line number
1601 call append(5, ['DA', 'DB'])
1602 let l = sign_getplaced(bufnr(''))
1603 call assert_equal(4, l[0].signs[0].lnum)
1604
1605 " Delete some lines after the sign and check the sign line number
1606 call deletebufline('', 6, 7)
1607 let l = sign_getplaced(bufnr(''))
1608 call assert_equal(4, l[0].signs[0].lnum)
1609
1610 " Break the undo. Otherwise the undo operation below will undo all the
1611 " changes made by this function.
1612 let &undolevels=&undolevels
1613
1614 " Delete the line with the sign
1615 call deletebufline('', 4)
1616 let l = sign_getplaced(bufnr(''))
1617 call assert_equal(4, l[0].signs[0].lnum)
1618
1619 " Undo the delete operation
1620 undo
1621 let l = sign_getplaced(bufnr(''))
1622 call assert_equal(5, l[0].signs[0].lnum)
1623
1624 " Break the undo
1625 let &undolevels=&undolevels
1626
1627 " Delete few lines at the end of the buffer including the line with the sign
1628 " Sign line number should not change (as it is placed outside of the buffer)
1629 call deletebufline('', 3, 6)
1630 let l = sign_getplaced(bufnr(''))
1631 call assert_equal(5, l[0].signs[0].lnum)
1632
1633 " Undo the delete operation. Sign should be restored to the previous line
1634 undo
1635 let l = sign_getplaced(bufnr(''))
1636 call assert_equal(5, l[0].signs[0].lnum)
1637
Bram Moolenaar2cbc1a02019-01-02 13:40:31 +01001638 sign unplace * group=*
1639 sign undefine sign1
1640 enew!
1641endfunc
1642
1643" Test for changing the type of a placed sign
1644func Test_sign_change_type()
1645 enew! | only!
1646
1647 sign define sign1 text=#> linehl=Comment
1648 sign define sign2 text=@@ linehl=Comment
1649
1650 call setline(1, ['A', 'B', 'C', 'D'])
1651 exe 'sign place 4 line=3 name=sign1 buffer=' . bufnr('')
1652 let l = sign_getplaced(bufnr(''))
1653 call assert_equal('sign1', l[0].signs[0].name)
1654 exe 'sign place 4 name=sign2 buffer=' . bufnr('')
1655 let l = sign_getplaced(bufnr(''))
1656 call assert_equal('sign2', l[0].signs[0].name)
1657 call sign_place(4, '', 'sign1', '')
1658 let l = sign_getplaced(bufnr(''))
1659 call assert_equal('sign1', l[0].signs[0].name)
1660
1661 exe 'sign place 4 group=g1 line=4 name=sign1 buffer=' . bufnr('')
1662 let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
1663 call assert_equal('sign1', l[0].signs[0].name)
1664 exe 'sign place 4 group=g1 name=sign2 buffer=' . bufnr('')
1665 let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
1666 call assert_equal('sign2', l[0].signs[0].name)
1667 call sign_place(4, 'g1', 'sign1', '')
1668 let l = sign_getplaced(bufnr(''), {'group' : 'g1'})
1669 call assert_equal('sign1', l[0].signs[0].name)
1670
1671 sign unplace * group=*
1672 sign undefine sign1
1673 sign undefine sign2
1674 enew!
1675endfunc
Bram Moolenaar6b7b7192019-01-11 13:42:41 +01001676
1677" Test for the sign_jump() function
1678func Test_sign_jump_func()
1679 enew! | only!
1680
1681 sign define sign1 text=#> linehl=Comment
1682
1683 edit foo
1684 set buftype=nofile
1685 call setline(1, ['A', 'B', 'C', 'D', 'E'])
1686 call sign_place(5, '', 'sign1', '', {'lnum' : 2})
1687 call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
1688 call sign_place(6, '', 'sign1', '', {'lnum' : 4})
1689 call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
1690 split bar
1691 set buftype=nofile
1692 call setline(1, ['P', 'Q', 'R', 'S', 'T'])
1693 call sign_place(5, '', 'sign1', '', {'lnum' : 2})
1694 call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
1695 call sign_place(6, '', 'sign1', '', {'lnum' : 4})
1696 call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
1697
1698 let r = sign_jump(5, '', 'foo')
1699 call assert_equal(2, r)
1700 call assert_equal(2, line('.'))
1701 let r = sign_jump(6, 'g1', 'foo')
1702 call assert_equal(5, r)
1703 call assert_equal(5, line('.'))
1704 let r = sign_jump(5, '', 'bar')
1705 call assert_equal(2, r)
1706 call assert_equal(2, line('.'))
1707
1708 " Error cases
1709 call assert_fails("call sign_jump(99, '', 'bar')", 'E157:')
1710 call assert_fails("call sign_jump(0, '', 'foo')", 'E474:')
1711 call assert_fails("call sign_jump(5, 'g5', 'foo')", 'E157:')
1712 call assert_fails('call sign_jump([], "", "foo")', 'E745:')
1713 call assert_fails('call sign_jump(2, [], "foo")', 'E730:')
1714 call assert_fails('call sign_jump(2, "", {})', 'E158:')
1715 call assert_fails('call sign_jump(2, "", "baz")', 'E158:')
1716
1717 sign unplace * group=*
1718 sign undefine sign1
1719 enew! | only!
1720endfunc
Bram Moolenaarf85e40a2019-06-16 13:55:40 +02001721
1722" Test for correct cursor position after the sign column appears or disappears.
1723func Test_sign_cursor_position()
1724 if !CanRunVimInTerminal()
1725 throw 'Skipped: cannot make screendumps'
1726 endif
1727
1728 let lines =<< trim END
1729 call setline(1, [repeat('x', 75), 'mmmm', 'yyyy'])
1730 call cursor(2,1)
1731 sign define s1 texthl=Search text==>
1732 redraw
1733 sign place 10 line=2 name=s1
1734 END
1735 call writefile(lines, 'XtestSigncolumn')
1736 let buf = RunVimInTerminal('-S XtestSigncolumn', {'rows': 6})
1737 call VerifyScreenDump(buf, 'Test_sign_cursor_01', {})
1738
1739 " update cursor position calculation
1740 call term_sendkeys(buf, "lh")
1741 call term_sendkeys(buf, ":sign unplace 10\<CR>")
1742 call VerifyScreenDump(buf, 'Test_sign_cursor_02', {})
1743
1744
1745 " clean up
1746 call StopVimInTerminal(buf)
1747 call delete('XtestSigncolumn')
1748endfunc
Bram Moolenaar394c5d82019-06-17 21:48:05 +02001749
1750" Return the 'len' characters in screen starting from (row,col)
1751func s:ScreenLine(row, col, len)
1752 let s = ''
1753 for i in range(a:len)
1754 let s .= nr2char(screenchar(a:row, a:col + i))
1755 endfor
1756 return s
1757endfunc
1758
1759" Test for 'signcolumn' set to 'number'.
1760func Test_sign_numcol()
1761 new
1762 call append(0, "01234")
1763 " With 'signcolumn' set to 'number', make sure sign is displayed in the
1764 " number column and line number is not displayed.
1765 set numberwidth=2
1766 set number
1767 set signcolumn=number
1768 sign define sign1 text==>
Bram Moolenaard6bcff42019-07-18 12:48:16 +02001769 sign define sign2 text=V
Bram Moolenaar394c5d82019-06-17 21:48:05 +02001770 sign place 10 line=1 name=sign1
1771 redraw!
1772 call assert_equal("=> 01234", s:ScreenLine(1, 1, 8))
1773
1774 " With 'signcolumn' set to 'number', when there is no sign, make sure line
1775 " number is displayed in the number column
1776 sign unplace 10
1777 redraw!
1778 call assert_equal("1 01234", s:ScreenLine(1, 1, 7))
1779
1780 " Disable number column. Check whether sign is displayed in the sign column
1781 set numberwidth=4
1782 set nonumber
1783 sign place 10 line=1 name=sign1
1784 redraw!
1785 call assert_equal("=>01234", s:ScreenLine(1, 1, 7))
1786
1787 " Enable number column. Check whether sign is displayed in the number column
1788 set number
1789 redraw!
Bram Moolenaar4dff4ae2019-06-19 16:31:28 +02001790 call assert_equal(" => 01234", s:ScreenLine(1, 1, 9))
Bram Moolenaar394c5d82019-06-17 21:48:05 +02001791
1792 " Disable sign column. Make sure line number is displayed
1793 set signcolumn=no
1794 redraw!
1795 call assert_equal(" 1 01234", s:ScreenLine(1, 1, 9))
1796
1797 " Enable auto sign column. Make sure both sign and line number are displayed
1798 set signcolumn=auto
1799 redraw!
1800 call assert_equal("=> 1 01234", s:ScreenLine(1, 1, 11))
1801
Bram Moolenaare4b407f2019-07-04 11:59:28 +02001802 " Test displaying signs in the number column with width 1
1803 call sign_unplace('*')
1804 call append(1, "abcde")
1805 call append(2, "01234")
1806 " Enable number column with width 1
1807 set number numberwidth=1 signcolumn=auto
1808 redraw!
1809 call assert_equal("3 01234", s:ScreenLine(3, 1, 7))
1810 " Place a sign and make sure number column width remains the same
1811 sign place 20 line=2 name=sign1
1812 redraw!
1813 call assert_equal("=>2 abcde", s:ScreenLine(2, 1, 9))
1814 call assert_equal(" 3 01234", s:ScreenLine(3, 1, 9))
1815 " Set 'signcolumn' to 'number', make sure the number column width increases
1816 set signcolumn=number
1817 redraw!
1818 call assert_equal("=> abcde", s:ScreenLine(2, 1, 8))
1819 call assert_equal(" 3 01234", s:ScreenLine(3, 1, 8))
1820 " Set 'signcolumn' to 'auto', make sure the number column width is 1.
1821 set signcolumn=auto
1822 redraw!
1823 call assert_equal("=>2 abcde", s:ScreenLine(2, 1, 9))
1824 call assert_equal(" 3 01234", s:ScreenLine(3, 1, 9))
1825 " Set 'signcolumn' to 'number', make sure the number column width is 2.
1826 set signcolumn=number
1827 redraw!
1828 call assert_equal("=> abcde", s:ScreenLine(2, 1, 8))
1829 call assert_equal(" 3 01234", s:ScreenLine(3, 1, 8))
1830 " Disable 'number' column
1831 set nonumber
1832 redraw!
1833 call assert_equal("=>abcde", s:ScreenLine(2, 1, 7))
1834 call assert_equal(" 01234", s:ScreenLine(3, 1, 7))
1835 " Enable 'number' column
1836 set number
1837 redraw!
1838 call assert_equal("=> abcde", s:ScreenLine(2, 1, 8))
1839 call assert_equal(" 3 01234", s:ScreenLine(3, 1, 8))
1840 " Remove the sign and make sure the width of the number column is 1.
1841 call sign_unplace('', {'id' : 20})
1842 redraw!
1843 call assert_equal("3 01234", s:ScreenLine(3, 1, 7))
1844 " When the first sign is placed with 'signcolumn' set to number, verify that
1845 " the number column width increases
1846 sign place 30 line=1 name=sign1
1847 redraw!
1848 call assert_equal("=> 01234", s:ScreenLine(1, 1, 8))
1849 call assert_equal(" 2 abcde", s:ScreenLine(2, 1, 8))
Bram Moolenaard6bcff42019-07-18 12:48:16 +02001850 " Add sign with multi-byte text
1851 set numberwidth=4
1852 sign place 40 line=2 name=sign2
1853 redraw!
1854 call assert_equal(" => 01234", s:ScreenLine(1, 1, 9))
1855 call assert_equal(" abcde", s:ScreenLine(2, 1, 9))
Bram Moolenaare4b407f2019-07-04 11:59:28 +02001856
1857 sign unplace * group=*
Bram Moolenaar394c5d82019-06-17 21:48:05 +02001858 sign undefine sign1
1859 set signcolumn&
1860 set number&
1861 enew! | close
1862endfunc
Bram Moolenaar809ce4d2019-07-13 21:21:40 +02001863
1864" Test for managing multiple signs using the sign functions
1865func Test_sign_funcs_multi()
1866 call writefile(repeat(["Sun is shining"], 30), "Xsign")
1867 edit Xsign
1868 let bnum = bufnr('')
1869
1870 " Define multiple signs at once
1871 call assert_equal([0, 0, 0, 0], sign_define([
1872 \ {'name' : 'sign1', 'text' : '=>', 'linehl' : 'Search',
1873 \ 'texthl' : 'Search'},
1874 \ {'name' : 'sign2', 'text' : '=>', 'linehl' : 'Search',
1875 \ 'texthl' : 'Search'},
1876 \ {'name' : 'sign3', 'text' : '=>', 'linehl' : 'Search',
1877 \ 'texthl' : 'Search'},
1878 \ {'name' : 'sign4', 'text' : '=>', 'linehl' : 'Search',
1879 \ 'texthl' : 'Search'}]))
1880
1881 " Negative cases for sign_define()
1882 call assert_equal([], sign_define([]))
1883 call assert_equal([-1], sign_define([{}]))
1884 call assert_fails('call sign_define([6])', 'E715:')
1885 call assert_fails('call sign_define(["abc"])', 'E715:')
1886 call assert_fails('call sign_define([[]])', 'E715:')
1887
1888 " Place multiple signs at once with specific sign identifier
1889 let l = sign_placelist([{'id' : 1, 'group' : 'g1', 'name' : 'sign1',
1890 \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 50},
1891 \ {'id' : 2, 'group' : 'g2', 'name' : 'sign2',
1892 \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 100},
1893 \ {'id' : 3, 'group' : '', 'name' : 'sign3',
1894 \ 'buffer' : 'Xsign', 'lnum' : 11}])
1895 call assert_equal([1, 2, 3], l)
1896 let s = sign_getplaced('Xsign', {'group' : '*'})
1897 call assert_equal([
1898 \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11,
1899 \ 'group' : 'g2', 'priority' : 100},
1900 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11,
1901 \ 'group' : 'g1', 'priority' : 50},
1902 \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11,
1903 \ 'group' : '', 'priority' : 10}], s[0].signs)
1904
1905 call sign_unplace('*')
1906
1907 " Place multiple signs at once with auto-generated sign identifier
1908 call assert_equal([1, 1, 5], sign_placelist([
1909 \ {'group' : 'g1', 'name' : 'sign1',
1910 \ 'buffer' : 'Xsign', 'lnum' : 11},
1911 \ {'group' : 'g2', 'name' : 'sign2',
1912 \ 'buffer' : 'Xsign', 'lnum' : 11},
1913 \ {'group' : '', 'name' : 'sign3',
1914 \ 'buffer' : 'Xsign', 'lnum' : 11}]))
1915 let s = sign_getplaced('Xsign', {'group' : '*'})
1916 call assert_equal([
1917 \ {'id' : 5, 'name' : 'sign3', 'lnum' : 11,
1918 \ 'group' : '', 'priority' : 10},
1919 \ {'id' : 1, 'name' : 'sign2', 'lnum' : 11,
1920 \ 'group' : 'g2', 'priority' : 10},
1921 \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11,
1922 \ 'group' : 'g1', 'priority' : 10}], s[0].signs)
1923
1924 " Change an existing sign without specifying the group
1925 call assert_equal([5], sign_placelist([
1926 \ {'id' : 5, 'name' : 'sign1', 'buffer' : 'Xsign'}]))
1927 let s = sign_getplaced('Xsign', {'id' : 5, 'group' : ''})
1928 call assert_equal([{'id' : 5, 'name' : 'sign1', 'lnum' : 11,
1929 \ 'group' : '', 'priority' : 10}], s[0].signs)
1930
1931 " Place sign without a sign name
1932 call assert_equal([-1], sign_placelist([{'id' : 10, 'buffer' : 'Xsign',
1933 \ 'lnum' : 12, 'group' : ''}]))
1934
1935 " Place sign without a buffer
1936 call assert_equal([-1], sign_placelist([{'id' : 10, 'name' : 'sign1',
1937 \ 'lnum' : 12, 'group' : ''}]))
1938
1939 " Invalid arguments
1940 call assert_equal([], sign_placelist([]))
1941 call assert_fails('call sign_placelist({})', "E714:")
1942 call assert_fails('call sign_placelist([[]])', "E715:")
1943 call assert_fails('call sign_placelist(["abc"])', "E715:")
1944 call assert_fails('call sign_placelist([100])', "E715:")
1945
1946 " Unplace multiple signs
1947 call assert_equal([0, 0, 0], sign_unplacelist([{'id' : 5},
1948 \ {'id' : 1, 'group' : 'g1'}, {'id' : 1, 'group' : 'g2'}]))
1949
1950 " Invalid arguments
1951 call assert_equal([], sign_unplacelist([]))
1952 call assert_fails('call sign_unplacelist({})', "E714:")
1953 call assert_fails('call sign_unplacelist([[]])', "E715:")
1954 call assert_fails('call sign_unplacelist(["abc"])', "E715:")
1955 call assert_fails('call sign_unplacelist([100])', "E715:")
1956 call assert_fails("call sign_unplacelist([{'id' : -1}])", 'E474')
1957
1958 call assert_equal([0, 0, 0, 0],
1959 \ sign_undefine(['sign1', 'sign2', 'sign3', 'sign4']))
1960 call assert_equal([], sign_getdefined())
1961
1962 " Invalid arguments
1963 call assert_equal([], sign_undefine([]))
1964 call assert_fails('call sign_undefine([[]])', 'E730:')
1965 call assert_fails('call sign_undefine([{}])', 'E731:')
1966 call assert_fails('call sign_undefine(["1abc2"])', 'E155:')
1967
1968 call sign_unplace('*')
1969 call sign_undefine()
1970 enew!
1971 call delete("Xsign")
1972endfunc