From 84004665d5010ed2a7f56301bece94ac61359fe6 Mon Sep 17 00:00:00 2001
From: w0rp <devw0rp@gmail.com>
Date: Wed, 19 Apr 2017 22:55:06 +0100
Subject: [PATCH] Remove error highlights when buffers are cleaned up

---
 autoload/ale/cleanup.vim            |  1 +
 autoload/ale/highlight.vim          | 19 +++++++++++++------
 test/test_highlight_placement.vader | 17 +++++++++++++++++
 3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/autoload/ale/cleanup.vim b/autoload/ale/cleanup.vim
index 3b0b1d90..8b6494ef 100644
--- a/autoload/ale/cleanup.vim
+++ b/autoload/ale/cleanup.vim
@@ -13,6 +13,7 @@ function! ale#cleanup#Buffer(buffer) abort
         " Clear delayed highlights for a buffer being removed.
         if g:ale_set_highlights
             call ale#highlight#UnqueueHighlights(a:buffer)
+            call ale#highlight#RemoveHighlights([])
         endif
 
         call remove(g:ale_buffer_info, a:buffer)
diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim
index 8d70ead5..8ff5120f 100644
--- a/autoload/ale/highlight.vim
+++ b/autoload/ale/highlight.vim
@@ -46,18 +46,25 @@ function! s:GetCurrentMatchIDs(loclist) abort
     return l:current_id_map
 endfunction
 
+" Given a loclist for current items to highlight, remove all highlights
+" except these which have matching loclist item entries.
+function! ale#highlight#RemoveHighlights(loclist) abort
+    let l:current_id_map = s:GetCurrentMatchIDs(a:loclist)
+
+    for l:match in s:GetALEMatches()
+        if !has_key(l:current_id_map, l:match.id)
+            call matchdelete(l:match.id)
+        endif
+    endfor
+endfunction
+
 function! ale#highlight#UpdateHighlights() abort
     let l:buffer = bufnr('%')
     let l:has_new_items = has_key(s:buffer_highlights, l:buffer)
     let l:loclist = l:has_new_items ? remove(s:buffer_highlights, l:buffer) : []
-    let l:current_id_map = s:GetCurrentMatchIDs(l:loclist)
 
     if l:has_new_items || !g:ale_enabled
-        for l:match in s:GetALEMatches()
-            if !has_key(l:current_id_map, l:match.id)
-                call matchdelete(l:match.id)
-            endif
-        endfor
+        call ale#highlight#RemoveHighlights(l:loclist)
     endif
 
     " Remove anything with a current match_id
diff --git a/test/test_highlight_placement.vader b/test/test_highlight_placement.vader
index 52e861d9..bca7bfda 100644
--- a/test/test_highlight_placement.vader
+++ b/test/test_highlight_placement.vader
@@ -74,3 +74,20 @@ Execute(Existing highlights should be kept):
   \   {'group': 'ALEWarning', 'id': 8, 'priority': 10, 'pos1': [4, 1, 1]},
   \ ],
   \ getmatches()
+
+" This test is important for preventing ALE from showing highlights for
+" the wrong files.
+Execute(Highlights set by ALE should be removed when buffer cleanup is done):
+  call ale#engine#InitBufferInfo(bufnr('%'))
+
+  call ale#highlight#SetHighlights(bufnr('%'), [
+  \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2},
+  \])
+
+  AssertEqual
+  \ [{'group': 'ALEError', 'id': 9, 'priority': 10, 'pos1': [3, 2, 1]}],
+  \ getmatches()
+
+  call ale#cleanup#Buffer(bufnr('%'))
+
+  AssertEqual [], getmatches()