Repository: Shougo/neco-vim Branch: master Commit: 7b722cd13a44 Files: 10 Total size: 31.4 KB Directory structure: gitextract_84jpmpud/ ├── .gitignore ├── LICENSE ├── autoload/ │ ├── cm/ │ │ └── sources/ │ │ └── necovim.vim │ ├── necovim/ │ │ └── helper.vim │ ├── necovim.vim │ └── neocomplete/ │ └── sources/ │ └── vim.vim ├── denops/ │ └── @ddc-sources/ │ └── necovim.ts ├── doc/ │ └── necovim.txt ├── plugin/ │ └── necovim.vim └── rplugin/ └── python3/ └── deoplete/ └── source/ └── vim.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.py[cod] doc/tags ================================================ FILE: LICENSE ================================================ MIT license Copyright (c) Shougo Matsushita 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. ================================================ FILE: autoload/cm/sources/necovim.vim ================================================ "============================================================================= " FILE: necovim.vim (NCM source) " AUTHOR: Karl Yngve Lervåg " License: MIT license "============================================================================= function! cm#sources#necovim#refresh(opt, ctx) abort let startcol = necovim#get_complete_position(a:ctx.typed) let base = strpart(a:ctx.typed, startcol) let cnd = necovim#gather_candidates(a:ctx.typed, base) call cm#complete(a:opt.name, a:ctx, startcol+1, cnd) endfunction ================================================ FILE: autoload/necovim/helper.vim ================================================ "============================================================================= " FILE: helper.vim " AUTHOR: Shougo Matsushita " License: MIT license "============================================================================= if !exists('s:internal_candidates_list') let s:internal_candidates_list = {} let s:global_candidates_list = { \ 'dictionary_variables' : {}, 'runtimepath' : &runtimepath } let s:script_candidates_list = {} let s:local_candidates_list = {} endif let s:dictionary_path = \ substitute(fnamemodify(expand(''), ':h'), '\\', '/', 'g') function! necovim#helper#make_cache() abort if &filetype !=# 'vim' return endif let s:script_candidates_list[bufnr('%')] = \ s:get_script_candidates(bufnr('%')) endfunction function! necovim#helper#augroup(cur_text, complete_str) abort " Make cache. if s:check_global_candidates('augroups') let s:global_candidates_list.augroups = s:get_augrouplist() endif return copy(s:global_candidates_list.augroups) endfunction function! necovim#helper#command(cur_text, complete_str) abort if a:complete_str ==# '' " Disable for huge candidates return [] endif if a:cur_text ==# '' || \ a:cur_text =~# '^[[:digit:],[:space:][:tab:]$''<>]*\h\w*$' " Commands. " Make cache. if s:check_global_candidates('commands') let s:global_candidates_list.commands = s:get_cmdlist() endif if !has_key(s:internal_candidates_list, 'commands') let s:internal_candidates_list.commands = s:make_cache_commands() endif let list = copy(s:internal_candidates_list.commands) \ + copy(s:global_candidates_list.commands) else " Commands args. " Expression. " Note: In command line window, expression completion should be disabled. let list = bufname('%') ==# '[Command Line]' ? [] : \ necovim#helper#expression(a:cur_text, a:complete_str) try let list += s:make_completion_list( \ getcompletion(a:cur_text, 'cmdline')) catch " Ignore getcompletion() error endtry endif " Filter by complete_str to reduce candidates let prefix = a:complete_str[:1] return filter(s:uniq_by(list, 'v:val.word'), \ { _, val -> stridx(val.word, prefix) == 0}) endfunction function! necovim#helper#environment(cur_text, complete_str) abort " Make cache. if s:check_global_candidates('environments') let s:global_candidates_list.environments = s:get_envlist() endif return copy(s:global_candidates_list.environments) endfunction function! necovim#helper#expand(cur_text, complete_str) abort return s:make_completion_list([ \ '', '', '', '', \ '', '', '', '' \ ]) endfunction function! necovim#helper#expression(cur_text, complete_str) abort return necovim#helper#function(a:cur_text, a:complete_str) \+ necovim#helper#var(a:cur_text, a:complete_str) endfunction function! necovim#helper#feature(cur_text, complete_str) abort if !has_key(s:internal_candidates_list, 'features') let s:internal_candidates_list.features = s:make_cache_features() endif return copy(s:internal_candidates_list.features) endfunction function! necovim#helper#filetype(cur_text, complete_str) abort if !has_key(s:internal_candidates_list, 'filetypes') let s:internal_candidates_list.filetypes = \ s:make_completion_list(map( \ split(globpath(&runtimepath, 'syntax/*.vim'), '\n') + \ split(globpath(&runtimepath, 'indent/*.vim'), '\n') + \ split(globpath(&runtimepath, 'ftplugin/*.vim'), '\n') \ , { _, val -> matchstr( \ fnamemodify(val, ':t:r'), '^[[:alnum:]-]*')})) endif return copy(s:internal_candidates_list.filetypes) endfunction function! necovim#helper#function(cur_text, complete_str) abort " Make cache. if s:check_global_candidates('functions') let s:global_candidates_list.functions = s:get_functionlist() endif if !has_key(s:internal_candidates_list, 'functions') let s:internal_candidates_list.functions = s:make_cache_functions() if has('nvim') let s:internal_candidates_list.functions += \ s:make_cache_functions_nvim() endif endif let script_functions = values(s:get_cached_script_candidates().functions) if a:complete_str =~# '^s:' let list = script_functions elseif a:complete_str =~# '^\a:' let list = deepcopy(script_functions) for keyword in list let keyword.word = '' . keyword.word[2:] let keyword.abbr = '' . keyword.abbr[2:] endfor else let list = copy(s:internal_candidates_list.functions) \ + copy(s:global_candidates_list.functions) \ + script_functions for functions in map(values(s:script_candidates_list), \ { _, val -> val.functions}) let list += values(filter(copy(functions), \ { _, val -> val.word[:1] !=# 's:'})) endfor endif return list endfunction function! necovim#helper#let(cur_text, complete_str) abort if a:cur_text !~# '=' return necovim#helper#var(a:cur_text, a:complete_str) elseif a:cur_text =~# '\= end_line let line = getline(line_num) if line =~# '\' break elseif line =~# '\ !empty(val) && val =~# '^\h\w*=\?' }), \ { _, val -> substitute(val, '^no\|=\zs.*$', '', '') }) for option in copy(options) if option[-1:] !=# '=' call add(options, 'no'.option) endif endfor return map(filter(options, { _, val -> val =~# '^\h\w*=\?' }), \ { _, val -> { \ 'word': substitute(val, '=$', '', ''), 'kind' : 'o', \ } \ }) endfunction function! s:make_cache_features() abort let helpfile = expand(findfile('doc/eval.txt', &runtimepath)) if !filereadable(helpfile) return [] endif let features = [] let lines = readfile(helpfile) let start = match(lines, 'acl') let end = match(lines, has('nvim') ? '^wsl' : '^x11') for l in lines[start : end] let _ = matchlist(l, '^\(\k\+\)\t\+\(.\+\)$') if !empty(_) call add(features, { \ 'word' : _[1], \ 'info' : _[2], \ }) endif endfor call add(features, { \ 'word' : 'patch', \ 'menu' : '; Included patches Ex: patch123', \ }) call add(features, { \ 'word' : 'patch-', \ 'menu' : '; Version and patches Ex: patch-7.4.237' \ }) return features endfunction function! s:make_cache_functions() abort let helpfile = expand(findfile('doc/builtin.txt', &runtimepath)) if !filereadable(helpfile) return [] endif let lines = readfile(helpfile) let functions = [] let start = match(lines, '^abs') let end = match(lines, '^abs', start, 2) if end <= 0 " NOTE: In neovim 0.10+, |builtin-function-list| is removed. Too bad. let end = match(lines, '^xor', start) endif for i in range(end - 1, start, -1) let func = matchstr(lines[i], '^\s*\zs\w\+(.\{-})') if func !=# '' call insert(functions, { \ 'word' : substitute(func, '(\zs.\+)', '', ''), \ 'abbr' : substitute(func, '(\zs\s\+', '', ''), \ 'info' : substitute(lines[i], '\t', ' ', 'g'), \ }) endif endfor return functions endfunction function! s:make_cache_functions_nvim() abort let helpfile = expand(findfile('doc/api.txt', &runtimepath)) if !filereadable(helpfile) return [] endif let lines = readfile(helpfile) let functions = [] let start = match(lines, '^nvim__get_hl_defs') let end = match(lines, '^nvim_ui_try_resize_grid') for i in range(end, start, -1) let func = matchstr(lines[i], '^\s*\zs\w\+(.\{-})') if func !=# '' call insert(functions, { \ 'word' : substitute(func, '(\zs.\+)', '', ''), \ 'abbr' : substitute(func, '(\zs\s\+', '', ''), \ 'info' : substitute(lines[i], '\t', ' ', 'g'), \ }) endif endfor return functions endfunction function! s:make_cache_commands() abort let helpfile = expand(findfile('doc/index.txt', &runtimepath)) if !filereadable(helpfile) return [] endif let lines = readfile(helpfile) let commands = [] let start = match(lines, '^|:!|') let end = match(lines, '^|:\~|', start) for lnum in range(end, start, -1) let desc = substitute(lines[lnum], '^\s\+\ze', '', 'g') let _ = matchlist(desc, '^|:\(.\{-}\)|\s\+\S\+\s\+\(.*\)$') if !empty(_) call add(commands, { \ 'word' : _[1], 'kind' : 'c', \ 'info': _[2], \ }) endif endfor return commands endfunction function! s:get_cmdlist() abort let list = exists('*nvim_get_commands') ? \ keys(nvim_get_commands({'builtin': v:false})) : \ getcompletion('', 'command') return s:make_completion_list(list) endfunction function! s:get_variablelist(dict, prefix) abort let kind_dict = \ ['0', '""', '()', '[]', '{}', '.', 'b', 'no', 'j', 'ch'] let list = [] for [key, Val] in items(a:dict) let kind = '?' silent! let kind = get(kind_dict, type(Val), '?') call add(list, { \ 'word' : a:prefix . key, \ 'kind' : kind, \ }) endfor return list endfunction function! s:get_functionlist() abort let keyword_dict = {} let function_prototypes = {} for line in split(execute('function'), '\n') let line = line[9:] if line =~# '^' continue endif let orig_line = line let word = matchstr(line, '\h[[:alnum:]_:#.]*()\?') if word !=# '' let keyword_dict[word] = { \ 'word' : word, 'abbr' : line, \} let function_prototypes[word] = orig_line[len(word):] endif endfor let s:global_candidates_list.function_prototypes = function_prototypes return values(keyword_dict) endfunction function! s:get_augrouplist() abort return s:make_completion_list(getcompletion('', 'augroup')) endfunction function! s:get_mappinglist() abort let keyword_list = [] for line in split(execute('map'), '\n') let map = matchstr(line, '^\a*\s*\zs\S\+') if map !~# '^<' || map =~# '^' continue endif call add(keyword_list, { 'word' : map }) endfor return keyword_list endfunction function! s:get_envlist() abort let keyword_list = [] for line in split(system('set'), '\n') let word = '$' . toupper(matchstr(line, '^\h\w*')) call add(keyword_list, { 'word' : word, 'kind' : 'e' }) endfor return keyword_list endfunction function! s:make_completion_list(list) abort return map(copy(a:list), { _, val -> val !=# '' && val[-1:] ==# '/' ? \ { 'word': val[:-2], 'abbr': val } : { 'word': val } \ }) endfunction function! s:analyze_function_line(line, keyword_dict, prototype) abort " Get script function. let line = substitute(matchstr(a:line, \ '\ val[0]}) endfunction ================================================ FILE: autoload/necovim.vim ================================================ "============================================================================= " FILE: necovim.vim " AUTHOR: Shougo Matsushita " License: MIT license "============================================================================= " Global options definition. let g:necovim#keyword_pattern = \ get(g:, 'necovim#keyword_pattern', \'\h[[:alnum:]-]*=\?\|\c\[:\%(\h\w*:\]\)\?\|&\h[[:alnum:]_:]*\|'. \'\%(\h\w*\)\?\|([^)]*)\?'. \'\|<\h[[:alnum:]_-]*>\?\|\h[[:alnum:]_:#]*[!(]\?\|$\h\w*') function! necovim#get_complete_position(input) abort if v:version < 800 echohl Error echomsg '[neco-vim] Vim 8.0 compatible is required' echohl None return -1 endif let cur_text = necovim#get_cur_text(a:input) if cur_text =~# '^\s*"' " Comment. return -1 endif let pattern = '\.\%(\h\w*\)\?$\|\%(' . \ g:necovim#keyword_pattern . '\)$' let [complete_pos, complete_str] = \ necovim#match_word(a:input, pattern) if a:input =~# '\' " SID functions. let prefix = matchstr(a:complete_str, '^\c') let complete_str = substitute( \ a:complete_str, '^\c', 's:', '') let list = deepcopy(necovim#helper#function(cur_text, complete_str)) for keyword in list let keyword.word = prefix . keyword.word[2:] let keyword.abbr = prefix . \ get(keyword, 'abbr', keyword.word)[2:] endfor elseif cur_text =~# '\[:alnum:]]*$' " Expand. let list = necovim#helper#expand(cur_text, a:complete_str) elseif a:complete_str =~# '^\$' " Environment. let list = necovim#helper#environment(cur_text, a:complete_str) else " Commands. let list = necovim#helper#command(cur_text, a:complete_str) endif return list endfunction function! necovim#get_cur_text(input) abort let cur_text = a:input if &filetype ==# 'vimshell' && exists('*vimshell#get_secondary_prompt') \ && empty(b:vimshell.continuation) return cur_text[len(vimshell#get_secondary_prompt()) :] endif let line = line('.') let cnt = 0 while cur_text =~# '^\s*\\' && line > 1 && cnt < 5 let cur_text = getline(line - 1) . \ substitute(cur_text, '^\s*\\', '', '') let line -= 1 let cnt += 1 endwhile return split(cur_text, '\s\+|\s\+\|', 1)[-1] endfunction function! necovim#match_word(cur_text, pattern) abort let complete_pos = match(a:cur_text, a:pattern) let complete_str = (complete_pos >=0) ? \ a:cur_text[complete_pos :] : '' return [complete_pos, complete_str] endfunction ================================================ FILE: autoload/neocomplete/sources/vim.vim ================================================ "============================================================================= " FILE: vim.vim " AUTHOR: Shougo Matsushita " License: MIT license "============================================================================= let s:source = { \ 'name' : 'vim', \ 'kind' : 'manual', \ 'filetypes' : { 'vim' : 1, 'vimconsole' : 1, }, \ 'mark' : '[vim]', \ 'is_volatile' : 1, \ 'rank' : 300, \ 'input_pattern' : '\.\w*', \} function! s:source.get_complete_position(context) abort return necovim#get_complete_position(a:context.input) endfunction function! s:source.gather_candidates(context) abort return necovim#gather_candidates(a:context.input, a:context.complete_str) endfunction function! neocomplete#sources#vim#define() abort return s:source endfunction ================================================ FILE: denops/@ddc-sources/necovim.ts ================================================ import { BaseSource, Context, Item, Previewer, } from "https://deno.land/x/ddc_vim@v4.0.4/types.ts"; import { Denops, fn } from "https://deno.land/x/ddc_vim@v4.0.4/deps.ts"; type Params = Record; export class Source extends BaseSource { isBytePos = true; override async getCompletePosition(args: { denops: Denops, context: Context, }): Promise { return await args.denops.call( 'necovim#get_complete_position', args.context.input) as number; } override async gather(args: { denops: Denops, context: Context, completeStr: string, }): Promise { return await args.denops.call( 'necovim#gather_candidates', args.context.input, args.completeStr) as Item[]; } override async getPreviewer(args: { denops: Denops, item: Item; }): Promise { const help = await fn.getcompletion(args.denops, args.item.word, "help"); if (help.length === 0) { return { kind: "empty", }; } else { return { kind: "help", tag: args.item.word, }; } } override params(): Params { return {}; } } ================================================ FILE: doc/necovim.txt ================================================ *necovim.txt* Vim completion source for neocomplete/deoplete/ddc. Version: 1.0 Author: Shougo License: MIT license CONTENTS *necovim-contents* Introduction |necovim-introduction| Install |necovim-install| Interface |necovim-interface| Variables |necovim-variables| FAQ |necovim-faq| ============================================================================== INTRODUCTION *necovim-introduction* *neco-vim* is the Vim completion source for neocomplete/deoplete/ddc. ============================================================================== INSTALL *necovim-install* Vim 8.0+ or neovim 0.5.0+ is required. ============================================================================== INTERFACE *necovim-interface* ------------------------------------------------------------------------------ VARIABLES *necovim-variables* *g:necovim#complete_functions* g:necovim#complete_functions It which appoints vim source call function when completes custom and customlist command. The key is command name. The value is function name. Default value is {}. > " Examples: if !exists('g:necovim#complete_functions') let g:necovim#complete_functions = {} endif let g:necovim#complete_functions.Ref = \ 'ref#complete' < ============================================================================== FAQ *necovim-faq* Q. How to enable neco-vim the completion in ddc.vim? A. > call ddc#custom#patch_filetype( \ ['vim', 'toml'], 'sources', ['necovim']) call ddc#custom#patch_global('sourceOptions', { \ '_': { \ 'matchers': ['matcher_head'], \ 'sorters': ['sorter_rank'] \ }, \ 'necovim': {'mark': 'vim'}, \ }) ============================================================================== vim:tw=78:ts=8:ft=help:norl:noet:fen:noet: ================================================ FILE: plugin/necovim.vim ================================================ "============================================================================= " FILE: necovim.vim " AUTHOR: Shougo Matsushita " License: MIT license "============================================================================= augroup necovim autocmd! autocmd BufWritePost,FileType vim call necovim#helper#make_cache() " Register source for NCM autocmd User CmSetup call cm#register_source({ \ 'name': 'vim', \ 'abbreviation': 'vim', \ 'priority': 9, \ 'scoping': 1, \ 'scopes': ['vim'], \ 'cm_refresh': 'cm#sources#necovim#refresh', \ 'cm_refresh_patterns': ['\w\+\.$'], \ }) augroup END let g:loaded_necovim = 1 ================================================ FILE: rplugin/python3/deoplete/source/vim.py ================================================ #============================================================================= # FILE: vim.py # AUTHOR: Shougo Matsushita # License: MIT license #============================================================================= from deoplete.base.source import Base import deoplete.util class Source(Base): def __init__(self, vim): Base.__init__(self, vim) self.name = 'vim' self.mark = '[vim]' self.filetypes = ['vim'] self.is_bytepos = True self.rank = 500 self.input_pattern = r'\.\w*' def get_complete_position(self, context): return self.vim.call('necovim#get_complete_position', context['input']) def gather_candidates(self, context): return self.vim.call('necovim#gather_candidates', context['input'], context['complete_str'])