config/.vim/autoload/omni/cpp/includes.vim
2009-11-01 19:04:42 +01:00

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