summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoload/ale/engine.vim40
-rw-r--r--autoload/ale/list.vim23
-rw-r--r--autoload/ale/util.vim23
-rw-r--r--test/test_setting_problems_found_in_previous_buffers.vader60
4 files changed, 123 insertions, 23 deletions
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index 59ba0fc8..828f8468 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -50,7 +50,11 @@ function! ale#engine#InitBufferInfo(buffer) abort
\ 'temporary_directory_list': [],
\ 'history': [],
\}
+
+ return 1
endif
+
+ return 0
endfunction
" Return 1 if ALE is busy checking a given buffer
@@ -408,8 +412,9 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
if l:item.lnum < 1
" When errors appear before line 1, put them at line 1.
let l:item.lnum = 1
- elseif l:item.lnum > l:last_line_number
+ elseif l:item.bufnr == a:buffer && l:item.lnum > l:last_line_number
" When errors go beyond the end of the file, put them at the end.
+ " This is only done for the current buffer.
let l:item.lnum = l:last_line_number
endif
@@ -701,6 +706,35 @@ function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
\)
endfunction
+function! s:AddProblemsFromOtherBuffers(buffer, linters) abort
+ let l:filename = expand('#' . a:buffer . ':p')
+ let l:loclist = []
+ let l:name_map = {}
+
+ " Build a map of the active linters.
+ for l:linter in a:linters
+ let l:name_map[l:linter.name] = 1
+ endfor
+
+ " Find the items from other buffers, for the linters that are enabled.
+ for l:info in values(g:ale_buffer_info)
+ for l:item in l:info.loclist
+ if has_key(l:item, 'filename')
+ \&& l:item.filename is# l:filename
+ \&& has_key(l:name_map, l:item.linter_name)
+ call add(l:loclist, l:item)
+ endif
+ endfor
+ endfor
+
+ if !empty(l:loclist)
+ call sort(l:loclist, function('ale#util#LocItemCompareWithText'))
+ call uniq(l:loclist, function('ale#util#LocItemCompareWithText'))
+
+ call ale#engine#SetResults(a:buffer, l:loclist)
+ endif
+endfunction
+
" Run a linter for a buffer.
"
" Returns 1 if the linter was successfully run.
@@ -720,7 +754,7 @@ endfunction
function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
" Initialise the buffer information if needed.
- call ale#engine#InitBufferInfo(a:buffer)
+ let l:new_buffer = ale#engine#InitBufferInfo(a:buffer)
call s:StopCurrentJobs(a:buffer, a:should_lint_file)
call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
@@ -745,6 +779,8 @@ function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
" disabled, or ALE itself is disabled.
if l:can_clear_results
call ale#engine#SetResults(a:buffer, [])
+ elseif l:new_buffer
+ call s:AddProblemsFromOtherBuffers(a:buffer, a:linters)
endif
endfunction
diff --git a/autoload/ale/list.vim b/autoload/ale/list.vim
index 6fe17d31..25920ce6 100644
--- a/autoload/ale/list.vim
+++ b/autoload/ale/list.vim
@@ -20,25 +20,6 @@ function! s:ShouldOpen(buffer) abort
return l:val is 1 || (l:val is# 'on_save' && l:saved)
endfunction
-" A comparison function for de-duplicating loclist items for quickfix.
-function! ale#list#TextLocItemCompare(left, right) abort
- let l:cmp_val = ale#util#LocItemCompare(a:left, a:right)
-
- if l:cmp_val
- return l:cmp_val
- endif
-
- if a:left.text < a:right.text
- return -1
- endif
-
- if a:left.text > a:right.text
- return 1
- endif
-
- return 0
-endfunction
-
function! ale#list#GetCombinedList() abort
let l:list = []
@@ -46,8 +27,8 @@ function! ale#list#GetCombinedList() abort
call extend(l:list, l:info.loclist)
endfor
- call sort(l:list, function('ale#list#TextLocItemCompare'))
- call uniq(l:list, function('ale#list#TextLocItemCompare'))
+ call sort(l:list, function('ale#util#LocItemCompareWithText'))
+ call uniq(l:list, function('ale#util#LocItemCompareWithText'))
return l:list
endfunction
diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim
index 969a19de..fd538425 100644
--- a/autoload/ale/util.vim
+++ b/autoload/ale/util.vim
@@ -21,6 +21,8 @@ function! ale#util#GetFunction(string_or_ref) abort
return a:string_or_ref
endfunction
+" Compare two loclist items for ALE, sorted by their buffers, filenames, and
+" line numbers and column numbers.
function! ale#util#LocItemCompare(left, right) abort
if a:left.bufnr < a:right.bufnr
return -1
@@ -59,6 +61,27 @@ function! ale#util#LocItemCompare(left, right) abort
return 0
endfunction
+" Compare two loclist items, including the text for the items.
+"
+" This function can be used for de-duplicating lists.
+function! ale#util#LocItemCompareWithText(left, right) abort
+ let l:cmp_value = ale#util#LocItemCompare(a:left, a:right)
+
+ if l:cmp_value
+ return l:cmp_value
+ endif
+
+ if a:left.text < a:right.text
+ return -1
+ endif
+
+ if a:left.text > a:right.text
+ return 1
+ endif
+
+ return 0
+endfunction
+
" This function will perform a binary search and a small sequential search
" on the list to find the last problem in the buffer and line which is
" on or before the column. The index of the problem will be returned.
diff --git a/test/test_setting_problems_found_in_previous_buffers.vader b/test/test_setting_problems_found_in_previous_buffers.vader
new file mode 100644
index 00000000..262b9d18
--- /dev/null
+++ b/test/test_setting_problems_found_in_previous_buffers.vader
@@ -0,0 +1,60 @@
+Before:
+ Save g:ale_buffer_info
+ Save &filetype
+
+ " Set up items in other buffers which should set in this one.
+ let g:ale_buffer_info = {}
+ call ale#engine#InitBufferInfo(bufnr('') + 1)
+ let g:ale_buffer_info[bufnr('') + 1].loclist =
+ \ ale#engine#FixLocList(bufnr('') + 1, 'linter_one', [
+ \ {'lnum': 1, 'filename': expand('%:p'), 'text': 'foo'},
+ \ {'lnum': 2, 'filename': expand('%:p'), 'text': 'bar'},
+ \ {'lnum': 2, 'text': 'ignore this one'},
+ \ ])
+ call ale#engine#InitBufferInfo(bufnr('') + 2)
+ let g:ale_buffer_info[bufnr('') + 2].loclist =
+ \ ale#engine#FixLocList(bufnr('') + 2, 'linter_two', [
+ \ {'lnum': 1, 'filename': expand('%:p'), 'text': 'foo'},
+ \ {'lnum': 3, 'filename': expand('%:p'), 'text': 'baz'},
+ \ {'lnum': 5, 'text': 'ignore this one'},
+ \ ])
+
+ call ale#linter#Define('foobar', {
+ \ 'name': 'linter_one',
+ \ 'callback': 'WhoCares',
+ \ 'executable': 'echo',
+ \ 'command': 'echo',
+ \ 'lint_file': 1,
+ \})
+ call ale#linter#Define('foobar', {
+ \ 'name': 'linter_two',
+ \ 'callback': 'WhoCares',
+ \ 'executable': 'echo',
+ \ 'command': 'echo',
+ \})
+
+After:
+ call ale#engine#Cleanup(bufnr(''))
+ Restore
+ call ale#linter#Reset()
+
+ " Items and markers, etc.
+ call setloclist(0, [])
+ call clearmatches()
+ sign unplace *
+
+Given foobar(A file with some lines):
+ foo
+ bar
+ baz
+
+Execute(Problems found from previously opened buffers should be set when linting for the first time):
+ call ale#engine#RunLinters(bufnr(''), ale#linter#Get(&filetype), 0)
+
+ AssertEqual
+ \ [
+ \ {'lnum': 1, 'bufnr': bufnr(''), 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'E', 'pattern': '', 'text': 'foo'},
+ \ {'lnum': 2, 'bufnr': bufnr(''), 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'E', 'pattern': '', 'text': 'bar'},
+ \ {'lnum': 3, 'bufnr': bufnr(''), 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'E', 'pattern': '', 'text': 'baz'},
+ \ ],
+ \ getloclist(0)