aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Odding <peter@peterodding.com>2013-05-13 23:02:06 +0200
committerPeter Odding <peter@peterodding.com>2013-05-13 23:02:06 +0200
commit7c61b34c0a6c27e72ad68f46ef28586f14ffa4b3 (patch)
tree6fadd3951926fa9e67f067c88b04e1781ac7ae82
parent9e8261a83ef5f3c1c9ed6e4a4c07ad7c7f139711 (diff)
parent9c88b0e71b41411735000645089670a3577f3e5d (diff)
downloadvim-easytags-7c61b34c0a6c27e72ad68f46ef28586f14ffa4b3.tar.gz
Updated miscellaneous scripts
-rw-r--r--autoload/xolox/easytags.vim32
-rw-r--r--autoload/xolox/misc/compat.vim4
-rw-r--r--autoload/xolox/misc/os.vim120
-rw-r--r--plugin/easytags.vim40
4 files changed, 128 insertions, 68 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
diff --git a/plugin/easytags.vim b/plugin/easytags.vim
index 935ef40..64361a7 100644
--- a/plugin/easytags.vim
+++ b/plugin/easytags.vim
@@ -1,6 +1,6 @@
" Vim plug-in
" Author: Peter Odding <peter@peterodding.com>
-" Last Change: April 19, 2013
+" Last Change: May 13, 2013
" URL: http://peterodding.com/code/vim/easytags/
" Requires: Exuberant Ctags (http://ctags.sf.net)
@@ -58,12 +58,12 @@ function! s:InitEasyTags(version)
" FIXME The code below that searches the $PATH is not used on Windows at
" the moment because xolox#misc#path#which() generally produces absolute
" paths and on Windows these absolute paths tend to contain spaces which
- " makes xolox#shell#execute() fail. I've tried quoting the program name
- " with double quotes but it fails just the same (it works with system()
- " though). Anyway the problem of having multiple conflicting versions of
- " Exuberant Ctags installed is not that relevant to Windows since it
- " doesn't have a package management system. I still want to fix
- " xolox#shell#execute() though.
+ " makes xolox#shell#execute_with_dll() fail. I've tried quoting the
+ " program name with double quotes but it fails just the same (it works
+ " with system() though). Anyway the problem of having multiple conflicting
+ " versions of Exuberant Ctags installed is not that relevant to Windows
+ " since it doesn't have a package management system. I still want to fix
+ " xolox#shell#execute_with_dll() though.
if s:CheckCtags('ctags', a:version)
let g:easytags_cmd = 'ctags'
return 1
@@ -96,23 +96,15 @@ function! s:CheckCtags(name, version)
" --list-languages option (and more).
if executable(a:name)
let command = a:name . ' --version'
- try
- let listing = join(xolox#shell#execute(command, 1), '\n')
- catch /^Vim\%((\a\+)\)\=:E117/
- " Ignore missing shell.vim plug-in.
- let listing = system(command)
- catch
- " xolox#shell#execute() converts shell errors to exceptions and since
- " we're checking whether one of several executables exists we don't want
- " to throw an error when the first one doesn't!
- return
- endtry
- let pattern = 'Exuberant Ctags \zs\(\d\+\(\.\d\+\)*\|Development\)'
- let g:easytags_ctags_version = matchstr(listing, pattern)
- if g:easytags_ctags_version == 'Development'
- return 1
- else
- return s:VersionToNumber(g:easytags_ctags_version) >= a:version
+ let result = xolox#misc#os#exec({'command': command, 'check': 0})
+ if result['exit_code'] == 0
+ let pattern = 'Exuberant Ctags \zs\(\d\+\(\.\d\+\)*\|Development\)'
+ let g:easytags_ctags_version = matchstr(result['stdout'][0], pattern)
+ if g:easytags_ctags_version == 'Development'
+ return 1
+ else
+ return s:VersionToNumber(g:easytags_ctags_version) >= a:version
+ endif
endif
endif
endfunction