123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- "=============================================================================
- " FILE: async_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 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, "\<CR>", '', '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:], "\<TAB>")
- 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 <namespace>".
- 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 <typedef \1>', '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
|