Full Code of Shougo/neco-vim for AI

master 7b722cd13a44 cached
10 files
31.4 KB
9.5k tokens
10 symbols
1 requests
Download .txt
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 <Shougo.Matsu at gmail.com>

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 <karl.yngve@gmail.com>
" 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 <Shougo.Matsu@gmail.com>
" 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('<sfile>'), ':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([
        \ '<cfile>', '<afile>', '<abuf>', '<amatch>',
        \ '<sfile>', '<cword>', '<cWORD>', '<client>'
        \ ])
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 = '<SID>' . keyword.word[2:]
      let keyword.abbr = '<SID>' . 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 =~# '\<let\s\+&\%([lg]:\)\?filetype\s*=\s*'
    " FileType.
    return necovim#helper#filetype(a:cur_text, a:complete_str)
  else
    return necovim#helper#expression(a:cur_text, a:complete_str)
  endif
endfunction
function! necovim#helper#option(cur_text, complete_str) abort
  " Make cache.
  if !has_key(s:internal_candidates_list, 'options')
    let s:internal_candidates_list.options = s:make_cache_options()
  endif

  if a:cur_text =~# '\<set\%[local]\s\+\%(filetype\|ft\)='
    return necovim#helper#filetype(a:cur_text, a:complete_str)
  else
    return copy(s:internal_candidates_list.options)
  endif
endfunction
function! necovim#helper#var_dictionary(cur_text, complete_str) abort
  let var_name = matchstr(a:cur_text,
        \'\%(\a:\)\?\h\w*\ze\.\%(\h\w*\%(()\?\)\?\)\?$')
  let list = []
  if a:cur_text =~# '[btwg]:\h\w*\.\%(\h\w*\%(()\?\)\?\)\?$'
    let list = get(
          \ s:global_candidates_list.dictionary_variables, var_name, [])
  elseif a:cur_text =~# 's:\h\w*\.\%(\h\w*\%(()\?\)\?\)\?$'
    let list = values(get(
          \ s:get_cached_script_candidates().dictionary_variables,
          \ var_name, {}))
  endif

  return list
endfunction
function! necovim#helper#var(cur_text, complete_str) abort
  " Make cache.
  if s:check_global_candidates('variables')
    let s:global_candidates_list.variables =
          \ s:get_variablelist(g:, 'g:') + s:get_variablelist(v:, 'v:')
          \ + s:make_completion_list(['v:val'])
  endif

  if a:complete_str =~# '^[swtb]:'
    let list = values(s:get_cached_script_candidates().variables)
    if a:complete_str !~# '^s:'
      let prefix = matchstr(a:complete_str, '^[swtb]:')
      let list += s:get_variablelist(eval(prefix), prefix)
    endif
  elseif a:complete_str =~# '^[vg]:'
    let list = copy(s:global_candidates_list.variables)
  else
    let list = s:get_local_variables()
  endif

  return list
endfunction

function! s:get_local_variables() abort
  " Get local variable list.

  let keyword_dict = {}
  " Search function.
  let line_num = line('.') - 1
  let end_line = max([line('.') - 100, 1])
  while line_num >= end_line
    let line = getline(line_num)
    if line =~# '\<endf\%[unction]\>'
      break
    elseif line =~# '\<fu\%[nction]!\?\s\+'
      " Get function arguments.
      call s:analyze_variable_line(line, keyword_dict)
      break
    endif

    let line_num -= 1
  endwhile
  let line_num += 1

  let end_line = line('.') - 1
  while line_num <= end_line
    let line = getline(line_num)

    if line =~# '\<\%(let\|const\|for\)\s\+'
      if line =~# '\<\%(let\|const\|for\)\s\+s:'
            \ && has_key(get(s:script_candidates_list,
            \                bufnr('%'), {}), 'variables')
        let candidates_list = s:script_candidates_list[bufnr('%')].variables
      else
        let candidates_list = keyword_dict
      endif

      call s:analyze_variable_line(line, candidates_list)
    endif

    let line_num += 1
  endwhile

  return values(keyword_dict)
endfunction

function! s:get_cached_script_candidates() abort
  return has_key(s:script_candidates_list, bufnr('%')) ?
        \ s:script_candidates_list[bufnr('%')] : {
        \   'functions' : {}, 'variables' : {},
        \   'function_prototypes' : {}, 'dictionary_variables' : {} }
endfunction
function! s:get_script_candidates(bufnumber) abort
  " Get script candidate list.

  let function_dict = {}
  let variable_dict = {}
  let dictionary_variable_dict = {}
  let function_prototypes = {}
  let var_pattern = '\a:[[:alnum:]_:]*\.\h\w*\%(()\?\)\?'

  for line in getbufline(a:bufnumber, 1, '$')
    if line =~# '\<fu\%[nction]!\?\s\+'
      call s:analyze_function_line(
            \ line, function_dict, function_prototypes)
    elseif line =~# '\<let\s\+'
      " Get script variable.
      call s:analyze_variable_line(line, variable_dict)
    elseif line =~ var_pattern
      while line =~ var_pattern
        let var_name = matchstr(line, '\a:[[:alnum:]_:]*\ze\.\h\w*')
        let candidates_dict = dictionary_variable_dict
        if !has_key(candidates_dict, var_name)
          let candidates_dict[var_name] = {}
        endif

        call s:analyze_dictionary_variable_line(
              \ line, candidates_dict[var_name], var_name)

        let line = line[matchend(line, var_pattern) :]
      endwhile
    endif
  endfor

  return {
        \ 'functions' : function_dict,
        \ 'variables' : variable_dict,
        \ 'function_prototypes' : function_prototypes,
        \ 'dictionary_variables' : dictionary_variable_dict,
        \ }
endfunction

function! s:make_cache_options() abort
  let options = map(filter(split(execute('set all'), '\s\{2,}\|\n')[1:],
        \ { _, val -> !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 =~# '^<SNR>'
      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 =~# '^<SNR>'
      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,
        \ '\<fu\%[nction]!\?\s\+\zs.*)'), '".*$', '', '')
  let orig_line = line
  let word = matchstr(line, '^\h[[:alnum:]_:#.]*()\?')
  if word !=# '' && !has_key(a:keyword_dict, word)
    let a:keyword_dict[word] = {
          \ 'word' : word, 'abbr' : line, 'kind' : 'f'
          \}
    let a:prototype[word] = orig_line[len(word):]
  endif
endfunction
function! s:analyze_variable_line(line, keyword_dict) abort
  if a:line =~# '\<\%(let\|const\|for\)\s\+\a[[:alnum:]_:]*'
    " let var = pattern.
    let word = matchstr(a:line,
          \ '\<\%(let\|const\|for\)\s\+\zs\a[[:alnum:]_:]*')
    let expression = matchstr(a:line,
          \ '\<\%(let\|const\)\s\+\a[[:alnum:]_:]*\s*=\s*\zs.*$')
    if !has_key(a:keyword_dict, word)
      let a:keyword_dict[word] = {
            \ 'word' : word,
            \ 'kind' : s:get_variable_type(expression)
            \}
    elseif expression !=# '' && a:keyword_dict[word].kind ==# ''
      " Update kind.
      let a:keyword_dict[word].kind = s:get_variable_type(expression)
    endif
  elseif a:line =~# '\<\%(let\|const\|for\)\s\+\[.\{-}\]'
    " let [var1, var2] = pattern.
    let words = split(matchstr(a:line,
          \'\<\%(let\|const\|for\)\s\+\[\zs.\{-}\ze\]'), '[,[:space:]]\+')
    let expressions = split(matchstr(a:line,
          \ '\<\%(let\|const\)\s\+\[.\{-}\]\s*=\s*\[\zs.\{-}\ze\]$'),
          \ '[,[:space:];]\+')

    let i = 0
    while i < len(words)
      let expression = get(expressions, i, '')
      let word = words[i]

      if !has_key(a:keyword_dict, word) 
        let a:keyword_dict[word] = {
              \ 'word' : word,
              \ 'kind' : s:get_variable_type(expression)
              \}
      elseif expression !=# '' && a:keyword_dict[word].kind ==# ''
        " Update kind.
        let a:keyword_dict[word].kind = s:get_variable_type(expression)
      endif

      let i += 1
    endwhile
  elseif a:line =~# '\<fu\%[nction]!\?\s\+'
    " Get function arguments.
    for arg in split(matchstr(a:line, '^[^(]*(\zs[^)]*'), '\s*,\s*')
      let word = 'a:' . (arg ==# '...' ?  '000' : matchstr(arg, '\w\+'))
      let a:keyword_dict[word] = {
            \ 'word' : word,
            \ 'kind' : (arg ==# '...' ?  '[]' : '')
            \}

    endfor
    if a:line =~# '\.\.\.)'
      " Extra arguments.
      for arg in range(5)
        let word = 'a:' . arg
        let a:keyword_dict[word] = {
              \ 'word' : word,
              \ 'kind' : (arg == 0 ?  '0' : '')
              \}
      endfor
    endif
  endif
endfunction
function! s:analyze_dictionary_variable_line(line, keyword_dict, var_name) abort
  let let_pattern = '\<let\s\+'.a:var_name.'\.\h\w*'
  let call_pattern = '\<call\s\+'.a:var_name.'\.\h\w*()\?'

  if a:line =~ let_pattern
    let word = matchstr(a:line, a:var_name.'\zs\.\h\w*')
    let kind = ''
  elseif a:line =~ call_pattern
    let word = matchstr(a:line, a:var_name.'\zs\.\h\w*()\?')
    let kind = '()'
  else
    let word = matchstr(a:line, a:var_name.'\zs.\h\w*\%(()\?\)\?')
    let kind = s:get_variable_type(
          \ matchstr(a:line, a:var_name.'\.\h\w*\zs.*$'))
  endif

  if !has_key(a:keyword_dict, word)
    let a:keyword_dict[word] = { 'word' : word, 'kind' : kind }
  elseif kind !=# '' && a:keyword_dict[word].kind ==# ''
    " Update kind.
    let a:keyword_dict[word].kind = kind
  endif
endfunction

" Initialize return types.
function! s:set_dictionary_helper(variable, keys, value) abort
  for key in split(a:keys, ',')
    let a:variable[key] = a:value
  endfor
endfunction
let s:function_return_types = {}
call s:set_dictionary_helper(
      \ s:function_return_types,
      \ 'len,match,matchend',
      \ '0')
call s:set_dictionary_helper(
      \ s:function_return_types,
      \ 'input,matchstr',
      \ '""')
call s:set_dictionary_helper(
      \ s:function_return_types,
      \ 'expand,filter,sort,split',
      \ '[]')

function! s:get_variable_type(expression) abort
  " Analyze variable type.
  if a:expression =~# '^\%(\s*+\)\?\s*\d\+\.\d\+'
    return '.'
  elseif a:expression =~# '^\%(\s*+\)\?\s*\d\+'
    return '0'
  elseif a:expression =~# '^\%(\s*\.\)\?\s*["'']'
    return '""'
  elseif a:expression =~# '\<function('
    return '()'
  elseif a:expression =~# '^\%(\s*+\)\?\s*\['
    return '[]'
  elseif a:expression =~# '^\s*{\|^\.\h[[:alnum:]_:]*'
    return '{}'
  elseif a:expression =~# '\<\h\w*('
    " Function.
    let func_name = matchstr(a:expression, '\<\zs\h\w*\ze(')
    return get(s:function_return_types, func_name, '')
  else
    return ''
  endif
endfunction

function! s:set_dictionary_helper(variable, keys, pattern) abort
  for key in split(a:keys, '\s*,\s*')
    if !has_key(a:variable, key)
      let a:variable[key] = a:pattern
    endif
  endfor
endfunction

function! s:check_global_candidates(key) abort
  if s:global_candidates_list.runtimepath !=# &runtimepath
    let s:global_candidates_list.runtimepath = &runtimepath
    return 1
  endif

  return !has_key(s:global_candidates_list, a:key)
endfunction

" Removes duplicates from a list.
function! s:uniq(list) abort
  return s:uniq_by(a:list, 'v:val')
endfunction

" Removes duplicates from a list.
function! s:uniq_by(list, f) abort
  let list = map(copy(a:list), printf('[v:val, %s]', a:f))
  let i = 0
  let seen = {}
  while i < len(list)
    let key = string(list[i][1])
    if has_key(seen, key)
      call remove(list, i)
    else
      let seen[key] = 1
      let i += 1
    endif
  endwhile
  return map(list, { _, val -> val[0]})
endfunction


================================================
FILE: autoload/necovim.vim
================================================
"=============================================================================
" FILE: necovim.vim
" AUTHOR:  Shougo Matsushita <Shougo.Matsu@gmail.com>
" License: MIT license
"=============================================================================

" Global options definition.
let g:necovim#keyword_pattern =
      \ get(g:, 'necovim#keyword_pattern',
      \'\h[[:alnum:]-]*=\?\|\c\[:\%(\h\w*:\]\)\?\|&\h[[:alnum:]_:]*\|'.
      \'<SID>\%(\h\w*\)\?\|<Plug>([^)]*)\?'.
      \'\|<\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 =~# '\<e\%[dit]\s' || complete_pos < 0
    " Use args pattern.
    let [complete_pos, complete_str] =
          \ necovim#match_word(a:input, '\S\+$')
  endif

  return complete_pos
endfunction

function! necovim#gather_candidates(input, complete_str) abort
  if v:version < 800
    echohl Error
    echomsg '[neco-vim] Vim 8.0 compatible is required'
    echohl None
    return []
  endif

  let cur_text = necovim#get_cur_text(a:input)

  if cur_text =~# '\h\w*\.\%(\h\w*\)\?$'
    " Dictionary.
    let complete_str = matchstr(cur_text, '.\%(\h\w*\)\?$')
    return necovim#helper#var_dictionary(
          \ cur_text, complete_str)
  elseif cur_text =~# '\<set\%(l\%[ocal]\|g\%[lobal]\)\?\s'
    let list = necovim#helper#option(cur_text, a:complete_str)
  elseif a:complete_str =~# '^&\%([gl]:\)\?'
    " Options.
    let prefix = matchstr(a:complete_str, '^&\%([gl]:\)\?')
    let list = deepcopy(necovim#helper#option(cur_text, a:complete_str))
    for keyword in list
      let keyword.word = prefix . keyword.word
    endfor
  elseif a:complete_str =~? '^\c<sid>'
    " SID functions.
    let prefix = matchstr(a:complete_str, '^\c<sid>')
    let complete_str = substitute(
          \ a:complete_str, '^\c<sid>', '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 =~# '\<let\s'
    let list = necovim#helper#let(cur_text, a:complete_str)
  elseif cur_text =~# '\<has([''"]\w*$'
    " Features.
    let list = necovim#helper#feature(cur_text, a:complete_str)
  elseif cur_text =~# '\<expand([''"][<>[: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\+\|<bar>', 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 <Shougo.Matsu@gmail.com>
" 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<string, never>;

export class Source extends BaseSource<Params> {
  isBytePos = true;

  override async getCompletePosition(args: {
    denops: Denops,
    context: Context,
  }): Promise<number> {
    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<Item[]> {
    return await args.denops.call(
        'necovim#gather_candidates',
        args.context.input, args.completeStr) as Item[];
  }

  override async getPreviewer(args: {
    denops: Denops,
    item: Item;
  }): Promise<Previewer> {
    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 <Shougo.Matsu at gmail.com>
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 <Shougo.Matsu@gmail.com>
" 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 <Shougo.Matsu at gmail.com>
# 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'])
Download .txt
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
Download .txt
SYMBOL INDEX (10 symbols across 2 files)

FILE: denops/@ddc-sources/necovim.ts
  type Params (line 9) | type Params = Record<string, never>;
  class Source (line 11) | class Source extends BaseSource<Params> {
    method getCompletePosition (line 14) | override async getCompletePosition(args: {
    method gather (line 22) | override async gather(args: {
    method getPreviewer (line 32) | override async getPreviewer(args: {
    method params (line 49) | override params(): Params { return {}; }

FILE: rplugin/python3/deoplete/source/vim.py
  class Source (line 11) | class Source(Base):
    method __init__ (line 12) | def __init__(self, vim):
    method get_complete_position (line 22) | def get_complete_position(self, context):
    method gather_candidates (line 26) | def gather_candidates(self, context):
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (34K chars).
[
  {
    "path": ".gitignore",
    "chars": 19,
    "preview": "*.py[cod]\ndoc/tags\n"
  },
  {
    "path": "LICENSE",
    "chars": 1097,
    "preview": "MIT license\n\nCopyright (c) Shougo Matsushita <Shougo.Matsu at gmail.com>\n\nPermission is hereby granted, free of charge, "
  },
  {
    "path": "autoload/cm/sources/necovim.vim",
    "chars": 548,
    "preview": "\"=============================================================================\n\" FILE: necovim.vim (NCM source)\n\" AUTHOR"
  },
  {
    "path": "autoload/necovim/helper.vim",
    "chars": 21034,
    "preview": "\"=============================================================================\n\" FILE: helper.vim\n\" AUTHOR:  Shougo Mats"
  },
  {
    "path": "autoload/necovim.vim",
    "chars": 3882,
    "preview": "\"=============================================================================\n\" FILE: necovim.vim\n\" AUTHOR:  Shougo Mat"
  },
  {
    "path": "autoload/neocomplete/sources/vim.vim",
    "chars": 841,
    "preview": "\"=============================================================================\n\" FILE: vim.vim\n\" AUTHOR:  Shougo Matsush"
  },
  {
    "path": "denops/@ddc-sources/necovim.ts",
    "chars": 1168,
    "preview": "import {\n  BaseSource,\n  Context,\n  Item,\n  Previewer,\n} from \"https://deno.land/x/ddc_vim@v4.0.4/types.ts\";\nimport { De"
  },
  {
    "path": "doc/necovim.txt",
    "chars": 1872,
    "preview": "*necovim.txt*\tVim completion source for neocomplete/deoplete/ddc.\n\nVersion: 1.0\nAuthor: Shougo <Shougo.Matsu at gmail.co"
  },
  {
    "path": "plugin/necovim.vim",
    "chars": 717,
    "preview": "\"=============================================================================\n\" FILE: necovim.vim\n\" AUTHOR:  Shougo Mat"
  },
  {
    "path": "rplugin/python3/deoplete/source/vim.py",
    "chars": 936,
    "preview": "#=============================================================================\n# FILE: vim.py\n# AUTHOR:  Shougo Matsushi"
  }
]

About this extraction

This page contains the full source code of the Shougo/neco-vim GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (31.4 KB), approximately 9.5k tokens, and a symbol index with 10 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!