"=============================================================================
" FILE: cache.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 conditionneocomplete#cache#
"
" 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.
" }}}
"=============================================================================
let s:save_cpo = &cpo
set cpo&vim
let s:Cache = neocomplete#util#get_vital().import('System.Cache.Deprecated')
" Cache loader.
function! neocomplete#cache#load_from_cache(cache_dir, filename, ...) abort "{{{
let is_string = get(a:000, 0, 0)
try
" Note: For neocomplete.
let list = []
if is_string
lua << EOF
do
local ret = vim.eval('list')
local list = {}
for line in io.lines(vim.eval(
'neocomplete#cache#encode_name(a:cache_dir, a:filename)')) do
list = (loadstring) and loadstring('return ' .. line)()
or load('return ' .. line)()
end
for i = 1, #list do
ret:add(list[i])
end
end
EOF
else
let list = eval(get(neocomplete#cache#readfile(
\ a:cache_dir, a:filename), 0, '[]'))
endif
if !empty(list) && is_string && type(list[0]) != type('')
" Type check.
throw 'Type error'
endif
return list
catch
" echomsg string(v:errmsg)
" echomsg string(v:exception)
" Delete old cache file.
let cache_name =
\ neocomplete#cache#encode_name(a:cache_dir, a:filename)
if filereadable(cache_name)
call delete(cache_name)
endif
return []
endtry
endfunction"}}}
" New cache loader.
function! neocomplete#cache#check_cache(cache_dir, key, async_cache_dictionary, keyword_cache, is_string) abort "{{{
if !has_key(a:async_cache_dictionary, a:key)
return
endif
let cache_list = a:async_cache_dictionary[a:key]
if !has_key(a:keyword_cache, a:key)
let a:keyword_cache[a:key] = []
endif
for cache in filter(copy(cache_list), 'filereadable(v:val.cachename)')
let a:keyword_cache[a:key] += neocomplete#cache#load_from_cache(
\ a:cache_dir, cache.filename, a:is_string)
endfor
call filter(cache_list, '!filereadable(v:val.cachename)')
if empty(cache_list)
" Delete from dictionary.
call remove(a:async_cache_dictionary, a:key)
return
endif
endfunction"}}}
" For buffer source cache loader.
function! neocomplete#cache#get_cache_list(cache_dir, async_cache_list) abort "{{{
let cache_list = a:async_cache_list
let loaded_keywords = []
let loaded = 0
for cache in filter(copy(cache_list), 'filereadable(v:val.cachename)')
let loaded = 1
let loaded_keywords = neocomplete#cache#load_from_cache(
\ a:cache_dir, cache.filename, 1)
endfor
call filter(cache_list, '!filereadable(v:val.cachename)')
return [loaded, loaded_keywords]
endfunction"}}}
function! neocomplete#cache#save_cache(cache_dir, filename, keyword_list) abort "{{{
if neocomplete#util#is_sudo()
return
endif
" Output cache.
let string = substitute(substitute(substitute(
\ string(a:keyword_list), '^[', '{', ''),
\ ']$', '}', ''), '\\', '\\\\', 'g')
call neocomplete#cache#writefile(
\ a:cache_dir, a:filename, [string])
endfunction"}}}
" Cache helper.
function! neocomplete#cache#getfilename(cache_dir, filename) abort "{{{
let cache_dir = neocomplete#get_data_directory() . '/' . a:cache_dir
return s:Cache.getfilename(cache_dir, a:filename)
endfunction"}}}
function! neocomplete#cache#filereadable(cache_dir, filename) abort "{{{
let cache_dir = neocomplete#get_data_directory() . '/' . a:cache_dir
return s:Cache.filereadable(cache_dir, a:filename)
endfunction"}}}
function! neocomplete#cache#readfile(cache_dir, filename) abort "{{{
let cache_dir = neocomplete#get_data_directory() . '/' . a:cache_dir
return s:Cache.readfile(cache_dir, a:filename)
endfunction"}}}
function! neocomplete#cache#writefile(cache_dir, filename, list) abort "{{{
if neocomplete#util#is_sudo()
return
endif
let cache_dir = neocomplete#get_data_directory() . '/' . a:cache_dir
return s:Cache.writefile(cache_dir, a:filename, a:list)
endfunction"}}}
function! neocomplete#cache#encode_name(cache_dir, filename) abort
" Check cache directory.
let cache_dir = neocomplete#get_data_directory() . '/' . a:cache_dir
return s:Cache.getfilename(cache_dir, a:filename)
endfunction
function! neocomplete#cache#check_old_cache(cache_dir, filename) abort "{{{
let cache_dir = neocomplete#get_data_directory() . '/' . a:cache_dir
return s:Cache.check_old_cache(cache_dir, a:filename)
endfunction"}}}
function! neocomplete#cache#make_directory(directory) abort "{{{
let directory =
\ neocomplete#get_data_directory() .'/'.a:directory
if !isdirectory(directory)
if neocomplete#util#is_sudo()
call neocomplete#print_error(printf(
\ 'Cannot create Directory "%s" in sudo session.', directory))
else
call mkdir(directory, 'p')
endif
endif
endfunction"}}}
let s:sdir = neocomplete#util#substitute_path_separator(
\ fnamemodify(expand('<sfile>'), ':p:h'))
function! neocomplete#cache#async_load_from_file(cache_dir, filename, pattern, mark) abort "{{{
if !neocomplete#cache#check_old_cache(a:cache_dir, a:filename)
\ || neocomplete#util#is_sudo()
return neocomplete#cache#encode_name(a:cache_dir, a:filename)
endif
let pattern_file_name =
\ neocomplete#cache#encode_name('keyword_patterns', a:filename)
let cache_name =
\ neocomplete#cache#encode_name(a:cache_dir, a:filename)
" Create pattern file.
call neocomplete#cache#writefile(
\ 'keyword_patterns', a:filename, [a:pattern])
" args: funcname, outputname, filename pattern mark
" minlen maxlen encoding
let fileencoding =
\ &fileencoding == '' ? &encoding : &fileencoding
let argv = [
\ 'load_from_file', cache_name, a:filename, pattern_file_name, a:mark,
\ g:neocomplete#min_keyword_length, fileencoding
\ ]
return s:async_load(argv, a:cache_dir, a:filename)
endfunction"}}}
function! neocomplete#cache#async_load_from_tags(cache_dir, filename, filetype, pattern, mark) abort "{{{
if !neocomplete#cache#check_old_cache(a:cache_dir, a:filename)
\ || neocomplete#util#is_sudo()
return neocomplete#cache#encode_name(a:cache_dir, a:filename)
endif
let cache_name =
\ neocomplete#cache#encode_name(a:cache_dir, a:filename)
let pattern_file_name =
\ neocomplete#cache#encode_name('tags_patterns', a:filename)
let tags_file_name = '$dummy$'
let filter_pattern =
\ get(g:neocomplete#tags_filter_patterns, a:filetype, '')
call neocomplete#cache#writefile('tags_patterns', a:filename,
\ [a:pattern, tags_file_name, filter_pattern, a:filetype])
" args: funcname, outputname, filename
" pattern mark minlen encoding
let fileencoding = &fileencoding == '' ? &encoding : &fileencoding
let argv = [
\ 'load_from_tags', cache_name, a:filename, pattern_file_name, a:mark,
\ g:neocomplete#min_keyword_length, fileencoding
\ ]
return s:async_load(argv, a:cache_dir, a:filename)
endfunction"}}}
function! s:async_load(argv, cache_dir, filename) abort "{{{
let vim_path = s:search_vim_path()
if vim_path == '' || !executable(vim_path)
call neocomplete#async_cache#main(a:argv)
else
let args = [vim_path, '-u', 'NONE', '-i', 'NONE', '-n',
\ '-N', '-S', s:sdir.'/async_cache.vim']
\ + a:argv
call vimproc#system_bg(args)
" call vimproc#system(args)
" call system(join(args))
endif
return neocomplete#cache#encode_name(a:cache_dir, a:filename)
endfunction"}}}
function! s:search_vim_path() abort "{{{
if exists('s:vim_path')
return s:vim_path
endif
if !neocomplete#has_vimproc()
return ''
endif
let paths = vimproc#get_command_name(v:progname, $PATH, -1)
if empty(paths)
if has('gui_macvim')
" MacVim check.
if !executable('/Applications/MacVim.app/Contents/MacOS/Vim')
call neocomplete#print_error(
\ 'You installed MacVim in not default directory!'.
\ ' You must add MacVim installed path in $PATH.')
let g:neocomplete#use_vimproc = 0
return ''
endif
let s:vim_path = '/Applications/MacVim.app/Contents/MacOS/Vim'
else
call neocomplete#print_error(
\ printf('Vim path : "%s" is not found.'.
\ ' You must add "%s" installed path in $PATH.',
\ v:progname, v:progname))
let g:neocomplete#use_vimproc = 0
return ''
endif
else
let base_path = neocomplete#util#substitute_path_separator(
\ fnamemodify(paths[0], ':p:h'))
let s:vim_path = base_path . '/vim'
if !executable(s:vim_path) && neocomplete#util#is_mac()
" Note: Search "Vim" instead of vim.
let s:vim_path = base_path. '/Vim'
endif
endif
return s:vim_path
endfunction"}}}
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: foldmethod=marker