diff options
Diffstat (limited to 'autoload')
| -rw-r--r-- | autoload/xolox/easytags.vim | 32 | ||||
| -rw-r--r-- | autoload/xolox/misc/compat.vim | 4 | ||||
| -rw-r--r-- | autoload/xolox/misc/os.vim | 120 | 
3 files changed, 112 insertions, 44 deletions
diff --git a/autoload/xolox/easytags.vim b/autoload/xolox/easytags.vim index 180d469..6183e11 100644 --- a/autoload/xolox/easytags.vim +++ b/autoload/xolox/easytags.vim @@ -1,11 +1,11 @@  " Vim script  " Author: Peter Odding <peter@peterodding.com> -" Last Change: May 5, 2013 +" Last Change: May 13, 2013  " URL: http://peterodding.com/code/vim/easytags/ -let g:xolox#easytags#version = '3.2' +let g:xolox#easytags#version = '3.3' -call xolox#misc#compat#check('easytags', 2) +call xolox#misc#compat#check('easytags', 3)  " Public interface through (automatic) commands. {{{1 @@ -238,19 +238,8 @@ function! s:run_ctags(starttime, cfile, tagsfile, firstrun, cmdline) " {{{3    let has_updates = 1    if a:cmdline != ''      call xolox#misc#msg#debug("easytags.vim %s: Executing %s.", g:xolox#easytags#version, a:cmdline) -    try -      let lines = xolox#shell#execute(a:cmdline, 1) -      let has_updates = a:firstrun || s:has_updates(a:cfile, join(lines, "\n")) -    catch /^Vim\%((\a\+)\)\=:E117/ -      " Ignore missing shell.vim plug-in. -      let output = system(a:cmdline) -      if v:shell_error -        let msg = "Failed to update tags file %s: %s!" -        throw printf(msg, fnamemodify(a:tagsfile, ':~'), strtrans(output)) -      endif -      let lines = split(output, "\n") -      let has_updates = a:firstrun || s:has_updates(a:cfile, output) -    endtry +    let lines = xolox#misc#os#exec({'command': a:cmdline})['stdout'] +    let has_updates = a:firstrun || s:has_updates(a:cfile, join(lines, "\n"))      if a:firstrun        if a:cfile != ''          call xolox#misc#timer#stop("easytags.vim %s: Created tags for %s in %s.", g:xolox#easytags#version, expand('%:p:~'), a:starttime) @@ -493,16 +482,7 @@ function! xolox#easytags#supported_filetypes() " {{{2      let listing = []      if !empty(g:easytags_cmd)        let command = g:easytags_cmd . ' --list-languages' -      try -        let listing = xolox#shell#execute(command, 1) -      catch /^Vim\%((\a\+)\)\=:E117/ -        " Ignore missing shell.vim plug-in. -        let listing = split(system(command), "\n") -        if v:shell_error -          let msg = "Failed to get supported languages! (output: %s)" -          throw printf(msg, strtrans(join(listing, "\n"))) -        endif -      endtry +      let listing = xolox#misc#os#exec({'command': command})['stdout']      endif      let s:supported_filetypes = map(copy(listing) + keys(xolox#misc#option#get('easytags_languages', {})), 's:check_filetype(listing, v:val)')      let msg = "easytags.vim %s: Retrieved %i supported languages in %s." diff --git a/autoload/xolox/misc/compat.vim b/autoload/xolox/misc/compat.vim index 52c5c28..70a4287 100644 --- a/autoload/xolox/misc/compat.vim +++ b/autoload/xolox/misc/compat.vim @@ -1,13 +1,13 @@  " Vim auto-load script  " Author: Peter Odding <peter@peterodding.com> -" Last Change: April 28, 2013 +" Last Change: May 13, 2013  " URL: http://peterodding.com/code/vim/misc/  " The following integer will be bumped whenever a change in the miscellaneous  " scripts breaks backwards compatibility. This enables my Vim plug-ins to fail  " early when they detect an incompatible version, instead of breaking at the  " worst possible moments :-). -let g:xolox#misc#compat#version = 2 +let g:xolox#misc#compat#version = 3  " Remember the directory where the miscellaneous scripts are loaded from  " so the user knows which plug-in to update if incompatibilities arise. diff --git a/autoload/xolox/misc/os.vim b/autoload/xolox/misc/os.vim index 451ca57..ef036df 100644 --- a/autoload/xolox/misc/os.vim +++ b/autoload/xolox/misc/os.vim @@ -1,29 +1,117 @@  " Vim auto-load script  " Author: Peter Odding <peter@peterodding.com> -" Last Change: November 24, 2011 +" Last Change: May 13, 2013  " URL: http://peterodding.com/code/vim/misc/ -let g:xolox#misc#os#version = '0.1' +let g:xolox#misc#os#version = '0.2' -" Check whether Vim is running on Microsoft Windows. - -function! xolox#misc#os#is_win() +function! xolox#misc#os#is_win() " {{{1 +  " Check whether Vim is running on Microsoft Windows.    return has('win16') || has('win32') || has('win64')  endfunction -" Execute an external command (hiding the console on Windows when possible). - -function! xolox#misc#os#exec(cmdline, ...) +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.    try -    " Try using my shell.vim plug-in. -    return call('xolox#shell#execute', [a:cmdline, 1] + a:000) -  catch /^Vim\%((\a\+)\)\=:E117/ -    " Fall back to system() when we get an "unknown function" error. -    let output = call('system', [a:cmdline] + a:000) -    if v:shell_error -      throw printf("os.vim %s: Command %s failed: %s", g:xolox#misc#os#version, a:cmdline, xolox#misc#str#trim(output)) + +    " Unpack the options. +    let cmd = a:options['command'] +    let async = get(a:options, 'async', 0) + +    " Write the input for the external command to a temporary file? +    if has_key(a:options, 'stdin') +      let tempin = tempname() +      if type(a:options['stdin']) == type([]) +        let lines = a:options['stdin'] +      else +        let lines = split(a:options['stdin'], "\n") +      endif +      call writefile(lines, tempin) +      let cmd .= ' < ' . xolox#misc#escape#shell(tempin) +    endif + +    " Redirect the standard output and standard error streams of the external +    " process to temporary files? (only in synchronous mode, which is the +    " default). +    if !async +      let tempout = tempname() +      let temperr = tempname() +      let cmd = printf('(%s) 1>%s 2>%s', cmd, +            \ xolox#misc#escape#shell(tempout), +            \ xolox#misc#escape#shell(temperr)) +    endif + +    " If A) we're on Windows, B) the vim-shell plug-in is installed and C) the +    " compiled DLL works, we'll use that because it's the most user friendly +    " method. If the plug-in is not installed Vim will raise the exception +    " "E117: Unknown function" which is caught and handled below. +    try +      if xolox#shell#can_use_dll() +        " Let the user know what's happening (in case they're interested). +        call xolox#misc#msg#debug("os.vim %s: Executing external command using compiled DLL: %s", g:xolox#misc#os#version, cmd) +        let exit_code = xolox#shell#execute_with_dll(cmd, async) +      endif +    catch /^Vim\%((\a\+)\)\=:E117/ +      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) +    endtry + +    " If we cannot use the DLL, we fall back to the default and generic +    " implementation using Vim's system() function. +    if !exists('exit_code') + +      " Enable asynchronous mode (very platform specific). +      if async +        if xolox#misc#os#is_win() +          let cmd = 'start /b ' . cmd +        elseif has('unix') +          let cmd = '(' . cmd . ') &' +        else +          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) +        endif +      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) +      let exit_code = v:shell_error +      endif -    return split(output, "\n") + +    let result = {} +    if !async +      " 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']) +      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 + +  finally +    " Cleanup any temporary files we created. +    for name in ['tempin', 'tempout', 'temperr'] +      if exists(name) +        call delete({name}) +      endif +    endfor +  endtry + +endfunction + +function! s:readfile(fname) " {{{1 +  " readfile() that swallows errors. +  try +    return readfile(a:fname) +  catch +    return []    endtry  endfunction  | 
