summaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2017-04-03 19:50:57 +0100
committerw0rp <devw0rp@gmail.com>2017-04-03 19:50:57 +0100
commit5f02595ea490ccdea3a80e457200e19665a82e68 (patch)
tree80de22f716c60283e15dbca03d0cdec4b2508681 /autoload
parent9691649b6519dd422c56071566a8071f1c6978fd (diff)
downloadale-5f02595ea490ccdea3a80e457200e19665a82e68.zip
#380 Add some experimental code for killing long-running processes in NeoVim
Diffstat (limited to 'autoload')
-rw-r--r--autoload/ale/engine.vim52
1 files changed, 46 insertions, 6 deletions
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index f1b27bb7..3eaf6e49 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -50,8 +50,48 @@ endfunction
" with SIGKILL if they don't terminate right away.
let s:job_kill_timers = {}
+" Check if a job is still running, in either Vim version.
+function! s:IsJobRunning(job) abort
+ if has('nvim')
+ try
+ " In NeoVim, if the job isn't running, jobpid() will throw.
+ call jobpid(a:job)
+ return 1
+ catch
+ endtry
+
+ return 0
+ endif
+
+ return job_status(a:job) ==# 'run'
+endfunction
+
function! s:KillHandler(timer) abort
- call job_stop(remove(s:job_kill_timers, a:timer), 'kill')
+ let l:job = remove(s:job_kill_timers, a:timer)
+
+ " For NeoVim, we have to send SIGKILL ourselves manually, as NeoVim
+ " doesn't do it properly.
+ if has('nvim')
+ let l:pid = 0
+
+ " We can fail to get the PID here if the job manages to stop already.
+ try
+ let l:pid = jobpid(l:job)
+ catch
+ endtry
+
+ if l:pid > 0
+ if has('win32')
+ " Windows
+ call system('taskkill /pid ' . l:pid . ' /f')
+ else
+ " Linux, Mac OSX, etc.
+ call system('kill -9 ' . l:pid)
+ endif
+ endif
+ else
+ call job_stop(l:job, 'kill')
+ endif
endfunction
function! ale#engine#ClearJob(job) abort
@@ -68,12 +108,12 @@ function! ale#engine#ClearJob(job) abort
" Ask nicely for the job to stop.
call job_stop(a:job)
+ endif
- " If a job doesn't stop immediately, queue a timer which will
- " send SIGKILL to the job, if it's alive by the time the timer ticks.
- if job_status(a:job) ==# 'run'
- let s:job_kill_timers[timer_start(100, function('s:KillHandler'))] = a:job
- endif
+ " If a job doesn't stop immediately, queue a timer which will
+ " send SIGKILL to the job, if it's alive by the time the timer ticks.
+ if s:IsJobRunning(a:job)
+ let s:job_kill_timers[timer_start(100, function('s:KillHandler'))] = a:job
endif
if has_key(s:job_info_map, l:job_id)