forked from aniani/vim
102 lines
2.4 KiB
VimL
102 lines
2.4 KiB
VimL
" Vim completion script
|
|
" Language: C
|
|
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
|
" Last Change: 2005 Sep 05
|
|
|
|
function! ccomplete#Complete(findstart, base)
|
|
if a:findstart
|
|
" locate the start of the word
|
|
let line = getline('.')
|
|
let start = col('.') - 1
|
|
while start > 0
|
|
if line[start - 1] =~ '\w\|\.'
|
|
let start -= 1
|
|
elseif start > 1 && line[start - 2] == '-' && line[start - 1] == '>'
|
|
let start -= 2
|
|
else
|
|
break
|
|
endif
|
|
endwhile
|
|
return start
|
|
endif
|
|
|
|
" return list of matches
|
|
if a:base !~ '\.\|->'
|
|
" Only one part, no "." or "->": complete from tags file.
|
|
let diclist = taglist(a:base)
|
|
return map(diclist, 'v:val["name"]')
|
|
endif
|
|
|
|
" Find variable locally in function or file.
|
|
let items = split(a:base, '\.\|->')
|
|
|
|
" At the moment we only do "aa.bb", not "aa.bb.cc"
|
|
if len(items) > 2
|
|
return []
|
|
endif
|
|
|
|
let line = ''
|
|
if searchdecl(items[0]) == 0 || searchdecl(items[0], 1) == 0
|
|
" Found, now figure out the type.
|
|
" TODO: join previous line if it makes sense
|
|
let line = getline('.')
|
|
let col = col('.')
|
|
else
|
|
" Find the variable in the tags file
|
|
let diclist = taglist(items[0])
|
|
for i in range(len(diclist))
|
|
" For now we only recognize a variable.
|
|
if diclist[i]['kind'] == 'v'
|
|
let line = diclist[i]['cmd']
|
|
if line[0] == '/' && line[1] == '^'
|
|
" the command is a search pattern, remove the leading /^
|
|
let line = strpart(line, 2)
|
|
endif
|
|
let col = match(line, items[0])
|
|
break
|
|
endif
|
|
endfor
|
|
endif
|
|
|
|
if line == ''
|
|
return []
|
|
endif
|
|
|
|
" Is there a * before the variable name?
|
|
let col -= 1
|
|
let star = 0
|
|
while col > 0
|
|
let col -= 1
|
|
if line[col] == '*'
|
|
let star = 1
|
|
elseif line[col] !~ '\s'
|
|
break
|
|
endif
|
|
endwhile
|
|
|
|
" Use the line up to the variable name and split it in tokens.
|
|
let lead = strpart(line, 0, col + 1)
|
|
let tokens = split(lead, '\s\+\|\<')
|
|
|
|
let basetext = matchstr(a:base, '.*\.\|->')
|
|
|
|
for i in range(len(tokens) - 1)
|
|
if tokens[i] == 'struct'
|
|
let name = tokens[i + 1]
|
|
" Todo: Use all tags files; What about local structures?
|
|
exe 'vimgrep /\<struct:' . name . '\>/j tags'
|
|
let res = []
|
|
for l in getqflist()
|
|
let memb = matchstr(l['text'], '[^\t]*')
|
|
if len(items) == 1 || memb =~ '^' . items[1]
|
|
call add(res, basetext . memb)
|
|
endif
|
|
endfor
|
|
return res
|
|
endif
|
|
endfor
|
|
|
|
return tokens
|
|
endfunction
|
|
|