summaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2016-10-23 22:41:00 +0100
committerw0rp <devw0rp@gmail.com>2016-10-23 22:41:00 +0100
commit7481facd7373dda4667c401695e6d8000ef52362 (patch)
tree11ebf0397b14aff2c9daab798aa6a323f2bde254 /autoload
parent36461b69d7dbf0abe494cd450dd9233eed7b672f (diff)
downloadale-7481facd7373dda4667c401695e6d8000ef52362.zip
#107 Stop jobs when buffers close
Diffstat (limited to 'autoload')
-rw-r--r--autoload/ale.vim5
-rw-r--r--autoload/ale/cleanup.vim15
-rw-r--r--autoload/ale/engine.vim60
-rw-r--r--autoload/ale/sign.vim8
-rw-r--r--autoload/ale/statusline.vim40
5 files changed, 83 insertions, 45 deletions
diff --git a/autoload/ale.vim b/autoload/ale.vim
index 44cd5825..3e86c8f9 100644
--- a/autoload/ale.vim
+++ b/autoload/ale.vim
@@ -27,8 +27,11 @@ function! ale#Lint(...) abort
let l:buffer = bufnr('%')
let l:linters = ale#linter#Get(&filetype)
+ " Initialise the buffer information if needed.
+ call ale#engine#InitBufferInfo(l:buffer)
+
" Set a variable telling us to clear the loclist later.
- let g:ale_buffer_should_reset_map[l:buffer] = 1
+ let g:ale_buffer_info[l:buffer].should_reset = 1
for l:linter in l:linters
" Check if a given linter has a program which can be executed.
diff --git a/autoload/ale/cleanup.vim b/autoload/ale/cleanup.vim
index 45eccb98..40a8a359 100644
--- a/autoload/ale/cleanup.vim
+++ b/autoload/ale/cleanup.vim
@@ -2,19 +2,16 @@
" Description: Utility functions related to cleaning state.
function! ale#cleanup#Buffer(buffer) abort
- if has_key(g:ale_buffer_count_map, a:buffer)
- call remove(g:ale_buffer_count_map, a:buffer)
- endif
-
if has_key(g:ale_buffer_loclist_map, a:buffer)
call remove(g:ale_buffer_loclist_map, a:buffer)
endif
- if has_key(g:ale_buffer_should_reset_map, a:buffer)
- call remove(g:ale_buffer_should_reset_map, a:buffer)
- endif
+ if has_key(g:ale_buffer_info, a:buffer)
+ " When buffers are removed, clear all of the jobs.
+ for l:job in get(g:ale_buffer_info[a:buffer], 'job_list', [])
+ call ale#engine#ClearJob(l:job)
+ endfor
- if has_key(g:ale_buffer_sign_dummy_map, a:buffer)
- call remove(g:ale_buffer_sign_dummy_map, a:buffer)
+ call remove(g:ale_buffer_info, a:buffer)
endif
endfunction
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index 5cdcd7ce..3af60ab6 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -20,7 +20,17 @@ function! s:GetJobID(job) abort
return ch_info(job_getchannel(a:job)).id
endfunction
-function! s:ClearJob(job) abort
+function! ale#engine#InitBufferInfo(buffer) abort
+ if !has_key(g:ale_buffer_info, a:buffer)
+ let g:ale_buffer_info[a:buffer] = {
+ \ 'job_list': [],
+ \ 'should_reset': 1,
+ \ 'dummy_sign_set': 0,
+ \}
+ endif
+endfunction
+
+function! ale#engine#ClearJob(job) abort
let l:job_id = s:GetJobID(a:job)
let l:linter = s:job_info_map[l:job_id].linter
@@ -37,7 +47,26 @@ function! s:ClearJob(job) abort
endif
call remove(s:job_info_map, l:job_id)
- call remove(l:linter, 'job')
+endfunction
+
+function! s:StopPreviousJobs(buffer, linter) abort
+ let l:new_job_list = []
+
+ for l:job in g:ale_buffer_info[a:buffer].job_list
+ let l:job_id = s:GetJobID(l:job)
+
+ if has_key(s:job_info_map, l:job_id)
+ \&& s:job_info_map[l:job_id].linter.name ==# a:linter.name
+ " Stop jobs which match the buffer and linter.
+ call ale#engine#ClearJob(l:job)
+ else
+ " Keep other jobs in the list.
+ call add(l:new_job_list, l:job)
+ endif
+ endfor
+
+ " Update the list, removing the previously run job.
+ let g:ale_buffer_info[a:buffer].job_list = l:new_job_list
endfunction
function! s:GatherOutput(job, data) abort
@@ -71,17 +100,11 @@ function! s:HandleExit(job) abort
endif
let l:job_info = s:job_info_map[l:job_id]
-
- call s:ClearJob(a:job)
-
let l:linter = l:job_info.linter
let l:output = l:job_info.output
let l:buffer = l:job_info.buffer
- if !has_key(g:ale_buffer_should_reset_map, l:buffer)
- " A job ended for a buffer which has been closed, so stop here.
- return
- endif
+ call s:StopPreviousJobs(l:buffer, l:linter)
let l:linter_loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output)
@@ -92,8 +115,10 @@ function! s:HandleExit(job) abort
let l:item.linter_name = l:linter.name
endfor
- if g:ale_buffer_should_reset_map[l:buffer]
- let g:ale_buffer_should_reset_map[l:buffer] = 0
+ if g:ale_buffer_info[l:buffer].should_reset
+ " Set the flag for resetting the loclist to 0 again, so we won't
+ " empty the list later.
+ let g:ale_buffer_info[l:buffer].should_reset = 0
let g:ale_buffer_loclist_map[l:buffer] = []
endif
@@ -150,10 +175,8 @@ function! s:FixLocList(buffer, loclist) abort
endfunction
function! ale#engine#Invoke(buffer, linter) abort
- if has_key(a:linter, 'job')
- " Stop previous jobs for the same linter.
- call s:ClearJob(a:linter.job)
- endif
+ " Stop previous jobs for the same linter.
+ call s:StopPreviousJobs(a:buffer, a:linter)
if has_key(a:linter, 'command_callback')
" If there is a callback for generating a command, call that instead.
@@ -227,7 +250,8 @@ function! ale#engine#Invoke(buffer, linter) abort
" Only proceed if the job is being run.
if has('nvim') || (l:job !=# 'no process' && job_status(l:job) ==# 'run')
- let a:linter.job = l:job
+ " Add the job to the list of jobs, so we can track them.
+ call add(g:ale_buffer_info[a:buffer].job_list, l:job)
" Store the ID for the job in the map to read back again.
let s:job_info_map[s:GetJobID(l:job)] = {
@@ -270,8 +294,8 @@ function! ale#engine#WaitForJobs(deadline) abort
let l:job_list = []
- for l:job_id in keys(s:job_info_map)
- call add(l:job_list, s:job_info_map[l:job_id].linter.job)
+ for l:info in values(g:ale_buffer_info)
+ call extend(l:job_list, l:info.job_list)
endfor
let l:should_wait_more = 1
diff --git a/autoload/ale/sign.vim b/autoload/ale/sign.vim
index 23666287..deec47f2 100644
--- a/autoload/ale/sign.vim
+++ b/autoload/ale/sign.vim
@@ -89,13 +89,13 @@ function! ale#sign#SetSigns(buffer, loclist) abort
let l:signlist = ale#sign#CombineSigns(a:loclist)
if len(l:signlist) > 0 || g:ale_sign_column_always
- if !get(g:ale_buffer_sign_dummy_map, a:buffer, 0)
+ if !g:ale_buffer_info[a:buffer].dummy_sign_set
" Insert a dummy sign if one is missing.
execute 'sign place ' . g:ale_sign_offset
\ . ' line=1 name=ALEDummySign buffer='
\ . a:buffer
- let g:ale_buffer_sign_dummy_map[a:buffer] = 1
+ let g:ale_buffer_info[a:buffer].dummy_sign_set = 1
endif
endif
@@ -121,10 +121,10 @@ function! ale#sign#SetSigns(buffer, loclist) abort
endfor
if !g:ale_sign_column_always && len(l:signlist) > 0
- if get(g:ale_buffer_sign_dummy_map, a:buffer, 0)
+ if g:ale_buffer_info[a:buffer].dummy_sign_set
execute 'sign unplace ' . g:ale_sign_offset . ' buffer=' . a:buffer
- let g:ale_buffer_sign_dummy_map[a:buffer] = 0
+ let g:ale_buffer_info[a:buffer].dummy_sign_set = 0
endif
endif
endfunction
diff --git a/autoload/ale/statusline.vim b/autoload/ale/statusline.vim
index 8a31bc39..48b4d687 100644
--- a/autoload/ale/statusline.vim
+++ b/autoload/ale/statusline.vim
@@ -14,34 +14,48 @@ function! ale#statusline#Update(buffer, loclist) abort
endif
endfor
- let g:ale_buffer_count_map[a:buffer] = [l:errors, l:warnings]
+ let g:ale_buffer_info[a:buffer].count = [l:errors, l:warnings]
endfunction
-" Returns a tuple of errors and warnings for use in third-party integrations.
-function! ale#statusline#Count(buffer) abort
+" Set the error and warning counts, calling for an update only if needed.
+" If counts cannot be set, return 0.
+function! s:SetupCount(buffer) abort
+ if !has_key(g:ale_buffer_info, a:buffer)
+ " Linters have not been run for the buffer yet, so stop here.
+ return 0
+ endif
+
" Cache is cold, so manually ask for an update.
- if !has_key(g:ale_buffer_count_map, a:buffer)
+ if !has_key(g:ale_buffer_info[a:buffer], 'count')
call ale#statusline#Update(a:buffer, get(g:ale_buffer_loclist_map, a:buffer, []))
endif
- return g:ale_buffer_count_map[a:buffer]
+ return 1
+endfunction
+
+" Returns a tuple of errors and warnings for use in third-party integrations.
+function! ale#statusline#Count(buffer) abort
+ if !s:SetupCount(a:buffer)
+ return [0, 0]
+ endif
+
+ return g:ale_buffer_info[a:buffer].count
endfunction
" Returns a formatted string that can be integrated in the statusline.
function! ale#statusline#Status() abort
+ let [l:error_format, l:warning_format, l:no_errors] = g:ale_statusline_format
let l:buffer = bufnr('%')
- " Cache is cold, so manually ask for an update.
- if !has_key(g:ale_buffer_count_map, l:buffer)
- call ale#statusline#Update(l:buffer, get(g:ale_buffer_loclist_map, l:buffer, []))
+ if !s:SetupCount(l:buffer)
+ return l:no_errors
endif
+ let [l:error_count, l:warning_count] = g:ale_buffer_info[l:buffer].count
+
" Build strings based on user formatting preferences.
- let l:errors = g:ale_buffer_count_map[l:buffer][0] ?
- \ printf(g:ale_statusline_format[0], g:ale_buffer_count_map[l:buffer][0]) : ''
- let l:warnings = g:ale_buffer_count_map[l:buffer][1] ?
- \ printf(g:ale_statusline_format[1], g:ale_buffer_count_map[l:buffer][1]) : ''
- let l:no_errors = g:ale_statusline_format[2]
+ let l:errors = l:error_count ? printf(l:error_format, l:error_count) : ''
+ let l:warnings = l:warning_count ? printf(l:warning_format, l:warning_count) : ''
" Different formats based on the combination of errors and warnings.
if empty(l:errors) && empty(l:warnings)