127 lines
4.4 KiB
VimL
127 lines
4.4 KiB
VimL
|
" Description: Omni completion script for cpp files
|
||
|
" Maintainer: Vissale NEANG
|
||
|
" Last Change: 26 sept. 2007
|
||
|
|
||
|
let g:omni#cpp#includes#CACHE_INCLUDES = {}
|
||
|
let g:omni#cpp#includes#CACHE_FILE_TIME = {}
|
||
|
|
||
|
let s:rePreprocIncludePart = '\C#\s*include\s*'
|
||
|
let s:reIncludeFilePart = '\(<\|"\)\(\f\|\s\)\+\(>\|"\)'
|
||
|
let s:rePreprocIncludeFile = s:rePreprocIncludePart . s:reIncludeFilePart
|
||
|
|
||
|
" Get the include list of a file
|
||
|
function! omni#cpp#includes#GetList(...)
|
||
|
if a:0 > 0
|
||
|
return s:GetIncludeListFromFile(a:1, (a:0 > 1)? a:2 : 0 )
|
||
|
else
|
||
|
return s:GetIncludeListFromCurrentBuffer()
|
||
|
endif
|
||
|
endfunc
|
||
|
|
||
|
" Get the include list from the current buffer
|
||
|
function! s:GetIncludeListFromCurrentBuffer()
|
||
|
let listIncludes = []
|
||
|
let originalPos = getpos('.')
|
||
|
|
||
|
call setpos('.', [0, 1, 1, 0])
|
||
|
let curPos = [1,1]
|
||
|
let alreadyInclude = {}
|
||
|
while curPos != [0,0]
|
||
|
let curPos = searchpos('\C\(^'.s:rePreprocIncludeFile.'\)', 'W')
|
||
|
if curPos != [0,0]
|
||
|
let szLine = getline('.')
|
||
|
let startPos = curPos[1]
|
||
|
let endPos = matchend(szLine, s:reIncludeFilePart, startPos-1)
|
||
|
if endPos!=-1
|
||
|
let szInclusion = szLine[startPos-1:endPos-1]
|
||
|
let szIncludeFile = substitute(szInclusion, '\('.s:rePreprocIncludePart.'\)\|[<>""]', '', 'g')
|
||
|
let szResolvedInclude = omni#cpp#utils#ResolveFilePath(szIncludeFile)
|
||
|
|
||
|
" Protection over self inclusion
|
||
|
if szResolvedInclude != '' && szResolvedInclude != omni#cpp#utils#ResolveFilePath(getreg('%'))
|
||
|
let includePos = curPos
|
||
|
if !has_key(alreadyInclude, szResolvedInclude)
|
||
|
call extend(listIncludes, [{'pos' : includePos, 'include' : szResolvedInclude}])
|
||
|
let alreadyInclude[szResolvedInclude] = 1
|
||
|
endif
|
||
|
endif
|
||
|
endif
|
||
|
endif
|
||
|
endwhile
|
||
|
|
||
|
call setpos('.', originalPos)
|
||
|
return listIncludes
|
||
|
endfunc
|
||
|
|
||
|
" Get the include list from a file
|
||
|
function! s:GetIncludeListFromFile(szFilePath, bUpdate)
|
||
|
let listIncludes = []
|
||
|
if a:szFilePath == ''
|
||
|
return listIncludes
|
||
|
endif
|
||
|
|
||
|
if !a:bUpdate && has_key(g:omni#cpp#includes#CACHE_INCLUDES, a:szFilePath)
|
||
|
return copy(g:omni#cpp#includes#CACHE_INCLUDES[a:szFilePath])
|
||
|
endif
|
||
|
|
||
|
let g:omni#cpp#includes#CACHE_FILE_TIME[a:szFilePath] = getftime(a:szFilePath)
|
||
|
|
||
|
let szFixedPath = escape(a:szFilePath, g:omni#cpp#utils#szEscapedCharacters)
|
||
|
execute 'silent! lvimgrep /\C\(^'.s:rePreprocIncludeFile.'\)/gj '.szFixedPath
|
||
|
|
||
|
let listQuickFix = getloclist(0)
|
||
|
let alreadyInclude = {}
|
||
|
for qf in listQuickFix
|
||
|
let szLine = qf.text
|
||
|
let startPos = qf.col
|
||
|
let endPos = matchend(szLine, s:reIncludeFilePart, startPos-1)
|
||
|
if endPos!=-1
|
||
|
let szInclusion = szLine[startPos-1:endPos-1]
|
||
|
let szIncludeFile = substitute(szInclusion, '\('.s:rePreprocIncludePart.'\)\|[<>""]', '', 'g')
|
||
|
let szResolvedInclude = omni#cpp#utils#ResolveFilePath(szIncludeFile)
|
||
|
|
||
|
" Protection over self inclusion
|
||
|
if szResolvedInclude != '' && szResolvedInclude != a:szFilePath
|
||
|
let includePos = [qf.lnum, qf.col]
|
||
|
if !has_key(alreadyInclude, szResolvedInclude)
|
||
|
call extend(listIncludes, [{'pos' : includePos, 'include' : szResolvedInclude}])
|
||
|
let alreadyInclude[szResolvedInclude] = 1
|
||
|
endif
|
||
|
endif
|
||
|
endif
|
||
|
endfor
|
||
|
|
||
|
let g:omni#cpp#includes#CACHE_INCLUDES[a:szFilePath] = listIncludes
|
||
|
|
||
|
return copy(listIncludes)
|
||
|
endfunc
|
||
|
|
||
|
" For debug purpose
|
||
|
function! omni#cpp#includes#Display()
|
||
|
let szPathBuffer = omni#cpp#utils#ResolveFilePath(getreg('%'))
|
||
|
call s:DisplayIncludeTree(szPathBuffer, 0)
|
||
|
endfunc
|
||
|
|
||
|
" For debug purpose
|
||
|
function! s:DisplayIncludeTree(szFilePath, indent, ...)
|
||
|
let includeGuard = {}
|
||
|
if a:0 >0
|
||
|
let includeGuard = a:1
|
||
|
endif
|
||
|
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
|
||
|
if has_key(includeGuard, szFilePath)
|
||
|
return
|
||
|
else
|
||
|
let includeGuard[szFilePath] = 1
|
||
|
endif
|
||
|
|
||
|
let szIndent = repeat(' ', a:indent)
|
||
|
echo szIndent . a:szFilePath
|
||
|
let incList = omni#cpp#includes#GetList(a:szFilePath)
|
||
|
for inc in incList
|
||
|
call s:DisplayIncludeTree(inc.include, a:indent+1, includeGuard)
|
||
|
endfor
|
||
|
endfunc
|
||
|
|
||
|
|