diff options
-rw-r--r-- | autoload/xolox/misc/README.md | 13 | ||||
-rw-r--r-- | autoload/xolox/misc/complete.vim | 18 | ||||
-rw-r--r-- | autoload/xolox/misc/escape.vim | 26 | ||||
-rw-r--r-- | autoload/xolox/misc/list.vim | 23 | ||||
-rw-r--r-- | autoload/xolox/misc/msg.vim | 83 | ||||
-rw-r--r-- | autoload/xolox/misc/option.vim | 46 | ||||
-rw-r--r-- | autoload/xolox/misc/os.vim | 12 | ||||
-rw-r--r-- | autoload/xolox/misc/path.vim | 158 | ||||
-rw-r--r-- | autoload/xolox/misc/str.vim | 12 | ||||
-rw-r--r-- | autoload/xolox/misc/timer.vim | 85 |
10 files changed, 476 insertions, 0 deletions
diff --git a/autoload/xolox/misc/README.md b/autoload/xolox/misc/README.md new file mode 100644 index 0000000..d305ddd --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/complete.vim b/autoload/xolox/misc/complete.vim new file mode 100644 index 0000000..2ada676 --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/escape.vim b/autoload/xolox/misc/escape.vim new file mode 100644 index 0000000..a698ae0 --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/list.vim b/autoload/xolox/misc/list.vim new file mode 100644 index 0000000..8857af1 --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/msg.vim b/autoload/xolox/misc/msg.vim new file mode 100644 index 0000000..9ba2b7c --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/option.vim b/autoload/xolox/misc/option.vim new file mode 100644 index 0000000..f785e1b --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/os.vim b/autoload/xolox/misc/os.vim new file mode 100644 index 0000000..0852e2d --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/path.vim b/autoload/xolox/misc/path.vim new file mode 100644 index 0000000..2b4510f --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/str.vim b/autoload/xolox/misc/str.vim new file mode 100644 index 0000000..19bfe09 --- /dev/null +++ b/autoload/xolox/misc/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/autoload/xolox/misc/timer.vim b/autoload/xolox/misc/timer.vim new file mode 100644 index 0000000..151972d --- /dev/null +++ b/autoload/xolox/misc/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 |