"============================================================================= " FILE: async_cache.vim " AUTHOR: Shougo Matsushita " 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 condition " " 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 function! s:main(argv) abort "{{{ " args: funcname, outputname filename pattern_file_name mark minlen fileencoding let [funcname, outputname, filename, pattern_file_name, mark, minlen, fileencoding] \ = a:argv if funcname ==# 'load_from_file' let keyword_list = s:load_from_file( \ filename, pattern_file_name, mark, minlen, fileencoding, 1) let string = '{' . escape(string(keyword_list)[1 : -2], '\\') . '}' else let keyword_list = s:load_from_tags( \ filename, pattern_file_name, mark, minlen, fileencoding) let string = string(keyword_list) endif if empty(keyword_list) return endif " For neocomplete. " Output cache. call writefile([string], outputname) endfunction"}}} function! s:load_from_file(filename, pattern_file_name, mark, minlen, fileencoding, is_string) abort "{{{ if !filereadable(a:filename) " File not found. return [] endif let lines = readfile(a:filename) if a:fileencoding !=# &encoding let lines = map(lines, 's:iconv(v:val, a:fileencoding, &encoding)') endif let pattern = get(readfile(a:pattern_file_name), 0, '\h\w*') let pattern2 = '^\%('.pattern.'\m\)' let keyword_list = [] let dup_check = {} for line in lines "{{{ let match = match(line, pattern) while match >= 0 "{{{ let match_str = matchstr(line, pattern2, match) if !has_key(dup_check, match_str) && len(match_str) >= a:minlen " Append list. call add(keyword_list, match_str) let dup_check[match_str] = 1 endif if match_str == '' break endif let match += len(match_str) let match = match(line, pattern, match) endwhile"}}} endfor"}}} if !a:is_string call map(keyword_list, "{'word' : match_str}") endif return keyword_list endfunction"}}} function! s:load_from_tags(filename, pattern_file_name, mark, minlen, fileencoding) abort "{{{ let keyword_lists = [] let dup_check = {} let [tags_file_name, filter_pattern] = \ readfile(a:pattern_file_name)[1 : 2] if tags_file_name !=# '$dummy$' " Check output. let tags_list = [] let i = 0 while i < 2 if filereadable(tags_file_name) " Use filename. let tags_list = map(readfile(tags_file_name), \ 's:iconv(v:val, a:fileencoding, &encoding)') break endif sleep 500m let i += 1 endwhile else if !filereadable(a:filename) return [] endif " Use filename. let tags_list = map(readfile(a:filename), \ 's:iconv(v:val, a:fileencoding, &encoding)') endif if empty(tags_list) return s:load_from_file(a:filename, a:pattern_file_name, \ a:mark, a:minlen, a:fileencoding, 0) endif for line in tags_list let tag = split(substitute(line, "\", '', 'g'), '\t', 1) " Add keywords. if line =~ '^!' || len(tag) < 3 || len(tag[0]) < a:minlen \ || has_key(dup_check, tag[0]) continue endif let opt = join(tag[2:], "\") let cmd = matchstr(opt, '.*/;"') let option = { \ 'cmd' : substitute(substitute(substitute(cmd, \'^\%([/?]\^\?\)\?\s*\|\%(\$\?[/?]\)\?;"$', '', 'g'), \ '\\\\', '\\', 'g'), '\\/', '/', 'g'), \ 'kind' : '' \} if option.cmd =~ '\d\+' let option.cmd = tag[0] endif for opt in split(opt[len(cmd):], '\t', 1) let key = matchstr(opt, '^\h\w*\ze:') if key == '' let option['kind'] = opt else let option[key] = matchstr(opt, '^\h\w*:\zs.*') endif endfor if has_key(option, 'file') \ || (has_key(option, 'access') && option.access != 'public') continue endif let abbr = has_key(option, 'signature')? tag[0] . option.signature : \ (option['kind'] == 'd' || option['cmd'] == '') ? \ tag[0] : option['cmd'] let abbr = substitute(abbr, '\s\+', ' ', 'g') " Substitute "namespace foobar" to "foobar ". let abbr = substitute(abbr, \'^\(namespace\|class\|struct\|enum\|union\)\s\+\(.*\)$', \'\2 <\1>', '') " Substitute typedef. let abbr = substitute(abbr, \'^typedef\s\+\(.*\)\s\+\(\h\w*\%(::\w*\)*\);\?$', \'\2 ', 'g') " Substitute extends and implements. let abbr = substitute(abbr, \'\<\%(extends\|implements\)\s\+\S\+\>', '', '') " Substitute marker. let abbr = substitute(abbr, '"\s*{{{', '', '') let keyword = { \ 'word' : tag[0], 'abbr' : abbr, 'menu' : '', \ 'kind' : option['kind'], \ } if has_key(option, 'struct') let keyword.menu = option.struct elseif has_key(option, 'class') let keyword.menu = option.class elseif has_key(option, 'enum') let keyword.menu = option.enum elseif has_key(option, 'union') let keyword.menu = option.union endif call add(keyword_lists, keyword) let dup_check[tag[0]] = 1 endfor"}}} if filter_pattern != '' call filter(keyword_lists, filter_pattern) endif return keyword_lists endfunction"}}} function! s:truncate(str, width) abort "{{{ " 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 = strdisplaywidth(a:str) if width > a:width let ret = s:strwidthpart(ret, a:width) let width = strdisplaywidth(ret) endif if width < a:width let ret .= repeat(' ', a:width - width) endif return ret endfunction"}}} function! s:strwidthpart(str, width) abort "{{{ let ret = a:str let width = strdisplaywidth(a:str) while width > a:width let char = matchstr(ret, '.$') let ret = ret[: -1 - len(char)] let width -= strwidth(char) endwhile return ret endfunction"}}} function! s:iconv(expr, from, to) abort 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 if argc() == 7 && \ (argv(0) ==# 'load_from_file' || argv(0) ==# 'load_from_tags') try call s:main(argv()) catch call writefile([v:throwpoint, v:exception], \ fnamemodify(argv(1), ':h:h').'/async_error_log') endtry qall! else function! neocomplete#async_cache#main(argv) abort "{{{ call s:main(a:argv) endfunction"}}} endif let &cpo = s:save_cpo unlet s:save_cpo " vim: foldmethod=marker