- Vitalized.

This commit is contained in:
Shougo Matsushita 2012-09-30 17:06:28 +09:00
parent cb51dd674d
commit c07fdec557
6 changed files with 547 additions and 85 deletions

View File

@ -1,7 +1,7 @@
"=============================================================================
" FILE: util.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
" Last Modified: 28 Sep 2012.
" Last Modified: 30 Sep 2012.
" License: MIT license {{{
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
@ -27,108 +27,34 @@
let s:save_cpo = &cpo
set cpo&vim
let s:V = vital#of('neocomplcache')
let s:List = vital#of('neocomplcache').import('Data.List')
let s:V = vital#of('neosnippet')
function! neocomplcache#util#truncate_smart(...)"{{{
return call(s:V.truncate_smart, a:000)
endfunction"}}}
function! neocomplcache#util#truncate(...)"{{{
return call(s:V.truncate, a:000)
endfunction"}}}
function! neocomplcache#util#strchars(...)"{{{
return call(s:V.strchars, a:000)
endfunction"}}}
function! neocomplcache#util#wcswidth(...)"{{{
return call(s:V.wcswidth, a:000)
endfunction"}}}
function! neocomplcache#util#strwidthpart(...)"{{{
return call(s:V.strwidthpart, a:000)
endfunction"}}}
function! neocomplcache#util#strwidthpart_reverse(...)"{{{
return call(s:V.strwidthpart_reverse, a:000)
endfunction"}}}
function! neocomplcache#util#substitute_path_separator(...)"{{{
function! neosnippet#util#substitute_path_separator(...)"{{{
return call(s:V.substitute_path_separator, a:000)
endfunction"}}}
function! neocomplcache#util#mb_strlen(...)"{{{
return call(s:V.strchars, a:000)
endfunction"}}}
function! neocomplcache#util#uniq(list)"{{{
let dict = {}
for item in a:list
if !has_key(dict, item)
let dict[item] = item
endif
endfor
return values(dict)
endfunction"}}}
function! neocomplcache#util#system(...)"{{{
function! neosnippet#util#system(...)"{{{
return call(s:V.system, a:000)
endfunction"}}}
function! neocomplcache#util#has_vimproc(...)"{{{
function! neosnippet#util#has_vimproc(...)"{{{
return call(s:V.has_vimproc, a:000)
endfunction"}}}
function! neocomplcache#util#is_windows(...)"{{{
function! neosnippet#util#is_windows(...)"{{{
return call(s:V.is_windows, a:000)
endfunction"}}}
function! neocomplcache#util#is_mac(...)"{{{
function! neosnippet#util#is_mac(...)"{{{
return call(s:V.is_mac, a:000)
endfunction"}}}
function! neocomplcache#util#get_last_status(...)"{{{
function! neosnippet#util#get_last_status(...)"{{{
return call(s:V.get_last_status, a:000)
endfunction"}}}
function! neocomplcache#util#escape_pattern(...)"{{{
function! neosnippet#util#escape_pattern(...)"{{{
return call(s:V.escape_pattern, a:000)
endfunction"}}}
function! neocomplcache#util#iconv(...)"{{{
function! neosnippet#util#iconv(...)"{{{
return call(s:V.iconv, a:000)
endfunction"}}}
function! neocomplcache#util#uniq(...)"{{{
return call(s:List.uniq, a:000)
endfunction"}}}
function! neocomplcache#util#glob(pattern, ...)"{{{
if a:pattern =~ "'"
" Use glob('*').
let cwd = getcwd()
let base = neocomplcache#util#substitute_path_separator(
\ fnamemodify(a:pattern, ':h'))
lcd `=base`
let files = map(split(neocomplcache#util#substitute_path_separator(
\ glob('*')), '\n'), "base . '/' . v:val")
lcd `=cwd`
return files
endif
" let is_force_glob = get(a:000, 0, 0)
let is_force_glob = get(a:000, 0, 1)
if !is_force_glob && a:pattern =~ '^[^\\*]\+/\*'
\ && neocomplcache#util#has_vimproc() && exists('*vimproc#readdir')
return filter(vimproc#readdir(a:pattern[: -2]), 'v:val !~ "/\\.\\.\\?$"')
else
" Escape [.
if neocomplcache#util#is_windows()
let glob = substitute(a:pattern, '\[', '\\[[]', 'g')
else
let glob = escape(a:pattern, '[')
endif
return split(neocomplcache#util#substitute_path_separator(glob(glob)), '\n')
endif
endfunction"}}}
function! neocomplcache#util#expand(path)"{{{
return expand(escape(a:path, '*?[]"={}'), 1)
endfunction"}}}
function! neocomplcache#util#set_dictionary_helper(...)"{{{
function! neosnippet#util#set_dictionary_helper(...)"{{{
return call(s:V.set_dictionary_helper, a:000)
endfunction"}}}

12
autoload/vital.vim Normal file
View File

@ -0,0 +1,12 @@
function! vital#of(name)
let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital')
let file = split(files, "\n")
if empty(file)
throw 'vital: version file not found: ' . a:name
endif
let ver = readfile(file[0], 'b')
if empty(ver)
throw 'vital: invalid version file: ' . a:name
endif
return vital#_{substitute(ver[0], '\W', '', 'g')}#new()
endfunction

153
autoload/vital/_fa9e4af.vim Normal file
View File

@ -0,0 +1,153 @@
let s:self_version = expand('<sfile>:t:r')
let s:loaded = {}
function! s:import(name, ...)
let module = {}
let debug = 0
for a in a:000
if type(a) == type({})
let module = a
elseif type(a) == type(0)
let debug = a
endif
unlet a
endfor
return extend(module, s:_import(a:name, s:_scripts(), debug), 'keep')
endfunction
function! s:load(...) dict
let scripts = s:_scripts()
let debug = has_key(self, 'debug') && self.debug
for arg in a:000
let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg]
let target = split(join(as, ''), '\W\+')
let dict = self
while 1 <= len(target)
let ns = remove(target, 0)
if !has_key(dict, ns)
let dict[ns] = {}
endif
if type(dict[ns]) == type({})
let dict = dict[ns]
else
unlet dict
break
endif
endwhile
if exists('dict')
call extend(dict, s:_import(name, scripts, debug))
endif
unlet arg
endfor
return self
endfunction
function! s:unload()
let s:loaded = {}
endfunction
function! s:_import(name, scripts, debug)
if type(a:name) == type(0)
return s:_build_module(a:name, a:debug)
endif
if a:name =~# '^[^A-Z]' || a:name =~# '\W[^A-Z]'
throw 'vital: module name must start with capital letter: ' . a:name
endif
let target = a:name ==# '' ? '' : '/' . substitute(a:name, '\W\+', '/', 'g')
let target = substitute(target, '\l\zs\ze\u', '_', 'g') " OrderedSet -> Ordered_Set
let target = substitute(target, '[/_]\zs\u', '\l\0', 'g') " Ordered_Set -> ordered_set
let tailpath = printf('autoload/vital/%s%s.vim', s:self_version, target)
" Note: The extra argument to globpath() was added in Patch 7.2.051.
if v:version > 702 || v:version == 702 && has('patch51')
let paths = split(globpath(&runtimepath, tailpath, 1), "\n")
else
let paths = split(globpath(&runtimepath, tailpath), "\n")
endif
let path = s:_unify_path(get(paths, 0, ''))
let sid = get(a:scripts, path, 0)
if !sid
try
source `=path`
catch /^Vim\%((\a\+)\)\?:E484/
throw 'vital: module not found: ' . a:name
catch /^Vim\%((\a\+)\)\?:E127/
" Ignore.
endtry
let sid = len(a:scripts) + 1 " We expect that the file newly read is +1.
let a:scripts[path] = sid
endif
return s:_build_module(sid, a:debug)
endfunction
function! s:_scripts()
let scripts = {}
for line in split(s:_redir('scriptnames'), "\n")
let list = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$')
if !empty(list)
let scripts[s:_unify_path(list[2])] = list[1] - 0
endif
endfor
return scripts
endfunction
if filereadable(expand('<sfile>:r') . '.VIM')
function! s:_unify_path(path)
" Note: On windows, vim can't expand path names from 8.3 formats.
" So if getting full path via <sfile> and $HOME was set as 8.3 format,
" vital load duplicated scripts. Below's :~ avoid this issue.
return tolower(fnamemodify(resolve(fnamemodify(
\ a:path, ':p:gs?[\\/]\+?/?')), ':~'))
endfunction
else
function! s:_unify_path(path)
return resolve(fnamemodify(a:path, ':p:gs?[\\/]\+?/?'))
endfunction
endif
function! s:_build_module(sid, debug)
if has_key(s:loaded, a:sid)
return copy(s:loaded[a:sid])
endif
let prefix = '<SNR>' . a:sid . '_'
let funcs = s:_redir('function')
let filter_pat = '^\s*function ' . prefix
let map_pat = prefix . '\zs\w\+'
let functions = map(filter(split(funcs, "\n"), 'v:val =~# filter_pat'),
\ 'matchstr(v:val, map_pat)')
let module = {}
for func in functions
let module[func] = function(prefix . func)
endfor
if has_key(module, '_vital_loaded')
let V = vital#{s:self_version}#new()
if has_key(module, '_vital_depends')
call call(V.load, module._vital_depends(), V)
endif
try
call module._vital_loaded(V)
catch
" FIXME: Show an error message for debug.
endtry
endif
if !a:debug
call filter(module, 'v:key =~# "^\\a"')
endif
let s:loaded[a:sid] = module
return copy(module)
endfunction
function! s:_redir(cmd)
redir => res
silent! execute a:cmd
redir END
return res
endfunction
function! vital#{s:self_version}#new()
return s:_import('', s:_scripts(), 0).load(['Prelude', ''])
endfunction

View File

@ -0,0 +1,367 @@
" vim:set et ts=2 sts=2 sw=2 tw=0:
" glob() wrapper which returns List
" and 'wildignore' does not affect
" this function's return value.
if v:version ># 703 ||
\ (v:version is 703 && has('patch465'))
function! s:glob(expr)
return glob(a:expr, 1, 1)
endfunction
else
function! s:glob(expr)
let R = glob(a:expr, 1)
return split(R, '\n')
endfunction
endif
" globpath() wrapper which returns List
" and 'suffixes' and 'wildignore' does not affect
" this function's return value.
function! s:globpath(path, expr)
let R = globpath(a:path, a:expr, 1)
return split(R, '\n')
endfunction
" Wrapper functions for type().
let [
\ s:__TYPE_NUMBER,
\ s:__TYPE_STRING,
\ s:__TYPE_FUNCREF,
\ s:__TYPE_LIST,
\ s:__TYPE_DICT,
\ s:__TYPE_FLOAT
\] = [
\ type(3),
\ type(""),
\ type(function('tr')),
\ type([]),
\ type({}),
\ has('float') ? type(str2float('0')) : -1
\]
" __TYPE_FLOAT = -1 when -float
" This doesn't match to anything.
" Number or Float
function! s:is_numeric(Value)
let _ = type(a:Value)
return _ ==# s:__TYPE_NUMBER
\ || _ ==# s:__TYPE_FLOAT
endfunction
" Number
function! s:is_integer(Value)
return type(a:Value) ==# s:__TYPE_NUMBER
endfunction
function! s:is_number(Value)
return type(a:Value) ==# s:__TYPE_NUMBER
endfunction
" Float
function! s:is_float(Value)
return type(a:Value) ==# s:__TYPE_FLOAT
endfunction
" String
function! s:is_string(Value)
return type(a:Value) ==# s:__TYPE_STRING
endfunction
" Funcref
function! s:is_funcref(Value)
return type(a:Value) ==# s:__TYPE_FUNCREF
endfunction
" List
function! s:is_list(Value)
return type(a:Value) ==# s:__TYPE_LIST
endfunction
" Dictionary
function! s:is_dict(Value)
return type(a:Value) ==# s:__TYPE_DICT
endfunction
function! s:truncate_smart(str, max, footer_width, separator)"{{{
let width = s:wcswidth(a:str)
if width <= a:max
let ret = a:str
else
let header_width = a:max - s:wcswidth(a:separator) - a:footer_width
let ret = s:strwidthpart(a:str, header_width) . a:separator
\ . s:strwidthpart_reverse(a:str, a:footer_width)
endif
return s:truncate(ret, a:max)
endfunction"}}}
function! s:truncate(str, width)"{{{
" Original function is from mattn.
" http://github.com/mattn/googlereader-vim/tree/master
if a:str =~# '^[\x00-\x7f]*$'
return len(a:str) < a:width ?
\ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width)
endif
let ret = a:str
let width = s:wcswidth(a:str)
if width > a:width
let ret = s:strwidthpart(ret, a:width)
let width = s:wcswidth(ret)
endif
if width < a:width
let ret .= repeat(' ', a:width - width)
endif
return ret
endfunction"}}}
function! s:strchars(str)"{{{
return len(substitute(a:str, '.', 'x', 'g'))
endfunction"}}}
function! s:strwidthpart(str, width)"{{{
if a:width <= 0
return ''
endif
let ret = a:str
let width = s:wcswidth(a:str)
while width > a:width
let char = matchstr(ret, '.$')
let ret = ret[: -1 - len(char)]
let width -= s:wcswidth(char)
endwhile
return ret
endfunction"}}}
function! s:strwidthpart_reverse(str, width)"{{{
if a:width <= 0
return ''
endif
let ret = a:str
let width = s:wcswidth(a:str)
while width > a:width
let char = matchstr(ret, '^.')
let ret = ret[len(char) :]
let width -= s:wcswidth(char)
endwhile
return ret
endfunction"}}}
if v:version >= 703
" Use builtin function.
function! s:wcswidth(str)"{{{
return strwidth(a:str)
endfunction"}}}
else
function! s:wcswidth(str)"{{{
if a:str =~# '^[\x00-\x7f]*$'
return strlen(a:str)
end
let mx_first = '^\(.\)'
let str = a:str
let width = 0
while 1
let ucs = char2nr(substitute(str, mx_first, '\1', ''))
if ucs == 0
break
endif
let width += s:_wcwidth(ucs)
let str = substitute(str, mx_first, '', '')
endwhile
return width
endfunction"}}}
" UTF-8 only.
function! s:_wcwidth(ucs)"{{{
let ucs = a:ucs
if (ucs >= 0x1100
\ && (ucs <= 0x115f
\ || ucs == 0x2329
\ || ucs == 0x232a
\ || (ucs >= 0x2e80 && ucs <= 0xa4cf
\ && ucs != 0x303f)
\ || (ucs >= 0xac00 && ucs <= 0xd7a3)
\ || (ucs >= 0xf900 && ucs <= 0xfaff)
\ || (ucs >= 0xfe30 && ucs <= 0xfe6f)
\ || (ucs >= 0xff00 && ucs <= 0xff60)
\ || (ucs >= 0xffe0 && ucs <= 0xffe6)
\ || (ucs >= 0x20000 && ucs <= 0x2fffd)
\ || (ucs >= 0x30000 && ucs <= 0x3fffd)
\ ))
return 2
endif
return 1
endfunction"}}}
endif
let s:is_windows = has('win16') || has('win32') || has('win64')
let s:is_cygwin = has('win32unix')
let s:is_mac = !s:is_windows && !s:is_cygwin
\ && (has('mac') || has('macunix') || has('gui_macvim') ||
\ (!executable('xdg-open') && system('uname') =~? '^darwin'))
function! s:is_windows()"{{{
return s:is_windows
endfunction"}}}
function! s:is_cygwin()"{{{
return s:is_cygwin
endfunction"}}}
function! s:is_mac()"{{{
return s:is_mac
endfunction"}}}
function! s:print_error(message)"{{{
echohl ErrorMsg
for m in split(a:message, "\n")
echomsg m
endfor
echohl None
endfunction"}}}
function! s:smart_execute_command(action, word)"{{{
execute a:action . ' ' . (a:word == '' ? '' : '`=a:word`')
endfunction"}}}
function! s:escape_file_searching(buffer_name)"{{{
return escape(a:buffer_name, '*[]?{}, ')
endfunction"}}}
function! s:escape_pattern(str)"{{{
return escape(a:str, '~"\.^$[]*')
endfunction"}}}
" iconv() wrapper for safety.
function! s:iconv(expr, from, to)
if a:from == '' || a:to == '' || a:from ==? a:to
return a:expr
endif
let result = iconv(a:expr, a:from, a:to)
return result != '' ? result : a:expr
endfunction
" Like builtin getchar() but returns string always.
function! s:getchar(...)
let c = call('getchar', a:000)
return type(c) == type(0) ? nr2char(c) : c
endfunction
" Like builtin getchar() but returns string always.
" and do inputsave()/inputrestore() before/after getchar().
function! s:getchar_safe(...)
let c = s:input_helper('getchar', a:000)
return type(c) == type("") ? c : nr2char(c)
endfunction
" Like builtin getchar() but
" do inputsave()/inputrestore() before/after input().
function! s:input_safe(...)
return s:input_helper('input', a:000)
endfunction
" Do inputsave()/inputrestore() before/after calling a:funcname.
function! s:input_helper(funcname, args)
let success = 0
if inputsave() !=# success
throw 'inputsave() failed'
endif
try
return call(a:funcname, a:args)
finally
if inputrestore() !=# success
throw 'inputrestore() failed'
endif
endtry
endfunction
function! s:set_default(var, val) "{{{
if !exists(a:var) || type({a:var}) != type(a:val)
let {a:var} = a:val
endif
endfunction"}}}
function! s:set_dictionary_helper(variable, keys, pattern)"{{{
for key in split(a:keys, '\s*,\s*')
if !has_key(a:variable, key)
let a:variable[key] = a:pattern
endif
endfor
endfunction"}}}
function! s:substitute_path_separator(path)"{{{
return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path
endfunction"}}}
function! s:path2directory(path)"{{{
return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h'))
endfunction"}}}
function! s:path2project_directory(path, ...)"{{{
let is_allow_empty = get(a:000, 0, 0)
let search_directory = s:path2directory(a:path)
let directory = ''
" Search VCS directory.
for d in ['.git', '.bzr', '.hg']
let d = finddir(d, s:escape_file_searching(search_directory) . ';')
if d != ''
let directory = fnamemodify(d, ':p:h:h')
break
endif
endfor
" Search project file.
if directory == ''
for d in ['build.xml', 'prj.el', '.project', 'pom.xml',
\ 'Makefile', 'configure', 'Rakefile', 'NAnt.build', 'tags', 'gtags']
let d = findfile(d, s:escape_file_searching(search_directory) . ';')
if d != ''
let directory = fnamemodify(d, ':p:h')
break
endif
endfor
endif
if directory == ''
" Search /src/ directory.
let base = s:substitute_path_separator(search_directory)
if base =~# '/src/'
let directory = base[: strridx(base, '/src/') + 3]
endif
endif
if directory == '' && !is_allow_empty
" Use original path.
let directory = search_directory
endif
return s:substitute_path_separator(directory)
endfunction"}}}
" Check vimproc."{{{
function! s:has_vimproc()"{{{
if !exists('s:exists_vimproc')
try
call vimproc#version()
let s:exists_vimproc = 1
catch
let s:exists_vimproc = 0
endtry
endif
return s:exists_vimproc
endfunction"}}}
"}}}
function! s:system(str, ...)"{{{
let command = a:str
let input = a:0 >= 1 ? a:1 : ''
let command = s:iconv(command, &encoding, 'char')
let input = s:iconv(input, &encoding, 'char')
if a:0 == 0
let output = s:has_vimproc() ?
\ vimproc#system(command) : system(command)
elseif a:0 == 1
let output = s:has_vimproc() ?
\ vimproc#system(command, input) : system(command, input)
else
" ignores 3rd argument unless you have vimproc.
let output = s:has_vimproc() ?
\ vimproc#system(command, input, a:2) : system(command, input)
endif
let output = s:iconv(output, 'char', &encoding)
return output
endfunction"}}}
function! s:get_last_status()"{{{
return s:has_vimproc() ?
\ vimproc#get_last_status() : v:shell_error
endfunction"}}}
" vim:set et ts=2 sts=2 sw=2 tw=0:

View File

@ -0,0 +1,3 @@
fa9e4af
Prelude

View File

@ -319,6 +319,7 @@ CHANGELOG *neosnippet-changelog*
2012-09-30
- Changed runtime directory.
- Vitalized.
2012-09-27
- Ver.3 development is started.