aboutsummaryrefslogtreecommitdiffstats
path: root/autoload
diff options
context:
space:
mode:
authorPeter Odding <peter@peterodding.com>2013-05-23 20:08:26 +0200
committerPeter Odding <peter@peterodding.com>2013-05-23 20:08:26 +0200
commit615dbc99fc60c08aa7993872e71a61b5f35e5017 (patch)
treefcc1a2f1800f0662e5979df3389b415c19cab63d /autoload
parentd9a9b89f3fc9a40aebca2df430ae1123f543ad62 (diff)
downloadvim-easytags-615dbc99fc60c08aa7993872e71a61b5f35e5017.tar.gz
Release 3.3.5
Diffstat (limited to 'autoload')
-rw-r--r--autoload/xolox/easytags.vim152
-rw-r--r--autoload/xolox/easytags/misc/buffer.vim86
-rw-r--r--autoload/xolox/easytags/misc/complete.vim28
-rw-r--r--autoload/xolox/easytags/misc/escape.vim62
-rw-r--r--autoload/xolox/easytags/misc/list.vim63
-rw-r--r--autoload/xolox/easytags/misc/msg.vim97
-rw-r--r--autoload/xolox/easytags/misc/open.vim98
-rw-r--r--autoload/xolox/easytags/misc/option.vim121
-rw-r--r--autoload/xolox/easytags/misc/os.vim194
-rw-r--r--autoload/xolox/easytags/misc/path.vim262
-rw-r--r--autoload/xolox/easytags/misc/str.vim24
-rw-r--r--autoload/xolox/easytags/misc/timer.vim109
12 files changed, 1223 insertions, 73 deletions
diff --git a/autoload/xolox/easytags.vim b/autoload/xolox/easytags.vim
index 1372f2c..90c495b 100644
--- a/autoload/xolox/easytags.vim
+++ b/autoload/xolox/easytags.vim
@@ -1,3 +1,9 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
" Vim script
" Author: Peter Odding <peter@peterodding.com>
" Last Change: May 23, 2013
@@ -10,11 +16,11 @@ let g:xolox#easytags#version = '3.3.5'
function! xolox#easytags#register(global) " {{{2
" Parse the &tags option and get a list of all tags files *including
" non-existing files* (this is why we can't just call tagfiles()).
- let tagfiles = xolox#misc#option#split_tags(&tags)
+ let tagfiles = xolox#easytags#misc#option#split_tags(&tags)
let expanded = map(copy(tagfiles), 'resolve(expand(v:val))')
" Add the filename to the &tags option when the user hasn't done so already.
let tagsfile = a:global ? g:easytags_file : xolox#easytags#get_tagsfile()
- if index(expanded, xolox#misc#path#absolute(tagsfile)) == -1
+ if index(expanded, xolox#easytags#misc#path#absolute(tagsfile)) == -1
" This is a real mess because of bugs in Vim?! :let &tags = '...' doesn't
" work on UNIX and Windows, :set tags=... doesn't work on Windows. What I
" mean with "doesn't work" is that tagfiles() == [] after the :let/:set
@@ -23,9 +29,9 @@ function! xolox#easytags#register(global) " {{{2
" <CR>. Now you entered the exact same value that the code below also did
" but suddenly Vim sees the tags file and tagfiles() != [] :-S
call add(tagfiles, tagsfile)
- let value = xolox#misc#option#join_tags(tagfiles)
+ let value = xolox#easytags#misc#option#join_tags(tagfiles)
let cmd = (a:global ? 'set' : 'setl') . ' tags=' . escape(value, '\ ')
- if xolox#misc#os#is_win() && v:version < 703
+ if xolox#easytags#misc#os#is_win() && v:version < 703
" TODO How to clear the expression from Vim's status line?
call feedkeys(":" . cmd . "|let &ro=&ro\<CR>", 'n')
else
@@ -39,8 +45,8 @@ let s:last_automatic_run = 0
function! xolox#easytags#autoload(event) " {{{2
try
- let do_update = xolox#misc#option#get('easytags_auto_update', 1)
- let do_highlight = xolox#misc#option#get('easytags_auto_highlight', 1) && &eventignore !~? '\<syntax\>'
+ let do_update = xolox#easytags#misc#option#get('easytags_auto_update', 1)
+ let do_highlight = xolox#easytags#misc#option#get('easytags_auto_highlight', 1) && &eventignore !~? '\<syntax\>'
" Don't execute this function for unsupported file types (doesn't load
" the list of file types if updates and highlighting are both disabled).
if (do_update || do_highlight) && !empty(xolox#easytags#select_supported_filetypes(&ft))
@@ -48,23 +54,23 @@ function! xolox#easytags#autoload(event) " {{{2
" Only for the CursorHold automatic command: check for unreasonable
" &updatetime values. The minimum value 4000 is kind of arbitrary
" (apart from being Vim's default) so I made it configurable.
- let updatetime_min = xolox#misc#option#get('easytags_updatetime_min', 4000)
+ let updatetime_min = xolox#easytags#misc#option#get('easytags_updatetime_min', 4000)
if &updatetime < updatetime_min
if s:last_automatic_run == 0
" Warn once about the low &updatetime value?
- if xolox#misc#option#get('easytags_updatetime_warn', 1)
- call xolox#misc#msg#warn("easytags.vim %s: The 'updatetime' option has an unreasonably low value, so I'll start compensating (see the easytags_updatetime_min option).", g:xolox#easytags#version)
+ if xolox#easytags#misc#option#get('easytags_updatetime_warn', 1)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: The 'updatetime' option has an unreasonably low value, so I'll start compensating (see the easytags_updatetime_min option).", g:xolox#easytags#version)
endif
let s:last_automatic_run = localtime()
else
let next_scheduled_run = s:last_automatic_run + max([1, updatetime_min / 1000])
if localtime() < next_scheduled_run
" It's not our time yet; wait for the next event.
- call xolox#misc#msg#debug("easytags.vim %s: Skipping this beat of 'updatetime' to compensate for low value.", g:xolox#easytags#version)
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: Skipping this beat of 'updatetime' to compensate for low value.", g:xolox#easytags#version)
" Shortcut to break out of xolox#easytags#autoload().
return
else
- call xolox#misc#msg#debug("easytags.vim %s: This is our beat of 'updatetime'!", g:xolox#easytags#version)
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: This is our beat of 'updatetime'!", g:xolox#easytags#version)
let s:last_automatic_run = localtime()
endif
endif
@@ -96,7 +102,7 @@ function! xolox#easytags#autoload(event) " {{{2
endif
endif
catch
- call xolox#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
endtry
endfunction
@@ -104,7 +110,7 @@ function! xolox#easytags#update(silent, filter_tags, filenames) " {{{2
try
let context = s:create_context()
let have_args = !empty(a:filenames)
- let starttime = xolox#misc#timer#start()
+ let starttime = xolox#easytags#misc#timer#start()
let cfile = s:check_cfile(a:silent, a:filter_tags, have_args)
let tagsfile = xolox#easytags#get_tagsfile()
let firstrun = !filereadable(tagsfile)
@@ -122,23 +128,23 @@ function! xolox#easytags#update(silent, filter_tags, filenames) " {{{2
endif
if cfile != ''
let msg = "easytags.vim %s: Updated tags for %s in %s."
- call xolox#misc#timer#stop(msg, g:xolox#easytags#version, expand('%:p:~'), starttime)
+ call xolox#easytags#misc#timer#stop(msg, g:xolox#easytags#version, expand('%:p:~'), starttime)
elseif have_args
let msg = "easytags.vim %s: Updated tags in %s."
- call xolox#misc#timer#stop(msg, g:xolox#easytags#version, starttime)
+ call xolox#easytags#misc#timer#stop(msg, g:xolox#easytags#version, starttime)
else
let msg = "easytags.vim %s: Filtered %i invalid tags in %s."
- call xolox#misc#timer#stop(msg, g:xolox#easytags#version, num_filtered, starttime)
+ call xolox#easytags#misc#timer#stop(msg, g:xolox#easytags#version, num_filtered, starttime)
endif
endif
" When :UpdateTags was executed manually we'll refresh the dynamic
" syntax highlighting so that new tags are immediately visible.
- if !a:silent && xolox#misc#option#get('easytags_auto_highlight', 1)
+ if !a:silent && xolox#easytags#misc#option#get('easytags_auto_highlight', 1)
HighlightTags
endif
return 1
catch
- call xolox#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
endtry
endfunction
@@ -147,7 +153,7 @@ function! s:check_cfile(silent, filter_tags, have_args) " {{{3
return ''
endif
let silent = a:silent || a:filter_tags
- if xolox#misc#option#get('easytags_autorecurse', 0)
+ if xolox#easytags#misc#option#get('easytags_autorecurse', 0)
let cdir = s:resolve(expand('%:p:h'))
if !isdirectory(cdir)
if silent | return '' | endif
@@ -170,49 +176,49 @@ function! s:check_cfile(silent, filter_tags, have_args) " {{{3
endfunction
function! s:prep_cmdline(cfile, tagsfile, firstrun, arguments, context) " {{{3
- let languages = xolox#misc#option#get('easytags_languages', {})
+ let languages = xolox#easytags#misc#option#get('easytags_languages', {})
let applicable_filetypes = xolox#easytags#select_supported_filetypes(&ft)
let ctags_language_name = xolox#easytags#to_ctags_ft(applicable_filetypes[0])
let language = get(languages, ctags_language_name, {})
if empty(language)
- let program = xolox#misc#option#get('easytags_cmd')
+ let program = xolox#easytags#misc#option#get('easytags_cmd')
let cmdline = [program, '--fields=+l', '--c-kinds=+p', '--c++-kinds=+p']
if a:firstrun
- call add(cmdline, xolox#misc#escape#shell('-f' . a:tagsfile))
+ call add(cmdline, xolox#easytags#misc#escape#shell('-f' . a:tagsfile))
call add(cmdline, '--sort=' . (&ic ? 'foldcase' : 'yes'))
else
call add(cmdline, '--sort=no')
call add(cmdline, '-f-')
endif
- if xolox#misc#option#get('easytags_include_members', 0)
+ if xolox#easytags#misc#option#get('easytags_include_members', 0)
call add(cmdline, '--extra=+q')
endif
else
- let program = get(language, 'cmd', xolox#misc#option#get('easytags_cmd'))
+ let program = get(language, 'cmd', xolox#easytags#misc#option#get('easytags_cmd'))
if empty(program)
- call xolox#misc#msg#warn("easytags.vim %s: No 'cmd' defined for language '%s', and also no global default!", g:xolox#easytags#version, ctags_language_name)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: No 'cmd' defined for language '%s', and also no global default!", g:xolox#easytags#version, ctags_language_name)
return
endif
let cmdline = [program] + get(language, 'args', [])
if a:firstrun
- call add(cmdline, xolox#misc#escape#shell(get(language, 'fileoutput_opt', '-f') . a:tagsfile))
+ call add(cmdline, xolox#easytags#misc#escape#shell(get(language, 'fileoutput_opt', '-f') . a:tagsfile))
else
- call add(cmdline, xolox#misc#escape#shell(get(language, 'stdout_opt', '-f-')))
+ call add(cmdline, xolox#easytags#misc#escape#shell(get(language, 'stdout_opt', '-f-')))
endif
endif
let have_args = 0
if a:cfile != ''
- if xolox#misc#option#get('easytags_autorecurse', 0)
- call add(cmdline, empty(language) ? '-R' : xolox#misc#escape#shell(get(language, 'recurse_flag', '-R')))
- call add(cmdline, xolox#misc#escape#shell(a:cfile))
+ if xolox#easytags#misc#option#get('easytags_autorecurse', 0)
+ call add(cmdline, empty(language) ? '-R' : xolox#easytags#misc#escape#shell(get(language, 'recurse_flag', '-R')))
+ call add(cmdline, xolox#easytags#misc#escape#shell(a:cfile))
else
if empty(language)
" TODO Should --language-force distinguish between C and C++?
" TODO --language-force doesn't make sense for JavaScript tags in HTML files?
let filetype = xolox#easytags#to_ctags_ft(applicable_filetypes[0])
- call add(cmdline, xolox#misc#escape#shell('--language-force=' . filetype))
+ call add(cmdline, xolox#easytags#misc#escape#shell('--language-force=' . filetype))
endif
- call add(cmdline, xolox#misc#escape#shell(a:cfile))
+ call add(cmdline, xolox#easytags#misc#escape#shell(a:cfile))
endif
let have_args = 1
else
@@ -223,7 +229,7 @@ function! s:prep_cmdline(cfile, tagsfile, firstrun, arguments, context) " {{{3
else
let matches = split(expand(arg), "\n")
if !empty(matches)
- call map(matches, 'xolox#misc#escape#shell(s:canonicalize(v:val, a:context))')
+ call map(matches, 'xolox#easytags#misc#escape#shell(s:canonicalize(v:val, a:context))')
call extend(cmdline, matches)
let have_args = 1
endif
@@ -238,14 +244,14 @@ function! s:run_ctags(starttime, cfile, tagsfile, firstrun, cmdline) " {{{3
let lines = []
let has_updates = 1
if a:cmdline != ''
- call xolox#misc#msg#debug("easytags.vim %s: Executing %s.", g:xolox#easytags#version, a:cmdline)
- let lines = xolox#misc#os#exec({'command': a:cmdline})['stdout']
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: Executing %s.", g:xolox#easytags#version, a:cmdline)
+ let lines = xolox#easytags#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)
+ call xolox#easytags#misc#timer#stop("easytags.vim %s: Created tags for %s in %s.", g:xolox#easytags#version, expand('%:p:~'), a:starttime)
else
- call xolox#misc#timer#stop("easytags.vim %s: Created tags in %s.", g:xolox#easytags#version, a:starttime)
+ call xolox#easytags#misc#timer#stop("easytags.vim %s: Created tags in %s.", g:xolox#easytags#version, a:starttime)
endif
return [[], 0]
endif
@@ -266,9 +272,9 @@ function! s:has_updates(cfile, output)
return 1
endif
let fingerprint = s:get_fingerprint(a:cfile, a:output)
- call xolox#misc#msg#debug("easytags.vim %s: Fingerprint of tags in %s is %s.", g:xolox#easytags#version, a:cfile, string(fingerprint))
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: Fingerprint of tags in %s is %s.", g:xolox#easytags#version, a:cfile, string(fingerprint))
if !empty(fingerprint) && get(s:fingerprints, a:cfile, '') ==# fingerprint
- call xolox#misc#msg#debug("easytags.vim %s: The fingerprint didn't change! We can take a shortcut :-)", g:xolox#easytags#version)
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: The fingerprint didn't change! We can take a shortcut :-)", g:xolox#easytags#version)
return 0
endif
let s:fingerprints[a:cfile] = fingerprint
@@ -344,7 +350,7 @@ function! xolox#easytags#highlight() " {{{2
let filetype = get(s:canonical_aliases, &ft, &ft)
let tagkinds = get(s:tagkinds, filetype, [])
if exists('g:syntax_on') && !empty(tagkinds) && !exists('b:easytags_nohl')
- let starttime = xolox#misc#timer#start()
+ let starttime = xolox#easytags#misc#timer#start()
let used_python = 0
for tagkind in tagkinds
let hlgroup_tagged = tagkind.hlgroup . 'Tag'
@@ -380,16 +386,16 @@ function! xolox#easytags#highlight() " {{{2
let matches = filter(copy(taglist), filter)
if matches != []
" Convert matched tags to :syntax command and execute it.
- let matches = xolox#misc#list#unique(map(matches, 'xolox#misc#escape#pattern(get(v:val, "name"))'))
+ let matches = xolox#easytags#misc#list#unique(map(matches, 'xolox#easytags#misc#escape#pattern(get(v:val, "name"))'))
let pattern = tagkind.pattern_prefix . '\%(' . join(matches, '\|') . '\)' . tagkind.pattern_suffix
let template = 'syntax match %s /%s/ containedin=ALLBUT,%s'
- let command = printf(template, hlgroup_tagged, escape(pattern, '/'), xolox#misc#option#get('easytags_ignored_syntax_groups'))
- call xolox#misc#msg#debug("easytags.vim %s: Executing command '%s'.", g:xolox#easytags#version, command)
+ let command = printf(template, hlgroup_tagged, escape(pattern, '/'), xolox#easytags#misc#option#get('easytags_ignored_syntax_groups'))
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: Executing command '%s'.", g:xolox#easytags#version, command)
try
execute command
catch /^Vim\%((\a\+)\)\=:E339/
let msg = "easytags.vim %s: Failed to highlight %i %s tags because pattern is too big! (%i KB)"
- call xolox#misc#msg#warn(msg, g:xolox#easytags#version, len(matches), tagkind.hlgroup, len(pattern) / 1024)
+ call xolox#easytags#misc#msg#warn(msg, g:xolox#easytags#version, len(matches), tagkind.hlgroup, len(pattern) / 1024)
endtry
endif
endif
@@ -400,11 +406,11 @@ function! xolox#easytags#highlight() " {{{2
let bufname = 'unnamed buffer #' . bufnr('%')
endif
let msg = "easytags.vim %s: Highlighted tags in %s in %s%s."
- call xolox#misc#timer#stop(msg, g:xolox#easytags#version, bufname, starttime, used_python ? " (using Python)" : "")
+ call xolox#easytags#misc#timer#stop(msg, g:xolox#easytags#version, bufname, starttime, used_python ? " (using Python)" : "")
return 1
endif
catch
- call xolox#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
endtry
endfunction
@@ -421,7 +427,7 @@ function! xolox#easytags#by_filetype(undo) " {{{2
call s:save_by_filetype(0, headers, entries, context)
call rename(global_tagsfile, disabled_tagsfile)
let msg = "easytags.vim %s: Finished copying tags from %s to %s! Note that your old tags file has been renamed to %s instead of deleting it, should you want to restore it."
- call xolox#misc#msg#info(msg, g:xolox#easytags#version, g:easytags_file, g:easytags_by_filetype, disabled_tagsfile)
+ call xolox#easytags#misc#msg#info(msg, g:xolox#easytags#version, g:easytags_file, g:easytags_by_filetype, disabled_tagsfile)
else
let headers = []
let all_entries = []
@@ -430,10 +436,10 @@ function! xolox#easytags#by_filetype(undo) " {{{2
call extend(all_entries, entries)
endfor
call xolox#easytags#write_tagsfile(global_tagsfile, headers, all_entries)
- call xolox#misc#msg#info("easytags.vim %s: Finished copying tags from %s to %s!", g:xolox#easytags#version, g:easytags_by_filetype, g:easytags_file)
+ call xolox#easytags#misc#msg#info("easytags.vim %s: Finished copying tags from %s to %s!", g:xolox#easytags#version, g:easytags_by_filetype, g:easytags_file)
endif
catch
- call xolox#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: %s (at %s)", g:xolox#easytags#version, v:exception, v:throwpoint)
endtry
endfunction
@@ -446,7 +452,7 @@ function! s:save_by_filetype(filter_tags, headers, entries, context)
" TODO This triggers on entries where the pattern contains tabs. The interesting thing is that Vim reads these entries fine... Fix it in xolox#easytags#read_tagsfile()?
let num_invalid += 1
if &vbs >= 1
- call xolox#misc#msg#debug("easytags.vim %s: Skipping tag without 'language:' field: %s",
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: Skipping tag without 'language:' field: %s",
\ g:xolox#easytags#version, string(entry))
endif
else
@@ -458,13 +464,13 @@ function! s:save_by_filetype(filter_tags, headers, entries, context)
endif
endfor
if num_invalid > 0
- call xolox#misc#msg#warn("easytags.vim %s: Skipped %i lines without 'language:' tag!", g:xolox#easytags#version, num_invalid)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: Skipped %i lines without 'language:' tag!", g:xolox#easytags#version, num_invalid)
endif
- let directory = xolox#misc#path#absolute(g:easytags_by_filetype)
+ let directory = xolox#easytags#misc#path#absolute(g:easytags_by_filetype)
for vim_ft in keys(filetypes)
- let tagsfile = xolox#misc#path#merge(directory, vim_ft)
+ let tagsfile = xolox#easytags#misc#path#merge(directory, vim_ft)
let existing = filereadable(tagsfile)
- call xolox#misc#msg#debug("easytags.vim %s: Writing %s tags to %s tags file %s.",
+ call xolox#easytags#misc#msg#debug("easytags.vim %s: Writing %s tags to %s tags file %s.",
\ g:xolox#easytags#version, len(filetypes[vim_ft]),
\ existing ? "existing" : "new", tagsfile)
if !existing
@@ -479,15 +485,15 @@ endfunction
function! xolox#easytags#supported_filetypes() " {{{2
if !exists('s:supported_filetypes')
- let starttime = xolox#misc#timer#start()
+ let starttime = xolox#easytags#misc#timer#start()
let listing = []
if !empty(g:easytags_cmd)
let command = g:easytags_cmd . ' --list-languages'
- let listing = xolox#misc#os#exec({'command': command})['stdout']
+ let listing = xolox#easytags#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 s:supported_filetypes = map(copy(listing) + keys(xolox#easytags#misc#option#get('easytags_languages', {})), 's:check_filetype(listing, v:val)')
let msg = "easytags.vim %s: Retrieved %i supported languages in %s."
- call xolox#misc#timer#stop(msg, g:xolox#easytags#version, len(s:supported_filetypes), starttime)
+ call xolox#easytags#misc#timer#stop(msg, g:xolox#easytags#version, len(s:supported_filetypes), starttime)
endif
return s:supported_filetypes
endfunction
@@ -533,7 +539,7 @@ function! xolox#easytags#read_tagsfile(tagsfile) " {{{2
endif
endfor
if num_invalid > 0
- call xolox#misc#msg#warn("easytags.vim %s: Ignored %i invalid line(s) in %s!", g:xolox#easytags#version, num_invalid, a:tagsfile)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: Ignored %i invalid line(s) in %s!", g:xolox#easytags#version, num_invalid, a:tagsfile)
endif
return [headers, entries]
endfunction
@@ -563,7 +569,7 @@ function! xolox#easytags#write_tagsfile(tagsfile, headers, entries) " {{{2
call sort(a:entries, function('s:foldcase_compare'))
endif
let lines = []
- if xolox#misc#os#is_win()
+ if xolox#easytags#misc#os#is_win()
" Exuberant Ctags on Windows requires \r\n but Vim's writefile() doesn't add them!
for line in a:headers
call add(lines, line . "\r")
@@ -609,10 +615,10 @@ function! s:cache_tagged_files(context) " {{{3
" Initialize the cache of tagged files on first use. After initialization
" we'll only update the cache when we're reading a tags file from disk for
" other purposes anyway (so the cache doesn't introduce too much overhead).
- let starttime = xolox#misc#timer#start()
+ let starttime = xolox#easytags#misc#timer#start()
for tagsfile in tagfiles()
if !filereadable(tagsfile)
- call xolox#misc#msg#warn("easytags.vim %s: Skipping unreadable tags file %s!", g:xolox#easytags#version, tagsfile)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: Skipping unreadable tags file %s!", g:xolox#easytags#version, tagsfile)
else
let fname = s:canonicalize(tagsfile, a:context)
let ftime = getftime(fname)
@@ -622,7 +628,7 @@ function! s:cache_tagged_files(context) " {{{3
endif
endif
endfor
- call xolox#misc#timer#stop("easytags.vim %s: Initialized cache of tagged files in %s.", g:xolox#easytags#version, starttime)
+ call xolox#easytags#misc#timer#stop("easytags.vim %s: Initialized cache of tagged files in %s.", g:xolox#easytags#version, starttime)
endif
endfunction
@@ -639,28 +645,28 @@ endfunction
function! xolox#easytags#get_tagsfile() " {{{2
let tagsfile = ''
" Look for a suitable project specific tags file?
- let dynamic_files = xolox#misc#option#get('easytags_dynamic_files', 0)
+ let dynamic_files = xolox#easytags#misc#option#get('easytags_dynamic_files', 0)
if dynamic_files == 1
let tagsfile = get(tagfiles(), 0, '')
elseif dynamic_files == 2
- let tagsfile = xolox#misc#option#eval_tags(&tags, 1)
+ let tagsfile = xolox#easytags#misc#option#eval_tags(&tags, 1)
let directory = fnamemodify(tagsfile, ':h')
if filewritable(directory) != 2
" If the directory of the dynamic tags file is not writable, we fall
" back to a file type specific tags file or the global tags file.
- call xolox#misc#msg#warn("easytags.vim %s: Dynamic tags files enabled but %s not writable so falling back.", g:xolox#easytags#version, directory)
+ call xolox#easytags#misc#msg#warn("easytags.vim %s: Dynamic tags files enabled but %s not writable so falling back.", g:xolox#easytags#version, directory)
let tagsfile = ''
endif
endif
" Check if a file type specific tags file is useful?
let applicable_filetypes = xolox#easytags#select_supported_filetypes(&ft)
if empty(tagsfile) && !empty(g:easytags_by_filetype) && !empty(applicable_filetypes)
- let directory = xolox#misc#path#absolute(g:easytags_by_filetype)
- let tagsfile = xolox#misc#path#merge(directory, applicable_filetypes[0])
+ let directory = xolox#easytags#misc#path#absolute(g:easytags_by_filetype)
+ let tagsfile = xolox#easytags#misc#path#merge(directory, applicable_filetypes[0])
endif
" Default to the global tags file?
if empty(tagsfile)
- let tagsfile = expand(xolox#misc#option#get('easytags_file'))
+ let tagsfile = expand(xolox#easytags#misc#option#get('easytags_file'))
endif
" If the tags file exists, make sure it is writable!
if filereadable(tagsfile) && filewritable(tagsfile) != 1
@@ -733,7 +739,7 @@ function! s:create_context() " {{{2
endfunction
function! s:resolve(filename) " {{{2
- if xolox#misc#option#get('easytags_resolve_links', 0)
+ if xolox#easytags#misc#option#get('easytags_resolve_links', 0)
return resolve(a:filename)
else
return a:filename
@@ -769,7 +775,7 @@ function! s:python_available() " {{{2
endfunction
function! s:highlight_with_python(syntax_group, tagkind) " {{{2
- if xolox#misc#option#get('easytags_python_enabled', 1) && s:python_available()
+ if xolox#easytags#misc#option#get('easytags_python_enabled', 1) && s:python_available()
" Gather arguments for Python function.
let context = {}
let context['tagsfiles'] = tagfiles()
@@ -780,7 +786,7 @@ function! s:highlight_with_python(syntax_group, tagkind) " {{{2
let context['prefix'] = get(a:tagkind, 'pattern_prefix', '')
let context['suffix'] = get(a:tagkind, 'pattern_suffix', '')
let context['filters'] = get(a:tagkind, 'python_filter', {})
- let context['ignoresyntax'] = xolox#misc#option#get('easytags_ignored_syntax_groups')
+ let context['ignoresyntax'] = xolox#easytags#misc#option#get('easytags_ignored_syntax_groups')
" Call the Python function and intercept the output.
try
redir => commands
@@ -856,7 +862,7 @@ call xolox#easytags#define_tagkind({
highlight def link cEnum Identifier
highlight def link cFunction Function
-if xolox#misc#option#get('easytags_include_members', 0)
+if xolox#easytags#misc#option#get('easytags_include_members', 0)
call xolox#easytags#define_tagkind({
\ 'filetype': 'c',
\ 'hlgroup': 'cMember',
diff --git a/autoload/xolox/easytags/misc/buffer.vim b/autoload/xolox/easytags/misc/buffer.vim
new file mode 100644
index 0000000..7fbaff8
--- /dev/null
+++ b/autoload/xolox/easytags/misc/buffer.vim
@@ -0,0 +1,86 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Handling of special buffers
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 19, 2013
+" URL: http://peterodding.com/code/vim/misc/
+"
+" The functions defined here make it easier to deal with special Vim buffers
+" that contain text generated by a Vim plug-in. For example my [vim-notes
+" plug-in] [vim-notes] generates several such buffers:
+"
+" - [:RecentNotes] [RecentNotes] lists recently modified notes
+" - [:ShowTaggedNotes] [ShowTaggedNotes] lists notes grouped by tags
+" - etc.
+"
+" Because the text in these buffers is generated, Vim shouldn't bother with
+" swap files and it should never prompt the user whether to save changes to
+" the generated text.
+"
+" [vim-notes]: http://peterodding.com/code/vim/notes/
+" [RecentNotes]: http://peterodding.com/code/vim/notes/#recentnotes_command
+" [ShowTaggedNotes]: http://peterodding.com/code/vim/notes/#showtaggednotes_command
+
+function! xolox#easytags#misc#buffer#is_empty() " {{{1
+ " Checks if the current buffer is an empty, unchanged buffer which can be
+ " reused. Returns 1 if an empty buffer is found, 0 otherwise.
+ return !&modified && expand('%') == '' && line('$') <= 1 && getline(1) == ''
+endfunction
+
+function! xolox#easytags#misc#buffer#prepare(...) " {{{1
+ " Open a special buffer, i.e. a buffer that will hold generated contents,
+ " not directly edited by the user. The buffer can be customized by passing a
+ " dictionary with the following key/value pairs as the first argument:
+ "
+ " - **name** (required): The base name of the buffer (i.e. the base name of
+ " the file loaded in the buffer, even though it isn't really a file and
+ " nothing is really 'loaded' :-)
+ " - **path** (required): The pathname of the buffer. May be relevant if
+ " [:lcd] [lcd] or ['autochdir'] [acd] is being used.
+ "
+ " [lcd]: http://vimdoc.sourceforge.net/htmldoc/editing.html#:lcd
+ " [acd]: http://vimdoc.sourceforge.net/htmldoc/options.html#'autochdir'
+ if a:0 == 1 && type(a:1) == type('')
+ " Backwards compatibility with old interface.
+ let options = {'name': a:1, 'path': a:1}
+ elseif type(a:1) == type({})
+ let options = a:1
+ else
+ throw "Invalid arguments"
+ endif
+ let winnr = 1
+ let found = 0
+ for bufnr in tabpagebuflist()
+ if xolox#easytags#misc#path#equals(options['path'], bufname(bufnr))
+ execute winnr . 'wincmd w'
+ let found = 1
+ break
+ else
+ let winnr += 1
+ endif
+ endfor
+ if !(found || xolox#easytags#misc#buffer#is_empty())
+ vsplit
+ endif
+ silent execute 'edit' fnameescape(options['path'])
+ lcd " clear working directory
+ setlocal buftype=nofile bufhidden=hide noswapfile
+ let &l:statusline = '[' . options['name'] . ']'
+ call xolox#easytags#misc#buffer#unlock()
+ silent %delete
+endfunction
+
+function! xolox#easytags#misc#buffer#lock() " {{{1
+ " Lock a special buffer so that its contents can no longer be edited.
+ setlocal readonly nomodifiable nomodified
+endfunction
+
+function! xolox#easytags#misc#buffer#unlock() " {{{1
+ " Unlock a special buffer so that its content can be updated.
+ setlocal noreadonly modifiable
+endfunction
diff --git a/autoload/xolox/easytags/misc/complete.vim b/autoload/xolox/easytags/misc/complete.vim
new file mode 100644
index 0000000..d85e4ab
--- /dev/null
+++ b/autoload/xolox/easytags/misc/complete.vim
@@ -0,0 +1,28 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Tab completion for user defined commands.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 19, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+function! xolox#easytags#misc#complete#keywords(arglead, cmdline, cursorpos)
+ " This function can be used to perform keyword completion for user defined
+ " Vim commands based on the contents of the current buffer. Here's an
+ " example of how you would use it:
+ "
+ " :command -nargs=* -complete=customlist,xolox#easytags#misc#complete#keywords MyCmd call s:MyCmd(<f-args>)
+ let words = {}
+ for line in getline(1, '$')
+ for word in split(line, '\W\+')
+ let words[word] = 1
+ endfor
+ endfor
+ return sort(keys(filter(words, 'v:key =~# a:arglead')))
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/escape.vim b/autoload/xolox/easytags/misc/escape.vim
new file mode 100644
index 0000000..26839c8
--- /dev/null
+++ b/autoload/xolox/easytags/misc/escape.vim
@@ -0,0 +1,62 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" String escaping functions.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 19, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+function! xolox#easytags#misc#escape#pattern(string) " {{{1
+ " Takes a single string argument and converts it into a [:substitute]
+ " [subcmd] / [substitute()] [subfun] pattern string that matches the given
+ " string literally.
+ "
+ " [subfun]: http://vimdoc.sourceforge.net/htmldoc/eval.html#substitute()
+ " [subcmd]: http://vimdoc.sourceforge.net/htmldoc/change.html#:substitute
+ if type(a:string) == type('')
+ let string = escape(a:string, '^$.*\~[]')
+ return substitute(string, '\n', '\\n', 'g')
+ endif
+ return ''
+endfunction
+
+function! xolox#easytags#misc#escape#substitute(string) " {{{1
+ " Takes a single string argument and converts it into a [:substitute]
+ " [subcmd] / [substitute()] [subfun] replacement string that inserts the
+ " given string literally.
+ if type(a:string) == type('')
+ let string = escape(a:string, '\&~%')
+ return substitute(string, '\n', '\\r', 'g')
+ endif
+ return ''
+endfunction
+
+function! xolox#easytags#misc#escape#shell(string) " {{{1
+ " Takes a single string argument and converts it into a quoted command line
+ " argument.
+ "
+ " I was going to add a long rant here about Vim's ['shellslash' option]
+ " [shellslash], but really, it won't make any difference. Let's just suffice
+ " to say that I have yet to encounter a single person out there who uses
+ " this option for its intended purpose (running a UNIX style shell on
+ " Microsoft Windows).
+ "
+ " [shellslash]: http://vimdoc.sourceforge.net/htmldoc/options.html#'shellslash'
+ if xolox#easytags#misc#os#is_win()
+ try
+ let ssl_save = &shellslash
+ set noshellslash
+ return shellescape(a:string)
+ finally
+ let &shellslash = ssl_save
+ endtry
+ else
+ return shellescape(a:string)
+ endif
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/list.vim b/autoload/xolox/easytags/misc/list.vim
new file mode 100644
index 0000000..04bb6a8
--- /dev/null
+++ b/autoload/xolox/easytags/misc/list.vim
@@ -0,0 +1,63 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" List handling functions.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 19, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+function! xolox#easytags#misc#list#unique(list) " {{{1
+ " Remove duplicate values from the given list in-place (preserves order).
+ call reverse(a:list)
+ call filter(a:list, 'count(a:list, v:val) == 1')
+ return reverse(a:list)
+endfunction
+
+function! xolox#easytags#misc#list#binsert(list, value, ...) " {{{1
+ " Performs in-place binary insertion, which depending on your use case can
+ " be more efficient than calling Vim's [sort()] [sort] function after each
+ " insertion (in cases where a single, final sort is not an option). Expects
+ " three arguments:
+ "
+ " 1. A list
+ " 2. A value to insert
+ " 3. 1 (true) when case should be ignored, 0 (false) otherwise
+ "
+ " [sort]: http://vimdoc.sourceforge.net/htmldoc/eval.html#sort()
+ let idx = s:binsert_r(a:list, 0, len(a:list), a:value, exists('a:1') && a:1)
+ return insert(a:list, a:value, idx)
+endfunction
+
+function! s:binsert_r(list, low, high, value, ignorecase)
+ let mid = a:low + (a:high - a:low) / 2
+ if a:low == a:high
+ return a:low
+ elseif a:ignorecase ? a:value >? a:list[mid] : a:value > a:list[mid]
+ return s:binsert_r(a:list, mid + 1, a:high, a:value, a:ignorecase)
+ elseif a:ignorecase ? a:value <? a:list[mid] : a:value < a:list[mid]
+ return s:binsert_r(a:list, a:low, mid, a:value, a:ignorecase)
+ else
+ return mid
+ endif
+endfunction
+
+if 0
+ " Tests for xolox#easytags#misc#list#binsert().
+ let s:list = ['a', 'B', 'e']
+ function! s:test(value, expected)
+ call xolox#easytags#misc#list#binsert(s:list, a:value, 1)
+ if s:list != a:expected
+ call xolox#easytags#misc#msg#warn("list.vim: Test failed! Expected %s, got %s",
+ \ string(a:expected), string(s:list))
+ endif
+ endfunction
+ call s:test('c', ['a', 'B', 'c', 'e'])
+ call s:test('D', ['a', 'B', 'c', 'D', 'e'])
+ call s:test('f', ['a', 'B', 'c', 'D', 'e', 'f'])
+endif
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/msg.vim b/autoload/xolox/easytags/misc/msg.vim
new file mode 100644
index 0000000..c5a7fa4
--- /dev/null
+++ b/autoload/xolox/easytags/misc/msg.vim
@@ -0,0 +1,97 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Functions to interact with the user.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 20, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+if !exists('g:xolox_message_buffer')
+ " For when I lose my :messages history :-\
+ let g:xolox_message_buffer = 100
+endif
+
+if !exists('g:xolox_messages')
+ let g:xolox_messages = []
+endif
+
+function! xolox#easytags#misc#msg#info(...) " {{{1
+ " Show a formatted informational message to the user. This function has the
+ " same argument handling as Vim's [printf()] [printf] function.
+ "
+ " [printf]: http://vimdoc.sourceforge.net/htmldoc/eval.html#printf()
+ call s:show_message('title', a:000)
+endfunction
+
+function! xolox#easytags#misc#msg#warn(...) " {{{1
+ " Show a formatted warning message to the user. This function has the same
+ " argument handling as Vim's [printf()] [printf] function.
+ call s:show_message('warningmsg', a:000)
+endfunction
+
+function! xolox#easytags#misc#msg#debug(...) " {{{1
+ " Show a formatted debugging message to the user, if the user has enabled
+ " increased verbosity by setting Vim's ['verbose'] [verbose] option to one
+ " (1) or higher. This function has the same argument handling as Vim's
+ " [printf()] [printf] function.
+ if &vbs >= 1
+ call s:show_message('question', a:000)
+ endif
+endfunction
+
+function! s:show_message(hlgroup, args) " {{{1
+ " The implementation of info() and warn().
+ let nargs = len(a:args)
+ if nargs == 1
+ let message = a:args[0]
+ elseif nargs >= 2
+ let message = call('printf', a:args)
+ endif
+ if exists('message')
+ try
+ " Temporarily disable Vim's |hit-enter| prompt and mode display.
+ if !exists('s:more_save')
+ let s:more_save = &more
+ let s:ruler_save = &ruler
+ let s:smd_save = &showmode
+ endif
+ set nomore noshowmode
+ if winnr('$') == 1 | set noruler | endif
+ augroup PluginXoloxHideMode
+ autocmd! CursorHold,CursorHoldI * call s:clear_message()
+ augroup END
+ execute 'echohl' a:hlgroup
+ " Redraw to avoid |hit-enter| prompt.
+ redraw
+ for line in split(message, "\n")
+ echomsg line
+ endfor
+ if g:xolox_message_buffer > 0
+ call add(g:xolox_messages, message)
+ if len(g:xolox_messages) > g:xolox_message_buffer
+ call remove(g:xolox_messages, 0)
+ endif
+ endif
+ finally
+ " Always clear message highlighting, even when interrupted by Ctrl-C.
+ echohl none
+ endtry
+ endif
+endfunction
+
+function! s:clear_message() " {{{1
+ " Callback to clear message after some time has passed.
+ echo ''
+ let &more = s:more_save
+ let &showmode = s:smd_save
+ let &ruler = s:ruler_save
+ unlet s:more_save s:ruler_save s:smd_save
+ autocmd! PluginXoloxHideMode
+ augroup! PluginXoloxHideMode
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/open.vim b/autoload/xolox/easytags/misc/open.vim
new file mode 100644
index 0000000..254dc61
--- /dev/null
+++ b/autoload/xolox/easytags/misc/open.vim
@@ -0,0 +1,98 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Integration between Vim and its environment.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 19, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+if !exists('s:version')
+ let s:version = '1.1'
+ let s:enoimpl = "open.vim %s: %s() hasn't been implemented for your platform! If you have suggestions, please contact peter@peterodding.com."
+ let s:handlers = ['gnome-open', 'kde-open', 'exo-open', 'xdg-open']
+endif
+
+function! xolox#easytags#misc#open#file(path, ...) " {{{1
+ " Given a pathname as the first argument, this opens the file with the
+ " program associated with the file type. So for example a text file might
+ " open in Vim, an `*.html` file would probably open in your web browser and
+ " a media file would open in a media player.
+ "
+ " This should work on Windows, Mac OS X and most Linux distributions. If
+ " this fails to find a file association, you can pass one or more external
+ " commands to try as additional arguments. For example:
+ "
+ " :call xolox#easytags#misc#open#file('/path/to/my/file', 'firefox', 'google-chrome')
+ "
+ " This generally shouldn't be necessary but it might come in handy now and
+ " then.
+ if xolox#easytags#misc#os#is_win()
+ try
+ call xolox#shell#open_with_windows_shell(a:path)
+ catch /^Vim\%((\a\+)\)\=:E117/
+ let command = '!start CMD /C START "" %s'
+ silent execute printf(command, xolox#easytags#misc#escape#shell(a:path))
+ endtry
+ return
+ elseif has('macunix')
+ let cmd = 'open ' . shellescape(a:path) . ' 2>&1'
+ call s:handle_error(cmd, system(cmd))
+ return
+ else
+ for handler in s:handlers + a:000
+ if executable(handler)
+ call xolox#easytags#misc#msg#debug("open.vim %s: Using '%s' to open '%s'.", s:version, handler, a:path)
+ let cmd = shellescape(handler) . ' ' . shellescape(a:path) . ' 2>&1'
+ call s:handle_error(cmd, system(cmd))
+ return
+ endif
+ endfor
+ endif
+ throw printf(s:enoimpl, s:script, 'xolox#easytags#misc#open#file')
+endfunction
+
+function! xolox#easytags#misc#open#url(url) " {{{1
+ " Given a URL as the first argument, this opens the URL in your preferred or
+ " best available web browser:
+ "
+ " - In GUI environments a graphical web browser will open (or a new tab will
+ " be created in an existing window)
+ " - In console Vim without a GUI environment, when you have any of `lynx`,
+ " `links` or `w3m` installed it will launch a command line web browser in
+ " front of Vim (temporarily suspending Vim)
+ let url = a:url
+ if url !~ '^\w\+://'
+ if url !~ '@'
+ let url = 'http://' . url
+ elseif url !~ '^mailto:'
+ let url = 'mailto:' . url
+ endif
+ endif
+ if has('unix') && !has('gui_running') && $DISPLAY == ''
+ for browser in ['lynx', 'links', 'w3m']
+ if executable(browser)
+ execute '!' . browser fnameescape(url)
+ call s:handle_error(browser . ' ' . url, '')
+ return
+ endif
+ endfor
+ endif
+ call xolox#easytags#misc#open#file(url, 'firefox', 'google-chrome')
+endfunction
+
+function! s:handle_error(cmd, output) " {{{1
+ if v:shell_error
+ let message = "open.vim %s: Failed to execute program! (command line: %s%s)"
+ let output = strtrans(xolox#easytags#misc#str#trim(a:output))
+ if output != ''
+ let output = ", output: " . string(output)
+ endif
+ throw printf(message, s:version, a:cmd, output)
+ endif
+endfunction
+
+" vim: et ts=2 sw=2 fdm=marker
diff --git a/autoload/xolox/easytags/misc/option.vim b/autoload/xolox/easytags/misc/option.vim
new file mode 100644
index 0000000..3d49486
--- /dev/null
+++ b/autoload/xolox/easytags/misc/option.vim
@@ -0,0 +1,121 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Vim and plug-in option handling.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 19, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+function! xolox#easytags#misc#option#get(name, ...) " {{{1
+ " Expects one or two arguments: 1. The name of a variable and 2. the default
+ " value if the variable does not exist.
+ "
+ " Returns the value of the variable from a buffer local variable, global
+ " variable or the default value, depending on which is defined.
+ "
+ " This is used by some of my Vim plug-ins for option handling, so that users
+ " can customize options for specific buffers.
+ if exists('b:' . a:name)
+ " Buffer local variable.
+ return eval('b:' . a:name)
+ elseif exists('g:' . a:name)
+ " Global variable.
+ return eval('g:' . a:name)
+ elseif exists('a:1')
+ " Default value.
+ return a:1
+ endif
+endfunction
+
+function! xolox#easytags#misc#option#split(value) " {{{1
+ " Given a multi-value Vim option like ['runtimepath'] [rtp] this returns a
+ " list of strings. For example:
+ "
+ " :echo xolox#easytags#misc#option#split(&runtimepath)
+ " ['/home/peter/Projects/Vim/misc',
+ " '/home/peter/Projects/Vim/colorscheme-switcher',
+ " '/home/peter/Projects/Vim/easytags',
+ " ...]
+ "
+ " [rtp]: http://vimdoc.sourceforge.net/htmldoc/options.html#'runtimepath'
+ let values = split(a:value, '[^\\]\zs,')
+ return map(values, 's:unescape(v:val)')
+endfunction
+
+function! s:unescape(s)
+ return substitute(a:s, '\\\([\\,]\)', '\1', 'g')
+endfunction
+
+function! xolox#easytags#misc#option#join(values) " {{{1
+ " Given a list of strings like the ones returned by
+ " `xolox#easytags#misc#option#split()`, this joins the strings together into a
+ " single value that can be used to set a Vim option.
+ let values = copy(a:values)
+ call map(values, 's:escape(v:val)')
+ return join(values, ',')
+endfunction
+
+function! s:escape(s)
+ return escape(a:s, ',\')
+endfunction
+
+function! xolox#easytags#misc#option#split_tags(value) " {{{1
+ " Customized version of `xolox#easytags#misc#option#split()` with specialized
+ " handling for Vim's ['tags' option] [tags].
+ "
+ " [tags]: http://vimdoc.sourceforge.net/htmldoc/options.html#'tags'
+ let values = split(a:value, '[^\\]\zs,')
+ return map(values, 's:unescape_tags(v:val)')
+endfunction
+
+function! s:unescape_tags(s)
+ return substitute(a:s, '\\\([\\, ]\)', '\1', 'g')
+endfunction
+
+function! xolox#easytags#misc#option#join_tags(values) " {{{1
+ " Customized version of `xolox#easytags#misc#option#join()` with specialized
+ " handling for Vim's ['tags' option] [tags].
+ let values = copy(a:values)
+ call map(values, 's:escape_tags(v:val)')
+ return join(values, ',')
+endfunction
+
+function! s:escape_tags(s)
+ return escape(a:s, ', ')
+endfunction
+
+function! xolox#easytags#misc#option#eval_tags(value, ...) " {{{1
+ " Evaluate Vim's ['tags' option] [tags] without looking at the file
+ " system, i.e. this will report tags files that don't exist yet. Expects
+ " the value of the ['tags' option] [tags] as the first argument. If the
+ " optional second argument is 1 (true) only the first match is returned,
+ " otherwise (so by default) a list with all matches is returned.
+ let pathnames = []
+ let first_only = exists('a:1') ? a:1 : 0
+ for pattern in xolox#easytags#misc#option#split_tags(a:value)
+ " Make buffer relative pathnames absolute.
+ if pattern =~ '^\./'
+ let directory = xolox#easytags#misc#escape#substitute(expand('%:p:h'))
+ let pattern = substitute(pattern, '^.\ze/', directory, '')
+ endif
+ " Make working directory relative pathnames absolute.
+ if xolox#easytags#misc#path#is_relative(pattern)
+ let pattern = xolox#easytags#misc#path#merge(getcwd(), pattern)
+ endif
+ " Ignore the trailing `;' for recursive upwards searching because we
+ " always want the most specific pathname available.
+ let pattern = substitute(pattern, ';$', '', '')
+ " Expand the pattern.
+ call extend(pathnames, split(expand(pattern), "\n"))
+ if first_only && !empty(pathnames)
+ return pathnames[0]
+ endif
+ endfor
+ return first_only ? '' : pathnames
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/os.vim b/autoload/xolox/easytags/misc/os.vim
new file mode 100644
index 0000000..c2ef4f4
--- /dev/null
+++ b/autoload/xolox/easytags/misc/os.vim
@@ -0,0 +1,194 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Operating system interfaces.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 20, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+let g:xolox#easytags#misc#os#version = '0.5'
+
+function! xolox#easytags#misc#os#is_win() " {{{1
+ " Returns 1 (true) when on Microsoft Windows, 0 (false) otherwise.
+ return has('win16') || has('win32') || has('win64')
+endfunction
+
+function! xolox#easytags#misc#os#find_vim() " {{{1
+ " Returns the program name of Vim as a string. On Windows and UNIX this
+ " simply returns [v:progname] [progname] while on Mac OS X there is some
+ " special magic to find MacVim's executable even though it's usually not on
+ " the executable search path.
+ "
+ " [progname]: http://vimdoc.sourceforge.net/htmldoc/eval.html#v:progname
+ let progname = ''
+ if has('macunix')
+ " Special handling for Mac OS X where MacVim is usually not on the $PATH.
+ call xolox#easytags#misc#msg#debug("os.vim %s: Trying MacVim workaround to find Vim executable ..", g:xolox#easytags#misc#os#version)
+ let segments = xolox#easytags#misc#path#split($VIMRUNTIME)
+ if segments[-3:] == ['Resources', 'vim', 'runtime']
+ let progname = xolox#easytags#misc#path#join(segments[0:-4] + ['MacOS', 'Vim'])
+ call xolox#easytags#misc#msg#debug("os.vim %s: The MacVim workaround resulted in the Vim executable %s.", g:xolox#easytags#misc#os#version, string(progname))
+ endif
+ endif
+ if empty(progname)
+ call xolox#easytags#misc#msg#debug("os.vim %s: Looking for Vim executable named %s on search path ..", g:xolox#easytags#misc#os#version, string(v:progname))
+ let candidates = xolox#easytags#misc#path#which(v:progname)
+ if !empty(candidates)
+ call xolox#easytags#misc#msg#debug("os.vim %s: Found %i candidate(s) on search path: %s.", g:xolox#easytags#misc#os#version, len(candidates), string(candidates))
+ let progname = candidates[0]
+ endif
+ endif
+ call xolox#easytags#misc#msg#debug("os.vim %s: Reporting Vim executable %s.", g:xolox#easytags#misc#os#version, string(progname))
+ return progname
+endfunction
+
+function! xolox#easytags#misc#os#exec(options) " {{{1
+ " 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.
+ 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#easytags#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#easytags#misc#escape#shell(tempout), xolox#easytags#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#easytags#misc#msg#debug("os.vim %s: Executing external command using compiled DLL: %s", g:xolox#easytags#misc#os#version, cmd)
+ let exit_code = xolox#shell#execute_with_dll({'command': cmd, 'async': async})
+ endif
+ catch /^Vim\%((\a\+)\)\=:E117/
+ call xolox#easytags#misc#msg#debug("os.vim %s: The vim-shell plug-in is not installed, falling back to system() function.", g:xolox#easytags#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#easytags#misc#os#is_win()
+ let cmd = 'start /b ' . cmd
+ elseif has('unix')
+ let cmd = '(' . cmd . ') &'
+ else
+ call xolox#easytags#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#easytags#misc#os#version)
+ 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#easytags#misc#msg#debug("os.vim %s: Generated shell expression: %s", g:xolox#easytags#misc#os#version, cmd)
+ let cmd = printf('sh -c %s', xolox#easytags#misc#escape#shell(cmd))
+ endif
+
+ " Let the user know what's happening (in case they're interested).
+ call xolox#easytags#misc#msg#debug("os.vim %s: Executing external command using system() function: %s", g:xolox#easytags#misc#os#version, cmd)
+ call system(cmd)
+ let exit_code = v:shell_error
+
+ endif
+
+ " 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
+ " 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#easytags#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
+ 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
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/path.vim b/autoload/xolox/easytags/misc/path.vim
new file mode 100644
index 0000000..f4a774d
--- /dev/null
+++ b/autoload/xolox/easytags/misc/path.vim
@@ -0,0 +1,262 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Pathname manipulation functions.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 20, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+let s:windows_compatible = xolox#easytags#misc#os#is_win()
+let s:mac_os_x_compatible = has('macunix')
+
+function! xolox#easytags#misc#path#which(...) " {{{1
+ " Scan the executable search path (`$PATH`) for one or more external
+ " programs. Expects one or more string arguments with program names. Returns
+ " a list with the absolute pathnames of all found programs. Here's an
+ " example:
+ "
+ " :echo xolox#easytags#misc#path#which('gvim', 'vim')
+ " ['/usr/local/bin/gvim',
+ " '/usr/bin/gvim',
+ " '/usr/local/bin/vim',
+ " '/usr/bin/vim']
+ let extensions = ['']
+ if s:windows_compatible
+ call extend(extensions, split($PATHEXT, ';'))
+ endif
+ let matches = []
+ let checked = {}
+ for program in a:000
+ for extension in extensions
+ for directory in split($PATH, s:windows_compatible ? ';' : ':')
+ let directory = xolox#easytags#misc#path#absolute(directory)
+ if isdirectory(directory)
+ let path = xolox#easytags#misc#path#merge(directory, program . extension)
+ if executable(path)
+ call add(matches, path)
+ endif
+ endif
+ endfor
+ endfor
+ endfor
+ return matches
+endfunction
+
+function! xolox#easytags#misc#path#split(path) " {{{1
+ " Split a pathname (the first and only argument) into a list of pathname
+ " components.
+ "
+ " On Windows, pathnames starting with two slashes or backslashes are UNC
+ " paths where the leading slashes are significant... In this case we split
+ " like this:
+ "
+ " - Input: `'//server/share/directory'`
+ " - Result: `['//server', 'share', 'directory']`
+ "
+ " Everything except Windows is treated like UNIX until someone has a better
+ " suggestion :-). In this case we split like this:
+ "
+ " - Input: `'/foo/bar/baz'`
+ " - Result: `['/', 'foo', 'bar', 'baz']`
+ "
+ " To join a list of pathname components back into a single pathname string,
+ " use the `xolox#easytags#misc#path#join()` function.
+ if type(a:path) == type('')
+ if s:windows_compatible
+ if a:path =~ '^[\/][\/]'
+ " UNC pathname.
+ return split(a:path, '\%>2c[\/]\+')
+ else
+ " If it's not a UNC path we can simply split on slashes & backslashes.
+ return split(a:path, '[\/]\+')
+ endif
+ else
+ " Everything else is treated as UNIX.
+ let absolute = (a:path =~ '^/')
+ let segments = split(a:path, '/\+')
+ return absolute ? insert(segments, '/') : segments
+ endif
+ endif
+ return []
+endfunction
+
+function! xolox#easytags#misc#path#join(parts) " {{{1
+ " Join a list of pathname components (the first and only argument) into a
+ " single pathname string. This is the counterpart to the
+ " `xolox#easytags#misc#path#split()` function and it expects a list of pathname
+ " components as returned by `xolox#easytags#misc#path#split()`.
+ if type(a:parts) == type([])
+ if s:windows_compatible
+ return join(a:parts, xolox#easytags#misc#path#directory_separator())
+ elseif a:parts[0] == '/'
+ " Absolute path on UNIX (non-Windows).
+ return '/' . join(a:parts[1:], '/')
+ else
+ " Relative path on UNIX (non-Windows).
+ return join(a:parts, '/')
+ endif
+ endif
+ return ''
+endfunction
+
+function! xolox#easytags#misc#path#directory_separator() " {{{1
+ " Find the preferred directory separator for the platform and settings.
+ return exists('+shellslash') && &shellslash ? '/' : '\'
+endfunction
+
+function! xolox#easytags#misc#path#absolute(path) " {{{1
+ " Canonicalize and resolve a pathname, *regardless of whether it exists*.
+ " This is intended to support string comparison to determine whether two
+ " pathnames point to the same directory or file.
+ if type(a:path) == type('')
+ let path = a:path
+ " Make the pathname absolute.
+ if path =~ '^\~'
+ " Expand ~ to $HOME.
+ let path = $HOME . '/' . path[1:]
+ elseif xolox#easytags#misc#path#is_relative(path)
+ " Make relative pathnames absolute.
+ let path = getcwd() . '/' . path
+ endif
+ " Resolve symbolic links to find the canonical pathname. In my tests this
+ " also removes all symbolic pathname segments (`.' and `..'), even when
+ " the pathname does not exist. Also there used to be a bug in resolve()
+ " where it wouldn't resolve pathnames ending in a directory separator.
+ " Since it's not much trouble to work around, that's what we do.
+ let path = resolve(substitute(path, s:windows_compatible ? '[\/]\+$' : '/\+$', '', ''))
+ " Normalize directory separators (especially relevant on Windows).
+ let parts = xolox#easytags#misc#path#split(path)
+ if s:windows_compatible && parts[0] =~ '^[\/][\/]'
+ " Also normalize the two leading "directory separators" (I'm not
+ " sure what else to call them :-) in Windows UNC pathnames.
+ let parts[0] = repeat(xolox#easytags#misc#path#directory_separator(), 2) . parts[0][2:]
+ endif
+ return xolox#easytags#misc#path#join(parts)
+ endif
+ return ''
+endfunction
+
+function! xolox#easytags#misc#path#relative(path, base) " {{{1
+ " Make an absolute pathname (the first argument) relative to a directory
+ " (the second argument).
+ let path = xolox#easytags#misc#path#split(a:path)
+ let base = xolox#easytags#misc#path#split(a:base)
+ while path != [] && base != [] && path[0] == base[0]
+ call remove(path, 0)
+ call remove(base, 0)
+ endwhile
+ let distance = repeat(['..'], len(base))
+ return xolox#easytags#misc#path#join(distance + path)
+endfunction
+
+
+function! xolox#easytags#misc#path#merge(parent, child, ...) " {{{1
+ " Join a directory pathname and filename into a single pathname.
+ if type(a:parent) == type('') && type(a:child) == type('')
+ " TODO Use xolox#easytags#misc#path#is_relative()?
+ if s:windows_compatible
+ let parent = substitute(a:parent, '[\\/]\+$', '', '')
+ let child = substitute(a:child, '^[\\/]\+', '', '')
+ return parent . '\' . child
+ else
+ let parent = substitute(a:parent, '/\+$', '', '')
+ let child = substitute(a:child, '^/\+', '', '')
+ return parent . '/' . child
+ endif
+ endif
+ return ''
+endfunction
+
+function! xolox#easytags#misc#path#commonprefix(paths) " {{{1
+ " Find the common prefix of path components in a list of pathnames.
+ let common = xolox#easytags#misc#path#split(a:paths[0])
+ for path in a:paths
+ let index = 0
+ for segment in xolox#easytags#misc#path#split(path)
+ if len(common) <= index
+ break
+ elseif common[index] != segment
+ call remove(common, index, -1)
+ break
+ endif
+ let index += 1
+ endfor
+ endfor
+ return xolox#easytags#misc#path#join(common)
+endfunction
+
+function! xolox#easytags#misc#path#encode(path) " {{{1
+ " Encode a pathname so it can be used as a filename. This uses URL encoding
+ " to encode special characters.
+ if s:windows_compatible
+ let mask = '[*|\\/:"<>?%]'
+ elseif s:mac_os_x_compatible
+ let mask = '[\\/%:]'
+ else
+ let mask = '[\\/%]'
+ endif
+ return substitute(a:path, mask, '\=printf("%%%x", char2nr(submatch(0)))', 'g')
+endfunction
+
+
+function! xolox#easytags#misc#path#decode(encoded_path) " {{{1
+ " Decode a pathname previously encoded with `xolox#easytags#misc#path#encode()`.
+ return substitute(a:encoded_path, '%\(\x\x\?\)', '\=nr2char("0x" . submatch(1))', 'g')
+endfunction
+
+" xolox#easytags#misc#path#equals(a, b) - Check whether two pathnames point to the same file. {{{1
+
+if s:windows_compatible
+ function! xolox#easytags#misc#path#equals(a, b)
+ return a:a ==? a:b || xolox#easytags#misc#path#absolute(a:a) ==? xolox#easytags#misc#path#absolute(a:b)
+ endfunction
+else
+ function! xolox#easytags#misc#path#equals(a, b)
+ return a:a ==# a:b || xolox#easytags#misc#path#absolute(a:a) ==# xolox#easytags#misc#path#absolute(a:b)
+ endfunction
+endif
+
+function! xolox#easytags#misc#path#is_relative(path) " {{{1
+ " Returns true (1) when the pathname given as the first argument is
+ " relative, false (0) otherwise.
+ if a:path =~ '^\w\+://'
+ return 0
+ elseif s:windows_compatible
+ return a:path !~ '^\(\w:\|[\\/]\)'
+ else
+ return a:path !~ '^/'
+ endif
+endfunction
+
+function! xolox#easytags#misc#path#tempdir() " {{{1
+ " Create a temporary directory and return the pathname of the directory.
+ if !exists('s:tempdir_counter')
+ let s:tempdir_counter = 1
+ endif
+ if exists('*mkdir')
+ if s:windows_compatible
+ let template = $TMP . '\vim_tempdir_'
+ elseif filewritable('/tmp') == 2
+ let template = '/tmp/vim_tempdir_'
+ endif
+ endif
+ if !exists('template')
+ throw "xolox#easytags#misc#path#tempdir() hasn't been implemented on your platform!"
+ endif
+ while 1
+ let directory = template . s:tempdir_counter
+ try
+ call mkdir(directory, '', 0700)
+ return directory
+ catch /\<E739\>/
+ " Keep looking for a non-existing directory.
+ endtry
+ let s:tempdir_counter += 1
+ endwhile
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/str.vim b/autoload/xolox/easytags/misc/str.vim
new file mode 100644
index 0000000..7eba730
--- /dev/null
+++ b/autoload/xolox/easytags/misc/str.vim
@@ -0,0 +1,24 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" String handling.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 19, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+function! xolox#easytags#misc#str#compact(s)
+ " Compact whitespace in the string given as the first argument.
+ return join(split(a:s), " ")
+endfunction
+
+function! xolox#easytags#misc#str#trim(s)
+ " Trim all whitespace from the start and end of the string given as the
+ " first argument.
+ return substitute(a:s, '^\_s*\(.\{-}\)\_s*$', '\1', '')
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/autoload/xolox/easytags/misc/timer.vim b/autoload/xolox/easytags/misc/timer.vim
new file mode 100644
index 0000000..0cb17cb
--- /dev/null
+++ b/autoload/xolox/easytags/misc/timer.vim
@@ -0,0 +1,109 @@
+" This Vim script was modified by a Python script that I use to manage the
+" inclusion of miscellaneous functions in the plug-ins that I publish to Vim
+" Online and GitHub. Please don't edit this file, instead make your changes on
+" the 'dev' branch of the git repository (thanks!). This file was generated on
+" May 23, 2013 at 20:08.
+
+" Timing of long during operations.
+"
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: May 20, 2013
+" URL: http://peterodding.com/code/vim/misc/
+
+if !exists('g:timer_enabled')
+ let g:timer_enabled = 0
+endif
+
+if !exists('g:timer_verbosity')
+ let g:timer_verbosity = 1
+endif
+
+let s:has_reltime = has('reltime')
+
+function! xolox#easytags#misc#timer#start() " {{{1
+ " Start a timer. This returns a list which can later be passed to
+ " `xolox#easytags#misc#timer#stop()`.
+ return s:has_reltime ? reltime() : [localtime()]
+endfunction
+
+function! xolox#easytags#misc#timer#stop(...) " {{{1
+ " Show a formatted debugging message to the user, if the user has enabled
+ " increased verbosity by setting Vim's ['verbose'] [verbose] option to one
+ " (1) or higher.
+ "
+ " This function has the same argument handling as Vim's [printf()] [printf]
+ " function with one difference: At the point where you want the elapsed time
+ " to be embedded, you write `%s` and you pass the list returned by
+ " `xolox#easytags#misc#timer#start()` as an argument.
+ "
+ " [verbose]: http://vimdoc.sourceforge.net/htmldoc/options.html#'verbose'
+ " [printf]: http://vimdoc.sourceforge.net/htmldoc/eval.html#printf()
+ if (g:timer_enabled || &verbose >= g:timer_verbosity)
+ call call('xolox#easytags#misc#msg#info', map(copy(a:000), 's:convert_value(v:val)'))
+ endif
+endfunction
+
+function! xolox#easytags#misc#timer#force(...) " {{{1
+ " Show a formatted message to the user. This function has the same argument
+ " handling as Vim's [printf()] [printf] function with one difference: At the
+ " point where you want the elapsed time to be embedded, you write `%s` and
+ " you pass the list returned by `xolox#easytags#misc#timer#start()` as an argument.
+ call call('xolox#easytags#misc#msg#info', map(copy(a:000), 's:convert_value(v:val)'))
+endfunction
+
+function! s:convert_value(value) " {{{1
+ if type(a:value) != type([])
+ return a:value
+ elseif !empty(a:value)
+ if s:has_reltime
+ let ts = xolox#easytags#misc#str#trim(reltimestr(reltime(a:value)))
+ else
+ let ts = localtime() - a:value[0]
+ endif
+ return xolox#easytags#misc#timer#format_timespan(ts)
+ else
+ return '?'
+ endif
+endfunction
+
+" Format number of seconds as human friendly description.
+
+let s:units = [['day', 60 * 60 * 24], ['hour', 60 * 60], ['minute', 60], ['second', 1]]
+
+function! xolox#easytags#misc#timer#format_timespan(ts) " {{{1
+ " Format a time stamp (a string containing a formatted floating point
+ " number) into a human friendly format, for example 70 seconds is phrased as
+ " "1 minute and 10 seconds".
+
+ " Convert timespan to integer.
+ let seconds = a:ts + 0
+
+ " Fast common case with extra precision from reltime().
+ if seconds < 5
+ let extract = matchstr(a:ts, '^\d\+\(\.0*[1-9][1-9]\?\)\?')
+ if extract =~ '[123456789]'
+ return extract . ' second' . (extract != '1' ? 's' : '')
+ endif
+ endif
+
+ " Generic but slow code.
+ let result = []
+ for [name, size] in s:units
+ if seconds >= size
+ let counter = seconds / size
+ let seconds = seconds % size
+ let suffix = counter != 1 ? 's' : ''
+ call add(result, printf('%i %s%s', counter, name, suffix))
+ endif
+ endfor
+
+ " Format the resulting text?
+ if len(result) == 1
+ return result[0]
+ else
+ return join(result[0:-2], ', ') . ' and ' . result[-1]
+ endif
+
+endfunction
+
+" vim: ts=2 sw=2 et