diff options
Diffstat (limited to 'autoload/xolox/misc/os.vim')
-rw-r--r-- | autoload/xolox/misc/os.vim | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/autoload/xolox/misc/os.vim b/autoload/xolox/misc/os.vim index ef036df..4dcf64d 100644 --- a/autoload/xolox/misc/os.vim +++ b/autoload/xolox/misc/os.vim @@ -1,19 +1,44 @@ -" Vim auto-load script +" Operating system interfaces. +" " Author: Peter Odding <peter@peterodding.com> -" Last Change: May 13, 2013 +" Last Change: May 19, 2013 " URL: http://peterodding.com/code/vim/misc/ -let g:xolox#misc#os#version = '0.2' +let g:xolox#misc#os#version = '0.3' function! xolox#misc#os#is_win() " {{{1 - " Check whether Vim is running on Microsoft Windows. + " Returns 1 (true) when on Microsoft Windows, 0 (false) otherwise. return has('win16') || has('win32') || has('win64') endfunction function! xolox#misc#os#exec(options) " {{{1 - " Execute an external command (hiding the console on Windows when possible). - " NB: Everything below is wrapped in a try/finally block to guarantee - " cleanup of temporary files. + " Execute an external command (hiding the console on Microsoft Windows when + " my [vim-shell plug-in] [vim-shell] is installed). + " + " Expects a dictionary with the following key/value pairs as the first + " argument: + " + " - **command** (required): The command line to execute + " - **async** (optional): set this to 1 (true) to execute the command in the + " background (asynchronously) + " - **stdin** (optional): a string or list of strings with the input for the + " external command + " - **check** (optional): set this to 0 (false) to disable checking of the + " exit code of the external command (by default an exception will be + " raised when the command fails) + " + " Returns a dictionary with one or more of the following key/value pairs: + " + " - **command** (always available): the generated command line that was used + " to run the external command + " - **exit_code** (only in synchronous mode): the exit status of the + " external command (an integer, zero on success) + " - **stdout** (only in synchronous mode): the output of the command on the + " standard output stream (a list of strings, one for each line) + " - **stderr** (only in synchronous mode): the output of the command on the + " standard error stream (as a list of strings, one for each line) + " + " [vim-shell]: http://peterodding.com/code/vim/shell/ try " Unpack the options. @@ -72,6 +97,14 @@ function! xolox#misc#os#exec(options) " {{{1 endif endif + " Execute the command line using 'sh' instead of the default shell, + " because we assume that standard output and standard error can be + " redirected separately, but (t)csh does not support this. + if has('unix') + call xolox#misc#msg#debug("os.vim %s: Generated shell expression: %s", g:xolox#misc#os#version, cmd) + let cmd = printf('sh -c %s', xolox#misc#escape#shell(cmd)) + endif + " Let the user know what's happening (in case they're interested). call xolox#misc#msg#debug("os.vim %s: Executing external command using system() function: %s", g:xolox#misc#os#version, cmd) call system(cmd) @@ -79,19 +112,29 @@ function! xolox#misc#os#exec(options) " {{{1 endif - let result = {} + " Return the results as a dictionary with one or more key/value pairs. + let result = {'command': cmd} if !async + let result['exit_code'] = exit_code + let result['stdout'] = s:readfile(tempout) + let result['stderr'] = s:readfile(temperr) " If we just executed a synchronous command and the caller didn't " specifically ask us *not* to check the exit code of the external " command, we'll do so now. if get(a:options, 'check', 1) && exit_code != 0 - let msg = "os.vim %s: External command failed with exit code %d: %s" - throw printf(msg, g:xolox#misc#os#version, result['exit_code'], result['command']) + " Prepare an error message with enough details so the user can investigate. + let msg = printf("os.vim %s: External command failed with exit code %d!", g:xolox#misc#os#version, result['exit_code']) + let msg .= printf("\nCommand line: %s", result['command']) + " If the external command reported an error, we'll include it in our message. + if !empty(result['stderr']) + " This is where we would normally expect to find an error message. + let msg .= printf("\nOutput on standard output stream:\n%s", join(result['stderr'], "\n")) + elseif !empty(result['stdout']) + " Exuberant Ctags on Windows XP reports errors on standard output :-x. + let msg .= printf("\nOutput on standard error stream:\n%s", join(result['stdout'], "\n")) + endif + throw msg endif - " Return the results as a dictionary with three key/value pairs. - let result['exit_code'] = exit_code - let result['stdout'] = s:readfile(tempout) - let result['stderr'] = s:readfile(temperr) endif return result |