aboutsummaryrefslogtreecommitdiffstats
path: root/autoload/xolox/misc/os.vim
diff options
context:
space:
mode:
Diffstat (limited to 'autoload/xolox/misc/os.vim')
-rw-r--r--autoload/xolox/misc/os.vim71
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