From a205f918f5797d9183f7f479360ed91bbce2b388 Mon Sep 17 00:00:00 2001 From: Peter Odding Date: Tue, 15 Mar 2011 23:00:55 +0100 Subject: Initial commit --- README.md | 13 +++++ complete.vim | 18 +++++++ escape.vim | 26 ++++++++++ list.vim | 23 +++++++++ msg.vim | 83 +++++++++++++++++++++++++++++++ option.vim | 46 +++++++++++++++++ os.vim | 12 +++++ path.vim | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ str.vim | 12 +++++ timer.vim | 85 ++++++++++++++++++++++++++++++++ 10 files changed, 476 insertions(+) create mode 100644 README.md create mode 100644 complete.vim create mode 100644 escape.vim create mode 100644 list.vim create mode 100644 msg.vim create mode 100644 option.vim create mode 100644 os.vim create mode 100644 path.vim create mode 100644 str.vim create mode 100644 timer.vim 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 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 +" 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 +" 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 +" 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 +" 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 +" 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 +" 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 +" 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 /\/ + " 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 +" 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 +" 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 -- cgit v1.2.3