123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- "=============================================================================
- " 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
|