aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Odding <peter@peterodding.com>2011-03-15 23:00:55 +0100
committerPeter Odding <peter@peterodding.com>2011-03-15 23:00:55 +0100
commita205f918f5797d9183f7f479360ed91bbce2b388 (patch)
treed2cf19205d9cd875a463b6835cd249cd183f9d28
downloadvim-easytags-a205f918f5797d9183f7f479360ed91bbce2b388.tar.gz
Initial commit
-rw-r--r--README.md13
-rw-r--r--complete.vim18
-rw-r--r--escape.vim26
-rw-r--r--list.vim23
-rw-r--r--msg.vim83
-rw-r--r--option.vim46
-rw-r--r--os.vim12
-rw-r--r--path.vim158
-rw-r--r--str.vim12
-rw-r--r--timer.vim85
10 files changed, 476 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d305ddd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# Miscellaneous auto-load Vim scripts
+
+The git repository at <http://github.com/xolox/vim-misc> contains Vim scripts
+that are used by most of the [Vim plug-ins I've written] [plugins] yet don't
+really belong with any single one. I'm hoping to include this repository as a
+git submodule in my other repositories so that I only have to maintain these
+files in one place.
+
+For lack of a better place: I hereby release these scripts under the MIT
+license, in other words feel free to do with them as you please but don't
+misrepresent this work as your own.
+
+[plugins]: http://peterodding.com/code/vim/
diff --git a/complete.vim b/complete.vim
new file mode 100644
index 0000000..2ada676
--- /dev/null
+++ b/complete.vim
@@ -0,0 +1,18 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Keyword completion from the current buffer for user defined commands.
+
+function! xolox#misc#complete#keywords(arglead, cmdline, cursorpos)
+ 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/escape.vim b/escape.vim
new file mode 100644
index 0000000..a698ae0
--- /dev/null
+++ b/escape.vim
@@ -0,0 +1,26 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Convert a string into a :substitute pattern that matches the string literally.
+
+function! xolox#misc#escape#pattern(string)
+ if type(a:string) == type('')
+ let string = escape(a:string, '^$.*\~[]')
+ return substitute(string, '\n', '\\n', 'g')
+ endif
+ return ''
+endfunction
+
+" Convert a string into a :substitute replacement that inserts the string literally.
+
+function! xolox#misc#escape#substitute(string)
+ if type(a:string) == type('')
+ let string = escape(a:string, '\&~%')
+ return substitute(string, '\n', '\\r', 'g')
+ endif
+ return ''
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/list.vim b/list.vim
new file mode 100644
index 0000000..8857af1
--- /dev/null
+++ b/list.vim
@@ -0,0 +1,23 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Remove duplicate values from {list} in-place (preserves order).
+
+function! xolox#misc#list#unique(list)
+ let index = 0
+ while index < len(a:list)
+ let value = a:list[index]
+ let match = index(a:list, value, index+1)
+ if match >= 0
+ call remove(a:list, match)
+ else
+ let index += 1
+ endif
+ unlet value
+ endwhile
+ return a:list
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/msg.vim b/msg.vim
new file mode 100644
index 0000000..9ba2b7c
--- /dev/null
+++ b/msg.vim
@@ -0,0 +1,83 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" 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
+
+" Show a formatted informational message to the user.
+
+function! xolox#misc#msg#info(...)
+ call s:show_message('title', a:000)
+endfunction
+
+" Show a formatted warning message to the user.
+
+function! xolox#misc#msg#warn(...)
+ call s:show_message('warningmsg', a:000)
+endfunction
+
+" Show a formatted debugging message to the user?
+
+function! xolox#misc#msg#debug(...)
+ if &vbs >= 1
+ call s:show_message('question', a:000)
+ endif
+endfunction
+
+" The implementation of info() and warn().
+
+function! s:show_message(hlgroup, args)
+ 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 | echomsg message
+ 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()
+ 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/option.vim b/option.vim
new file mode 100644
index 0000000..f785e1b
--- /dev/null
+++ b/option.vim
@@ -0,0 +1,46 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Functions to parse multi-valued Vim options like &tags and &runtimepath.
+
+function! xolox#misc#option#split(value)
+ 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#misc#option#join(values)
+ 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#misc#option#split_tags(value)
+ 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#misc#option#join_tags(values)
+ 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
+
+" vim: ts=2 sw=2 et
diff --git a/os.vim b/os.vim
new file mode 100644
index 0000000..0852e2d
--- /dev/null
+++ b/os.vim
@@ -0,0 +1,12 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Check whether Vim is running on Microsoft Windows.
+
+function! xolox#misc#os#is_win()
+ return has('win16') || has('win32') || has('win64')
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/path.vim b/path.vim
new file mode 100644
index 0000000..2b4510f
--- /dev/null
+++ b/path.vim
@@ -0,0 +1,158 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+let s:windows_compatible = has('win32') || has('win64')
+
+" Split a pathname into a list of path components.
+
+function! xolox#misc#path#split(path)
+ if type(a:path) == type('')
+ if s:windows_compatible
+ return split(a:path, '[\/]\+')
+ else
+ let absolute = (a:path =~ '^/')
+ let segments = split(a:path, '/\+')
+ return absolute ? insert(segments, '/') : segments
+ endif
+ endif
+ return []
+endfunction
+
+" Join a list of path components into a pathname.
+
+function! xolox#misc#path#join(parts)
+ if type(a:parts) == type([])
+ if !s:windows_compatible && a:parts[0] == '/'
+ return join(a:parts, '/')[1 : -1]
+ else
+ return join(a:parts, '/')
+ endif
+ endif
+ return ''
+endfunction
+
+" Canonicalize and resolve a pathname.
+
+function! xolox#misc#path#absolute(path)
+ if type(a:path) == type('')
+ let path = fnamemodify(a:path, ':p')
+ " resolve() doesn't work when there's a trailing path separator.
+ if path =~ '/$'
+ let stripped_slash = 1
+ let path = substitute(path, '/$', '', '')
+ endif
+ let path = resolve(path)
+ " Restore the path separator after calling resolve().
+ if exists('stripped_slash') && path !~ '/$'
+ let path .= '/'
+ endif
+ return path
+ endif
+ return ''
+endfunction
+
+" Make an absolute pathname relative.
+
+function! xolox#misc#path#relative(path, base)
+ let path = xolox#misc#path#split(a:path)
+ let base = xolox#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#misc#path#join(distance + path)
+endfunction
+
+" Join a directory and filename into a single pathname.
+
+function! xolox#misc#path#merge(parent, child, ...)
+ if type(a:parent) == type('') && type(a:child) == type('')
+ 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
+
+" Find the common prefix of path components in a list of pathnames.
+
+function! xolox#misc#path#commonprefix(paths)
+ let common = xolox#misc#path#split(a:paths[0])
+ for path in a:paths
+ let index = 0
+ for segment in xolox#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#misc#path#join(common)
+endfunction
+
+" Encode a pathname so it can be used as a filename.
+
+function! xolox#misc#path#encode(path)
+ let mask = s:windows_compatible ? '[*|\\/:"<>?%]' : '[\\/%]'
+ return substitute(a:path, mask, '\=printf("%%%x", char2nr(submatch(0)))', 'g')
+endfunction
+
+" Decode a pathname previously encoded with xolox#misc#path#encode().
+
+function! xolox#misc#path#decode(encoded_path)
+ return substitute(a:encoded_path, '%\(\x\x\?\)', '\=nr2char("0x" . submatch(1))', 'g')
+endfunction
+
+" Check whether two pathnames point to the same file.
+
+if s:windows_compatible
+ function! xolox#misc#path#equals(a, b)
+ return a:a ==? a:b || xolox#misc#path#absolute(a:a) ==? xolox#misc#path#absolute(a:b)
+ endfunction
+else
+ function! xolox#misc#path#equals(a, b)
+ return a:a ==# a:b || xolox#misc#path#absolute(a:a) ==# xolox#misc#path#absolute(a:b)
+ endfunction
+endif
+
+" Create a temporary directory and return the path.
+
+function! xolox#misc#path#tempdir()
+ 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#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/str.vim b/str.vim
new file mode 100644
index 0000000..19bfe09
--- /dev/null
+++ b/str.vim
@@ -0,0 +1,12 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" URL: http://peterodding.com/code/vim/misc/
+
+" Trim whitespace from start and end of string.
+
+function! xolox#misc#str#trim(s)
+ return substitute(a:s, '^\s*\(.\{-}\)\s*$', '\1', '')
+endfunction
+
+" vim: ts=2 sw=2 et
diff --git a/timer.vim b/timer.vim
new file mode 100644
index 0000000..151972d
--- /dev/null
+++ b/timer.vim
@@ -0,0 +1,85 @@
+" Vim auto-load script
+" Author: Peter Odding <peter@peterodding.com>
+" Last Change: March 15, 2011
+" 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')
+
+" Start a timer.
+
+function! xolox#misc#timer#start()
+ if g:timer_enabled || &verbose >= g:timer_verbosity
+ return s:has_reltime ? reltime() : [localtime()]
+ endif
+ return []
+endfunction
+
+" Stop a timer and print the elapsed time (only if the user is interested).
+
+function! xolox#misc#timer#stop(...)
+ if (g:timer_enabled || &verbose >= g:timer_verbosity)
+ call call('xolox#misc#msg#info', map(copy(a:000), 's:convert_value(v:val)'))
+ endif
+endfunction
+
+function! s:convert_value(value)
+ if type(a:value) != type([])
+ return a:value
+ elseif !empty(a:value)
+ if s:has_reltime
+ let ts = xolox#misc#str#trim(reltimestr(reltime(a:value)))
+ else
+ let ts = localtime() - a:value[0]
+ endif
+ return xolox#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#misc#timer#format_timespan(ts)
+
+ " 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