"=============================================================================
" FILE: util.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
" License: MIT license {{{
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to
" permit persons to whom the Software is furnished to do so, subject to
" the following conditions:
"
" The above copyright notice and this permission notice shall be included
" in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
" }}}
"=============================================================================
function! vimshell#util#get_vital() abort "{{{
if !exists('s:V')
let s:V = vital#vimshell#of()
endif
return s:V
endfunction"}}}
function! s:get_prelude() abort "{{{
if !exists('s:Prelude')
let s:Prelude = vimshell#util#get_vital().import('Prelude')
endif
return s:Prelude
endfunction"}}}
function! s:get_list() abort "{{{
if !exists('s:List')
let s:List = vimshell#util#get_vital().import('Data.List')
endif
return s:List
endfunction"}}}
function! s:get_process() abort "{{{
if !exists('s:Process')
let s:Process = vimshell#util#get_vital().import('Process')
endif
return s:Process
endfunction"}}}
function! s:get_string() abort "{{{
if !exists('s:String')
let s:String = vimshell#util#get_vital().import('Data.String')
endif
return s:String
endfunction"}}}
function! vimshell#util#truncate_smart(...) abort "{{{
return call(s:get_string().truncate_skipping, a:000)
endfunction"}}}
function! vimshell#util#truncate(...) abort "{{{
return call(s:get_string().truncate, a:000)
endfunction"}}}
function! vimshell#util#strchars(...) abort "{{{
return call(s:get_string().strchars, a:000)
endfunction"}}}
function! vimshell#util#strwidthpart(...) abort "{{{
return call(s:get_string().strwidthpart, a:000)
endfunction"}}}
function! vimshell#util#strwidthpart_reverse(...) abort "{{{
return call(s:get_string().strwidthpart_reverse, a:000)
endfunction"}}}
" Use builtin function.
function! vimshell#util#strwidthpart_len(str, width) abort "{{{
let ret = a:str
let width = strwidth(a:str)
while width > a:width
let char = matchstr(ret, '.$')
let ret = ret[: -1 - len(char)]
let width -= strwidth(char)
endwhile
return width
endfunction"}}}
function! vimshell#util#strwidthpart_len_reverse(str, width) abort "{{{
let ret = a:str
let width = strwidth(a:str)
while width > a:width
let char = matchstr(ret, '^.')
let ret = ret[len(char) :]
let width -= strwidth(char)
endwhile
return width
endfunction"}}}
function! s:buflisted(bufnr) abort "{{{
return exists('t:tabpagebuffer') ?
\ has_key(t:tabpagebuffer, a:bufnr) && buflisted(a:bufnr) :
\ buflisted(a:bufnr)
endfunction"}}}
function! vimshell#util#expand(path) abort "{{{
return s:get_prelude().substitute_path_separator(
\ (a:path =~ '^\~') ? substitute(a:path, '^\~', expand('~'), '') :
\ (a:path =~ '^\$\h\w*') ? substitute(a:path,
\ '^\$\h\w*', '\=eval(submatch(0))', '') :
\ a:path)
endfunction"}}}
function! vimshell#util#set_default(var, val, ...) abort "{{{
if !exists(a:var) || type({a:var}) != type(a:val)
let alternate_var = get(a:000, 0, '')
let {a:var} = exists(alternate_var) ?
\ {alternate_var} : a:val
endif
return {a:var}
endfunction"}}}
function! vimshell#util#set_default_dictionary_helper(variable, keys, value) abort "{{{
for key in split(a:keys, '\s*,\s*')
if !has_key(a:variable, key)
let a:variable[key] = a:value
endif
endfor
endfunction"}}}
function! vimshell#util#set_dictionary_helper(variable, keys, value) abort "{{{
for key in split(a:keys, '\s*,\s*')
let a:variable[key] = a:value
endfor
endfunction"}}}
function! vimshell#util#substitute_path_separator(...) abort "{{{
return call(s:get_prelude().substitute_path_separator, a:000)
endfunction"}}}
function! vimshell#util#is_windows(...) abort "{{{
return call(s:get_prelude().is_windows, a:000)
endfunction"}}}
function! vimshell#util#escape_file_searching(...) abort "{{{
return call(s:get_prelude().escape_file_searching, a:000)
endfunction"}}}
function! vimshell#util#sort_by(...) abort "{{{
return call(s:get_list().sort_by, a:000)
endfunction"}}}
function! vimshell#util#uniq(...) abort "{{{
return call(s:get_list().uniq, a:000)
endfunction"}}}
function! vimshell#util#uniq_by(...) abort "{{{
return call(s:get_list().uniq_by, a:000)
endfunction"}}}
function! vimshell#util#has_vimproc(...) abort "{{{
return call(s:get_process().has_vimproc, a:000)
endfunction"}}}
function! vimshell#util#input_yesno(message) abort "{{{
let yesno = input(a:message . ' [yes/no]: ')
while yesno !~? '^\%(y\%[es]\|n\%[o]\)$'
redraw
if yesno == ''
echo 'Canceled.'
break
endif
" Retry.
call vimshell#echo_error('Invalid input.')
let yesno = input(a:message . ' [yes/no]: ')
endwhile
return yesno =~? 'y\%[es]'
endfunction"}}}
function! vimshell#util#is_cmdwin() abort "{{{
return bufname('%') ==# '[Command Line]'
endfunction"}}}
function! vimshell#util#is_auto_select() abort "{{{
return get(g:, 'neocomplcache_enable_auto_select', 0)
\ || get(g:, 'neocomplete#enable_auto_select', 0)
\ || &completeopt =~# 'noinsert'
endfunction"}}}
function! vimshell#util#is_complete_hold() abort "{{{
return (get(g:, 'neocomplcache_enable_cursor_hold_i', 0)
\ && !get(g:, 'neocomplcache_enable_insert_char_pre', 0)) ||
\ get(g:, 'neocomplete#enable_cursor_hold_i', 0)
endfunction"}}}
function! vimshell#util#is_auto_delimiter() abort "{{{
return get(g:, 'neocomplcache_enable_auto_delimiter', 0) ||
\ get(g:, 'neocomplete#enable_auto_delimiter', 0)
endfunction"}}}
" Sudo check.
function! vimshell#util#is_sudo() abort "{{{
return $SUDO_USER != '' && $USER !=# $SUDO_USER
\ && $HOME !=# expand('~'.$USER)
\ && $HOME ==# expand('~'.$SUDO_USER)
endfunction"}}}
function! vimshell#util#path2project_directory(...) abort
return call(s:get_prelude().path2project_directory, a:000)
endfunction
function! vimshell#util#enable_auto_complete() abort "{{{
if exists(':NeoCompleteUnlock')
NeoCompleteUnlock
endif
if exists(':NeoComplcacheUnLock')
NeoComplcacheUnLock
endif
endfunction"}}}
function! vimshell#util#disable_auto_complete() abort "{{{
" Skip next auto completion.
if exists(':NeoCompleteLock')
NeoCompleteLock
endif
if exists(':NeoComplcacheLock')
NeoComplcacheLock
endif
endfunction"}}}
function! vimshell#util#alternate_buffer() abort "{{{
if bufnr('%') != bufnr('#') && s:buflisted(bufnr('#'))
buffer #
return
endif
let listed_buffer = filter(range(1, bufnr('$')),
\ "s:buflisted(v:val) || v:val == bufnr('%')")
let current = index(listed_buffer, bufnr('%'))
if current < 0 || len(listed_buffer) < 3
enew
return
endif
execute 'buffer' ((current < len(listed_buffer) / 2) ?
\ listed_buffer[current+1] : listed_buffer[current-1])
endfunction"}}}
function! vimshell#util#delete_buffer(...) abort "{{{
let bufnr = get(a:000, 0, bufnr('%'))
call vimshell#util#alternate_buffer()
execute 'silent bwipeout!' bufnr
endfunction"}}}
function! s:buflisted(bufnr) abort "{{{
return exists('t:tabpagebuffer') ?
\ has_key(t:tabpagebuffer, a:bufnr) && buflisted(a:bufnr) :
\ buflisted(a:bufnr)
endfunction"}}}
function! vimshell#util#glob(pattern, ...) abort "{{{
if a:pattern =~ "'"
" Use glob('*').
let cwd = getcwd()
let base = vimshell#util#substitute_path_separator(
\ fnamemodify(a:pattern, ':h'))
try
execute (haslocaldir() ? 'lcd' : 'cd') fnameescape(base)
let files = map(split(vimshell#util#substitute_path_separator(
\ glob('*')), '\n'), "base . '/' . v:val")
finally
execute (haslocaldir() ? 'lcd' : 'cd') fnameescape(cwd)
endtry
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 =~ '^[^\\*]\+/\*'
\ && vimshell#util#has_vimproc() && exists('*vimproc#readdir')
return filter(vimproc#readdir(a:pattern[: -2]), 'v:val !~ "/\\.\\.\\?$"')
else
" Escape [.
if vimshell#util#is_windows()
let glob = substitute(a:pattern, '\[', '\\[[]', 'g')
else
let glob = escape(a:pattern, '[')
endif
return split(vimshell#util#substitute_path_separator(glob(glob)), '\n')
endif
endfunction"}}}
function! vimshell#util#get_vimshell_winnr(buffer_name) abort "{{{
for winnr in filter(range(1, winnr('$')),
\ "getbufvar(winbufnr(v:val), '&filetype') ==# 'vimshell'")
let buffer_context = get(getbufvar(
\ winbufnr(winnr), 'vimshell'), 'context', {})
if !empty(buffer_context) &&
\ buffer_context.buffer_name ==# a:buffer_name
return winnr
endif
endfor
return -1
endfunction"}}}
function! vimshell#util#head_match(checkstr, headstr) abort "{{{
return stridx(a:checkstr, a:headstr) == 0
endfunction"}}}
function! vimshell#util#tail_match(checkstr, tailstr) abort "{{{
return a:tailstr == '' || a:checkstr ==# a:tailstr
\|| a:checkstr[: -len(a:tailstr)-1] ==# a:tailstr
endfunction"}}}
function! vimshell#util#resolve(filename) abort "{{{
return ((vimshell#util#is_windows() && fnamemodify(a:filename, ':e') ==? 'LNK')
\ || getftype(a:filename) ==# 'link') ?
\ substitute(resolve(a:filename), '\\', '/', 'g') : a:filename
endfunction"}}}
function! vimshell#util#escape_match(str) abort "{{{
return escape(a:str, '~" \.^$[]')
endfunction"}}}
function! vimshell#util#system(...) abort "{{{
return call(s:get_process().system, a:000)
endfunction"}}}
function! vimshell#util#set_variables(variables) abort "{{{
let variables_save = {}
for [key, value] in items(a:variables)
let save_value = exists(key) ? eval(key) : ''
let variables_save[key] = save_value
execute 'let' key '=' string(value)
endfor
return variables_save
endfunction"}}}
function! vimshell#util#restore_variables(variables) abort "{{{
for [key, value] in items(a:variables)
execute 'let' key '=' string(value)
endfor
endfunction"}}}
" vim: foldmethod=marker