summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2017-02-16 22:19:53 +0000
committerw0rp <devw0rp@gmail.com>2017-02-16 22:19:53 +0000
commit843370b96f9a92a2298ed7985a8f620784fc9421 (patch)
tree00ca288fc4df7d64d2e6e68aabcf64e131e7472b
parentca17b5aebdd9bb2e31d01ae16e18047bae375c3c (diff)
downloadale-843370b96f9a92a2298ed7985a8f620784fc9421.zip
#254 Capture command exit codes in the history
-rw-r--r--autoload/ale/debugging.vim9
-rw-r--r--autoload/ale/engine.vim30
-rw-r--r--autoload/ale/history.vim15
-rw-r--r--test/test_ale_info.vader27
-rw-r--r--test/test_history_saving.vader5
5 files changed, 82 insertions, 4 deletions
diff --git a/autoload/ale/debugging.vim b/autoload/ale/debugging.vim
index 737a90d7..1ca7736b 100644
--- a/autoload/ale/debugging.vim
+++ b/autoload/ale/debugging.vim
@@ -68,7 +68,14 @@ function! s:EchoCommandHistory() abort
endif
for l:item in g:ale_buffer_info[l:buffer].history
- echom '(' . l:item.status . ') ' . string(l:item.command)
+ let l:status_message = l:item.status
+
+ " Include the exit code in output if we have it.
+ if l:item.status ==# 'finished'
+ let l:status_message .= ' - exit code ' . l:item.exit_code
+ endif
+
+ echom '(' . l:status_message . ') ' . string(l:item.command)
endfor
endfunction
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index d072d459..a6b9df38 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -270,7 +270,23 @@ function! ale#engine#SetResults(buffer, loclist) abort
endif
endfunction
-function! s:HandleExitNeoVim(job, data, event) abort
+function! s:SetExitCode(job, exit_code) abort
+ let l:job_id = s:GetJobID(a:job)
+
+ if !has_key(s:job_info_map, l:job_id)
+ return
+ endif
+
+ let l:buffer = s:job_info_map[l:job_id].buffer
+
+ call ale#history#SetExitCode(l:buffer, l:job_id, a:exit_code)
+endfunction
+
+function! s:HandleExitNeoVim(job, exit_code, event) abort
+ if g:ale_history_enabled
+ call s:SetExitCode(a:job, a:exit_code)
+ endif
+
call s:HandleExit(a:job)
endfunction
@@ -278,6 +294,12 @@ function! s:HandleExitVim(channel) abort
call s:HandleExit(ch_getjob(a:channel))
endfunction
+" Vim returns the exit status with one callback,
+" and the channel will close later in another callback.
+function! s:HandleExitStatusVim(job, exit_code) abort
+ call s:SetExitCode(a:job, a:exit_code)
+endfunction
+
function! s:FixLocList(buffer, loclist) abort
" Some errors have line numbers beyond the end of the file,
" so we need to adjust them so they set the error at the last line
@@ -415,6 +437,12 @@ function! s:RunJob(options) abort
\ 'close_cb': function('s:HandleExitVim'),
\}
+ if g:ale_history_enabled
+ " We only need to capture the exit status if we are going to
+ " save it in the history. Otherwise, we don't care.
+ let l:job_options.exit_cb = function('s:HandleExitStatusVim')
+ endif
+
if l:output_stream ==# 'stderr'
" Read from stderr instead of stdout.
let l:job_options.err_cb = function('s:GatherOutputVim')
diff --git a/autoload/ale/history.vim b/autoload/ale/history.vim
index 6524b916..f52c1d75 100644
--- a/autoload/ale/history.vim
+++ b/autoload/ale/history.vim
@@ -24,3 +24,18 @@ function! ale#history#Add(buffer, status, job_id, command) abort
let g:ale_buffer_info[a:buffer].history = l:history
endfunction
+
+" Set an exit code for a command which finished.
+function! ale#history#SetExitCode(buffer, job_id, exit_code) abort
+ " Search backwards to find a matching job ID. IDs might be recycled,
+ " so finding the last one should be good enough.
+ for l:obj in reverse(g:ale_buffer_info[a:buffer].history[:])
+ if l:obj.job_id == a:job_id
+ " If we find a match, then set the code and status, and stop here.
+ let l:obj.exit_code = a:exit_code
+ let l:obj.status = 'finished'
+
+ return
+ endif
+ endfor
+endfunction
diff --git a/test/test_ale_info.vader b/test/test_ale_info.vader
index c8c20677..92025f23 100644
--- a/test/test_ale_info.vader
+++ b/test/test_ale_info.vader
@@ -191,3 +191,30 @@ Execute (ALEInfo should return command history):
\ '(started) [''/bin/bash'', ''\c'', ''last command'']',
\ ], "\n"),
\ g:output
+
+Given testft.testft2 (Empty buffer with two filetypes):
+Execute (ALEInfo command history should print exit codes correctly):
+ let g:ale_buffer_info[bufnr('%')] = {
+ \ 'history': [
+ \ {'status': 'finished', 'exit_code': 0, 'job_id': 347, 'command': 'first command'},
+ \ {'status': 'finished', 'exit_code': 1, 'job_id': 347, 'command': ['/bin/bash', '\c', 'last command']},
+ \ ],
+ \}
+
+ call ale#linter#Define('testft', g:testlinter1)
+ call ale#linter#Define('testft2', g:testlinter2)
+ redir => g:output
+ silent ALEInfo
+ redir END
+ AssertEqual
+ \ join([
+ \ '',
+ \ ' Current Filetype: testft.testft2',
+ \ 'Available Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Linter Variables:',
+ \ g:globals_string . g:command_header,
+ \ '(finished - exit code 0) ''first command''',
+ \ '(finished - exit code 1) [''/bin/bash'', ''\c'', ''last command'']',
+ \ ], "\n"),
+ \ g:output
diff --git a/test/test_history_saving.vader b/test/test_history_saving.vader
index b3afdca2..23b9170b 100644
--- a/test/test_history_saving.vader
+++ b/test/test_history_saving.vader
@@ -35,9 +35,10 @@ Execute(History should be set when commands are run):
let g:history = g:ale_buffer_info[bufnr('%')].history
AssertEqual 1, len(g:history)
- AssertEqual ['status', 'job_id', 'command'], keys(g:history[0])
+ AssertEqual sort(['status', 'exit_code', 'job_id', 'command']), sort(keys(g:history[0]))
AssertEqual ['/bin/bash', '-c', 'echo command history test'], g:history[0].command
- AssertEqual 'started', g:history[0].status
+ AssertEqual 'finished', g:history[0].status
+ AssertEqual 0, g:history[0].exit_code
" The Job ID will change each time, but we can check the type.
AssertEqual type(1), type(g:history[0].job_id)