Skip to content

Commit 9c88b0e

Browse files
committed
Make xolox#misc#os#exec() report exit codes (breaks backwards compatibility)
Working towards fixing this issue: xolox/vim-lua-ftplugin#8
1 parent 38ded48 commit 9c88b0e

File tree

2 files changed

+106
-18
lines changed

2 files changed

+106
-18
lines changed

autoload/xolox/misc/compat.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
" Vim auto-load script
22
" Author: Peter Odding <peter@peterodding.com>
3-
" Last Change: April 28, 2013
3+
" Last Change: May 13, 2013
44
" URL: http://peterodding.com/code/vim/misc/
55

66
" The following integer will be bumped whenever a change in the miscellaneous
77
" scripts breaks backwards compatibility. This enables my Vim plug-ins to fail
88
" early when they detect an incompatible version, instead of breaking at the
99
" worst possible moments :-).
10-
let g:xolox#misc#compat#version = 2
10+
let g:xolox#misc#compat#version = 3
1111

1212
" Remember the directory where the miscellaneous scripts are loaded from
1313
" so the user knows which plug-in to update if incompatibilities arise.

autoload/xolox/misc/os.vim

Lines changed: 104 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,117 @@
11
" Vim auto-load script
22
" Author: Peter Odding <peter@peterodding.com>
3-
" Last Change: November 24, 2011
3+
" Last Change: May 13, 2013
44
" URL: http://peterodding.com/code/vim/misc/
55

6-
let g:xolox#misc#os#version = '0.1'
6+
let g:xolox#misc#os#version = '0.2'
77

8-
" Check whether Vim is running on Microsoft Windows.
9-
10-
function! xolox#misc#os#is_win()
8+
function! xolox#misc#os#is_win() " {{{1
9+
" Check whether Vim is running on Microsoft Windows.
1110
return has('win16') || has('win32') || has('win64')
1211
endfunction
1312

14-
" Execute an external command (hiding the console on Windows when possible).
15-
16-
function! xolox#misc#os#exec(cmdline, ...)
13+
function! xolox#misc#os#exec(options) " {{{1
14+
" Execute an external command (hiding the console on Windows when possible).
15+
" NB: Everything below is wrapped in a try/finally block to guarantee
16+
" cleanup of temporary files.
1717
try
18-
" Try using my shell.vim plug-in.
19-
return call('xolox#shell#execute', [a:cmdline, 1] + a:000)
20-
catch /^Vim\%((\a\+)\)\=:E117/
21-
" Fall back to system() when we get an "unknown function" error.
22-
let output = call('system', [a:cmdline] + a:000)
23-
if v:shell_error
24-
throw printf("os.vim %s: Command %s failed: %s", g:xolox#misc#os#version, a:cmdline, xolox#misc#str#trim(output))
18+
19+
" Unpack the options.
20+
let cmd = a:options['command']
21+
let async = get(a:options, 'async', 0)
22+
23+
" Write the input for the external command to a temporary file?
24+
if has_key(a:options, 'stdin')
25+
let tempin = tempname()
26+
if type(a:options['stdin']) == type([])
27+
let lines = a:options['stdin']
28+
else
29+
let lines = split(a:options['stdin'], "\n")
30+
endif
31+
call writefile(lines, tempin)
32+
let cmd .= ' < ' . xolox#misc#escape#shell(tempin)
33+
endif
34+
35+
" Redirect the standard output and standard error streams of the external
36+
" process to temporary files? (only in synchronous mode, which is the
37+
" default).
38+
if !async
39+
let tempout = tempname()
40+
let temperr = tempname()
41+
let cmd = printf('(%s) 1>%s 2>%s', cmd,
42+
\ xolox#misc#escape#shell(tempout),
43+
\ xolox#misc#escape#shell(temperr))
44+
endif
45+
46+
" If A) we're on Windows, B) the vim-shell plug-in is installed and C) the
47+
" compiled DLL works, we'll use that because it's the most user friendly
48+
" method. If the plug-in is not installed Vim will raise the exception
49+
" "E117: Unknown function" which is caught and handled below.
50+
try
51+
if xolox#shell#can_use_dll()
52+
" Let the user know what's happening (in case they're interested).
53+
call xolox#misc#msg#debug("os.vim %s: Executing external command using compiled DLL: %s", g:xolox#misc#os#version, cmd)
54+
let exit_code = xolox#shell#execute_with_dll(cmd, async)
55+
endif
56+
catch /^Vim\%((\a\+)\)\=:E117/
57+
call xolox#misc#msg#debug("os.vim %s: The vim-shell plug-in is not installed, falling back to system() function.", g:xolox#misc#os#version)
58+
endtry
59+
60+
" If we cannot use the DLL, we fall back to the default and generic
61+
" implementation using Vim's system() function.
62+
if !exists('exit_code')
63+
64+
" Enable asynchronous mode (very platform specific).
65+
if async
66+
if xolox#misc#os#is_win()
67+
let cmd = 'start /b ' . cmd
68+
elseif has('unix')
69+
let cmd = '(' . cmd . ') &'
70+
else
71+
call xolox#misc#msg#warn("os.vim %s: I don't know how to run commands asynchronously on your platform! Falling back to synchronous mode.", g:xolox#misc#os#version)
72+
endif
73+
endif
74+
75+
" Let the user know what's happening (in case they're interested).
76+
call xolox#misc#msg#debug("os.vim %s: Executing external command using system() function: %s", g:xolox#misc#os#version, cmd)
77+
call system(cmd)
78+
let exit_code = v:shell_error
79+
2580
endif
26-
return split(output, "\n")
81+
82+
let result = {}
83+
if !async
84+
" If we just executed a synchronous command and the caller didn't
85+
" specifically ask us *not* to check the exit code of the external
86+
" command, we'll do so now.
87+
if get(a:options, 'check', 1) && exit_code != 0
88+
let msg = "os.vim %s: External command failed with exit code %d: %s"
89+
throw printf(msg, g:xolox#misc#os#version, result['exit_code'], result['command'])
90+
endif
91+
" Return the results as a dictionary with three key/value pairs.
92+
let result['exit_code'] = exit_code
93+
let result['stdout'] = s:readfile(tempout)
94+
let result['stderr'] = s:readfile(temperr)
95+
endif
96+
return result
97+
98+
finally
99+
" Cleanup any temporary files we created.
100+
for name in ['tempin', 'tempout', 'temperr']
101+
if exists(name)
102+
call delete({name})
103+
endif
104+
endfor
105+
endtry
106+
107+
endfunction
108+
109+
function! s:readfile(fname) " {{{1
110+
" readfile() that swallows errors.
111+
try
112+
return readfile(a:fname)
113+
catch
114+
return []
27115
endtry
28116
endfunction
29117

0 commit comments

Comments
 (0)