Skip to content

Commit a94f7aa

Browse files
committed
Fix #964 - Remove signs when multiple signs end up on a single line
1 parent 21c4b90 commit a94f7aa

2 files changed

Lines changed: 44 additions & 16 deletions

File tree

autoload/ale/sign.vim

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -214,24 +214,32 @@ function! s:BuildSignMap(current_sign_list, grouped_items) abort
214214
let l:sign_offset = g:ale_sign_offset
215215

216216
for [l:line, l:sign_id, l:name] in a:current_sign_list
217-
let l:sign_map[l:line] = {
218-
\ 'current_id': l:sign_id,
219-
\ 'current_name': l:name,
217+
let l:sign_info = get(l:sign_map, l:line, {
218+
\ 'current_id_list': [],
219+
\ 'current_name_list': [],
220220
\ 'new_id': 0,
221221
\ 'new_name': '',
222222
\ 'items': [],
223-
\}
223+
\})
224224

225+
" Increment the sign offset for new signs, by the maximum sign ID.
225226
if l:sign_id > l:sign_offset
226227
let l:sign_offset = l:sign_id
227228
endif
229+
230+
" Remember the sign names and IDs in separate Lists, so they are easy
231+
" to work with.
232+
call add(l:sign_info.current_id_list, l:sign_id)
233+
call add(l:sign_info.current_name_list, l:name)
234+
235+
let l:sign_map[l:line] = l:sign_info
228236
endfor
229237

230238
for l:group in a:grouped_items
231239
let l:line = l:group[0].lnum
232240
let l:sign_info = get(l:sign_map, l:line, {
233-
\ 'current_id': 0,
234-
\ 'current_name': '',
241+
\ 'current_id_list': [],
242+
\ 'current_name_list': [],
235243
\ 'new_id': 0,
236244
\ 'new_name': '',
237245
\ 'items': [],
@@ -240,11 +248,18 @@ function! s:BuildSignMap(current_sign_list, grouped_items) abort
240248
let l:sign_info.new_name = ale#sign#GetSignName(l:group)
241249
let l:sign_info.items = l:group
242250

243-
if l:sign_info.current_name isnot# l:sign_info.new_name
251+
let l:index = index(
252+
\ l:sign_info.current_name_list,
253+
\ l:sign_info.new_name
254+
\)
255+
256+
if l:index >= 0
257+
" We have a sign with this name already, so use the same ID.
258+
let l:sign_info.new_id = l:sign_info.current_id_list[l:index]
259+
else
260+
" This sign name replaces the previous name, so use a new ID.
244261
let l:sign_info.new_id = l:sign_offset + 1
245262
let l:sign_offset += 1
246-
else
247-
let l:sign_info.new_id = l:sign_info.current_id
248263
endif
249264

250265
let l:sign_map[l:line] = l:sign_info
@@ -278,7 +293,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
278293
let l:item.sign_id = l:info.new_id
279294
endfor
280295

281-
if l:info.new_id isnot l:info.current_id
296+
if index(l:info.current_id_list, l:info.new_id) < 0
282297
call add(l:command_list, 'sign place '
283298
\ . (l:info.new_id)
284299
\ . ' line=' . l:line_str
@@ -291,12 +306,14 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
291306

292307
" Remove signs without new IDs.
293308
for l:info in values(a:sign_map)
294-
if l:info.current_id && l:info.current_id isnot l:info.new_id
295-
call add(l:command_list, 'sign unplace '
296-
\ . (l:info.current_id)
297-
\ . ' buffer=' . a:buffer
298-
\)
299-
endif
309+
for l:current_id in l:info.current_id_list
310+
if l:current_id isnot l:info.new_id
311+
call add(l:command_list, 'sign unplace '
312+
\ . l:current_id
313+
\ . ' buffer=' . a:buffer
314+
\)
315+
endif
316+
endfor
300317
endfor
301318

302319
" Remove the dummy sign to close the sign column if we need to.

test/sign/test_sign_placement.vader

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,14 @@ Execute(It should be possible to clear signs with empty lists):
266266

267267
Execute(No exceptions should be thrown when setting signs for invalid buffers):
268268
call ale#sign#SetSigns(123456789, [{'lnum': 15, 'col': 2, 'type': 'W', 'text': 'e'}])
269+
270+
Execute(Signs should be removed when lines have multiple sign IDs on them):
271+
" We can fail to remove signs if there are multiple signs on one line,
272+
" say after deleting lines in Vim, etc.
273+
exec 'sign place 1000347 line=3 name=ALEErrorSign buffer=' . bufnr('')
274+
exec 'sign place 1000348 line=3 name=ALEWarningSign buffer=' . bufnr('')
275+
exec 'sign place 1000349 line=10 name=ALEErrorSign buffer=' . bufnr('')
276+
exec 'sign place 1000350 line=10 name=ALEWarningSign buffer=' . bufnr('')
277+
278+
call ale#sign#SetSigns(bufnr(''), [])
279+
AssertEqual [], ParseSigns()

0 commit comments

Comments
 (0)