Vim configuration cleanup.

parent 8e5833e4
let g:netrw_dirhistmax =10
let g:netrw_dirhist_cnt =4
let g:netrw_dirhist_1='/home/sander/Desktop/bapc-2009'
let g:netrw_dirhist_2='/home/sander/Desktop/bapc-2009/preliminary'
let g:netrw_dirhist_3='/home/sander/Programming/web/vo20/cache'
let g:netrw_dirhist_4='/home/sander/.vim'
" OmniCppComplete initialization
call omni#cpp#complete#Init()
" OmniCppComplete initialization
call omni#cpp#complete#Init()
" Description: Omni completion debug functions
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
let s:CACHE_DEBUG_TRACE = []
" Start debug, clear the debug file
function! omni#common#debug#Start()
let s:CACHE_DEBUG_TRACE = []
call extend(s:CACHE_DEBUG_TRACE, ['============ Debug Start ============'])
call writefile(s:CACHE_DEBUG_TRACE, "Omni.dbg")
endfunc
" End debug, write to debug file
function! omni#common#debug#End()
call extend(s:CACHE_DEBUG_TRACE, ["============= Debug End ============="])
call extend(s:CACHE_DEBUG_TRACE, [""])
call writefile(s:CACHE_DEBUG_TRACE, "Omni.dbg")
endfunc
" Debug trace function
function! omni#common#debug#Trace(szFuncName, ...)
let szTrace = a:szFuncName
let paramNum = a:0
if paramNum>0
let szTrace .= ':'
endif
for i in range(paramNum)
let szTrace = szTrace .' ('. string(eval('a:'.string(i+1))).')'
endfor
call extend(s:CACHE_DEBUG_TRACE, [szTrace])
endfunc
" Description: Omni completion utils
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
" For sort numbers in list
function! omni#common#utils#CompareNumber(i1, i2)
let num1 = eval(a:i1)
let num2 = eval(a:i2)
return num1 == num2 ? 0 : num1 > num2 ? 1 : -1
endfunc
" TagList function calling the vim taglist() with try catch
" The only throwed exception is 'TagList:UserInterrupt'
" We also force the noignorecase option to avoid linear search when calling
" taglist()
function! omni#common#utils#TagList(szTagQuery)
let result = []
let bUserIgnoreCase = &ignorecase
" Forcing noignorecase search => binary search can be used in taglist()
" if tags in the tag file are sorted
if bUserIgnoreCase
set noignorecase
endif
try
let result = taglist(a:szTagQuery)
catch /^Vim:Interrupt$/
" Restoring user's setting
if bUserIgnoreCase
set ignorecase
endif
throw 'TagList:UserInterrupt'
catch
"Note: it seems that ctags can generate corrupted files, in this case
"taglist() will fail to read the tagfile and an exception from
"has_add() is thrown
endtry
" Restoring user's setting
if bUserIgnoreCase
set ignorecase
endif
return result
endfunc
" Same as TagList but don't throw exception
function! omni#common#utils#TagListNoThrow(szTagQuery)
let result = []
try
let result = omni#common#utils#TagList(a:szTagQuery)
catch
endtry
return result
endfunc
" Get the word under the cursor
function! omni#common#utils#GetWordUnderCursor()
let szLine = getline('.')
let startPos = getpos('.')[2]-1
let startPos = (startPos < 0)? 0 : startPos
if szLine[startPos] =~ '\w'
let startPos = searchpos('\<\w\+', 'cbn', line('.'))[1] - 1
endif
let startPos = (startPos < 0)? 0 : startPos
let szResult = matchstr(szLine, '\w\+', startPos)
return szResult
endfunc
" Description: Omni completion script for cpp files
" Maintainer: Vissale NEANG
" Last Change: 27 sept. 2007
if v:version < 700
echohl WarningMsg
echomsg "omni#cpp#complete.vim: Please install vim 7.0 or higher for omni-completion"
echohl None
finish
endif
call omni#cpp#settings#Init()
let s:OmniCpp_ShowScopeInAbbr = g:OmniCpp_ShowScopeInAbbr
let s:OmniCpp_ShowPrototypeInAbbr = g:OmniCpp_ShowPrototypeInAbbr
let s:OmniCpp_ShowAccess = g:OmniCpp_ShowAccess
let s:szCurrentWorkingDir = getcwd()
" Cache data
let s:CACHE_TAG_POPUP_ITEMS = {}
let s:CACHE_TAG_FILES = {}
let s:CACHE_TAG_ENV = ''
let s:CACHE_OVERLOADED_FUNCTIONS = {}
" Has preview window?
let s:hasPreviewWindow = match(&completeopt, 'preview')>=0
let s:hasPreviewWindowOld = s:hasPreviewWindow
" Popup item list
let s:popupItemResultList = []
" May complete indicator
let s:bMayComplete = 0
" Init mappings
function! omni#cpp#complete#Init()
call omni#cpp#settings#Init()
set omnifunc=omni#cpp#complete#Main
inoremap <expr> <C-X><C-O> omni#cpp#maycomplete#Complete()
inoremap <expr> . omni#cpp#maycomplete#Dot()
inoremap <expr> > omni#cpp#maycomplete#Arrow()
inoremap <expr> : omni#cpp#maycomplete#Scope()
endfunc
" Find the start position of the completion
function! s:FindStartPositionOfCompletion()
" Locate the start of the item, including ".", "->" and "[...]".
let line = getline('.')
let start = col('.') - 1
let lastword = -1
while start > 0
if line[start - 1] =~ '\w'
let start -= 1
elseif line[start - 1] =~ '\.'
" Searching for dot '.'
if lastword == -1
let lastword = start
endif
let start -= 1
elseif start > 1 && line[start - 2] == '-' && line[start - 1] == '>'
" Searching for '->'
if lastword == -1
let lastword = start
endif
let start -= 2
elseif start > 1 && line[start - 2] == ':' && line[start - 1] == ':'
" Searching for '::' for namespaces and class
if lastword == -1
let lastword = start
endif
let start -= 2
elseif line[start - 1] == ']'
" Skip over [...].
let n = 0
let start -= 1
while start > 0
let start -= 1
if line[start] == '['
if n == 0
break
endif
let n -= 1
elseif line[start] == ']' " nested []
let n += 1
endif
endwhile
else
break
endif
endwhile
if lastword==-1
" For completion on the current scope
let lastword = start
endif
return lastword
endfunc
" Returns if szKey1.szKey2 is in the cache
" @return
" - 0 = key not found
" - 1 = szKey1.szKey2 found
" - 2 = szKey1.[part of szKey2] found
function! s:IsCached(cache, szKey1, szKey2)
" Searching key in the result cache
let szResultKey = a:szKey1 . a:szKey2
let result = [0, szResultKey]
if a:szKey2 != ''
let szKey = a:szKey2
while len(szKey)>0
if has_key(a:cache, a:szKey1 . szKey)
let result[1] = a:szKey1 . szKey
if szKey != a:szKey2
let result[0] = 2
else
let result[0] = 1
endif
break
endif
let szKey = szKey[:-2]
endwhile
else
if has_key(a:cache, szResultKey)
let result[0] = 1
endif
endif
return result
endfunc
" Extend a tag item to a popup item
function! s:ExtendTagItemToPopupItem(tagItem, szTypeName)
let tagItem = a:tagItem
" Add the access
let szItemMenu = ''
let accessChar = {'public': '+','protected': '#','private': '-'}
if g:OmniCpp_ShowAccess
if has_key(tagItem, 'access') && has_key(accessChar, tagItem.access)
let szItemMenu = szItemMenu.accessChar[tagItem.access]
else
let szItemMenu = szItemMenu." "
endif
endif
" Formating optional menu string we extract the scope information
let szName = substitute(tagItem.name, '.*::', '', 'g')
let szItemWord = szName
let szAbbr = szName
if !g:OmniCpp_ShowScopeInAbbr
let szScopeOfTag = omni#cpp#utils#ExtractScope(tagItem)
let szItemMenu = szItemMenu.' '.szScopeOfTag[2:]
let szItemMenu = substitute(szItemMenu, '\s\+$', '', 'g')
else
let szAbbr = tagItem.name
endif
if g:OmniCpp_ShowAccess
let szItemMenu = substitute(szItemMenu, '^\s\+$', '', 'g')
else
let szItemMenu = substitute(szItemMenu, '\(^\s\+\)\|\(\s\+$\)', '', 'g')
endif
" Formating information for the preview window
if index(['f', 'p'], tagItem.kind[0])>=0
let szItemWord .= '('
if g:OmniCpp_ShowPrototypeInAbbr && has_key(tagItem, 'signature')
let szAbbr .= tagItem.signature
else
let szAbbr .= '('
endif
endif
let szItemInfo = ''
if s:hasPreviewWindow
let szItemInfo = omni#cpp#utils#GetPreviewWindowStringFromTagItem(tagItem)
endif
" If a function is a ctor we add a new key in the tagItem
if index(['f', 'p'], tagItem.kind[0])>=0
if match(szName, '^\~') < 0 && a:szTypeName =~ '\C\<'.szName.'$'
" It's a ctor
let tagItem['ctor'] = 1
elseif has_key(tagItem, 'access') && tagItem.access == 'friend'
" Friend function
let tagItem['friendfunc'] = 1
endif
endif
" Extending the tag item to a popup item
let tagItem['word'] = szItemWord
let tagItem['abbr'] = szAbbr
let tagItem['menu'] = szItemMenu
let tagItem['info'] = szItemInfo
let tagItem['dup'] = (s:hasPreviewWindow && index(['f', 'p', 'm'], tagItem.kind[0])>=0)
return tagItem
endfunc
" Get tag popup item list
function! s:TagPopupList(szTypeName, szBase)
let result = []
" Searching key in the result cache
let cacheResult = s:IsCached(s:CACHE_TAG_POPUP_ITEMS, a:szTypeName, a:szBase)
" Building the tag query, we don't forget dtors when a:szBase==''
if a:szTypeName!=''
" Scope search
let szTagQuery = '^' . a:szTypeName . '::' . a:szBase . '\~\?\w\+$'
else
" Global search
let szTagQuery = '^' . a:szBase . '\w\+$'
endif
" If the result is already in the cache we return it
if cacheResult[0]
let result = s:CACHE_TAG_POPUP_ITEMS[ cacheResult[1] ]
if cacheResult[0] == 2
let result = filter(copy(result), 'v:val.name =~ szTagQuery' )
endif
return result
endif
try
" Getting tags
let result = omni#common#utils#TagList(szTagQuery)
" We extend tag items to popup items
call map(result, 's:ExtendTagItemToPopupItem(v:val, a:szTypeName)')
" We store the result in a cache
if cacheResult[1] != ''
let s:CACHE_TAG_POPUP_ITEMS[ cacheResult[1] ] = result
endif
catch /^TagList:UserInterrupt$/
endtry
return result
endfunc
" Find complete matches for a completion on the global scope
function! s:SearchGlobalMembers(szBase)
if a:szBase != ''
let tagPopupList = s:TagPopupList('', a:szBase)
let tagPopupList = filter(copy(tagPopupList), g:omni#cpp#utils#szFilterGlobalScope)
call extend(s:popupItemResultList, tagPopupList)
endif
endfunc
" Search class, struct, union members
" @param resolvedTagItem: a resolved tag item
" @param szBase: string base
" @return list of tag items extended to popup items
function! s:SearchMembers(resolvedTagItem, szBase)
let result = []
if a:resolvedTagItem == {}
return result
endif
" Get type info without the starting '::'
let szTagName = omni#cpp#utils#ExtractTypeInfoFromTag(a:resolvedTagItem)[2:]
" Unnamed type case. A tag item representing an unnamed type is a variable
" ('v') a member ('m') or a typedef ('t')
if index(['v', 't', 'm'], a:resolvedTagItem.kind[0])>=0 && has_key(a:resolvedTagItem, 'typeref')
" We remove the 'struct:' or 'class:' etc...
let szTagName = substitute(a:resolvedTagItem.typeref, '^\w\+:', '', 'g')
endif
return copy(s:TagPopupList(szTagName, a:szBase))
endfunc
" Return if the tag env has changed
function! s:HasTagEnvChanged()
if s:CACHE_TAG_ENV == &tags
return 0
else
let s:CACHE_TAG_ENV = &tags
return 1
endif
endfunc
" Return if a tag file has changed in tagfiles()
function! s:HasATagFileOrTagEnvChanged()
if s:HasTagEnvChanged()
let s:CACHE_TAG_FILES = {}
return 1
endif
let result = 0
for tagFile in tagfiles()
if tagFile == ""
continue
endif
if has_key(s:CACHE_TAG_FILES, tagFile)
let currentFiletime = getftime(tagFile)
if currentFiletime > s:CACHE_TAG_FILES[tagFile]
" The file has changed, updating the cache
let s:CACHE_TAG_FILES[tagFile] = currentFiletime
let result = 1
endif
else
" We store the time of the file
let s:CACHE_TAG_FILES[tagFile] = getftime(tagFile)
let result = 1
endif
endfor
return result
endfunc
" Initialization
call s:HasATagFileOrTagEnvChanged()
" Filter same function signatures of base classes
function! s:FilterOverloadedFunctions(tagPopupList)
let result = []
for tagPopupItem in a:tagPopupList
if has_key(tagPopupItem, 'kind') && index(['f', 'p'], tagPopupItem.kind[0])>=0 && has_key(tagPopupItem, 'signature')
if !has_key(s:CACHE_OVERLOADED_FUNCTIONS, tagPopupItem.word . tagPopupItem.signature)
let s:CACHE_OVERLOADED_FUNCTIONS[tagPopupItem.word . tagPopupItem.signature] = 1
call extend(result, [tagPopupItem])
endif
else
call extend(result, [tagPopupItem])
endif
endfor
return result
endfunc
" Access filter
function! s:GetAccessFilter(szFilter, szAccessFilter)
let szFilter = a:szFilter
if g:OmniCpp_DisplayMode == 0
if a:szAccessFilter == 'public'
" We only get public members
let szFilter .= "&& v:val.access == 'public'"
elseif a:szAccessFilter == 'protected'
" We get public and protected members
let szFilter .= "&& v:val.access != 'private'"
endif
endif
return szFilter
endfunc
" Filter class members in the popup menu after a completion with -> or .
function! s:FilterClassMembers(tagPopupList, szAccessFilter)
let szFilter = "(!has_key(v:val, 'friendfunc') && !has_key(v:val, 'ctor') && has_key(v:val, 'kind') && index(['m', 'p', 'f'], v:val.kind[0])>=0 && has_key(v:val, 'access'))"
call filter(a:tagPopupList, s:GetAccessFilter(szFilter, a:szAccessFilter))
call extend(s:popupItemResultList, s:FilterOverloadedFunctions(a:tagPopupList))
endfunc
" Filter class scope members in the popup menu after a completion with ::
" We only display attribute and functions members that
" have an access information. We also display nested
" class, struct, union, and enums, typedefs
function! s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
let szFilter = "!has_key(v:val, 'friendfunc') && has_key(v:val, 'kind') && (index(['m', 'p', 'f'], v:val.kind[0])>=0 && has_key(v:val, 'access'))"
let szFilter = s:GetAccessFilter(szFilter, a:szAccessFilter)
let szFilter .= "|| index(['c','e','g','s','t','u'], v:val.kind[0])>=0"
call filter(a:tagPopupList, szFilter)
call extend(s:popupItemResultList, s:FilterOverloadedFunctions(a:tagPopupList))
endfunc
" Filter static class members in the popup menu
function! s:FilterStaticClassMembers(tagPopupList, szAccessFilter)
let szFilter = "!has_key(v:val, 'friendfunc') && has_key(v:val, 'kind') && (index(['m', 'p', 'f'], v:val.kind[0])>=0 && has_key(v:val, 'access') && match(v:val.cmd, '\\Cstatic')!=-1)"
let szFilter = s:GetAccessFilter(szFilter, a:szAccessFilter)
let szFilter = szFilter . "|| index(['c','e','g','n','s','t','u','v'], v:val.kind[0])>=0"
call filter(a:tagPopupList, szFilter)
call extend(s:popupItemResultList, s:FilterOverloadedFunctions(a:tagPopupList))
endfunc
" Filter scope members in the popup menu
function! s:FilterNamespaceScopeMembers(tagPopupList)
call extend(s:popupItemResultList, a:tagPopupList)
endfunc
" Init data at the start of completion
function! s:InitComplete()
" Reset the popup item list
let s:popupItemResultList = []
let s:CACHE_OVERLOADED_FUNCTIONS = {}
" Reset includes cache when the current working directory has changed
let szCurrentWorkingDir = getcwd()
if s:szCurrentWorkingDir != szCurrentWorkingDir
let s:szCurrentWorkingDir = szCurrentWorkingDir
let g:omni#cpp#includes#CACHE_INCLUDES = {}
let g:omni#cpp#includes#CACHE_FILE_TIME = {}
endif
" Has preview window ?
let s:hasPreviewWindow = match(&completeopt, 'preview')>=0
let bResetCache = 0
" Reset tag env or tag files dependent caches
if s:HasATagFileOrTagEnvChanged()
let bResetCache = 1
endif
if (s:OmniCpp_ShowScopeInAbbr != g:OmniCpp_ShowScopeInAbbr)
\|| (s:OmniCpp_ShowPrototypeInAbbr != g:OmniCpp_ShowPrototypeInAbbr)
\|| (s:OmniCpp_ShowAccess != g:OmniCpp_ShowAccess)
let s:OmniCpp_ShowScopeInAbbr = g:OmniCpp_ShowScopeInAbbr
let s:OmniCpp_ShowPrototypeInAbbr = g:OmniCpp_ShowPrototypeInAbbr
let s:OmniCpp_ShowAccess = g:OmniCpp_ShowAccess
let bResetCache = 1
endif
if s:hasPreviewWindow != s:hasPreviewWindowOld
let s:hasPreviewWindowOld = s:hasPreviewWindow
let bResetCache = 1
endif
if bResetCache
let g:omni#cpp#namespaces#CacheResolve = {}
let s:CACHE_TAG_POPUP_ITEMS = {}
let g:omni#cpp#utils#CACHE_TAG_INHERITS = {}
call garbagecollect()
endif
" Check for updates
for szIncludeName in keys(g:omni#cpp#includes#CACHE_INCLUDES)
let fTime = getftime(szIncludeName)
let bNeedUpdate = 0
if has_key(g:omni#cpp#includes#CACHE_FILE_TIME, szIncludeName)
if fTime != g:omni#cpp#includes#CACHE_FILE_TIME[szIncludeName]
let bNeedUpdate = 1
endif
else
let g:omni#cpp#includes#CACHE_FILE_TIME[szIncludeName] = fTime
let bNeedUpdate = 1
endif
if bNeedUpdate
" We have to update include list and namespace map of this file
call omni#cpp#includes#GetList(szIncludeName, 1)
call omni#cpp#namespaces#GetMapFromBuffer(szIncludeName, 1)
endif
endfor
let s:bDoNotComplete = 0
endfunc
" This function is used for the 'omnifunc' option.
function! omni#cpp#complete#Main(findstart, base)
if a:findstart
"call omni#common#debug#Start()
call s:InitComplete()
" Note: if s:bMayComplete==1 g:omni#cpp#items#data is build by MayComplete functions
if !s:bMayComplete
" If the cursor is in a comment we go out
if omni#cpp#utils#IsCursorInCommentOrString()
" Returning -1 is not enough we have to set a variable to let
" the second call of omni#cpp#complete knows that the
" cursor was in a comment
" Why is there a second call when the first call returns -1 ?
let s:bDoNotComplete = 1
return -1
endif
" We get items here (whend a:findstart==1) because GetItemsToComplete()
" depends on the cursor position.
" When a:findstart==0 the cursor position is modified
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction())
endif
" Get contexts stack
let s:contextStack = omni#cpp#namespaces#GetContexts()
" Reinit of may complete indicator
let s:bMayComplete = 0
return s:FindStartPositionOfCompletion()
endif
" If the cursor is in a comment we return an empty result
if s:bDoNotComplete
let s:bDoNotComplete = 0
return []
endif
if len(g:omni#cpp#items#data)==0
" A) CURRENT_SCOPE_COMPLETION_MODE
" 1) Displaying data of each context
let szAccessFilter = 'all'
for szCurrentContext in s:contextStack
if szCurrentContext == '::'
continue
endif
let resolvedTagItem = omni#cpp#utils#GetResolvedTagItem(s:contextStack, omni#cpp#utils#CreateTypeInfo(szCurrentContext))
if resolvedTagItem != {}
" We don't search base classes because bases classes are
" already in the context stack
let tagPopupList = s:SearchMembers(resolvedTagItem, a:base)
if index(['c','s'], resolvedTagItem.kind[0])>=0
" It's a class or struct
call s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
let szAccessFilter = 'protected'
else
" It's a namespace or union, we display all members
call s:FilterNamespaceScopeMembers(tagPopupList)
endif
endif
endfor
" 2) Displaying global scope members
if g:OmniCpp_GlobalScopeSearch
call s:SearchGlobalMembers(a:base)
endif
else
let typeInfo = omni#cpp#items#ResolveItemsTypeInfo(s:contextStack, g:omni#cpp#items#data)
if typeInfo != {}
if g:omni#cpp#items#data[-1].kind == 'itemScope'
" B) SCOPE_COMPLETION_MODE
if omni#cpp#utils#GetTypeInfoString(typeInfo)==''
call s:SearchGlobalMembers(a:base)
else
for resolvedTagItem in omni#cpp#utils#GetResolvedTags(s:contextStack, typeInfo)
let tagPopupList = s:SearchMembers(resolvedTagItem, a:base)
if index(['c','s'], resolvedTagItem.kind[0])>=0
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTag(resolvedTagItem)
if g:OmniCpp_DisplayMode==0
" We want to complete a class or struct
" If this class is a base class so we display all class members
if index(s:contextStack, szTypeInfo)<0
let szAccessFilter = 'public'
call s:FilterStaticClassMembers(tagPopupList, szAccessFilter)
else
let szAccessFilter = (s:contextStack[0] == szTypeInfo)? 'all' : 'protected'
call s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
endif
else
if index(s:contextStack, szTypeInfo)<0
let szAccessFilter = 'public'
else
let szAccessFilter = (s:contextStack[0] == szTypeInfo)? 'all' : 'protected'
endif
call s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
endif
else
" We want to complete a namespace
call s:FilterNamespaceScopeMembers(tagPopupList)
endif
endfor
endif
else
" C) CLASS_MEMBERS_COMPLETION_MODE
for resolvedTagItem in omni#cpp#utils#GetResolvedTags(s:contextStack, typeInfo)
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTag(resolvedTagItem)
if index(s:contextStack, szTypeInfo)<0
let szAccessFilter = 'public'
else
let szAccessFilter = (s:contextStack[0] == szTypeInfo)? 'all' : 'protected'
endif
call s:FilterClassMembers(s:SearchMembers(resolvedTagItem, a:base), szAccessFilter)
endfor
endif
endif
endif
"call omni#common#debug#End()
return s:popupItemResultList
endfunc
" 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
" Description: Omni completion script for cpp files
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
" Build the item list of an instruction
" An item is an instruction between a -> or . or ->* or .*
" We can sort an item in different kinds:
" eg: ((MyClass1*)(pObject))->_memberOfClass1.get() ->show()
" | cast | | member | | method | | method |
" @return a list of item
" an item is a dictionnary where keys are:
" tokens = list of token
" kind = itemVariable|itemCast|itemCppCast|itemTemplate|itemFunction|itemUnknown|itemThis|itemScope
function! omni#cpp#items#Get(tokens, ...)
let bGetWordUnderCursor = (a:0>0)? a:1 : 0
let result = []
let itemsDelimiters = ['->', '.', '->*', '.*']
let tokens = reverse(omni#cpp#utils#BuildParenthesisGroups(a:tokens))
" fsm states:
" 0 = initial state
" TODO: add description of fsm states
let state=(bGetWordUnderCursor)? 1 : 0
let item = {'tokens' : [], 'kind' : 'itemUnknown'}
let parenGroup=-1
for token in tokens
if state==0
if index(itemsDelimiters, token.value)>=0
let item = {'tokens' : [], 'kind' : 'itemUnknown'}
let state = 1
elseif token.value=='::'
let state = 9
let item.kind = 'itemScope'
" Maybe end of tokens
elseif token.kind =='cppOperatorPunctuator'
" If it's a cppOperatorPunctuator and the current token is not
" a itemsDelimiters or '::' we can exit
let state=-1
break
endif
elseif state==1
call insert(item.tokens, token)
if token.kind=='cppWord'
" It's an attribute member or a variable
let item.kind = 'itemVariable'
let state = 2
" Maybe end of tokens
elseif token.value=='this'
let item.kind = 'itemThis'
let state = 2
" Maybe end of tokens
elseif token.value==')'
let parenGroup = token.group
let state = 3
elseif token.value==']'
let parenGroup = token.group
let state = 4
elseif token.kind == 'cppDigit'
let state = -1
break
endif
elseif state==2
if index(itemsDelimiters, token.value)>=0
call insert(result, item)
let item = {'tokens' : [], 'kind' : 'itemUnknown'}
let state = 1
elseif token.value == '::'
call insert(item.tokens, token)
" We have to get namespace or classscope
let state = 8
" Maybe end of tokens
else
call insert(result, item)
let state=-1
break
endif
elseif state==3
call insert(item.tokens, token)
if token.value=='(' && token.group == parenGroup
let state = 5
" Maybe end of tokens
endif
elseif state==4
call insert(item.tokens, token)
if token.value=='[' && token.group == parenGroup
let state = 1
endif
elseif state==5
if token.kind=='cppWord'
" It's a function or method
let item.kind = 'itemFunction'
call insert(item.tokens, token)
let state = 2
" Maybe end of tokens
elseif token.value == '>'
" Maybe a cpp cast or template
let item.kind = 'itemTemplate'
call insert(item.tokens, token)
let parenGroup = token.group
let state = 6
else
" Perhaps it's a C cast eg: ((void*)(pData)) or a variable eg:(*pData)
let item.kind = omni#cpp#utils#GetCastType(item.tokens)
let state=-1
call insert(result, item)
break
endif
elseif state==6
call insert(item.tokens, token)
if token.value == '<' && token.group == parenGroup
" Maybe a cpp cast or template
let state = 7
endif
elseif state==7
call insert(item.tokens, token)
if token.kind=='cppKeyword'
" It's a cpp cast
let item.kind = omni#cpp#utils#GetCastType(item.tokens)
let state=-1
call insert(result, item)
break
else
" Template ?
let state=-1
call insert(result, item)
break
endif
elseif state==8
if token.kind=='cppWord'
call insert(item.tokens, token)
let state = 2
" Maybe end of tokens
else
let state=-1
call insert(result, item)
break
endif
elseif state==9
if token.kind == 'cppWord'
call insert(item.tokens, token)
let state = 10
" Maybe end of tokens
else
let state=-1
call insert(result, item)
break
endif
elseif state==10
if token.value == '::'
call insert(item.tokens, token)
let state = 9
" Maybe end of tokens
else
let state=-1
call insert(result, item)
break
endif
endif
endfor
if index([2, 5, 8, 9, 10], state)>=0
if state==5
let item.kind = omni#cpp#utils#GetCastType(item.tokens)
endif
call insert(result, item)
endif
return result
endfunc
" Resolve type information of items
" @param namespaces: list of namespaces used in the file
" @param szCurrentClassScope: the current class scope, only used for the first
" item to detect if this item is a class member (attribute, method)
" @param items: list of item, can be an empty list @see GetItemsToComplete
function! omni#cpp#items#ResolveItemsTypeInfo(contextStack, items)
" Note: kind = itemVariable|cCast|cppCast|template|function|itemUnknown|this
" For the first item, if it's a variable we try to detect the type of the
" variable with the function searchdecl. If it fails, thanks to the
" current class scope, we try to detect if the variable is an attribute
" member.
" If the kind of the item is a function, we have to first check if the
" function is a method of the class, if it fails we try to get a match in
" the global namespace. After that we get the returned type of the
" function.
" It the kind is a C cast or C++ cast, there is no problem, it's the
" easiest case. We just extract the type of the cast.
let szCurrentContext = ''
let typeInfo = {}
" Note: We search the decl only for the first item
let bSearchDecl = 1
for item in a:items
let curItem = item
if index(['itemVariable', 'itemFunction'], curItem.kind)>=0
" Note: a variable can be : MyNs::MyClass::_var or _var or (*pVar)
" or _var[0][0]
let szSymbol = s:GetSymbol(curItem.tokens)
" If we have MyNamespace::myVar
" We add MyNamespace in the context stack set szSymbol to myVar
if match(szSymbol, '::\w\+$') >= 0
let szCurrentContext = substitute(szSymbol, '::\w\+$', '', 'g')
let szSymbol = matchstr(szSymbol, '\w\+$')
endif
let tmpContextStack = a:contextStack
if szCurrentContext != ''
let tmpContextStack = [szCurrentContext] + a:contextStack
endif
if curItem.kind == 'itemVariable'
let typeInfo = s:GetTypeInfoOfVariable(tmpContextStack, szSymbol, bSearchDecl)
else
let typeInfo = s:GetTypeInfoOfReturnedType(tmpContextStack, szSymbol)
endif
elseif curItem.kind == 'itemThis'
if len(a:contextStack)
let typeInfo = omni#cpp#utils#CreateTypeInfo(substitute(a:contextStack[0], '^::', '', 'g'))
endif
elseif curItem.kind == 'itemCast'
let typeInfo = omni#cpp#utils#CreateTypeInfo(s:ResolveCCast(curItem.tokens))
elseif curItem.kind == 'itemCppCast'
let typeInfo = omni#cpp#utils#CreateTypeInfo(s:ResolveCppCast(curItem.tokens))
elseif curItem.kind == 'itemScope'
let typeInfo = omni#cpp#utils#CreateTypeInfo(substitute(s:TokensToString(curItem.tokens), '\s', '', 'g'))
endif
if omni#cpp#utils#IsTypeInfoValid(typeInfo)
let szCurrentContext = omni#cpp#utils#GetTypeInfoString(typeInfo)
endif
let bSearchDecl = 0
endfor
return typeInfo
endfunc
" Get symbol name
function! s:GetSymbol(tokens)
let szSymbol = ''
let state = 0
for token in a:tokens
if state == 0
if token.value == '::'
let szSymbol .= token.value
let state = 1
elseif token.kind == 'cppWord'
let szSymbol .= token.value
let state = 2
" Maybe end of token
endif
elseif state == 1
if token.kind == 'cppWord'
let szSymbol .= token.value
let state = 2
" Maybe end of token
else
" Error
break
endif
elseif state == 2
if token.value == '::'
let szSymbol .= token.value
let state = 1
else
break
endif
endif
endfor
return szSymbol
endfunc
" Search a declaration.
" eg: std::map
" can be empty
" Note: The returned type info can be a typedef
" The typedef resolution is done later
" @return
" - a dictionnary where keys are
" - type: the type of value same as type()
" - value: the value
function! s:GetTypeInfoOfVariable(contextStack, szVariable, bSearchDecl)
let result = {}
if a:bSearchDecl
" Search type of declaration
"let result = s:SearchTypeInfoOfDecl(a:szVariable)
let result = s:SearchDecl(a:szVariable)
endif
if result=={}
let szFilter = "index(['m', 'v'], v:val.kind[0])>=0"
let tagItem = s:ResolveSymbol(a:contextStack, a:szVariable, szFilter)
if tagItem=={}
return result
endif
let szCmdWithoutVariable = substitute(omni#cpp#utils#ExtractCmdFromTagItem(tagItem), '\C\<'.a:szVariable.'\>.*', '', 'g')
let tokens = omni#cpp#tokenizer#Tokenize(omni#cpp#utils#GetCodeFromLine(szCmdWithoutVariable))
let result = omni#cpp#utils#CreateTypeInfo(omni#cpp#utils#ExtractTypeInfoFromTokens(tokens))
" TODO: Namespace resolution for result
if result != {} && result.value==''
" result.value==''
" eg:
" struct
" {
" }gVariable;
if has_key(tagItem, 'typeref')
" Maybe the variable is a global var of an
" unnamed class, struct or union.
" eg:
" 1)
" struct
" {
" }gVariable;
" In this case we need the tags (the patched version)
" Note: We can have a named type like this:
" 2)
" class A
" {
" }gVariable;
if s:IsUnnamedType(tagItem)
" It's an unnamed type we are in the case 1)
let result = omni#cpp#utils#CreateTypeInfo(tagItem)
else
" It's not an unnamed type we are in the case 2)
" eg: tagItem.typeref = 'struct:MY_STRUCT::MY_SUBSTRUCT'
let szTypeRef = substitute(tagItem.typeref, '^\w\+:', '', '')
" eg: szTypeRef = 'MY_STRUCT::MY_SUBSTRUCT'
let result = omni#cpp#utils#CreateTypeInfo(szTypeRef)
endif
endif
endif
endif
return result
endfunc
" Get the type info string from the returned type of function
function! s:GetTypeInfoOfReturnedType(contextStack, szFunctionName)
let result = {}
let szFilter = "index(['f', 'p'], v:val.kind[0])>=0"
let tagItem = s:ResolveSymbol(a:contextStack, a:szFunctionName, szFilter)
if tagItem != {}
let szCmdWithoutVariable = substitute(omni#cpp#utils#ExtractCmdFromTagItem(tagItem), '\C\<'.a:szFunctionName.'\>.*', '', 'g')
let tokens = omni#cpp#tokenizer#Tokenize(omni#cpp#utils#GetCodeFromLine(szCmdWithoutVariable))
let result = omni#cpp#utils#CreateTypeInfo(omni#cpp#utils#ExtractTypeInfoFromTokens(tokens))
" TODO: Namespace resolution for result
return result
endif
return result
endfunc
" Resolve a symbol, return a tagItem
" Gets the first symbol found in the context stack
function! s:ResolveSymbol(contextStack, szSymbol, szTagFilter)
let tagItem = {}
for szCurrentContext in a:contextStack
if szCurrentContext != '::'
let szTagQuery = substitute(szCurrentContext, '^::', '', 'g').'::'.a:szSymbol
else
let szTagQuery = a:szSymbol
endif
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
call filter(tagList, a:szTagFilter)
if len(tagList)
let tagItem = tagList[0]
break
endif
endfor
return tagItem
endfunc
" Return if the tag item represent an unnamed type
function! s:IsUnnamedType(tagItem)
let bResult = 0
if has_key(a:tagItem, 'typeref')
" Note: Thanks for __anon !
let bResult = match(a:tagItem.typeref, '\C\<__anon') >= 0
endif
return bResult
endfunc
" Search the declaration of a variable and return the type info
function! s:SearchTypeInfoOfDecl(szVariable)
let szReVariable = '\C\<'.a:szVariable.'\>'
let originalPos = getpos('.')
let origPos = originalPos[1:2]
let curPos = origPos
let stopPos = origPos
while curPos !=[0,0]
" We go to the start of the current scope
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
if curPos != [0,0]
let matchPos = curPos
" Now want to search our variable but we don't want to go in child
" scope
while matchPos != [0,0]
let matchPos = searchpos('{\|'.szReVariable, 'W', stopPos[0])
if matchPos != [0,0]
" We ignore matches under comment
if omni#cpp#utils#IsCursorInCommentOrString()
continue
endif
" Getting the current line
let szLine = getline('.')
if match(szLine, szReVariable)>=0
" We found our variable
" Check if the current instruction is a decl instruction
let tokens = omni#cpp#utils#TokenizeCurrentInstruction()
let szTypeInfo = s:ExtractTypeInfoFromDecl(tokens)
if szTypeInfo != ''
call setpos('.', originalPos)
return omni#cpp#utils#CreateTypeInfo(szTypeInfo)
endif
else
" We found a child scope, we don't want to go in, thus
" we search for the end } of this child scope
let bracketEnd = searchpairpos('{', '', '}', 'nW', g:omni#cpp#utils#expIgnoreComments)
if bracketEnd == [0,0]
break
endif
if bracketEnd[0] >= stopPos[0]
" The end of the scope is after our cursor we stop
" the search
break
else
" We move the cursor and continue to search our
" variable
call setpos('.', [0, bracketEnd[0], bracketEnd[1], 0])
endif
endif
endif
endwhile
" Backing to the start of the scope
call setpos('.', [0,curPos[0], curPos[1], 0])
let stopPos = curPos
endif
endwhile
let result = {}
if s:LocalSearchDecl(a:szVariable)==0 && !omni#cpp#utils#IsCursorInCommentOrString()
let tokens = omni#cpp#utils#TokenizeCurrentInstruction()
let szTypeInfo = s:ExtractTypeInfoFromDecl(tokens)
if szTypeInfo != ''
let result = omni#cpp#utils#CreateTypeInfo(szTypeInfo)
endif
endif
call setpos('.', originalPos)
return result
endfunc
" Search a declaration
" @return
" - tokens of the current instruction if success
" - empty list if failure
function! s:SearchDecl(szVariable)
let result = {}
let originalPos = getpos('.')
let searchResult = s:LocalSearchDecl(a:szVariable)
if searchResult==0
" searchdecl() may detect a decl if the variable is in a conditional
" instruction (if, elseif, while etc...)
" We have to check if the detected decl is really a decl instruction
let tokens = omni#cpp#utils#TokenizeCurrentInstruction()
for token in tokens
" Simple test
if index(['if', 'elseif', 'while', 'for', 'switch'], token.value)>=0
" Invalid declaration instruction
call setpos('.', originalPos)
return result
endif
endfor
let szTypeInfo = s:ExtractTypeInfoFromDecl(tokens)
if szTypeInfo != ''
let result = omni#cpp#utils#CreateTypeInfo(szTypeInfo)
endif
endif
call setpos('.', originalPos)
return result
endfunc
" Extract the type info string from an instruction.
" We use a small parser to extract the type
" We parse the code according to a C++ BNF from: http://www.nongnu.org/hcb/#basic.link
" @param tokens: token list of the current instruction
function! s:ExtractTypeInfoFromDecl(tokens)
return omni#cpp#utils#ExtractTypeInfoFromTokens(a:tokens)
endfunc
" Convert tokens to string
function! s:TokensToString(tokens)
let result = ''
for token in a:tokens
let result = result . token.value . ' '
endfor
return result[:-2]
endfunc
" Resolve a cast.
" Resolve a C++ cast
" @param list of token. tokens must be a list that represents
" a cast expression (C++ cast) the function does not control
" if it's a cast or not
" eg: static_cast<MyClass*>(something)
" @return type info string
function! s:ResolveCppCast(tokens)
return omni#cpp#utils#ExtractTypeInfoFromTokens(s:ResolveCast(a:tokens, '<', '>'))
endfunc
" Resolve a cast.
" Resolve a C cast
" @param list of token. tokens must be a list that represents
" a cast expression (C cast) the function does not control
" if it's a cast or not
" eg: (MyClass*)something
" @return type info string
function! s:ResolveCCast(tokens)
return omni#cpp#utils#ExtractTypeInfoFromTokens(s:ResolveCast(a:tokens, '(', ')'))
endfunc
" Resolve a cast.
" Resolve a C cast
" @param list of token. tokens must be a list that represents
" a cast expression (C cast) the function does not control
" if it's a cast or not
" eg: (MyClass*)something
" @return type tokens
function! s:ResolveCast(tokens, startChar, endChar)
let tokens = omni#cpp#utils#BuildParenthesisGroups(a:tokens)
" We remove useless parenthesis eg: (((MyClass)))
let tokens = omni#cpp#utils#SimplifyParenthesis(tokens)
let countItem=0
let startIndex = -1
let endIndex = -1
let i = 0
for token in tokens
if startIndex==-1
if token.value==a:startChar
let countItem += 1
let startIndex = i
endif
else
if token.value==a:startChar
let countItem += 1
elseif token.value==a:endChar
let countItem -= 1
endif
if countItem==0
let endIndex = i
break
endif
endif
let i+=1
endfor
return tokens[startIndex+1 : endIndex-1]
endfunc
" Replacement for build-in function 'searchdecl'
" It does not require that the upper-level bracket is in the first column.
" Otherwise it should be equal to 'searchdecl(name, 0, 1)'
" @param name: name of variable to find declaration for
function! s:LocalSearchDecl(name)
if g:OmniCpp_LocalSearchDecl == 0
let bUserIgnoreCase = &ignorecase
" Forcing the noignorecase option
" avoid bug when, for example, if we have a declaration like this : "A a;"
set noignorecase
let result = searchdecl(a:name, 0, 1)
" Restoring user's setting
let &ignorecase = bUserIgnoreCase
return result
endif
let lastpos = getpos('.')
let winview = winsaveview()
let lastfoldenable = &foldenable
let &foldenable = 0
" We add \C (noignorecase) to
" avoid bug when, for example, if we have a declaration like this : "A a;"
let varname = "\\C\\<" . a:name . "\\>"
" Go to first blank line before begin of highest scope
normal 99[{
let scopepos = getpos('.')
while (line('.') > 1) && (len(split(getline('.'))) > 0)
call cursor(line('.')-1, 0)
endwhile
let declpos = [ 0, 0, 0, 0 ]
while search(varname, '', scopepos[1]) > 0
" Check if we are a string or a comment
if omni#cpp#utils#IsCursorInCommentOrString()
continue
endif
" Remember match
let declpos = getpos('.')
endwhile
if declpos[1] != 0
" We found a match
call winrestview(winview)
call setpos('.', declpos)
let &foldenable = lastfoldenable
return 0
endif
while search(varname, '', lastpos[1]) > 0
" Check if current scope is ending before variable
let old_cur = getpos('.')
normal ]}
let new_cur = getpos('.')
call setpos('.', old_cur)
if (new_cur[1] < lastpos[1]) || ((new_cur[1] == lastpos[1]) && (new_cur[2] < lastpos[2]))
continue
endif
" Check if we are a string or a comment
if omni#cpp#utils#IsCursorInCommentOrString()
continue
endif
" We found match
call winrestview(winview)
call setpos('.', old_cur)
let &foldenable = lastfoldenable
return 0
endwhile
" No match found.
call winrestview(winview)
let &foldenable = lastfoldenable
return 1
endfunc
" Description: Omni completion script for cpp files
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
" Check if we can use omni completion in the current buffer
function! s:CanUseOmnicompletion()
" For C and C++ files and only if the omnifunc is omni#cpp#complete#Main
return (index(['c', 'cpp'], &filetype)>=0 && &omnifunc == 'omni#cpp#complete#Main' && !omni#cpp#utils#IsCursorInCommentOrString())
endfunc
" Return the mapping of omni completion
function! omni#cpp#maycomplete#Complete()
let szOmniMapping = "\<C-X>\<C-O>"
" 0 = don't select first item
" 1 = select first item (inserting it to the text, default vim behaviour)
" 2 = select first item (without inserting it to the text)
if g:OmniCpp_SelectFirstItem == 0
" We have to force the menuone option to avoid confusion when there is
" only one popup item
set completeopt-=menu
set completeopt+=menuone
let szOmniMapping .= "\<C-P>"
elseif g:OmniCpp_SelectFirstItem == 2
" We have to force the menuone option to avoid confusion when there is
" only one popup item
set completeopt-=menu
set completeopt+=menuone
let szOmniMapping .= "\<C-P>"
let szOmniMapping .= "\<C-R>=pumvisible() ? \"\\<down>\" : \"\"\<cr>"
endif
return szOmniMapping
endfunc
" May complete function for dot
function! omni#cpp#maycomplete#Dot()
if s:CanUseOmnicompletion() && g:OmniCpp_MayCompleteDot
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction('.'))
if len(g:omni#cpp#items#data)
let s:bMayComplete = 1
return '.' . omni#cpp#maycomplete#Complete()
endif
endif
return '.'
endfunc
" May complete function for arrow
function! omni#cpp#maycomplete#Arrow()
if s:CanUseOmnicompletion() && g:OmniCpp_MayCompleteArrow
let index = col('.') - 2
if index >= 0
let char = getline('.')[index]
if char == '-'
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction('>'))
if len(g:omni#cpp#items#data)
let s:bMayComplete = 1
return '>' . omni#cpp#maycomplete#Complete()
endif
endif
endif
endif
return '>'
endfunc
" May complete function for double points
function! omni#cpp#maycomplete#Scope()
if s:CanUseOmnicompletion() && g:OmniCpp_MayCompleteScope
let index = col('.') - 2
if index >= 0
let char = getline('.')[index]
if char == ':'
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction(':'))
if len(g:omni#cpp#items#data)
if len(g:omni#cpp#items#data[-1].tokens) && g:omni#cpp#items#data[-1].tokens[-1].value != '::'
let s:bMayComplete = 1
return ':' . omni#cpp#maycomplete#Complete()
endif
endif
endif
endif
endif
return ':'
endfunc
" Description: Omni completion script for cpp files
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
let g:omni#cpp#namespaces#CacheResolve = {}
let g:omni#cpp#namespaces#CacheUsing = {}
" TODO: For the next release
"let g:omni#cpp#namespaces#CacheAlias = {}
" Get the using namespace list from a line
function! s:GetNamespaceAliasListFromLine(szLine)
let result = {}
let tokens = omni#cpp#tokenizer#Tokenize(a:szLine)
let szAlias = ''
let szNamespace = ''
let state = 0
for token in tokens
if state==0
let szAlias = ''
let szNamespace = ''
if token.value == '/*'
let state = 1
elseif token.value == '//'
" It's a comment
let state = -1
break
elseif token.value == 'namespace'
let state = 2
endif
elseif state==1
if token.value == '*/'
let state=0
endif
elseif state==2
if token.kind == 'cppWord'
let szAlias .= token.value
let state = 3
else
let state = -1
break
endif
elseif state == 3
if token.value == '='
let state = 4
else
let state = -1
break
endif
elseif state == 4
if token.value == '::'
let szNamespace .= token.value
let state = 5
elseif token.kind == 'cppWord'
let szNamespace .= token.value
let state = 6
" Maybe end of tokens
endif
elseif state==5
if token.kind == 'cppWord'
let szNamespace .= token.value
let state = 6
" Maybe end of tokens
else
" Error, we can't have 'namespace ALIAS = Something::'
let state = -1
break
endif
elseif state==6
if token.value == '::'
let szNamespace .= token.value
let state = 5
else
call extend(result, {szAlias : szNamespace})
let state = 0
endif
endif
endfor
if state == 6
call extend(result, {szAlias : szNamespace})
endif
return result
endfunc
" Get the using namespace list from a line
function! s:GetNamespaceListFromLine(szLine)
let result = []
let tokens = omni#cpp#tokenizer#Tokenize(a:szLine)
let szNamespace = ''
let state = 0
for token in tokens
if state==0
let szNamespace = ''
if token.value == '/*'
let state = 1
elseif token.value == '//'
" It's a comment
let state = -1
break
elseif token.value == 'using'
let state = 2
endif
elseif state==1
if token.value == '*/'
let state=0
endif
elseif state==2
if token.value == 'namespace'
let state = 3
else
" Error, 'using' must be followed by 'namespace'
let state = -1
break
endif
elseif state==3
if token.value == '::'
let szNamespace .= token.value
let state = 4
elseif token.kind == 'cppWord'
let szNamespace .= token.value
let state = 5
" Maybe end of tokens
endif
elseif state==4
if token.kind == 'cppWord'
let szNamespace .= token.value
let state = 5
" Maybe end of tokens
else
" Error, we can't have 'using namespace Something::'
let state = -1
break
endif
elseif state==5
if token.value == '::'
let szNamespace .= token.value
let state = 4
else
call extend(result, [szNamespace])
let state = 0
endif
endif
endfor
if state == 5
call extend(result, [szNamespace])
endif
return result
endfunc
" Get the namespace list from a namespace map
function! s:GetUsingNamespaceListFromMap(namespaceMap, ...)
let stopLine = 0
if a:0>0
let stopLine = a:1
endif
let result = []
let keys = sort(keys(a:namespaceMap), 'omni#common#utils#CompareNumber')
for i in keys
if stopLine != 0 && i > stopLine
break
endif
call extend(result, a:namespaceMap[i])
endfor
return result
endfunc
" Get global using namespace list from the current buffer
function! omni#cpp#namespaces#GetListFromCurrentBuffer(...)
let namespaceMap = s:GetAllUsingNamespaceMapFromCurrentBuffer()
let result = []
if namespaceMap != {}
let result = s:GetUsingNamespaceListFromMap(namespaceMap, (a:0 > 0)? a:1 : line('.'))
endif
return result
endfunc
" Get global using namespace map from the current buffer and include files recursively
function! s:GetAllUsingNamespaceMapFromCurrentBuffer(...)
let includeGuard = (a:0>0)? a:1 : {}
let szBufferName = getreg("%")
let szFilePath = omni#cpp#utils#ResolveFilePath(szBufferName)
let szFilePath = (szFilePath=='')? szBufferName : szFilePath
let namespaceMap = {}
if has_key(includeGuard, szFilePath)
return namespaceMap
else
let includeGuard[szFilePath] = 1
endif
let namespaceMap = omni#cpp#namespaces#GetMapFromCurrentBuffer()
if g:OmniCpp_NamespaceSearch != 2
" We don't search included files if OmniCpp_NamespaceSearch != 2
return namespaceMap
endif
for inc in omni#cpp#includes#GetList()
let lnum = inc.pos[0]
let tmpMap = s:GetAllUsingNamespaceMapFromFile(inc.include, includeGuard)
if tmpMap != {}
if has_key(namespaceMap, lnum)
call extend(namespaceMap[lnum], s:GetUsingNamespaceListFromMap(tmpMap))
else
let namespaceMap[lnum] = s:GetUsingNamespaceListFromMap(tmpMap)
endif
endif
endfor
return namespaceMap
endfunc
" Get global using namespace map from a file and include files recursively
function! s:GetAllUsingNamespaceMapFromFile(szFilePath, ...)
let includeGuard = {}
if a:0 >0
let includeGuard = a:1
endif
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
let szFilePath = (szFilePath=='')? a:szFilePath : szFilePath
let namespaceMap = {}
if has_key(includeGuard, szFilePath)
return namespaceMap
else
let includeGuard[szFilePath] = 1
endif
" If g:OmniCpp_NamespaceSearch == 1 (search namespaces only in the current
" buffer) we don't use cache for the current buffer
let namespaceMap = omni#cpp#namespaces#GetMapFromBuffer(szFilePath, g:OmniCpp_NamespaceSearch==1)
if g:OmniCpp_NamespaceSearch != 2
" We don't search included files if OmniCpp_NamespaceSearch != 2
return namespaceMap
endif
for inc in omni#cpp#includes#GetList(szFilePath)
let lnum = inc.pos[0]
let tmpMap = s:GetAllUsingNamespaceMapFromFile(inc.include, includeGuard)
if tmpMap != {}
if has_key(namespaceMap, lnum)
call extend(namespaceMap[lnum], s:GetUsingNamespaceListFromMap(tmpMap))
else
let namespaceMap[lnum] = s:GetUsingNamespaceListFromMap(tmpMap)
endif
endif
endfor
return namespaceMap
endfunc
" Get global using namespace map from a the current buffer
function! omni#cpp#namespaces#GetMapFromCurrentBuffer()
let namespaceMap = {}
let originalPos = getpos('.')
call setpos('.', [0, 1, 1, 0])
let curPos = [1,1]
while curPos != [0,0]
let curPos = searchpos('\C^using\s\+namespace', 'W')
if curPos != [0,0]
let szLine = getline('.')
let startPos = curPos[1]
let endPos = match(szLine, ';', startPos-1)
if endPos!=-1
" We get the namespace list from the line
let namespaceMap[curPos[0]] = s:GetNamespaceListFromLine(szLine)
endif
endif
endwhile
call setpos('.', originalPos)
return namespaceMap
endfunc
" Get global using namespace map from a file
function! omni#cpp#namespaces#GetMapFromBuffer(szFilePath, ...)
let bUpdate = 0
if a:0 > 0
let bUpdate = a:1
endif
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
let szFilePath = (szFilePath=='')? a:szFilePath : szFilePath
if !bUpdate && has_key(g:omni#cpp#namespaces#CacheUsing, szFilePath)
return copy(g:omni#cpp#namespaces#CacheUsing[szFilePath])
endif
let namespaceMap = {}
" The file exists, we get the global namespaces in this file
let szFixedPath = escape(szFilePath, g:omni#cpp#utils#szEscapedCharacters)
execute 'silent! lvimgrep /\C^using\s\+namespace/gj '.szFixedPath
" key = line number
" value = list of namespaces
let listQuickFix = getloclist(0)
for qf in listQuickFix
let szLine = qf.text
let startPos = qf.col
let endPos = match(szLine, ';', startPos-1)
if endPos!=-1
" We get the namespace list from the line
let namespaceMap[qf.lnum] = s:GetNamespaceListFromLine(szLine)
endif
endfor
if szFixedPath != ''
let g:omni#cpp#namespaces#CacheUsing[szFixedPath] = namespaceMap
endif
return copy(namespaceMap)
endfunc
" Get the stop position when searching for local variables
function! s:GetStopPositionForLocalSearch()
" Stop position when searching a local variable
let originalPos = getpos('.')
let origPos = originalPos[1:2]
let stopPosition = origPos
let curPos = origPos
while curPos !=[0,0]
let stopPosition = curPos
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
endwhile
call setpos('.', originalPos)
return stopPosition
endfunc
" Get namespaces alias used at the cursor postion in a vim buffer
" Note: The result depends on the current cursor position
" @return
" - Map of namespace alias
function! s:GetNamespaceAliasMap()
" We store the cursor position because searchpairpos() moves the cursor
let result = {}
let originalPos = getpos('.')
let origPos = originalPos[1:2]
let stopPos = s:GetStopPositionForLocalSearch()
let stopLine = stopPos[0]
let curPos = origPos
let lastLine = 0
let nextStopLine = origPos[0]
let szReAlias = '\Cnamespace\s\+\w\+\s\+='
while curPos !=[0,0]
let curPos = searchpos('}\|\('. szReAlias .'\)', 'bW',stopLine)
if curPos!=[0,0] && curPos[0]!=lastLine
let lastLine = curPos[0]
let szLine = getline('.')
if origPos[0] == curPos[0]
" We get the line until cursor position
let szLine = szLine[:origPos[1]]
endif
let szLine = omni#cpp#utils#GetCodeFromLine(szLine)
if match(szLine, szReAlias)<0
" We found a '}'
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
else
" We get the namespace alias from the line
call extend(result, s:GetNamespaceAliasListFromLine(szLine))
let nextStopLine = curPos[0]
endif
endif
endwhile
" Setting the cursor to the original position
call setpos('.', originalPos)
call s:ResolveAliasKeys(result)
return result
endfunc
" Resolve an alias
" eg: namespace IAmAnAlias1 = Ns1
" eg: namespace IAmAnAlias2 = IAmAnAlias1::Ns2
" => IAmAnAlias2 = Ns1::Ns2
function! s:ResolveAliasKey(mapNamespaceAlias, szAlias)
let szResult = a:mapNamespaceAlias[a:szAlias]
" ::Ns1::Ns2::Ns3 => ['Ns1', 'Ns2', 'Ns3']
let listNamespace = split(szResult, '::')
if len(listNamespace)
" szBeginPart = 'Ns1'
let szBeginPart = remove(listNamespace, 0)
" Is 'Ns1' an alias ?
if has_key(a:mapNamespaceAlias, szBeginPart) && szBeginPart != a:szAlias
" Resolving alias 'Ns1'
" eg: Ns1 = NsResolved
let szResult = s:ResolveAliasKey(a:mapNamespaceAlias, szBeginPart)
" szEndPart = 'Ns2::Ns3'
let szEndPart = join(listNamespace, '::')
if szEndPart != ''
" Concatenation => szResult = 'NsResolved::Ns2::Ns3'
let szResult .= '::' . szEndPart
endif
endif
endif
return szResult
endfunc
" Resolve all keys in the namespace alias map
function! s:ResolveAliasKeys(mapNamespaceAlias)
let mapNamespaceAlias = a:mapNamespaceAlias
call map(mapNamespaceAlias, 's:ResolveAliasKey(mapNamespaceAlias, v:key)')
endfunc
" Resolve namespace alias
function! omni#cpp#namespaces#ResolveAlias(mapNamespaceAlias, szNamespace)
let szResult = a:szNamespace
" ::Ns1::Ns2::Ns3 => ['Ns1', 'Ns2', 'Ns3']
let listNamespace = split(a:szNamespace, '::')
if len(listNamespace)
" szBeginPart = 'Ns1'
let szBeginPart = remove(listNamespace, 0)
" Is 'Ns1' an alias ?
if has_key(a:mapNamespaceAlias, szBeginPart)
" Resolving alias 'Ns1'
" eg: Ns1 = NsResolved
let szResult = a:mapNamespaceAlias[szBeginPart]
" szEndPart = 'Ns2::Ns3'
let szEndPart = join(listNamespace, '::')
if szEndPart != ''
" Concatenation => szResult = 'NsResolved::Ns2::Ns3'
let szResult .= '::' . szEndPart
endif
" If a:szNamespace starts with '::' we add '::' to the beginning
" of the result
if match(a:szNamespace, '^::')>=0
let szResult = omni#cpp#utils#SimplifyScope('::' . szResult)
endif
endif
endif
return szResult
endfunc
" Resolve namespace alias
function! s:ResolveAliasInNamespaceList(mapNamespaceAlias, listNamespaces)
call map(a:listNamespaces, 'omni#cpp#namespaces#ResolveAlias(a:mapNamespaceAlias, v:val)')
endfunc
" Get namespaces used at the cursor postion in a vim buffer
" Note: The result depends on the current cursor position
" @return
" - List of namespace used in the reverse order
function! omni#cpp#namespaces#GetUsingNamespaces()
" We have to get local using namespace declarations
" We need the current cursor position and the position of the start of the
" current scope
" We store the cursor position because searchpairpos() moves the cursor
let result = []
let originalPos = getpos('.')
let origPos = originalPos[1:2]
let stopPos = s:GetStopPositionForLocalSearch()
let stopLine = stopPos[0]
let curPos = origPos
let lastLine = 0
let nextStopLine = origPos[0]
while curPos !=[0,0]
let curPos = searchpos('\C}\|\(using\s\+namespace\)', 'bW',stopLine)
if curPos!=[0,0] && curPos[0]!=lastLine
let lastLine = curPos[0]
let szLine = getline('.')
if origPos[0] == curPos[0]
" We get the line until cursor position
let szLine = szLine[:origPos[1]]
endif
let szLine = omni#cpp#utils#GetCodeFromLine(szLine)
if match(szLine, '\Cusing\s\+namespace')<0
" We found a '}'
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
else
" We get the namespace list from the line
let result = s:GetNamespaceListFromLine(szLine) + result
let nextStopLine = curPos[0]
endif
endif
endwhile
" Setting the cursor to the original position
call setpos('.', originalPos)
" 2) Now we can get all global using namespace declaration from the
" beginning of the file to nextStopLine
let result = omni#cpp#namespaces#GetListFromCurrentBuffer(nextStopLine) + result
" Resolving alias in the namespace list
" TODO: For the next release
"let g:omni#cpp#namespaces#CacheAlias= s:GetNamespaceAliasMap()
"call s:ResolveAliasInNamespaceList(g:omni#cpp#namespaces#CacheAlias, result)
return ['::'] + result
endfunc
" Resolve a using namespace regarding the current context
" For each namespace used:
" - We get all possible contexts where the namespace
" can be define
" - We do a comparison test of each parent contexts with the current
" context list
" - If one and only one parent context is present in the
" current context list we add the namespace in the current
" context
" - If there is more than one of parent contexts in the
" current context the namespace is ambiguous
" @return
" - result item
" - kind = 0|1
" - 0 = unresolved or error
" - 1 = resolved
" - value = resolved namespace
function! s:ResolveNamespace(namespace, mapCurrentContexts)
let result = {'kind':0, 'value': ''}
" If the namespace is already resolved we add it in the list of
" current contexts
if match(a:namespace, '^::')>=0
let result.kind = 1
let result.value = a:namespace
return result
elseif match(a:namespace, '\w\+::\w\+')>=0
let mapCurrentContextsTmp = copy(a:mapCurrentContexts)
let resolvedItem = {}
for nsTmp in split(a:namespace, '::')
let resolvedItem = s:ResolveNamespace(nsTmp, mapCurrentContextsTmp)
if resolvedItem.kind
" Note: We don't extend the map
let mapCurrentContextsTmp = {resolvedItem.value : 1}
else
break
endif
endfor
if resolvedItem!={} && resolvedItem.kind
let result.kind = 1
let result.value = resolvedItem.value
endif
return result
endif
" We get all possible parent contexts of this namespace
let listTagsOfNamespace = []
if has_key(g:omni#cpp#namespaces#CacheResolve, a:namespace)
let listTagsOfNamespace = g:omni#cpp#namespaces#CacheResolve[a:namespace]
else
let listTagsOfNamespace = omni#common#utils#TagList('^'.a:namespace.'$')
let g:omni#cpp#namespaces#CacheResolve[a:namespace] = listTagsOfNamespace
endif
if len(listTagsOfNamespace)==0
return result
endif
call filter(listTagsOfNamespace, 'v:val.kind[0]=="n"')
" We extract parent context from tags
" We use a map to avoid multiple entries
let mapContext = {}
for tagItem in listTagsOfNamespace
let szParentContext = omni#cpp#utils#ExtractScope(tagItem)
let mapContext[szParentContext] = 1
endfor
let listParentContext = keys(mapContext)
" Now for each parent context we test if the context is in the current
" contexts list
let listResolvedNamespace = []
for szParentContext in listParentContext
if has_key(a:mapCurrentContexts, szParentContext)
call extend(listResolvedNamespace, [omni#cpp#utils#SimplifyScope(szParentContext.'::'.a:namespace)])
endif
endfor
" Now we know if the namespace is ambiguous or not
let len = len(listResolvedNamespace)
if len==1
" Namespace resolved
let result.kind = 1
let result.value = listResolvedNamespace[0]
elseif len > 1
" Ambiguous namespace, possible matches are in listResolvedNamespace
else
" Other cases
endif
return result
endfunc
" Resolve namespaces
"@return
" - List of resolved namespaces
function! omni#cpp#namespaces#ResolveAll(namespacesUsed)
" We add the default context '::'
let contextOrder = 0
let mapCurrentContexts = {}
" For each namespace used:
" - We get all possible contexts where the namespace
" can be define
" - We do a comparison test of each parent contexts with the current
" context list
" - If one and only one parent context is present in the
" current context list we add the namespace in the current
" context
" - If there is more than one of parent contexts in the
" current context the namespace is ambiguous
for ns in a:namespacesUsed
let resolvedItem = s:ResolveNamespace(ns, mapCurrentContexts)
if resolvedItem.kind
let contextOrder+=1
let mapCurrentContexts[resolvedItem.value] = contextOrder
endif
endfor
" Build the list of current contexts from the map, we have to keep the
" order
let mapReorder = {}
for key in keys(mapCurrentContexts)
let mapReorder[ mapCurrentContexts[key] ] = key
endfor
let result = []
for key in sort(keys(mapReorder))
call extend(result, [mapReorder[key]])
endfor
return result
endfunc
" Build the context stack
function! s:BuildContextStack(namespaces, szCurrentScope)
let result = copy(a:namespaces)
if a:szCurrentScope != '::'
let tagItem = omni#cpp#utils#GetResolvedTagItem(a:namespaces, omni#cpp#utils#CreateTypeInfo(a:szCurrentScope))
if has_key(tagItem, 'inherits')
let listBaseClass = omni#cpp#utils#GetClassInheritanceList(a:namespaces, omni#cpp#utils#CreateTypeInfo(a:szCurrentScope))
let result = listBaseClass + result
elseif has_key(tagItem, 'kind') && index(['c', 's', 'u', 'n'], tagItem.kind[0])>=0
call insert(result, omni#cpp#utils#ExtractTypeInfoFromTag(tagItem))
endif
endif
return result
endfunc
" Returns the class scope at the current position of the cursor
" @return a string that represents the class scope
" eg: ::NameSpace1::Class1
" The returned string always starts with '::'
" Note: In term of performance it's the weak point of the script
function! s:GetClassScopeAtCursor()
" We store the cursor position because searchpairpos() moves the cursor
let originalPos = getpos('.')
let endPos = originalPos[1:2]
let listCode = []
let result = {'namespaces': [], 'scope': ''}
while endPos!=[0,0]
let endPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
let szReStartPos = '[;{}]\|\%^'
let startPos = searchpairpos(szReStartPos, '', '{', 'bWn', g:omni#cpp#utils#expIgnoreComments)
" If the file starts with a comment so the startPos can be [0,0]
" we change it to [1,1]
if startPos==[0,0]
let startPos = [1,1]
endif
" Get lines backward from cursor position to last ; or { or }
" or when we are at the beginning of the file.
" We store lines in listCode
if endPos!=[0,0]
" We remove the last character which is a '{'
" We also remove starting { or } or ; if exits
let szCodeWithoutComments = substitute(omni#cpp#utils#GetCode(startPos, endPos)[:-2], '^[;{}]', '', 'g')
call insert(listCode, {'startLine' : startPos[0], 'code' : szCodeWithoutComments})
endif
endwhile
" Setting the cursor to the original position
call setpos('.', originalPos)
let listClassScope = []
let bResolved = 0
let startLine = 0
" Now we can check in the list of code if there is a function
for code in listCode
" We get the name of the namespace, class, struct or union
" and we store it in listClassScope
let tokens = omni#cpp#tokenizer#Tokenize(code.code)
let bContinue=0
let bAddNamespace = 0
let state=0
for token in tokens
if state==0
if index(['namespace', 'class', 'struct', 'union'], token.value)>=0
if token.value == 'namespace'
let bAddNamespace = 1
endif
let state= 1
" Maybe end of tokens
endif
elseif state==1
if token.kind == 'cppWord'
" eg: namespace MyNs { class MyCl {}; }
" => listClassScope = [MyNs, MyCl]
call extend( listClassScope , [token.value] )
" Add the namespace in result
if bAddNamespace
call extend(result.namespaces, [token.value])
let bAddNamespace = 0
endif
let bContinue=1
break
endif
endif
endfor
if bContinue==1
continue
endif
" Simple test to check if we have a chance to find a
" class method
let aPos = matchend(code.code, '::\s*\~*\s*\w\+\s*(')
if aPos ==-1
continue
endif
let startLine = code.startLine
let listTmp = []
" eg: 'void MyNamespace::MyClass::foo('
" => tokens = ['MyClass', '::', 'MyNamespace', 'void']
let tokens = reverse(omni#cpp#tokenizer#Tokenize(code.code[:aPos-1])[:-4])
let state = 0
" Reading tokens backward
for token in tokens
if state==0
if token.kind=='cppWord'
call insert(listTmp, token.value)
let state=1
endif
elseif state==1
if token.value=='::'
let state=2
else
break
endif
elseif state==2
if token.kind=='cppWord'
call insert(listTmp, token.value)
let state=1
else
break
endif
endif
endfor
if len(listTmp)
if len(listClassScope)
let bResolved = 1
" Merging class scopes
" eg: current class scope = 'MyNs::MyCl1'
" method class scope = 'MyCl1::MyCl2'
" If we add the method class scope to current class scope
" we'll have MyNs::MyCl1::MyCl1::MyCl2 => it's wrong
" we want MyNs::MyCl1::MyCl2
let index = 0
for methodClassScope in listTmp
if methodClassScope==listClassScope[-1]
let listTmp = listTmp[index+1:]
break
else
let index+=1
endif
endfor
endif
call extend(listClassScope, listTmp)
break
endif
endfor
let szClassScope = '::'
if len(listClassScope)
if bResolved
let szClassScope .= join(listClassScope, '::')
else
let szClassScope = join(listClassScope, '::')
" The class scope is not resolved, we have to check using
" namespace declarations and search the class scope in each
" namespace
if startLine != 0
let namespaces = ['::'] + omni#cpp#namespaces#GetListFromCurrentBuffer(startLine)
let namespaces = omni#cpp#namespaces#ResolveAll(namespaces)
let tagItem = omni#cpp#utils#GetResolvedTagItem(namespaces, omni#cpp#utils#CreateTypeInfo(szClassScope))
if tagItem != {}
let szClassScope = omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)
endif
endif
endif
endif
let result.scope = szClassScope
return result
endfunc
" Get all contexts at the cursor position
function! omni#cpp#namespaces#GetContexts()
" Get the current class scope at the cursor, the result depends on the current cursor position
let scopeItem = s:GetClassScopeAtCursor()
let listUsingNamespace = copy(g:OmniCpp_DefaultNamespaces)
call extend(listUsingNamespace, scopeItem.namespaces)
if g:OmniCpp_NamespaceSearch && &filetype != 'c'
" Get namespaces used in the file until the cursor position
let listUsingNamespace = omni#cpp#namespaces#GetUsingNamespaces() + listUsingNamespace
" Resolving namespaces, removing ambiguous namespaces
let namespaces = omni#cpp#namespaces#ResolveAll(listUsingNamespace)
else
let namespaces = ['::'] + listUsingNamespace
endif
call reverse(namespaces)
" Building context stack from namespaces and the current class scope
return s:BuildContextStack(namespaces, scopeItem.scope)
endfunc
" Description: Omni completion script for cpp files
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
function! omni#cpp#settings#Init()
" Global scope search on/off
" 0 = disabled
" 1 = enabled
if !exists('g:OmniCpp_GlobalScopeSearch')
let g:OmniCpp_GlobalScopeSearch = 1
endif
" Sets the namespace search method
" 0 = disabled
" 1 = search namespaces in the current file
" 2 = search namespaces in the current file and included files
if !exists('g:OmniCpp_NamespaceSearch')
let g:OmniCpp_NamespaceSearch = 1
endif
" Set the class scope completion mode
" 0 = auto
" 1 = show all members (static, public, protected and private)
if !exists('g:OmniCpp_DisplayMode')
let g:OmniCpp_DisplayMode = 0
endif
" Set if the scope is displayed in the abbr column of the popup
" 0 = no
" 1 = yes
if !exists('g:OmniCpp_ShowScopeInAbbr')
let g:OmniCpp_ShowScopeInAbbr = 0
endif
" Set if the function prototype is displayed in the abbr column of the popup
" 0 = no
" 1 = yes
if !exists('g:OmniCpp_ShowPrototypeInAbbr')
let g:OmniCpp_ShowPrototypeInAbbr = 0
endif
" Set if the access (+,#,-) is displayed
" 0 = no
" 1 = yes
if !exists('g:OmniCpp_ShowAccess')
let g:OmniCpp_ShowAccess = 1
endif
" Set the list of default namespaces
" eg: ['std']
if !exists('g:OmniCpp_DefaultNamespaces')
let g:OmniCpp_DefaultNamespaces = []
endif
" Set MayComplete to '.'
" 0 = disabled
" 1 = enabled
" default = 1
if !exists('g:OmniCpp_MayCompleteDot')
let g:OmniCpp_MayCompleteDot = 1
endif
" Set MayComplete to '->'
" 0 = disabled
" 1 = enabled
" default = 1
if !exists('g:OmniCpp_MayCompleteArrow')
let g:OmniCpp_MayCompleteArrow = 1
endif
" Set MayComplete to dot
" 0 = disabled
" 1 = enabled
" default = 0
if !exists('g:OmniCpp_MayCompleteScope')
let g:OmniCpp_MayCompleteScope = 0
endif
" When completeopt does not contain longest option, this setting
" controls the behaviour of the popup menu selection when starting the completion
" 0 = don't select first item
" 1 = select first item (inserting it to the text)
" 2 = select first item (without inserting it to the text)
" default = 0
if !exists('g:OmniCpp_SelectFirstItem')
let g:OmniCpp_SelectFirstItem= 0
endif
" Use local search function for variable definitions
" 0 = use standard vim search function
" 1 = use local search function
" default = 0
if !exists('g:OmniCpp_LocalSearchDecl')
let g:OmniCpp_LocalSearchDecl= 0
endif
endfunc
" Description: Omni completion tokenizer
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
" TODO: Generic behaviour for Tokenize()
" From the C++ BNF
let s:cppKeyword = ['asm', 'auto', 'bool', 'break', 'case', 'catch', 'char', 'class', 'const', 'const_cast', 'continue', 'default', 'delete', 'do', 'double', 'dynamic_cast', 'else', 'enum', 'explicit', 'export', 'extern', 'false', 'float', 'for', 'friend', 'goto', 'if', 'inline', 'int', 'long', 'mutable', 'namespace', 'new', 'operator', 'private', 'protected', 'public', 'register', 'reinterpret_cast', 'return', 'short', 'signed', 'sizeof', 'static', 'static_cast', 'struct', 'switch', 'template', 'this', 'throw', 'true', 'try', 'typedef', 'typeid', 'typename', 'union', 'unsigned', 'using', 'virtual', 'void', 'volatile', 'wchar_t', 'while', 'and', 'and_eq', 'bitand', 'bitor', 'compl', 'not', 'not_eq', 'or', 'or_eq', 'xor', 'xor_eq']
let s:reCppKeyword = '\C\<'.join(s:cppKeyword, '\>\|\<').'\>'
" The order of items in this list is very important because we use this list to build a regular
" expression (see below) for tokenization
let s:cppOperatorPunctuator = ['->*', '->', '--', '-=', '-', '!=', '!', '##', '#', '%:%:', '%=', '%>', '%:', '%', '&&', '&=', '&', '(', ')', '*=', '*', ',', '...', '.*', '.', '/=', '/', '::', ':>', ':', ';', '?', '[', ']', '^=', '^', '{', '||', '|=', '|', '}', '~', '++', '+=', '+', '<<=', '<%', '<:', '<<', '<=', '<', '==', '=', '>>=', '>>', '>=', '>']
" We build the regexp for the tokenizer
let s:reCComment = '\/\*\|\*\/'
let s:reCppComment = '\/\/'
let s:reComment = s:reCComment.'\|'.s:reCppComment
let s:reCppOperatorOrPunctuator = escape(join(s:cppOperatorPunctuator, '\|'), '*./^~[]')
" Tokenize a c++ code
" a token is dictionary where keys are:
" - kind = cppKeyword|cppWord|cppOperatorPunctuator|unknown|cComment|cppComment|cppDigit
" - value = 'something'
" Note: a cppWord is any word that is not a cpp keyword
function! omni#cpp#tokenizer#Tokenize(szCode)
let result = []
" The regexp to find a token, a token is a keyword, word or
" c++ operator or punctuator. To work properly we have to put
" spaces and tabs to our regexp.
let reTokenSearch = '\(\w\+\)\|\s\+\|'.s:reComment.'\|'.s:reCppOperatorOrPunctuator
" eg: 'using namespace std;'
" ^ ^
" start=0 end=5
let startPos = 0
let endPos = matchend(a:szCode, reTokenSearch)
let len = endPos-startPos
while endPos!=-1
" eg: 'using namespace std;'
" ^ ^
" start=0 end=5
" token = 'using'
" We also remove space and tabs
let token = substitute(strpart(a:szCode, startPos, len), '\s', '', 'g')
" eg: 'using namespace std;'
" ^ ^
" start=5 end=15
let startPos = endPos
let endPos = matchend(a:szCode, reTokenSearch, startPos)
let len = endPos-startPos
" It the token is empty we continue
if token==''
continue
endif
" Building the token
let resultToken = {'kind' : 'unknown', 'value' : token}
" Classify the token
if token =~ '^\d\+'
" It's a digit
let resultToken.kind = 'cppDigit'
elseif token=~'^\w\+$'
" It's a word
let resultToken.kind = 'cppWord'
" But maybe it's a c++ keyword
if match(token, s:reCppKeyword)>=0
let resultToken.kind = 'cppKeyword'
endif
else
if match(token, s:reComment)>=0
if index(['/*','*/'],token)>=0
let resultToken.kind = 'cComment'
else
let resultToken.kind = 'cppComment'
endif
else
" It's an operator
let resultToken.kind = 'cppOperatorPunctuator'
endif
endif
" We have our token, let's add it to the result list
call extend(result, [resultToken])
endwhile
return result
endfunc
" Description: Omni completion script for cpp files
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
let g:omni#cpp#utils#CACHE_TAG_INHERITS = {}
let g:omni#cpp#utils#szFilterGlobalScope = "(!has_key(v:val, 'class') && !has_key(v:val, 'struct') && !has_key(v:val, 'union') && !has_key(v:val, 'namespace')"
let g:omni#cpp#utils#szFilterGlobalScope .= "&& (!has_key(v:val, 'enum') || (has_key(v:val, 'enum') && v:val.enum =~ '^\\w\\+$')))"
" Expression used to ignore comments
" Note: this expression drop drastically the performance
"let omni#cpp#utils#expIgnoreComments = 'match(synIDattr(synID(line("."), col("."), 1), "name"), '\CcComment')!=-1'
" This one is faster but not really good for C comments
let omni#cpp#utils#reIgnoreComment = escape('\/\/\|\/\*\|\*\/', '*/\')
let omni#cpp#utils#expIgnoreComments = 'getline(".") =~ g:omni#cpp#utils#reIgnoreComment'
" Characters to escape in a filename for vimgrep
"TODO: Find more characters to escape
let omni#cpp#utils#szEscapedCharacters = ' %#'
" Resolve the path of the file
" TODO: absolute file path
function! omni#cpp#utils#ResolveFilePath(szFile)
let result = ''
let listPath = split(globpath(&path, a:szFile), "\n")
if len(listPath)
let result = listPath[0]
endif
return simplify(result)
endfunc
" Get code without comments and with empty strings
" szSingleLine must not have carriage return
function! omni#cpp#utils#GetCodeFromLine(szSingleLine)
" We set all strings to empty strings, it's safer for
" the next of the process
let szResult = substitute(a:szSingleLine, '".*"', '""', 'g')
" Removing c++ comments, we can use the pattern ".*" because
" we are modifying a line
let szResult = substitute(szResult, '\/\/.*', '', 'g')
" Now we have the entire code in one line and we can remove C comments
return s:RemoveCComments(szResult)
endfunc
" Remove C comments on a line
function! s:RemoveCComments(szLine)
let result = a:szLine
" We have to match the first '/*' and first '*/'
let startCmt = match(result, '\/\*')
let endCmt = match(result, '\*\/')
while startCmt!=-1 && endCmt!=-1 && startCmt<endCmt
if startCmt>0
let result = result[ : startCmt-1 ] . result[ endCmt+2 : ]
else
" Case where '/*' is at the start of the line
let result = result[ endCmt+2 : ]
endif
let startCmt = match(result, '\/\*')
let endCmt = match(result, '\*\/')
endwhile
return result
endfunc
" Get a c++ code from current buffer from [lineStart, colStart] to
" [lineEnd, colEnd] without c++ and c comments, without end of line
" and with empty strings if any
" @return a string
function! omni#cpp#utils#GetCode(posStart, posEnd)
let posStart = a:posStart
let posEnd = a:posEnd
if a:posStart[0]>a:posEnd[0]
let posStart = a:posEnd
let posEnd = a:posStart
elseif a:posStart[0]==a:posEnd[0] && a:posStart[1]>a:posEnd[1]
let posStart = a:posEnd
let posEnd = a:posStart
endif
" Getting the lines
let lines = getline(posStart[0], posEnd[0])
let lenLines = len(lines)
" Formatting the result
let result = ''
if lenLines==1
let sStart = posStart[1]-1
let sEnd = posEnd[1]-1
let line = lines[0]
let lenLastLine = strlen(line)
let sEnd = (sEnd>lenLastLine)?lenLastLine : sEnd
if sStart >= 0
let result = omni#cpp#utils#GetCodeFromLine(line[ sStart : sEnd ])
endif
elseif lenLines>1
let sStart = posStart[1]-1
let sEnd = posEnd[1]-1
let lenLastLine = strlen(lines[-1])
let sEnd = (sEnd>lenLastLine)?lenLastLine : sEnd
if sStart >= 0
let lines[0] = lines[0][ sStart : ]
let lines[-1] = lines[-1][ : sEnd ]
for aLine in lines
let result = result . omni#cpp#utils#GetCodeFromLine(aLine)." "
endfor
let result = result[:-2]
endif
endif
" Now we have the entire code in one line and we can remove C comments
return s:RemoveCComments(result)
endfunc
" Extract the scope (context) of a tag item
" eg: ::MyNamespace
" @return a string of the scope. a scope from tag always starts with '::'
function! omni#cpp#utils#ExtractScope(tagItem)
let listKindScope = ['class', 'struct', 'union', 'namespace', 'enum']
let szResult = '::'
for scope in listKindScope
if has_key(a:tagItem, scope)
let szResult = szResult . a:tagItem[scope]
break
endif
endfor
return szResult
endfunc
" Simplify scope string, remove consecutive '::' if any
function! omni#cpp#utils#SimplifyScope(szScope)
let szResult = substitute(a:szScope, '\(::\)\+', '::', 'g')
if szResult=='::'
return szResult
else
return substitute(szResult, '::$', '', 'g')
endif
endfunc
" Check if the cursor is in comment
function! omni#cpp#utils#IsCursorInCommentOrString()
return match(synIDattr(synID(line("."), col(".")-1, 1), "name"), '\C\<cComment\|\<cCppString\|\<cIncluded')>=0
endfunc
" Tokenize the current instruction until the cursor position.
" @return list of tokens
function! omni#cpp#utils#TokenizeCurrentInstruction(...)
let szAppendText = ''
if a:0>0
let szAppendText = a:1
endif
let startPos = searchpos('[;{}]\|\%^', 'bWn')
let curPos = getpos('.')[1:2]
" We don't want the character under the cursor
let column = curPos[1]-1
let curPos[1] = (column<1)?1:column
return omni#cpp#tokenizer#Tokenize(omni#cpp#utils#GetCode(startPos, curPos)[1:] . szAppendText)
endfunc
" Tokenize the current instruction until the word under the cursor.
" @return list of tokens
function! omni#cpp#utils#TokenizeCurrentInstructionUntilWord()
let startPos = searchpos('[;{}]\|\%^', 'bWn')
" Saving the current cursor pos
let originalPos = getpos('.')
" We go at the end of the word
execute 'normal gee'
let curPos = getpos('.')[1:2]
" Restoring the original cursor pos
call setpos('.', originalPos)
let szCode = omni#cpp#utils#GetCode(startPos, curPos)[1:]
return omni#cpp#tokenizer#Tokenize(szCode)
endfunc
" Build parenthesis groups
" add a new key 'group' in the token
" where value is the group number of the parenthesis
" eg: (void*)(MyClass*)
" group1 group0
" if a parenthesis is unresolved the group id is -1
" @return a copy of a:tokens with parenthesis group
function! omni#cpp#utils#BuildParenthesisGroups(tokens)
let tokens = copy(a:tokens)
let kinds = {'(': '()', ')' : '()', '[' : '[]', ']' : '[]', '<' : '<>', '>' : '<>', '{': '{}', '}': '{}'}
let unresolved = {'()' : [], '[]': [], '<>' : [], '{}' : []}
let groupId = 0
" Note: we build paren group in a backward way
" because we can often have parenthesis unbalanced
" instruction
" eg: doSomething(_member.get()->
for token in reverse(tokens)
if index([')', ']', '>', '}'], token.value)>=0
let token['group'] = groupId
call extend(unresolved[kinds[token.value]], [token])
let groupId+=1
elseif index(['(', '[', '<', '{'], token.value)>=0
if len(unresolved[kinds[token.value]])
let tokenResolved = remove(unresolved[kinds[token.value]], -1)
let token['group'] = tokenResolved.group
else
let token['group'] = -1
endif
endif
endfor
return reverse(tokens)
endfunc
" Determine if tokens represent a C cast
" @return
" - itemCast
" - itemCppCast
" - itemVariable
" - itemThis
function! omni#cpp#utils#GetCastType(tokens)
" Note: a:tokens is not modified
let tokens = omni#cpp#utils#SimplifyParenthesis(omni#cpp#utils#BuildParenthesisGroups(a:tokens))
if tokens[0].value == '('
return 'itemCast'
elseif index(['static_cast', 'dynamic_cast', 'reinterpret_cast', 'const_cast'], tokens[0].value)>=0
return 'itemCppCast'
else
for token in tokens
if token.value=='this'
return 'itemThis'
endif
endfor
return 'itemVariable'
endif
endfunc
" Remove useless parenthesis
function! omni#cpp#utils#SimplifyParenthesis(tokens)
"Note: a:tokens is not modified
let tokens = a:tokens
" We remove useless parenthesis eg: (((MyClass)))
if len(tokens)>2
while tokens[0].value=='(' && tokens[-1].value==')' && tokens[0].group==tokens[-1].group
let tokens = tokens[1:-2]
endwhile
endif
return tokens
endfunc
" Function create a type info
function! omni#cpp#utils#CreateTypeInfo(param)
let type = type(a:param)
return {'type': type, 'value':a:param}
endfunc
" Extract type info from a tag item
" eg: ::MyNamespace::MyClass
function! omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)
let szTypeInfo = omni#cpp#utils#ExtractScope(a:tagItem) . '::' . substitute(a:tagItem.name, '.*::', '', 'g')
return omni#cpp#utils#SimplifyScope(szTypeInfo)
endfunc
" Build a class inheritance list
function! omni#cpp#utils#GetClassInheritanceList(namespaces, typeInfo)
let result = []
for tagItem in omni#cpp#utils#GetResolvedTags(a:namespaces, a:typeInfo)
call extend(result, [omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)])
endfor
return result
endfunc
" Get class inheritance list where items in the list are tag items.
" TODO: Verify inheritance order
function! omni#cpp#utils#GetResolvedTags(namespaces, typeInfo)
let result = []
let tagItem = omni#cpp#utils#GetResolvedTagItem(a:namespaces, a:typeInfo)
if tagItem!={}
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)
if has_key(g:omni#cpp#utils#CACHE_TAG_INHERITS, szTypeInfo)
let result = g:omni#cpp#utils#CACHE_TAG_INHERITS[szTypeInfo]
else
call extend(result, [tagItem])
if has_key(tagItem, 'inherits')
for baseClassTypeInfo in split(tagItem.inherits, ',')
let namespaces = [omni#cpp#utils#ExtractScope(tagItem), '::']
call extend(result, omni#cpp#utils#GetResolvedTags(namespaces, omni#cpp#utils#CreateTypeInfo(baseClassTypeInfo)))
endfor
endif
let g:omni#cpp#utils#CACHE_TAG_INHERITS[szTypeInfo] = result
endif
endif
return result
endfunc
" Get a tag item after a scope resolution and typedef resolution
function! omni#cpp#utils#GetResolvedTagItem(namespaces, typeInfo)
let typeInfo = {}
if type(a:typeInfo) == 1
let typeInfo = omni#cpp#utils#CreateTypeInfo(a:typeInfo)
else
let typeInfo = a:typeInfo
endif
let result = {}
if !omni#cpp#utils#IsTypeInfoValid(typeInfo)
return result
endif
" Unnamed type case eg: '1::2'
if typeInfo.type == 4
" Here there is no typedef or namespace to resolve, the tagInfo.value is a tag item
" representing a variable ('v') a member ('m') or a typedef ('t') and the typename is
" always in global scope
return typeInfo.value
endif
" Named type case eg: 'MyNamespace::MyClass'
let szTypeInfo = omni#cpp#utils#GetTypeInfoString(typeInfo)
" Resolving namespace alias
" TODO: For the next release
"let szTypeInfo = omni#cpp#namespaces#ResolveAlias(g:omni#cpp#namespaces#CacheAlias, szTypeInfo)
if szTypeInfo=='::'
return result
endif
" We can only get members of class, struct, union and namespace
let szTagFilter = "index(['c', 's', 'u', 'n', 't'], v:val.kind[0])>=0"
let szTagQuery = szTypeInfo
if s:IsTypeInfoResolved(szTypeInfo)
" The type info is already resolved, we remove the starting '::'
let szTagQuery = substitute(szTypeInfo, '^::', '', 'g')
if len(split(szTagQuery, '::'))==1
" eg: ::MyClass
" Here we have to get tags that have no parent scope
" That's why we change the szTagFilter
let szTagFilter .= '&& ' . g:omni#cpp#utils#szFilterGlobalScope
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
call filter(tagList, szTagFilter)
if len(tagList)
let result = tagList[0]
endif
else
" eg: ::MyNamespace::MyClass
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
call filter(tagList, szTagFilter)
if len(tagList)
let result = tagList[0]
endif
endif
else
" The type is not resolved
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
call filter(tagList, szTagFilter)
if len(tagList)
" Resolving scope (namespace, nested class etc...)
let szScopeOfTypeInfo = s:ExtractScopeFromTypeInfo(szTypeInfo)
if s:IsTypeInfoResolved(szTypeInfo)
let result = s:GetTagOfSameScope(tagList, szScopeOfTypeInfo)
else
" For each namespace of the namespace list we try to get a tag
" that can be in the same scope
if g:OmniCpp_NamespaceSearch && &filetype != 'c'
for scope in a:namespaces
let szTmpScope = omni#cpp#utils#SimplifyScope(scope.'::'.szScopeOfTypeInfo)
let result = s:GetTagOfSameScope(tagList, szTmpScope)
if result!={}
break
endif
endfor
else
let szTmpScope = omni#cpp#utils#SimplifyScope('::'.szScopeOfTypeInfo)
let result = s:GetTagOfSameScope(tagList, szTmpScope)
endif
endif
endif
endif
if result!={}
" We have our tagItem but maybe it's a typedef or an unnamed type
if result.kind[0]=='t'
" Here we can have a typedef to another typedef, a class, struct, union etc
" but we can also have a typedef to an unnamed type, in that
" case the result contains a 'typeref' key
let namespaces = [omni#cpp#utils#ExtractScope(result), '::']
if has_key(result, 'typeref')
let result = omni#cpp#utils#GetResolvedTagItem(namespaces, omni#cpp#utils#CreateTypeInfo(result))
else
let szCmd = omni#cpp#utils#ExtractCmdFromTagItem(result)
let szCode = substitute(omni#cpp#utils#GetCodeFromLine(szCmd), '\C\<'.result.name.'\>.*', '', 'g')
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTokens(omni#cpp#tokenizer#Tokenize(szCode))
let result = omni#cpp#utils#GetResolvedTagItem(namespaces, omni#cpp#utils#CreateTypeInfo(szTypeInfo))
" TODO: Namespace resolution for result
endif
endif
endif
return result
endfunc
" Returns if the type info is valid
" @return
" - 1 if valid
" - 0 otherwise
function! omni#cpp#utils#IsTypeInfoValid(typeInfo)
if a:typeInfo=={}
return 0
else
if a:typeInfo.type == 1 && a:typeInfo.value==''
" String case
return 0
elseif a:typeInfo.type == 4 && a:typeInfo.value=={}
" Dictionary case
return 0
endif
endif
return 1
endfunc
" Get the string of the type info
function! omni#cpp#utils#GetTypeInfoString(typeInfo)
if a:typeInfo.type == 1
return a:typeInfo.value
else
return substitute(a:typeInfo.value.typeref, '^\w\+:', '', 'g')
endif
endfunc
" A resolved type info starts with '::'
" @return
" - 1 if type info starts with '::'
" - 0 otherwise
function! s:IsTypeInfoResolved(szTypeInfo)
return match(a:szTypeInfo, '^::')!=-1
endfunc
" A returned type info's scope may not have the global namespace '::'
" eg: '::NameSpace1::NameSpace2::MyClass' => '::NameSpace1::NameSpace2'
" 'NameSpace1::NameSpace2::MyClass' => 'NameSpace1::NameSpace2'
function! s:ExtractScopeFromTypeInfo(szTypeInfo)
let szScope = substitute(a:szTypeInfo, '\w\+$', '', 'g')
if szScope =='::'
return szScope
else
return substitute(szScope, '::$', '', 'g')
endif
endfunc
" @return
" - the tag with the same scope
" - {} otherwise
function! s:GetTagOfSameScope(listTags, szScopeToMatch)
for tagItem in a:listTags
let szScopeOfTag = omni#cpp#utils#ExtractScope(tagItem)
if szScopeOfTag == a:szScopeToMatch
return tagItem
endif
endfor
return {}
endfunc
" Extract the cmd of a tag item without regexp
function! omni#cpp#utils#ExtractCmdFromTagItem(tagItem)
let line = a:tagItem.cmd
let re = '\(\/\^\)\|\(\$\/\)'
if match(line, re)!=-1
let line = substitute(line, re, '', 'g')
return line
else
" TODO: the cmd is a line number
return ''
endif
endfunc
" Extract type from tokens.
" eg: examples of tokens format
" 'const MyClass&'
" 'const map < int, int >&'
" 'MyNs::MyClass'
" '::MyClass**'
" 'MyClass a, *b = NULL, c[1] = {};
" 'hello(MyClass a, MyClass* b'
" @return the type info string eg: ::std::map
" can be empty
function! omni#cpp#utils#ExtractTypeInfoFromTokens(tokens)
let szResult = ''
let state = 0
let tokens = omni#cpp#utils#BuildParenthesisGroups(a:tokens)
" If there is an unbalanced parenthesis we are in a parameter list
let bParameterList = 0
for token in tokens
if token.value == '(' && token.group==-1
let bParameterList = 1
break
endif
endfor
if bParameterList
let tokens = reverse(tokens)
let state = 0
let parenGroup = -1
for token in tokens
if state==0
if token.value=='>'
let parenGroup = token.group
let state=1
elseif token.kind == 'cppWord'
let szResult = token.value.szResult
let state=2
elseif index(['*', '&'], token.value)<0
break
endif
elseif state==1
if token.value=='<' && token.group==parenGroup
let state=0
endif
elseif state==2
if token.value=='::'
let szResult = token.value.szResult
let state=3
else
break
endif
elseif state==3
if token.kind == 'cppWord'
let szResult = token.value.szResult
let state=2
else
break
endif
endif
endfor
return szResult
endif
for token in tokens
if state==0
if token.value == '::'
let szResult .= token.value
let state = 1
elseif token.kind == 'cppWord'
let szResult .= token.value
let state = 2
" Maybe end of token
endif
elseif state==1
if token.kind == 'cppWord'
let szResult .= token.value
let state = 2
" Maybe end of token
else
break
endif
elseif state==2
if token.value == '::'
let szResult .= token.value
let state = 1
else
break
endif
endif
endfor
return szResult
endfunc
" Get the preview window string
function! omni#cpp#utils#GetPreviewWindowStringFromTagItem(tagItem)
let szResult = ''
let szResult .= 'name: '.a:tagItem.name."\n"
for tagKey in keys(a:tagItem)
if index(['name', 'static'], tagKey)>=0
continue
endif
let szResult .= tagKey.': '.a:tagItem[tagKey]."\n"
endfor
return substitute(szResult, "\n$", '', 'g')
endfunc
*omnicppcomplete.txt* Plugin for C/C++ omnicompletion
*omnicppcomplete*
Author: Vissale NEANG (fromtonrouge AT gmail DOT com)
Last Change: 26 sept. 2007
OmniCppComplete version 0.41
For Vim version 7.0 and above
==============================================================================
1. Overview |omnicpp-overview|
2. Downloads |omnicpp-download|
3. Installation |omnicpp-installation|
4. Options |omnicpp-options|
5. Features |omnicpp-features|
6. Limitations |omnicpp-limitations|
7. FAQ & TIPS |omnicpp-faq|
8. History |omnicpp-history|
9. Thanks |omnicpp-thanks|
==============================================================================
1. Overview~
*omnicpp-overview*
The purpose of this script is to provide an 'omnifunc' function for C and C++
language. In a C++ file, while in insert mode, you can use CTRL-X CTRL-O to:
* Complete namespaces, classes, structs and unions
* Complete attribute members and return type of functions
* Complete the "this" pointer
* Complete an object after a cast (C and C++ cast)
* Complete typedefs and anonymous types
You can set a "may complete" behaviour to start a completion automatically
after a '.', '->' or '::'. Please see |omnicpp-may-complete| for more details.
The script needs an |Exuberant_ctags| database to work properly.
==============================================================================
2. Downloads~
*omnicpp-download*
You can download the latest release of the script from this url :
http://www.vim.org/scripts/script.php?script_id=1520
You can download |Exuberant_ctags| from :
http://ctags.sourceforge.net
==============================================================================
3. Installation~
*omnicpp-installation*
3.1. Script installation~
Unzip the downloaded file in your personal |vimfiles| directory (~/.vim under
unix or %HOMEPATH%\vimfiles under windows). The 'omnifunc' will be
automatically set for C and C++ files.
You also have to enable plugins by adding these two lines in your|.vimrc|file: >
set nocp
filetype plugin on
<
Please see |cp| and |filetype-plugin-on| sections for more details.
3.1.1. Files~
After installation you should find these files :
after\ftplugin\cpp.vim
after\ftplugin\c.vim
autoload\omni\common\debug.vim
\utils.vim
autoload\omni\cpp\complete.vim
\includes.vim
\items.vim
\maycomplete.vim
\namespaces.vim
\settings.vim
\tokenizer.vim
\utils.vim
doc\omnicppcomplete.txt
3.2. Building the Exuberant Ctags database~
To extract C/C++ symbols information, the script needs an |Exuberant_ctags|
database.
You have to build your database with at least the following options:
--c++-kinds=+p : Adds prototypes in the database for C/C++ files.
--fields=+iaS : Adds inheritance (i), access (a) and function
signatures (S) information.
--extra=+q : Adds context to the tag name. Note: Without this
option, the script cannot get class members.
Thus to build recursively a ctags database from the current directory, the
command looks like this:
>
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .
<
You can add a map in your |.vimrc| file, eg: >
map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
<
Or you can add these options in your ctags config file (~/.ctags under unix or
%HOMEPATH%\ctags.cnf under windows) and execute the command : >
:!ctags -R .
<
If your project contains files of other languages you may add the following
options:
--languages=c++ : Builds only the tags for C++ files.
If your project contains macros you may also use the -I option.
Please read the ctags help or ctags man page for more details.
3.3. Setting the 'tags' option~
The default value of the option 'tags' is "./tags,tags" ("./tags,./TAGS,tags,TAGS"
when |+emacs_tags| is enabled), if you build your tag database with the cmd above,
you normally don't have to change this setting (The cmd used above generates a
file with the name "tags"). In this case your current working directory must be
the directory where the tags file reside.
Note: When |+emacs_tags| is enabled, the script may display members twice, it's
recommended to set tags to "./tags,tags' or "./TAGS,TAGS".
If your tags file is not named "tags" you have to add it in the 'tags'
option eg: >
set tags+=/usr/tagsdir/mytagfile
<
You can ensure that the 'tags' option is set properly by executing the following
command: >
:tselect MyClass
<
Where MyClass is a class of your project. This command should display all
possible tags for the type MyClass.
3.4. Simple test~
Now you can do a simple test. Edit a C++ file and write the simplest case : >
MyClass myObject;
myObject.<C-X><C-O>
<
You should see class members of MyClass.
==============================================================================
4. Options~
*omnicpp-options*
You can change completion behaviour by setting script options in your |.vimrc|
configuration file.
4.1. Global scope search toggle~
*OmniCpp_GlobalScopeSearch*
You can enable/disable the global scope search by setting the
OmniCpp_GlobalScopeSearch option.
Possible values are :
0 = disabled
1 = enabled
[default=1] >
let OmniCpp_GlobalScopeSearch = 1
<
4.2. Namespace search method~
*OmniCpp_NamespaceSearch*
You can change the 'using namespace' search behaviour by setting the
OmniCpp_NamespaceSearch option.
Possible values are :
0 = namespaces disabled
1 = search namespaces in the current buffer
2 = search namespaces in the current buffer and in included files
[default=1] >
let OmniCpp_NamespaceSearch = 1
<
When OmniCpp_NamespaceSearch is 2, "using namespace" declarations are parsed
in the current buffer and also in included files. To find included files, the
script use the vim env 'path', so you have to set it properly.
Note: included files are searched with lvimgrep, thus the location list of the
current window is changed.
Note: When the 'filetype' is "c", namespace search is always disabled even if
OmniCpp_NamespaceSearch != 0
4.3. Class scope completion mode~
*OmniCpp_DisplayMode*
When you are completing a class scope (eg: MyClass::<C-X><C-O>), depending on
the current scope, you may see sometimes static, public, protected or private
members and sometimes you may see all members. By default the choice is done
automatically by the script but you can override it with the
OmniCpp_DisplayMode option.
Note: This option can be use when you have friend classes in your project (the
script does not support friend classes).
Possible values are :
0 = auto
1 = always show all members
[default=0] >
let OmniCpp_DisplayMode = 0
<
4.4. Show scope in abbreviation~
*OmniCpp_ShowScopeInAbbr*
By default, in the |omnicpp-popup| menu, you will see the scope of a match in
the last column. You can remove this column and add the scope at the beginning
of match abbreviation.
eg:
OmniCpp_ShowScopeInAbbr = 0
+-------------------------------------+
|method1( f + MyNamespace::MyClass|
|_member1 m + MyNamespace::MyClass|
|_member2 m # MyNamespace::MyClass|
|_member3 m - MyNamespace::MyClass|
+-------------------------------------+
OmniCpp_ShowScopeInAbbr = 1
+-------------------------------------+
|MyNamespace::MyClass::method1( f + |
|MyNamespace::MyClass::_member1 m + |
|MyNamespace::MyClass::_member2 m # |
|MyNamespace::MyClass::_member3 m - |
+-------------------------------------+
Possible values are :
0 = don't show scope in abbreviation
1 = show scope in abbreviation and remove the last column
[default=0] >
let OmniCpp_ShowScopeInAbbr = 0
<
4.5. Show prototype in abbreviation~
*OmniCpp_ShowPrototypeInAbbr*
This option allows to display the prototype of a function in the abbreviation
part of the popup menu.
Possible values are:
0 = don't display prototype in abbreviation
1 = display prototype in abbreviation
[default=0] >
let OmniCpp_ShowPrototypeInAbbr = 0
<
4.6. Show access~
*OmniCpp_ShowAccess*
This option allows to show/hide the access information ('+', '#', '-') in the
popup menu.
Possible values are:
0 = hide access
1 = show access
[default=1] >
let OmniCpp_ShowAccess = 1
4.7. Default using namespace list~
*OmniCpp_DefaultNamespaces*
When |OmniCpp_NamespaceSearch| is not 0, the script will parse using namespace
declarations in the current buffer and maybe in included files.
You can specify manually a default namespace list if you want with the
OmniCpp_DefaultNamespaces option. Each item in the list is a namespace name.
eg: If you have
let OmniCpp_DefaultNamespaces = ["std", "MyNamespace"]
It will be the same as inserting this declarations at the top of the
current buffer :
using namespace std;
using namespace MyNamespace;
This option can be use if you don't want to parse using namespace declarations
in included files and want to add namespaces that are always used in your
project.
Possible values are :
List of String
[default=[]] >
let OmniCpp_DefaultNamespaces = []
<
4.8. May complete behaviour~
*omnicpp-may-complete*
This feature allows you to run automatically a completion after a '.', '->'
or '::'. By default, the "may complete" feature is set automatically for '.'
and '->'. The reason to not set this feature for the scope operator '::' is
sometimes you don't want to complete a namespace that contains many members.
To enable/disable the "may complete" behaviour for dot, arrow and scope
operator, you can change the option OmniCpp_MayCompleteDot,
OmniCpp_MayCompleteArrow and OmniCpp_MayCompleteScope respectively.
*OmniCpp_MayCompleteDot*
Possible values are :
0 = May complete disabled for dot
1 = May complete enabled for dot
[default=1] >
let OmniCpp_MayCompleteDot = 1
<
*OmniCpp_MayCompleteArrow*
Possible values are :
0 = May complete disabled for arrow
1 = May complete enabled for arrow
[default=1] >
let OmniCpp_MayCompleteArrow = 1
<
*OmniCpp_MayCompleteScope*
Possible values are :
0 = May complete disabled for scope
1 = May complete enabled for scope
[default=0] >
let OmniCpp_MayCompleteScope = 0
<
Note: You can obviously continue to use <C-X><C-O>
4.9. Select/Don't select first popup item~
*OmniCpp_SelectFirstItem*
Note: This option is only used when 'completeopt' does not contain "longest".
When 'completeopt' does not contain "longest", Vim automatically select the
first entry of the popup menu. You can change this behaviour with the
OmniCpp_SelectFirstItem option.
Possible values are:
0 = don't select first popup item
1 = select first popup item (inserting it to the text)
2 = select first popup item (without inserting it to the text)
[default=0] >
let OmniCpp_SelectFirstItem = 0
4.10 Use local search function for variable definitions~
*OmniCpp_LocalSearchDecl*
The internal search function for variable definitions of vim requires that the
enclosing braces of the function are located in the first column. You can
change this behaviour with the OmniCpp_LocalSearchDecl option. The local
version works irrespective the position of braces.
Possible values are:
0 = use standard vim search function
1 = use local search function
[default=0] >
==============================================================================
5. Features~
*omnicpp-features*
5.1. Popup menu~
*omnicpp-popup*
Popup menu format:
+-------------------------------------+
|method1( f + MyNamespace::MyClass|
|_member1 m + MyNamespace::MyClass|
|_member2 m # MyNamespace::MyClass|
|_member3 m - MyNamespace::MyClass|
+-------------------------------------+
^ ^ ^ ^
(1) (2)(3) (4)
(1) name of the symbol, when a match ends with '(' it's a function.
(2) kind of the symbol, possible kinds are :
* c = classes
* d = macro definitions
* e = enumerators (values inside an enumeration)
* f = function definitions
* g = enumeration names
* m = class, struct, and union members
* n = namespaces
* p = function prototypes
* s = structure names
* t = typedefs
* u = union names
* v = variable definitions
(3) access, possible values are :
* + = public
* # = protected
* - = private
Note: enumerators have no access information
(4) scope where the symbol is defined.
Note: If the scope is empty it's a global symbol
Note: anonymous scope may end with __anon[number]
eg: If you have an anonymous enum in MyNamespace::MyClass : >
namespace MyNamespace
{
class MyClass
{
private:
enum
{
E_ENUM0,
E_ENUM1,
E_ENUM2
};
};
}
<
You should see :
+----------------------------------------------+
|E_ENUM0 e MyNamespace::MyClass::__anon1|
|E_ENUM1 e MyNamespace::MyClass::__anon1|
|E_ENUM2 e MyNamespace::MyClass::__anon1|
+----------------------------------------------+
^
__anon[number]
5.2. Global scope completion~
The global scope completion allows you to complete global symbols for the base
you are currently typing. The base can start with '::' or not.
Note: Global scope completion only works with a non empty base, if you run a
completion just after a '::' the completion will fail. The reason is that if
there is no base to complete the script will try to display all the tags in
the database. For small project it could be not a problem but for others you
may wait 5 minutes or more for a result.
eg1 : >
pthread_cr<C-X><C-O> => pthread_create
<
Where pthread_create is a global function.
eg2: >
::globa<C-X><C-O> => ::global_func(
+----------------+
|global_func( f|
|global_var1 v|
|global_var2 v|
+----------------+
<
Where global_var1, global_var2 and global_func are global symbols
eg3: >
::<C-X><C-O> => [NO MATCH]
<
No match because a global completion from an empty base is not allowed.
5.3. Namespace scope completion~
You can complete namespace members after a 'MyNamespace::'. Contrary to global
scope completion you can run a completion from an empty base.
Possible members are:
* Namespaces
* Classes
* Structs
* Unions
* Enums
* Functions
* Variables
* Typedefs
eg: >
MyNamespace::<C-X><C-O>
+--------------------------------+
|E_ENUM0 e MyNamespace|
|E_ENUM1 e MyNamespace|
|E_ENUM2 e MyNamespace|
|MyClass c MyNamespace|
|MyEnum g MyNamespace|
|MyStruct s MyNamespace|
|MyUnion u MyNamespace|
|SubNamespace n MyNamespace|
|doSomething( f MyNamespace|
|myVar v MyNamespace|
|something_t t MyNamespace|
+--------------------------------+
5.4. Class scope completion~
You can complete class members after a 'MyClass::'. Contrary to global scope
completion you can run a completion from an empty base.
By default, there is two behaviours for class scope completion.
a) Completion of a base class of the current class scope
When you are completing a base class of the current class scope, you
will see all members of this class in the popup menu.
eg: >
class A
{
public:
enum
{
E_ENUM0,
E_ENUM1,
E_ENUM2,
};
void func1();
static int _staticMember;
private:
int _member;
};
class B : public A
{
public:
void doSomething();
};
void MyClassB::doSomething()
{
MyClassA::<C-X><C-O>
+---------------------------+
|E_ENUM0 e MyClassA|
|E_ENUM1 e MyClassA|
|E_ENUM2 e MyClassA|
|func1( f + MyClassA|
|_member m - MyClassA|
|_staticMember m + MyClassA|
+---------------------------+
}
<
b) Completion of a non base class of the current class scope
When you are completing a class that is not a base class of the
current class you will see only enumerators and static members.
eg: >
class C
{
public:
void doSomething();
};
void MyClassC::doSomething()
{
MyClassA::<C-X><C-O>
+---------------------------+
|E_ENUM0 e MyClassA|
|E_ENUM1 e MyClassA|
|E_ENUM2 e MyClassA|
|_staticMember m + MyClassA|
+---------------------------+
}
<
You can override the default behaviour by setting the
|OmniCpp_DisplayMode| option.
5.5. Current scope completion~
When you start a completion from an empty instruction you are in "Current
scope completion" mode. You will see possible members of each context in
the context stack.
eg: >
void MyClass::doSomething()
{
using namespace MyNamespace;
using namespace SubNamespace;
// You will see members of each context in the context stack
// 1) MyClass members
// 2) MyNamespace::SubNamespace members
// 3) MyNamespace members
<C-X><C-O>
+------------------------------------------+
|_member1 m + MyClass |
|_member2 m # MyClass |
|func1( f MyNamespace::SubNamespace|
|var v MyNamespace::SubNamespace|
|func1( f MyNamespace |
|var v MyNamespace |
+------------------------------------------+
}
<
5.6. Class, Struct and Union members completion~
You can complete members of class, struct and union instances after a '->' or
'.'.
eg: >
MyClass myObject;
myObject.<C-X><C-O>
+-----------------------+
|_member1 m + MyClass |
|_member2 m # MyClass |
+-----------------------+
<
5.7. Attribute members and returned type completion~
You can complete a class member or a return type of a function.
eg: >
MyClass myObject;
// Completion of the member _member1
myObject._member1-><C-X><C-O>
+------------------------+
|get( m + AnotherClass1|
+------------------------+
// Completion of the return type of the function get()
myObject._member1->get()-><C-X><C-O>
+--------------------------+
|_member1 m + AnotherClass2|
|_member2 m # AnotherClass2|
|_member3 m - AnotherClass2|
+--------------------------+
5.8. Anonymous type completion~
Note: To use this feature you need at least|Exuberant_ctags| version 5.6
You can complete an anonymous type like this : >
struct
{
int a;
int b;
int c;
}globalVar;
void func()
{
globalVar.<C-X><C-O>
+---------------+
|a m + __anon1|
|b m + __anon1|
|c m + __anon1|
+---------------+
}
<
Where globalVar is a global variable of an anonymous type
5.9. Typedef completion~
You can complete a typedef. The typedef is resolved recursively, thus typedef
of typedef of... may not be a problem.
You can also complete a typedef of an anonymous type, eg : >
typedef struct
{
int a;
int b;
int c;
}something_t;
something_t globalVar;
void func()
{
globalVar.<C-X><C-O>
+---------------+
|a m + __anon1|
|b m + __anon1|
|c m + __anon1|
+---------------+
}
<
Where globalVar is a global variable of typedef of an anonymous type.
5.10. Completion of the "this" pointer~
You can complete the "this" pointer.
eg: >
this-><C-X><C-O>
+-----------------------+
|_member1 m + MyClass |
|_member2 m # MyClass |
+-----------------------+
(*this).<C-X><C-O>
+-----------------------+
|_member1 m + MyClass |
|_member2 m # MyClass |
+-----------------------+
<
5.11. Completion after a cast~
You can complete an object after a C or C++ cast.
eg: >
// C cast style
((AnotherStruct*)pStruct)-><C-X><C-O>
// C++ cast style
static_cast<AnotherStruct*>(pStruct)-><C-X><C-O>
<
5.12. Preview window~
If the 'completeopt' option contains the setting "preview" (this is the
default value), you will see a preview window during the completion.
This window shows useful information like function signature, filename where
the symbol is define etc...
The preview window contains tag information, the list below is non exhaustive.
* name : name of the tag
* cmd : regexp or line number that helps to find the tag
* signature : signature for prototypes and functions
* kind : kind of the tag (eg: namespace, class etc...)
* access : access information (eg: public, protected, private)
* inherits : list of base classes
* filename : filename where the tag is define
5.13. Code tokenization~
When you start a completion, the current instruction is tokenized ignoring
spaces, tabs, carriage returns and comments. Thus you can complete a symbol
even if the current instruction is on multiple lines, has comments between
words etc... :
eg: this case is unrealistic but it's just for illustration >
myObject [ 0 ]/* Why is there a comment here ?*/
->_member
-> <C-X><C-O>
<
==============================================================================
6. Limitations~
*omnicpp-limitations*
Some C++ features are not supported by the script, some implemented features
may not work properly in some conditions. They are multiple reasons like a
lack of information in the database, performance issues and so on...
6.1. Attribute members and returned type completion~
To work properly, the completion of attribute members and returned type of
functions depends on how you write your code in the class declaration.
Because the tags database does not contain information like return type or
type of a member, the script use the cmd information of the tag to determine
the type of an attribute member or the return type of a function.
Thus, because the cmd is a regular expression (or line number for #define) if
you write your code like this : >
class MyClass
{
public:
MyOtherClass
_member;
};
<
The type of _member will not be recognized, because the cmd will be
/^ _member;$/ and does not contain the type MyOtherClass.
The correct case should be : >
class MyClass
{
public:
MyOtherClass _member;
};
<
It's the same problem for return type of function : >
class MyClass
{
public:
MyOtherClass
getOtherClass();
};
<
Here the cmd will be /^ getOtherClass();$/ and the script won't find the
return type.
The correct case should be : >
class MyClass
{
public:
MyOtherClass getOtherClass();
};
<
6.2. Static members~
It's the same problem as above, tags database does not contain information
about static members. The only fast way to get this information is to use the
cmd.
6.3. Typedef~
It's the same problem as above, tags database does not contain information
about the type of a typedef. The script use the cmd information to resolve the
typedef.
6.4. Restricted inheritance access~
Tags database contains inheritance information but unfortunately inheritance
access are not available. We could use the cmd but we often find code
indentation like this : >
class A :
public B,
protected C,
private D
{
};
<
Here the cmd will be /^class A :$/, we can't extract inheritance access.
6.5. Using namespace parsing~
When you start a completion, using namespace declarations are parsed from the
cursor position to the first scope to detect local using namespace
declarations. After that, global using namespace declarations are parsed in the
file and included files.
There is a limitation for global using namespace detection, for performance
issues only using namespace that starts a line will be detected.
6.6. Friend classes~
Tags database does not contain information about friend classes. The script
does not support friend classes.
6.7. Templates~
At the moment, |Exuberant_ctags| does not provide additional information for
templates. That's why the script does not handle templates.
==============================================================================
7. FAQ & TIPS~
*omnicpp-faq*
* How to complete STL objects ?
If you have some troubles to generate a good ctags database for STL you
can try this solution :
1) Download SGI's STL from SGI's site
(http://www.sgi.com/tech/stl/download.html)
2) Replace all __STL_BEGIN_NAMESPACE by "namespace std {" and
__STL_END_NAMESPACE by "}" from header and source files. (with Vim,
or with tar and sed or another tool)
3) Run ctags and put the generated tags file in a directory eg:
~/MyTags/stl.tags
4) set tags+=~/MyTags/stl.tags
The main problem is that you can't tell to ctags that
__STL_BEGIN_NAMESPACE = "namespace std {" even with the option -I.
That's why you need the step 2).
Here is another solution if you have STL sources using _GLIBCXX_STD macro
(Tip by Nicola Bonelli) : >
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
<
* How to close automatically the preview window after a completion ?
(Tip by Kamil Renczewski)
You can add to your |vimrc| the following lines : >
autocmd CursorMovedI * if pumvisible() == 0|pclose|endif
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
<
==============================================================================
8. History~
*omnicpp-history*
Version O.41
- It's recommended to update ctags to version 5.7 or higher
- The plugin is now activated for C files
- New value for OmniCpp_SelectFirstItem when the option is equal to
2 the first item is selected without inserting it to
the text (patch from Marek Olszewski)
- Bug when completing union members fixed with ctags 5.7
(reported by Willem-Jan de Hoog)
- New option OmniCpp_LocalSearchDecl (patch from Roland Kuck)
- Bug when tags=something,,somethingelse (reported by Tobias Pflug)
- Bug with nested structure (reported by Mikhail Daen)
- Bug where the script fails to detect the type of a variable when
the ignorecase option is on (reported by Alexey Vakhov)
- Error message when trying to use completion on a not yet saved
Vim buffer (reported by Neil Bird)
- Error message when trying to use completion on an file opened from
a tselect command (reported by Henrique Andrade)
Version 0.4
- The script is renamed to OmniCppComplete according to the library
script directory structure.
- OmniCpp_ClassScopeCompletionMethod renamed to OmniCpp_DisplayMode
- Fixed a bug where the quickfix list is modified after a completion.
- OmniCpp_ShowPrototypeInAbbr option added. It allows to show the
function signature in the abbreviation.
- OmniCpp_ShowAccess option added. It allows to hide the access
information in the popup menu.
- The tags database format must be a ctags 5.6 database if you want to
complete anonymous types.
- Fixed current scope detection not working properly in destructors.
- Don't show protected and private members according to the current scope.
- Overloaded functions are now filtered properly.
- New cache system using less memory.
- The class scope of a method is now resolved properly with "using
namespace" declarations.
- OmniCpp_SelectFirstItem option added. It allows to not select the first
item in the popup menu when 'completeopt' does not contain "longest".
- Fixed the bug where a "random" item in the popup menu is selected
by default when 'completeopt' does not contain "longest" option.
- The script is now split in library scripts.
- Cache added for 'using namespace' search in included files
- Default value for OmniCpp_NamespaceSearch is now 1 (search only in the
current buffer).
- Namespace search automatically disabled for C files even if
OmniCpp_NamespaceSearch != 0.
- To avoid linear search in tags files, the ignorecase option is now
disabled when getting tags datas (the user setting is restored after).
- Fixed a bug where friend functions may crash the script and also crash vim.
Version 0.32
- Optimizations in search members methods.
- 'May complete' behaviour is now set to default for dot '.' and arrow
'->' (mappings are set in after/ftplugin/cpp.vim)
- Fixed the option CppOmni_ShowScopeInAbbr not detected after the first
completion.
- Exceptions catched from taglist() when a tag file is corrupted.
- Fixed a bug where enumerators in global scope didn't appear in the
popup menu.
Version 0.31
WARNING: For this release and future releases you have to build your tags
database with this cmd :
"ctags -R --c++-kinds=+p --fields=+iaS --extra=+q ."
Please read installation instructions in the documentation for details
- May complete added, please see installation notes for details.
- Fixed a bug where the completion works while in a comment or in a string.
Version 0.3
WARNING: For this release and future releases you have to build your tags
database with this cmd :
"ctags -R --c++-kinds=+p --fields=+iaS --extra=+q ."
Please read installation instructions in the documentation for details
- Documentation added.
- Fixed a bug where typedefs were not correctly resolved in namespaces
in some cases.
- Fixed a bug where the type can not be detected when we have a decl
like this: class A {}globalVar;
- Fixed a bug in type detection where searchdecl() (gd) find
incorrect declaration instruction.
- Global scope completion now only works with non-empty base.
- Using namespace list is now parsed in the current buffer and in
included files.
- Fixed a bug where the completion fails in some cases when the user
sets the ignorecase to on
- Preview window information added
- Some improvements in type detection, the type can be properly detected
with a declaration like this:
'Class1 *class1A = NULL, **class1B = NULL, class1C[9], class1D[1] = {};'
- Fixed a bug where parent scopes were not displayed in the popup menu
in the current scope completion mode.
- Fixed a bug where an error message was displayed when the last
instruction was not finished.
- Fixed a bug where the completion fails if a punctuator or operator was
immediately after the cursor.
- The script can now detect parent contexts at the cursor position
thanks to 'using namespace' declarations.
It can also detect ambiguous namespaces. They are not included in
the context list.
- Fixed a bug where the current scope is not properly detected when
a file starts with a comment
- Fixed a bug where the type is not detected when we have myObject[0]
- Removed the system() call in SearchMembers(), no more calls to the
ctags binary. The user have to build correctly his database with the cmd:
"ctags -R --c++-kinds=+p --fields=+iaS --extra=+q ."
- File time cache removed, the user have to rebuild his data base after a
modification.
Version 0.22
- Completion of unnamed type (eg: You can complete g_Var defined like
this 'struct {int a; int b;}g_Var;'). It also works for a typedef of
an unnamed type (eg: 'typedef struct {int a; int b;}t_mytype; t_mytype
g_Var;').
- Tag file's time cache added, if a tag file has changed the global
scope result cache is cleared.
- Fixed a bug where the tokenization process enter in an infinite loop
when a file starts with '/*'.
Version 0.21
- Improvements on the global scope completion.
The user can now see the progression of the search and complete
matches are stored in a cache for optimization. The cache is cleared
when the tag env is modified.
- Within a class scope when the user complete an empty word, the popup
menu displays the members of the class then members of the global
scope.
- Fixed a bug where a current scope completion failed after a punctuator
or operator (eg: after a '=' or '!=').
Version 0.2
- Improvements in type detection (eg: when a variable is declared in a
parameter list, a catch clause, etc...)
- Code tokenization => ignoring spaces, tabs, carriage returns and comments
You can complete a code even if the instruction has bad
indentation, spaces or carriage returns between words
- Completion of class members added
- Detection of the current scope at the cursor position.
If you run a completion from en empty line, members of the current
scope are displayed. It works on the global namespace and the current
class scope (but there is not the combination of the 2 for the moment)
- Basic completion on the global namespace (very slow)
- Completion of returned type added
- this pointer completion added
- Completion after a cast added (C and C++ cast)
- Fixed a bug where the matches of the complete menu are not filtered
according to what the user typed
- Change the output of the popup menu. The type of the member
(function, member, enum etc...) is now display as a single letter.
The access information is display like this : '+' for a public member
'#' for a protected member and '-' for a private member.
The last information is the class, namespace or enum where the member is define.
Version 0.12:
- Complete check added to the search process, you can now cancel
the search during a complete search.
Version 0.1:
- First release
==============================================================================
9. Thanks~
*omnicpp-thanks*
* For advices, bug report, documentation, help, ideas :
Alexey Vakhov (bug report)
Arthur Axel "fREW" Schmidt (documentation)
Dennis Lubert (bug report)
Henrique Andrade (bug report)
Kamil Renczewski (tips)
Marek Olszewski (patch)
Markus Trenkwalder (bug report)
Martin Stubenschrott (bug report)
Mikhail Daen (bug report)
Neil Bird (bug report)
Nicola Bonelli (tips)
Robert Webb (bug report)
Roland Kuck (patch)
Tobias Pflug (bug report)
Willem-Jan de Hoog (bug report)
Yegappan Lakshmanan (advices)
* Darren Hiebert for Exuberant Ctags
* All Vim devs for Vim
* Bram Moolenaar for Vim
* You for using this script :)
==============================================================================
vim:tw=78:fo=tcq2:isk=!-~,^*,^\|,^\":ts=8:ft=help:norl:
set errorformat=%f:%l:%c:%m
function Latex()
update
let file=expand('%:t:r')
let opts='-src -shell-escape -interaction=nonstopmode'
let errors=system('pdflatex '.opts.' '.file.'|~/.vim/script/latex-errorfilter')
if errors==""
echo 'LaTeX ok: No warning/error'
else
cexpr errors
endif
endfunction
map <F4> :call Latex()<CR>
map <F6> :cprev<CR>
map <F7> :cnext<CR>
map <F8> :clist<CR>
#!/usr/bin/gawk -f
# filter an LaTeX .log file and print a list of warnings and errors
# Usage: latex-errorfilter file.log
# or latex file.tex | latex-errorfilter
/\(|\)/ {
str=$0;
while(i=match(str, /\)|\(/))
if (substr(str, i, 1)==")"){
pop1();
str=substr(str, i+1);
}else{
str=substr(str, i+1);
end=match(str, /\(|\)|[[:space:]]/)
push1(substr(str, 1, end?end-1:80))
str=substr(str,end)
}
}
# errors: messages[file,line,context]=message
/^!/ {
message = "Error: " substr($0,3)
getline
messages[readstack1(), substr($1,3)+0, $NF]=message;
}
# Overfull and Underfull warnings: boxes[file,line]=message
/^.+erfull/ {
boxes[readstack1(),$NF+0]=$0
}
/Warning:/ {
message="";
label=""
for(len=0; NF>0; getline){
message=message (len==79?"":" ") $0
len=length($0)
}
gsub(/^.*Warning: /, "", message)
gsub(/\([^\)]*\)/, "", message)
gsub(/[[:space:]]+/, " ", message)
$0=message; lineno=$NF+0;
# change .aux to .tex if necessary
file = gensub(/\.aux$/, "\\.tex", 1, readstack1());
# treat some special messages about labels
if (message ~ /.*Label `.*' multiply defined\..*/){
label=gensub(/Label `(.*)' multiply defined\./, "\\1", 1, message)
("awk -- '/\\label{" label "}/{l=NR;};END{print l}' " file) | \
getline lineno # find last definition of label
}
if (message ~ /.*Reference `.*' on page.*/)
label=gensub(/.*Reference `(.*)' on page.*/, "\\1", 1, message)
# don't want duplicated warnings
if (message ~/There were multiply-defined labels\./ ||
message ~ /There were undefined references\./)
next;
messages[file,lineno,label]="Warning: "message;
}
END{
# find all useful lines
for (combined in messages){
split(combined, separate, SUBSEP)
lines[separate[1], separate[2]]=1
}
for(combined in messages){
split(combined, separate, SUBSEP)
file=separate[1];
line=separate[2];
label=separate[3];
printf("%s:%d:%d:%s\n", file, line, findcolumn(file,line,label),
messages[combined])
}
for(combined in boxes){
split(combined, separate, SUBSEP)
printf("%s:%d:1:%s\n", separate[1], separate[2], boxes[combined]);
}
}
function push1(thisvalue){
if(thisvalue)
stack1[++stack1index] = thisvalue
# print "PUSH: " thisvalue
}
function pop1( tmpvalue){
if (stack1index <1 ){
return ""
}
tmpvalue = stack1[stack1index]
delete stack1[stack1index]
--stack1index
# print "POP: " tmpvalue
return tmpvalue
}
function readstack1(){ # non destructive pop top
return stack1[stack1index]
}
# find the column of string on a given line in a given file
function findcolumn(file,number,str, line,col){
if (file && !read[file]){
for(line=1;(getline<file)>0;line++)
if (lines[file,line])
content[file,line]=$0
read[file]=1;
close(file)
}
sub(/\\/, "\\\\", str)
col=match(content[file,number], str)
return col?col:1
}
This source diff could not be displayed because it is too large. You can view the blob instead.
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.8 //
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.8 //
This source diff could not be displayed because it is too large. You can view the blob instead.
# This viminfo file was generated by Vim 7.2.
# You may edit it if you're careful!
# Value of 'encoding' when this file was written
*encoding=utf-8
# hlsearch on (H) or off (h):
~h
# Last Search Pattern:
~MSle0~/create
# Last Substitute Search Pattern:
~MSle0&write_to_log
# Last Substitute String:
$write_to_all_logs
# Command Line History (newest to oldest):
:wq
:q
:w
:Q
:270
:n
:c
:e /usr/share/duoworks/core/model
:e /usr/share/duoworks/core/model.php
:e model/variable.php
:help formatting
:help format
:help textwidth
:set textwidth=80
:2
:!pdflatex -src -shell-escape -interaction=nonstopmode %
:!pdflatex -src -shell-escape %
:e core/boot.php
:w ~/.vim/ftdetect/phpt.vim
:!mkdir -p ~/.vim/ftdetect
# Search String History (newest to oldest):
?/create
?/create(
?/svn
?/start(
?/cover
?/test
?/help
? \<cur\>
? ));
? write_to_log
? \<kids\>
? \<tex\>
?/pattern
? \<noremap\>
?/TERM
?/Experi
?/Exper
? \<mod_flv_streaming\>
?/clean
?//
# Expression History (newest to oldest):
# Input Line History (newest to oldest):
# Input Line History (newest to oldest):
# Registers:
"0 CHAR 0
|| exit(1)
""1 LINE 0
return 0;
"2 LINE 0
}
"3 LINE 0
{
"4 LINE 0
$failed = $failed || unlink($file);
"5 LINE 0
else
"6 LINE 0
if( is_dir($file ))
"7 LINE 0
$old = umask(0);
chmod("/path/some_dir/some_file.txt", 0755);
umask($old);
// Checking
$old == umask() || die('An error occured while changing back the umask');
"8 LINE 0
}
"9 LINE 0
"b CHAR 0
327
<:vim textiwkbkbkbkbkbkbkbkbkbkbhelp textwidth kdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkd:help format :help form kbkbkbkbkbkbkbkbkbkbkbformat kdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkdkd
"c CHAR 0
Vkukukukukukukukukukukukukukukukukukukukuku
"q CHAR 0

"- CHAR 0
d
# File marks:
'0 54 2 /usr/share/duoworks/sys/scripts/file_ops.php
'1 138 24 /usr/share/duoworks/module/js/controller/index.php
'2 119 74 /usr/share/duoworks/module/js/controller/index.php
'3 110 34 /usr/share/duoworks/module/js/controller/index.php
'4 1 0 /usr/share/duoworks/sys/verify
'5 95 24 /usr/share/duoworks/sys/verify
'6 117 1 /usr/share/duoworks/sys/verify
'7 271 0 /usr/share/duoworks/lib/activerecord/model.php
'8 1 0 /usr/share/duoworks/sys/codecoverage/Filter.php
'9 584 27 /usr/share/duoworks/Phakefile
# Jumplist (newest first):
-' 54 2 /usr/share/duoworks/sys/scripts/file_ops.php
-' 1 0 /usr/share/duoworks/sys/scripts/file_ops.php
-' 138 24 /usr/share/duoworks/module/js/controller/index.php
-' 1 0 /usr/share/duoworks/module/js/controller/index.php
-' 119 74 /usr/share/duoworks/module/js/controller/index.php
-' 110 34 /usr/share/duoworks/module/js/controller/index.php
-' 1 0 /usr/share/duoworks/sys/verify
-' 95 24 /usr/share/duoworks/sys/verify
-' 117 1 /usr/share/duoworks/sys/verify
-' 271 0 /usr/share/duoworks/lib/activerecord/model.php
-' 1 0 /usr/share/duoworks/lib/activerecord/model.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Filter.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/TextUI/Command.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Util.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/CodeCoverage.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/File/Iterator.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/File/Iterator/Factory.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Driver/Xdebug.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Token/Stream/TextUI/Command.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Token/Stream.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Token/Exception.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Driver.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/HTML/Node.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/HTML/Node/Iterator.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/HTML/Node/Directory.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/HTML/Node/File.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/Clover.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/HTML.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Text/Template.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Token.php
-' 1 0 /usr/share/duoworks/sys/scripts/phake.php
-' 219 0 /usr/share/duoworks/sys/scripts/db/modelify.php
-' 1 0 /usr/share/duoworks/sys/scripts/db/modelify.php
-' 31 0 /usr/share/duoworks/sys/scripts/install.php
-' 1 0 /usr/share/duoworks/sys/scripts/install.php
-' 21 0 /usr/share/duoworks/sys/scripts/clean.php
-' 1 0 /usr/share/duoworks/sys/scripts/clean.php
-' 1 0 /usr/share/duoworks/sys/scripts/tests/run-tests.php
-' 5 1 /usr/share/duoworks/sys/scripts/tests/bootstrap.php
-' 1 0 /usr/share/duoworks/sys/scripts/tests/bootstrap.php
-' 1 0 /usr/share/duoworks/sys/scripts/parse_cli.php
-' 1 0 /usr/share/duoworks/sys/scripts/guidelines/check.php
-' 69 0 /usr/share/duoworks/sys/scripts/file_ops.php
-' 175 0 /usr/share/duoworks/sys/scripts/configure.php
-' 1 0 /usr/share/duoworks/sys/scripts/configure.php
-' 584 27 /usr/share/duoworks/Phakefile
-' 566 46 /usr/share/duoworks/Phakefile
-' 21 23 /usr/share/duoworks/Phakefile
-' 1 0 /usr/share/duoworks/Phakefile
-' 81 1 /usr/share/duoworks/core/model.php
-' 1 0 /usr/share/duoworks/core/model.php
-' 1 0 /usr/share/duoworks/core/model
-' 1 0 ~/Programming/web/vo20/model/variable.php
-' 63 2 /usr/share/duoworks/core/model.php
-' 278 1 /usr/share/duoworks/lib/activerecord/model.php
-' 238 16 ~/Programming/web/vo20/module/exam/view/create.php
-' 1 0 ~/Programming/web/vo20/module/exam/view/create.php
-' 107 0 /usr/share/duoworks/core/model.php
-' 1 29 /usr/share/duoworks/svn-commit.tmp
-' 364 26 /usr/share/duoworks/core/boot.php
-' 1 0 /usr/share/duoworks/core/boot.php
-' 1 0 ~/Programming/web/vo20/module/index/controller/index.php
-' 1 1 ~/Programming/web/vo20/cache/1287421747.log
-' 1 67 ~/Programming/web/vo20/svn-commit.tmp
-' 5 57 /usr/share/duoworks/svn-commit.tmp
-' 1 43 ~/tmp/uva/.git/COMMIT_EDITMSG
-' 87 0 ~/tmp/uva/paper/paper.tex
-' 1 0 ~/tmp/uva/paper/paper.tex
-' 53 0 ~/tmp/uva/paper/paper.tex
-' 73 0 ~/tmp/uva/paper/paper.tex
-' 57 67 ~/tmp/uva/paper/paper.tex
-' 295 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 309 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 307 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 45 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 1 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 335 22 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 268 8 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 275 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 96 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 116 0 ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
-' 1 0 ~/tmp/uva/main.c
-' 1 0 ~/tmp/uva/graphics/.gitignore
-' 7 4 ~/tmp/uva/2010-09-03-uva/.gitignore
-' 1 0 ~/tmp/uva/2010-09-03-uva/.gitignore
-' 299 1 /usr/share/duoworks/core/boot.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Filter.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/TextUI/Command.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Util.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/CodeCoverage.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/File/Iterator.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/File/Iterator/Factory.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Driver/Xdebug.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Token/Stream/TextUI/Command.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Token/Stream.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Token/Exception.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Driver.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/HTML/Node.php
-' 1 0 /usr/share/duoworks/sys/codecoverage/Report/HTML/Node/Iterator.php
# History of marks within files (newest to oldest):
> /usr/share/duoworks/sys/scripts/file_ops.php
" 54 2
^ 54 3
. 50 67
+ 65 10
+ 64 19
+ 64 13
+ 66 7
+ 65 27
+ 67 9
+ 64 23
+ 66 21
+ 65 23
+ 64 0
+ 65 0
+ 64 0
+ 65 0
+ 64 7
+ 66 7
+ 67 0
+ 64 18
+ 66 15
+ 58 9
+ 60 11
+ 61 0
+ 54 1
+ 53 1
+ 52 10
+ 53 39
+ 50 67
> /usr/share/duoworks/module/js/controller/index.php
" 138 24
^ 119 75
. 111 35
+ 34 2
+ 32 23
+ 33 39
+ 32 3
+ 33 3
+ 32 2
+ 33 2
+ 120 0
+ 112 66
+ 110 8
+ 109 18
+ 110 17
+ 109 0
+ 121 13
+ 122 48
+ 110 41
+ 109 12
+ 122 64
+ 41 15
+ 109 69
+ 108 10
+ 109 22
+ 112 25
+ 110 0
+ 122 65
+ 108 59
+ 62 34
+ 107 43
+ 99 6
+ 103 68
+ 105 47
+ 110 34
+ 110 3
+ 110 17
+ 110 7
+ 110 2
+ 112 2
+ 113 0
+ 115 18
+ 120 0
+ 115 18
+ 111 35
> /usr/share/duoworks/sys/verify
" 1 0
^ 95 25
. 95 24
+ 1 13
+ 58 10
+ 58 13
+ 59 0
+ 58 21
+ 112 1
+ 111 1
+ 110 1
+ 109 1
+ 108 1
+ 107 1
+ 106 1
+ 105 1
+ 105 0
+ 104 1
+ 103 1
+ 102 2
+ 96 39
+ 101 2
+ 97 53
+ 98 49
+ 99 40
+ 100 8
+ 113 1
+ 114 1
+ 115 1
+ 116 1
+ 117 1
+ 41 14
+ 41 18
+ 42 0
+ 41 17
+ 95 24
> /usr/share/duoworks/lib/activerecord/model.php
" 271 0
^ 269 55
. 246 64
+ 268 45
+ 266 49
+ 268 39
+ 269 8
+ 301 66
+ 225 0
+ 228 63
+ 234 47
+ 239 4
+ 234 4
+ 246 64
> /usr/share/duoworks/sys/scripts/configure.php
" 175 0
. 176 0
+ 176 0
> /usr/share/duoworks/sys/scripts/guidelines/check.php
" 1 0
> /usr/share/duoworks/sys/scripts/parse_cli.php
" 1 0
> /usr/share/duoworks/sys/scripts/tests/bootstrap.php
" 5 1
. 6 0
+ 6 0
> /usr/share/duoworks/sys/scripts/tests/run-tests.php
" 1 0
^ 1653 76
. 1653 75
+ 1653 75
> /usr/share/duoworks/sys/scripts/clean.php
" 21 0
^ 80 56
. 80 55
+ 79 82
+ 80 46
+ 79 82
+ 80 42
+ 79 79
+ 79 79
+ 80 41
+ 80 44
+ 81 34
+ 82 0
+ 90 9
+ 80 12
+ 59 0
+ 80 55
> /usr/share/duoworks/sys/scripts/install.php
" 31 0
> /usr/share/duoworks/sys/scripts/db/modelify.php
" 219 0
> /usr/share/duoworks/sys/scripts/phake.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Token.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Text/Template.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Report/HTML.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Report/Clover.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Report/HTML/Node/File.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Report/HTML/Node/Directory.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Report/HTML/Node/Iterator.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Report/HTML/Node.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Driver.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Token/Exception.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Token/Stream.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Token/Stream/TextUI/Command.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Driver/Xdebug.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/File/Iterator/Factory.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/File/Iterator.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/CodeCoverage.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Util.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/TextUI/Command.php
" 1 0
> /usr/share/duoworks/sys/codecoverage/Filter.php
" 1 0
> /usr/share/duoworks/Phakefile
" 584 27
^ 548 77
. 574 33
+ 531 17
+ 329 68
+ 522 5
+ 524 3
+ 525 3
+ 528 3
+ 528 7
+ 530 12
+ 533 29
+ 530 44
+ 528 2
+ 528 2
+ 525 2
+ 524 2
+ 530 33
+ 528 21
+ 528 10
+ 528 27
+ 526 71
+ 528 0
+ 526 63
+ 528 0
+ 526 58
+ 527 26
+ 523 0
+ 522 39
+ 527 28
+ 470 0
+ 535 0
+ 536 0
+ 541 0
+ 539 0
+ 531 0
+ 405 69
+ 443 0
+ 434 1
+ 434 0
+ 438 0
+ 438 52
+ 438 0
+ 435 51
+ 436 66
+ 443 34
+ 444 2
+ 443 41
+ 444 0
+ 443 32
+ 444 29
+ 438 0
+ 444 45
+ 445 51
+ 443 0
+ 444 27
+ 443 33
+ 444 6
+ 443 0
+ 435 6
+ 583 0
+ 585 21
+ 585 0
+ 1 5
+ 1 5
+ 1 5
+ 1 5
+ 3 0
+ 1 5
+ 583 0
+ 585 0
+ 583 1
+ 584 1
+ 401 0
+ 408 0
+ 406 13
+ 424 25
+ 426 56
+ 584 1
+ 16 70
+ 17 39
+ 24 32
+ 21 25
+ 23 5
+ 21 25
+ 23 62
+ 28 52
+ 32 5
+ 36 39
+ 40 33
+ 103 35
+ 115 40
+ 218 35
+ 262 42
+ 275 48
+ 312 0
+ 313 18
+ 314 9
+ 548 19
+ 566 35
+ 565 34
+ 564 37
+ 574 33
> /usr/share/duoworks/core/model.php
" 81 1
> ~/Programming/web/vo20/model/variable.php
" 1 0
> /usr/share/duoworks/core/model
" 1 0
> ~/Programming/web/vo20/module/exam/view/create.php
" 238 16
> /usr/share/duoworks/svn-commit.tmp
" 1 29
^ 1 30
. 1 29
+ 2 48
+ 3 48
+ 4 57
+ 5 57
+ 1 29
> /usr/share/duoworks/core/boot.php
" 364 26
^ 364 27
. 364 26
+ 328 23
+ 324 51
+ 328 47
+ 317 48
+ 383 50
+ 377 2
+ 382 0
+ 382 2
+ 382 0
+ 378 3
+ 379 38
+ 384 1
+ 350 70
+ 345 20
+ 344 23
+ 345 15
+ 344 25
+ 343 15
+ 342 15
+ 345 77
+ 347 44
+ 356 14
+ 357 22
+ 359 17
+ 347 46
+ 345 76
+ 347 73
+ 348 31
+ 347 72
+ 348 15
+ 220 0
+ 363 3
+ 364 2
+ 365 2
+ 364 26
> ~/Programming/web/vo20/module/index/controller/index.php
" 1 0
> ~/Programming/web/vo20/cache/1287421747.log
" 1 1
> ~/Programming/web/vo20/svn-commit.tmp
" 1 67
^ 1 68
. 1 67
+ 1 67
> ~/tmp/uva/.git/COMMIT_EDITMSG
" 1 43
^ 1 44
. 1 43
+ 5 0
+ 1 48
+ 6 61
+ 7 29
+ 1 33
+ 3 3
+ 1 43
> ~/tmp/uva/paper/paper.tex
" 87 0
^ 73 71
. 75 0
+ 42 44
+ 43 0
+ 34 0
+ 30 0
+ 32 0
+ 33 3
+ 32 1
+ 30 3
+ 32 3
+ 30 0
+ 18 76
+ 19 12
+ 25 3
+ 21 1
+ 16 1
+ 40 1
+ 39 52
+ 41 26
+ 40 0
+ 39 50
+ 38 79
+ 40 0
+ 41 15
+ 42 2
+ 41 41
+ 3 0
+ 41 20
+ 56 46
+ 56 46
+ 57 43
+ 56 79
+ 57 67
+ 57 33
+ 59 32
+ 74 1
+ 73 75
+ 56 75
+ 58 68
+ 72 78
+ 81 42
+ 61 76
+ 79 42
+ 79 42
+ 82 0
+ 79 76
+ 80 80
+ 57 67
+ 57 67
+ 58 68
+ 59 31
+ 57 78
+ 59 31
+ 61 0
+ 59 31
+ 75 0
+ 75 71
+ 77 0
+ 76 77
+ 73 32
+ 69 49
+ 73 64
+ 65 39
+ 69 48
+ 72 76
+ 73 0
+ 60 0
+ 75 0
> /usr/share/vim/vim72/doc/options.txt
" 3029 6
> /usr/share/vim/vim72/doc/change.txt
" 1237 6
> ~/tmp/uva/2010-10-19-uva/2010-10-19-uva.tex
" 295 0
^ 312 14
. 312 11
+ 200 0
+ 201 0
+ 202 0
+ 203 0
+ 204 0
+ 205 0
+ 206 0
+ 207 0
+ 208 0
+ 209 0
+ 210 0
+ 211 0
+ 212 0
+ 213 0
+ 214 0
+ 215 0
+ 228 0
+ 229 0
+ 230 0
+ 231 0
+ 232 0
+ 233 0
+ 234 0
+ 235 0
+ 236 0
+ 237 0
+ 238 0
+ 239 0
+ 240 0
+ 241 0
+ 246 0
+ 249 0
+ 242 35
+ 251 0
+ 253 0
+ 254 0
+ 255 0
+ 256 0
+ 257 0
+ 258 0
+ 259 0
+ 261 0
+ 262 0
+ 263 0
+ 265 0
+ 266 0
+ 267 0
+ 274 0
+ 275 0
+ 259 16
+ 258 16
+ 258 16
+ 264 32
+ 230 35
+ 241 67
+ 260 19
+ 259 37
+ 95 0
+ 94 0
+ 275 0
+ 275 0
+ 268 0
+ 268 0
+ 268 0
+ 272 0
+ 273 0
+ 268 9
+ 272 9
+ 268 0
+ 246 0
+ 248 0
+ 268 14
+ 270 14
+ 269 27
+ 243 14
+ 245 14
+ 244 22
+ 246 28
+ 247 26
+ 248 0
+ 244 1
+ 338 53
+ 334 15
+ 335 12
+ 334 1
+ 335 23
+ 336 31
+ 304 0
+ 309 0
+ 309 0
+ 309 1
+ 309 0
+ 307 0
+ 309 0
+ 308 62
+ 308 0
+ 310 1
+ 311 1
+ 307 53
+ 312 11
> /usr/share/vim/vim72/doc/help.txt
" 63 0
> /usr/share/vim/vim72/doc/editing.txt
" 374 62
> /usr/share/vim/vim72/doc/visual.txt
" 256 0
> ~/help
" 1 0
> ~/tmp/uva/main.c
" 1 0
> ~/tmp/uva/graphics/.gitignore
" 1 0
^ 1 2
. 1 0
+ 1 0
> ~/tmp/uva/2010-09-03-uva/.gitignore
" 7 4
^ 7 5
. 7 4
+ 7 4
> /usr/share/duoworks/test/module/hello-world/controller/index.php
" 9 19
. 9 14
+ 9 14
> /usr/share/duoworks/test/module/hello-world/index.phpt
" 20 6
. 20 6
+ 2 5
+ 20 6
> /usr/share/duoworks/test/module/example/index.phpt
" 2 1
^ 20 2
. 2 0
+ 8 23
+ 16 66
+ 20 12
+ 12 35
+ 13 28
+ 1 7
+ 2 1
+ 2 0
> /usr/share/duoworks/test/module/example/index.log
" 1 0
> /usr/share/duoworks/test/module/example/controller/index.php
" 5 25
^ 5 26
. 5 25
+ 5 23
+ 11 1
+ 5 32
+ 3 18
+ 7 24
+ 10 1
+ 7 30
+ 9 21
+ 5 25
> /usr/share/duoworks/test/core/model.phpt
" 1 4
> /usr/share/vim/vim72/doc/filetype.txt
" 179 39
> /usr/share/duoworks/test/module/example/controller/index.phpt
" 16 47
^ 16 48
. 16 47
+ 10 0
+ 2 25
+ 8 28
+ 21 0
+ 20 0
+ 2 31
+ 10 29
+ 11 0
+ 4 24
+ 2 7
+ 11 1
+ 16 49
+ 11 7
+ 16 0
+ 14 0
+ 11 0
+ 14 13
+ 13 25
+ 14 21
+ 12 33
+ 16 47
> /usr/share/duoworks/test/module/example/controller/index.log
" 6 0
> /usr/share/php5/phake/lib/phake.php
" 177 0
> /usr/share/duoworks/sys/scripts/tests/run.sh
" 33 0
> ~/.vimrc
" 9 11
^ 9 12
. 9 11
+ 4 12
+ 5 13
+ 49 0
+ 49 17
+ 14 33
+ 16 7
+ 17 0
+ 16 0
+ 15 0
+ 50 0
+ 6 9
+ 7 15
+ 49 0
+ 24 8
+ 47 0
+ 30 1
+ 30 2
+ 33 0
+ 34 0
+ 33 0
+ 34 0
+ 33 1
+ 32 0
+ 30 0
+ 11 15
+ 12 2
+ 11 4
+ 18 37
+ 19 5
+ 18 1
+ 19 0
+ 18 4
+ 19 12
+ 18 16
+ 19 61
+ 21 48
+ 22 23
+ 23 0
+ 22 59
+ 22 59
+ 22 0
+ 22 95
+ 9 11
> ~/tmp/uva/graphics/ass6/main.c
" 193 24
^ 193 25
. 200 25
+ 3 43
+ 4 34
+ 5 28
+ 6 20
+ 7 20
+ 8 0
+ 8 0
+ 168 42
+ 171 0
+ 177 42
+ 191 46
+ 189 7
+ 191 12
+ 203 3
+ 203 0
+ 182 49
+ 182 0
+ 194 0
+ 194 1
+ 195 2
+ 196 0
+ 193 0
+ 194 0
+ 196 3
+ 183 10
+ 184 8
+ 184 0
+ 185 0
+ 186 0
+ 185 5
+ 186 9
+ 185 36
+ 183 36
+ 185 44
+ 183 47
+ 213 21
+ 198 0
+ 197 32
+ 200 43
+ 199 8
+ 202 0
+ 199 9
+ 199 40
+ 200 15
+ 201 0
+ 200 18
+ 199 37
+ 200 25
> ~/tmp/uva/graphics/ass6/Makefile
" 32 0
> ~/tmp/uva/os/ass3/fishbones.c
" 120 3
^ 136 6
. 128 0
+ 91 25
+ 89 19
+ 89 16
+ 87 42
+ 89 18
+ 87 14
+ 91 0
+ 89 24
+ 106 0
+ 105 28
+ 103 2
+ 105 0
+ 87 43
+ 87 56
+ 92 0
+ 103 2
+ 92 11
+ 87 0
+ 92 54
+ 104 24
+ 104 8
+ 111 33
+ 112 30
+ 111 50
+ 144 30
+ 131 7
+ 160 7
+ 160 13
+ 160 48
+ 160 54
+ 160 14
+ 158 38
+ 159 35
+ 160 0
+ 160 1
+ 159 7
+ 68 4
+ 69 4
+ 65 2
+ 64 2
+ 65 32
+ 31 27
+ 89 26
+ 83 9
+ 83 0
+ 72 0
+ 94 0
+ 96 36
+ 97 0
+ 95 0
+ 16 11
+ 14 0
+ 70 11
+ 115 11
+ 160 15
+ 160 0
+ 149 32
+ 160 46
+ 149 0
+ 84 1
+ 83 4
+ 64 3
+ 65 3
+ 35 0
+ 26 0
+ 26 0
+ 23 1
+ 23 12
+ 23 12
+ 24 0
+ 23 0
+ 19 27
+ 20 0
+ 19 27
+ 70 0
+ 51 20
+ 67 22
+ 51 22
+ 30 0
+ 28 3
+ 168 23
+ 87 0
+ 26 49
+ 27 0
+ 26 49
+ 17 25
+ 49 22
+ 33 1
+ 112 17
+ 148 17
+ 132 39
+ 135 25
+ 145 0
+ 142 0
+ 145 32
+ 135 41
+ 135 5
+ 133 26
+ 135 0
+ 128 0
> ~/tmp/uva/os/ass3/logger.c
" 96 14
^ 96 15
. 96 14
+ 47 13
+ 44 30
+ 48 3
+ 76 0
+ 80 26
+ 77 21
+ 47 31
+ 44 18
+ 8 19
+ 2 21
+ 4 52
+ 5 53
+ 2 13
+ 32 67
+ 50 37
+ 99 0
+ 100 54
+ 110 0
+ 102 20
+ 110 1
+ 103 8
+ 110 0
+ 105 0
+ 110 0
+ 109 19
+ 109 16
+ 109 0
+ 110 0
+ 100 36
+ 83 29
+ 8 0
+ 10 0
+ 19 34
+ 34 31
+ 64 8
+ 89 7
+ 106 7
+ 109 30
+ 9 0
+ 10 0
+ 9 16
+ 109 2
+ 10 0
+ 7 15
+ 93 7
+ 94 2
+ 109 8
+ 66 7
+ 70 17
+ 72 0
+ 66 0
+ 67 0
+ 109 11
+ 34 1
+ 36 0
+ 34 11
+ 35 8
+ 37 44
+ 40 29
+ 38 21
+ 35 12
+ 40 38
+ 37 18
+ 19 49
+ 24 11
+ 21 18
+ 22 15
+ 37 0
+ 40 0
+ 94 11
+ 85 9
+ 94 0
+ 94 2
+ 96 2
+ 98 0
+ 96 1
+ 96 1
+ 94 2
+ 95 0
+ 98 0
+ 96 10
+ 85 2
+ 96 12
+ 96 2
+ 85 1
+ 93 14
+ 94 11
+ 96 1
+ 96 0
+ 94 0
+ 93 14
+ 94 0
+ 96 0
+ 93 11
+ 93 1
+ 96 2
+ 93 9
+ 96 1
+ 97 0
+ 96 14
> /usr/share/duodocs/css/Default.css
" 527 21
^ 527 22
. 527 21
+ 1336 9
+ 1337 18
+ 1338 14
+ 1319 15
+ 1320 16
+ 1304 21
+ 1272 10
+ 1265 30
+ 1259 30
+ 1253 31
+ 1242 39
+ 1230 26
+ 1212 40
+ 1085 17
+ 1086 21
+ 1087 26
+ 1077 11
+ 1078 14
+ 1079 19
+ 1067 10
+ 1068 11
+ 1069 14
+ 1070 19
+ 978 15
+ 970 8
+ 916 0
+ 917 19
+ 3 0
+ 826 44
+ 826 53
+ 827 0
+ 772 45
+ 772 55
+ 772 55
+ 772 55
+ 756 45
+ 756 45
+ 756 53
+ 756 53
+ 756 54
+ 721 44
+ 721 53
+ 722 0
+ 587 49
+ 587 59
+ 587 70
+ 588 0
+ 460 0
+ 427 0
+ 368 0
+ 358 0
+ 164 0
+ 159 0
+ 157 0
+ 156 0
+ 155 0
+ 152 0
+ 150 0
+ 149 0
+ 148 0
+ 146 0
+ 144 0
+ 143 0
+ 142 0
+ 141 0
+ 3 18
+ 4 78
+ 4 78
+ 5 11
+ 4 78
+ 6 57
+ 7 0
+ 10 13
+ 11 0
+ 14 0
+ 17 12
+ 27 0
+ 45 0
+ 72 0
+ 73 0
+ 74 0
+ 81 0
+ 92 0
+ 98 0
+ 105 0
+ 112 0
+ 119 0
+ 129 0
+ 141 0
+ 206 27
+ 206 45
+ 206 45
+ 206 54
+ 206 0
+ 206 0
+ 205 16
+ 527 12
+ 528 0
+ 526 8
+ 527 21
> /etc/lighttpd/lighttpd.conf
" 3 0
^ 101 56
. 86 35
+ 18 0
+ 192 1
+ 193 0
+ 164 2
+ 165 2
+ 167 1
+ 168 1
+ 169 1
+ 165 37
+ 166 0
+ 166 0
+ 163 1
+ 166 1
+ 165 1
+ 164 3
+ 165 3
+ 182 21
+ 182 1
+ 170 1
+ 182 23
+ 190 1
+ 182 3
+ 184 1
+ 185 59
+ 189 74
+ 17 0
+ 18 0
+ 169 0
+ 168 0
+ 167 0
+ 166 0
+ 165 0
+ 164 0
+ 163 0
+ 170 48
+ 179 73
+ 170 59
+ 179 46
+ 181 0
+ 162 0
+ 170 2
+ 171 29
+ 181 0
+ 176 8
+ 177 8
+ 176 38
+ 177 42
+ 179 41
+ 171 0
+ 172 0
+ 111 82
+ 67 0
+ 68 25
+ 70 0
+ 67 0
+ 68 25
+ 69 0
+ 23 0
+ 30 58
+ 110 75
+ 172 46
+ 173 0
+ 110 83
+ 170 0
+ 182 0
+ 30 0
+ 170 0
+ 182 0
+ 170 0
+ 173 1
+ 177 0
+ 176 1
+ 175 1
+ 177 1
+ 173 1
+ 177 1
+ 176 1
+ 175 1
+ 173 24
+ 175 33
+ 178 2
+ 173 23
+ 175 33
+ 176 2
+ 179 1
+ 180 1
+ 181 1
+ 180 47
+ 182 3
+ 183 0
+ 10 0
+ 14 0
+ 13 0
+ 14 0
+ 13 0
+ 21 0
+ 20 58
+ 85 58
+ 86 34
+ 86 35
> /etc/lighttpd/conf-enabled/duoworks.conf
" 1 0
. 2 0
+ 1 0
+ 1 27
+ 2 0
> ~/tmp/uva/os/ass3/view-logs.bash
" 1 0
^ 9 10
. 9 10
+ 9 18
+ 7 3
+ 3 31
+ 7 3
+ 8 0
+ 6 0
+ 3 18
+ 6 30
+ 4 0
+ 6 29
+ 4 80
+ 5 61
+ 9 10
> ~/tmp/uva/os/ass3/screenrc
" 4 13
^ 9 16
. 4 13
+ 4 14
+ 7 14
+ 9 13
+ 7 13
+ 4 13
> ~/tmp/uva/os/ass3/Makefile
" 33 9
^ 33 18
. 33 9
+ 41 5
+ 26 7
+ 22 30
+ 33 9
+ 26 20
+ 33 9
> ~/tmp/uva/os/ass3/logger.h
" 4 0
^ 20 35
. 2 0
+ 6 0
+ 20 4
+ 19 4
+ 18 7
+ 19 0
+ 18 0
+ 6 0
+ 6 0
+ 5 0
+ 10 14
+ 14 14
+ 10 13
+ 14 10
+ 9 3
+ 8 27
+ 13 3
+ 12 40
+ 8 28
+ 3 0
+ 6 0
+ 3 22
+ 17 30
+ 18 78
+ 19 46
+ 20 38
+ 18 74
+ 21 21
+ 19 42
+ 21 36
+ 20 34
+ 2 0
> ~/tmp/uva/os/ass3/fishbones
" 1 0
> ~/tmp/uva/os/ass3/.screenrc
" 1 8
^ 1 11
. 1 8
+ 5 0
+ 1 26
+ 5 0
+ 8 0
+ 5 0
+ 8 0
+ 5 0
+ 8 0
+ 5 4
+ 7 26
+ 8 31
+ 1 0
+ 8 5
+ 10 0
+ 8 5
+ 9 27
+ 10 0
+ 10 0
+ 1 5
+ 5 4
+ 8 4
+ 1 0
+ 1 0
+ 1 0
+ 1 4
+ 10 0
+ 9 0
+ 2 0
+ 1 6
+ 3 7
+ 6 7
+ 1 8
> ~/tmp/uva/os/ass3/example.in
" 1 12
^ 1 1
. 1 1
+ 2 0
+ 1 1
> ~/tmp/uva/.git/config
" 8 18
^ 8 19
. 8 19
+ 9 0
+ 8 19
> /usr/share/vim/vim72/doc/usr_20.txt
" 384 0
> /usr/share/vim/vim72/doc/autocmd.txt
" 69 0
> /usr/share/vim/vim72/doc/spell.txt
" 46 0
> /usr/share/vim/vim72/doc/usr_25.txt
" 45 0
> ~/tmp/uva/paper/.gitignore
" 1 8
^ 1 9
. 1 8
+ 2 0
+ 1 8
> ~/tmp/uva/.gitignore
" 3 4
^ 3 5
. 3 4
+ 3 4
> /usr/share/vim/vim72/doc/usr_24.txt
" 510 0
> ~/:help
" 1 0
> /usr/share/vim/vim72/doc/pattern.txt
" 30 0
> /usr/share/vim/vim72/doc/windows.txt
" 606 0
> /usr/share/vim/vim72/doc/quickfix.txt
" 1443 8
> ~/Documents/Voortgezet Onderwijs 2.0/tex/paper/paper.tex
" 38 43
^ 38 44
. 38 44
+ 34 0
+ 35 20
+ 40 0
+ 35 72
+ 35 31
+ 35 76
+ 35 19
+ 35 32
+ 40 0
+ 41 0
+ 37 33
+ 36 52
+ 37 77
+ 37 77
+ 38 42
+ 37 77
+ 39 0
+ 38 44
> ~/Programming/web/vo20/index.php
" 1 0
> ~/Programming/web/vo20/tags
" 60 0
> ~/Programming/web/vo20/.vimrc
" 1 0
> ~/Programming/web/vo20/Phakefile
" 1 0
> /usr/share/vim/vim72/doc/usr_05.txt
" 332 0
> ~/.bashrc
" 1 0
> /etc/apt/sources.list.d/lottanzb-ppa-lucid.list
" 1 48
^ 1 49
. 1 48
+ 1 48
# This viminfo file was generated by Vim 7.2.
# You may edit it if you're careful!
# Value of 'encoding' when this file was written
*encoding=utf-8
# hlsearch on (H) or off (h):
~h
# Last Search Pattern:
~Msle0~/)
# Last Substitute Search Pattern:
~MSle0&ab
# Last Substitute String:
$
# Command Line History (newest to oldest):
:w
:set nonumber
:set nonumbers
:q
:vs
:set number
:set autoindent
:Q
:wq
:q!
:split
:help
:help v_u
:heko v_u
:/doc/
:s/ab/
:Q!
:e
:o
:s/Boot/g
:s/Boot/
:s/Boot
:s/boot
:s/boot/
:wq!
:next
# Search String History (newest to oldest):
? )
? doc
? ab
? Boot
? boot
? \<DS_\>
? \<index\>
? changes
? \<deb\>
? }
# Expression History (newest to oldest):
# Input Line History (newest to oldest):
# Input Line History (newest to oldest):
# Registers:
"1 LINE 0
"2 LINE 0
int sym = 0;
"3 LINE 0
"4 LINE 0
char *unused = malloc((len+1) * sizeof(char));
"5 LINE 0
"6 LINE 0
int sym = 0;
"7 LINE 0
strcpy(unused, symbols);
"8 LINE 0
printf("unused: %s\n", unused);
"9 LINE 0
""- CHAR 0
/
# File marks:
'0 108 4 ~/Desktop/bapc-2009/d.c
'1 23 7 ~/Desktop/bapc-2009/a.c
'2 2 0 /etc/php5/conf.d/xdebug.ini
'3 1 0 /tmp/tutoriHJbUr
'4 398 0 /tmp/tutorHpGuJF
'5 2 9 ~/Desktop/vo20-index.dot
'6 3 37 /etc/php5/conf.d/xdebug.ini
'7 180 1 /etc/lighttpd/lighttpd.conf
'8 181 0 /etc/lighttpd/lighttpd.conf
'9 1 38 /usr/share/duoworks/svn-commit.tmp
# Jumplist (newest first):
-' 108 4 ~/Desktop/bapc-2009/d.c
-' 87 1 ~/Desktop/bapc-2009/d.c
-' 89 1 ~/Desktop/bapc-2009/d.c
-' 76 2 ~/Desktop/bapc-2009/d.c
-' 71 32 ~/Desktop/bapc-2009/d.c
-' 119 8 ~/Desktop/bapc-2009/d.c
-' 137 14 ~/Desktop/bapc-2009/d.c
-' 139 23 ~/Desktop/bapc-2009/d.c
-' 144 1 ~/Desktop/bapc-2009/d.c
-' 154 16 ~/Desktop/bapc-2009/d.c
-' 39 0 ~/Desktop/bapc-2009/d.c
-' 228 0 ~/Desktop/bapc-2009/d.c
-' 1 0 ~/Desktop/bapc-2009/d.c
-' 23 7 ~/Desktop/bapc-2009/a.c
-' 1 0 ~/Desktop/bapc-2009/a.c
-' 2 0 /etc/php5/conf.d/xdebug.ini
-' 1 0 /etc/php5/conf.d/xdebug.ini
-' 1 0 /tmp/tutoriHJbUr
-' 398 0 /tmp/tutorHpGuJF
-' 381 0 /tmp/tutorHpGuJF
-' 377 0 /tmp/tutorHpGuJF
-' 382 0 /tmp/tutorHpGuJF
-' 379 0 /tmp/tutorHpGuJF
-' 332 39 /tmp/tutorHpGuJF
-' 324 52 /tmp/tutorHpGuJF
-' 311 0 /tmp/tutorHpGuJF
-' 322 0 /tmp/tutorHpGuJF
-' 86 0 /tmp/tutorHpGuJF
-' 1 0 /tmp/tutorHpGuJF
-' 2 9 ~/Desktop/vo20-index.dot
-' 1 0 ~/Desktop/vo20-index.dot
-' 3 37 /etc/php5/conf.d/xdebug.ini
-' 180 1 /etc/lighttpd/lighttpd.conf
-' 1 0 /etc/lighttpd/lighttpd.conf
-' 181 0 /etc/lighttpd/lighttpd.conf
-' 1 38 /usr/share/duoworks/svn-commit.tmp
-' 1 47 ~/Programming/web/vo20/svn-commit.tmp
-' 2 46 ~/Programming/web/vo20/svn-commit.tmp
-' 26 0 ~/graph.dot
-' 1 0 ~/graph.dot
-' 5 3 /usr/share/duoworks/svn-commit.tmp
-' 4 10 /usr/share/duoworks/cache/svn-prop.tmp
-' 1 0 /usr/share/duoworks/cache/svn-prop.tmp
-' 1 0 ~/Programming/web/duoscript/trunk/svn-prop.tmp
-' 2 7 ~/Programming/web/duoscript/trunk/svn-prop.tmp
-' 41 1 /usr/share/duoworks/lib/activerecord/model.php
-' 1 0 /usr/share/duoworks/lib/activerecord/model.php
-' 537 1 /usr/share/duoworks/core/model.php
-' 1 0 /usr/share/duoworks/core/model.php
-' 98 6 /etc/phpsh/config.sample
-' 1 0 /etc/phpsh/config.sample
-' 1 0 ~/Desktop/ua.html
-' 109 0 /usr/share/duoworks/sys/update
-' 1 0 /usr/share/duoworks/sys/update
-' 102 15 /usr/share/duoworks/sys/update
-' 178 47 /etc/lighttpd/lighttpd.conf
-' 176 2 /etc/lighttpd/lighttpd.conf
-' 1024 0 ~/.wine/drive_c/Program Files/RegexBuddy 3/RegexBuddy.ini
-' 1 0 ~/.wine/drive_c/Program Files/RegexBuddy 3/RegexBuddy.ini
-' 8 0 /usr/share/duoworks/sys/scripts/phake.php
-' 1 0 /usr/share/duoworks/sys/scripts/phake.php
-' 6 1 /usr/share/duoworks/sys/scripts/configure.php
-' 1 0 /usr/share/duoworks/sys/scripts/configure.php
-' 176 1 /usr/share/duoworks/sys/scripts/configure.php
-' 6 29 /usr/share/duoworks/sys/scripts/phake.php
-' 9 40 /etc/apache2/sites-enabled/000-default
-' 1 0 /etc/apache2/sites-enabled/000-default
-' 1 0 /etc/apache2/httpd.conf
-' 38 0 /etc/apache2/apache2.conf
-' 1 0 /etc/apache2/apache2.conf
-' 1 0 /var/log/lighttpd/access.log
-' 1 0 /etc/apt/sources.list
-' 12 0 ~/Programming/web/codemirror/sandbox/etc/schroot/schroot.conf
-' 1 0 ~/Programming/web/codemirror/sandbox/etc/schroot/schroot.conf
-' 1 0 ~/Desktop/compreply.log
-' 119 0 /usr/share/gtksourceview-2.0/styles/oblivion.xml
-' 1 0 /usr/share/gtksourceview-2.0/styles/oblivion.xml
-' 8 29 ~/Programming/web/duoscript/trunk/scripts/minify.sh
-' 1 0 ~/Programming/web/duoscript/trunk/scripts/minify.sh
-' 1 0 /etc/apt/sources.list.d/google-chrome.list.save
-' 1 0 /etc/apt/sources.list.d/google-chrome.list.distUpgrade
-' 1 0 /etc/apt/sources.list.d/google-chrome.list
-' 140 0 ~/Programming/web/duoscript/trunk/jsl.latest.conf
-' 1 0 ~/Programming/web/duoscript/trunk/jsl.latest.conf
-' 1 0 ~/Programming/web/duoscript/trunk/lint.sh
-' 46 7 ~/Programming/web/duoscript/trunk/tmp.js
-' 1 0 ~/Programming/web/duoscript/trunk/tmp.js
-' 71 20 ~/Programming/web/duoscript/trunk/tmp.js
-' 1 0 ~/.bashrc
-' 60 20 ~/.subversion/config
-' 1 0 ~/.subversion/config
-' 1 0 ~/Programming/web/duoscript/trunk/scripts/deploy.sh
-' 1 0 /tmp/tutoriHJbUr
-' 398 0 /tmp/tutorHpGuJF
-' 381 0 /tmp/tutorHpGuJF
-' 377 0 /tmp/tutorHpGuJF
-' 382 0 /tmp/tutorHpGuJF
-' 379 0 /tmp/tutorHpGuJF
-' 332 39 /tmp/tutorHpGuJF
# History of marks within files (newest to oldest):
> ~/Desktop/bapc-2009/d.c
" 108 4
^ 108 5
. 108 4
+ 114 0
+ 110 2
+ 112 0
+ 89 47
+ 89 1
+ 89 22
+ 59 17
+ 81 0
+ 80 0
+ 81 0
+ 67 0
+ 59 42
+ 67 5
+ 62 0
+ 61 8
+ 67 36
+ 77 1
+ 70 1
+ 69 1
+ 65 8
+ 66 0
+ 65 30
+ 79 13
+ 69 37
+ 63 41
+ 69 18
+ 67 18
+ 76 2
+ 71 6
+ 69 32
+ 63 21
+ 71 30
+ 76 3
+ 73 46
+ 76 4
+ 61 9
+ 63 9
+ 95 29
+ 111 31
+ 95 32
+ 89 11
+ 114 10
+ 119 0
+ 113 8
+ 114 34
+ 114 0
+ 114 1
+ 113 0
+ 114 1
+ 114 2
+ 114 2
+ 114 0
+ 114 0
+ 114 3
+ 114 0
+ 114 33
+ 76 27
+ 66 0
+ 76 0
+ 76 28
+ 100 22
+ 103 3
+ 102 3
+ 104 3
+ 103 4
+ 114 0
+ 103 40
+ 111 0
+ 105 2
+ 107 3
+ 76 32
+ 71 2
+ 71 33
+ 102 16
+ 65 76
+ 71 27
+ 71 54
+ 76 0
+ 74 0
+ 71 0
+ 106 25
+ 89 0
+ 82 41
+ 89 24
+ 103 32
+ 172 29
+ 170 0
+ 89 0
+ 89 0
+ 89 0
+ 89 0
+ 86 0
+ 170 1
+ 108 4
+ 106 4
+ 108 3
+ 114 2
+ 180 0
+ 179 9
+ 108 4
> /etc/apt/sources.list.d/am-monkeyd-nautilus-elementary-ppa-lucid.list
" 1 0
> /etc/apt/sources.list.d/duocoding.list
" 1 0
> /etc/apt/sources.list.d/elementaryart-ppa-lucid.list
" 1 0
> /etc/apt/sources.list.d/getdeb.list
" 1 0
> /etc/apt/sources.list.d/google-chrome.list
" 1 0
> /etc/apt/sources.list.d/lottanzb-ppa-lucid.list
" 1 0
> /etc/apt/sources.list.d/nilarimogard-webupd8-karmic.list
" 1 0
> /etc/apt/sources.list.d/opera.list
" 1 0
> /etc/apt/sources.list.d/rabbitvcs-ppa-lucid.list
" 1 0
> /etc/apt/sources.list.d/ricotz-ppa-lucid.list
" 1 0
> /etc/apt/sources.list
" 1 0
^ 57 54
. 58 0
+ 59 33
+ 57 54
+ 58 0
> ~/Desktop/bapc-2009/a.c
" 23 7
^ 23 4
. 21 10
+ 1 18
+ 2 19
+ 8 12
+ 29 0
+ 8 24
+ 26 15
+ 8 24
+ 28 20
+ 29 0
+ 26 19
+ 26 19
+ 26 1
+ 28 1
+ 3 26
+ 6 0
+ 5 0
+ 3 0
+ 5 1
+ 26 1
+ 27 0
+ 27 0
+ 25 0
+ 19 25
+ 18 13
+ 19 41
+ 21 17
+ 24 1
+ 23 0
+ 21 25
+ 23 20
+ 21 2
+ 22 2
+ 24 2
+ 21 2
+ 21 1
+ 22 1
+ 24 1
+ 21 16
+ 19 21
+ 21 17
+ 13 0
+ 18 11
+ 19 27
+ 15 0
+ 13 10
+ 10 27
+ 13 22
+ 14 21
+ 19 22
+ 18 8
+ 12 0
+ 21 25
+ 17 0
+ 16 14
+ 16 19
+ 21 12
+ 10 28
+ 13 5
+ 21 10
> /etc/php5/conf.d/xdebug.ini
" 2 0
. 3 0
+ 3 0
> /tmp/tutoriHJbUr
" 1 0
. 10 26
+ 10 26
> /tmp/tutorHpGuJF
" 398 0
^ 311 0
. 381 0
+ 76 0
+ 85 31
+ 109 45
+ 132 46
+ 134 41
+ 203 46
+ 222 47
+ 265 0
+ 265 0
+ 265 0
+ 289 28
+ 310 0
+ 312 0
+ 311 0
+ 332 0
+ 379 0
+ 382 0
+ 379 0
+ 382 0
+ 379 0
+ 379 0
+ 382 0
+ 381 0
m 347 2
> /usr/share/vim/vim72/d
\ No newline at end of file
......@@ -15,35 +15,7 @@ if $COLORTERM == 'gnome-terminal'
set t_Co=256
endif
" ,rl = run pdflatex (on current file)
map ,rl :!pdflatex -src -shell-escape -interaction=nonstopmode %
" trigger pdflatex (above) on FileWritePost event
:autocmd BufWritePost *.tex :!pdflatex -src -shell-escape -interaction=nonstopmode % | grep -A 4 -i "error"
set nocp
filetype plugin on
" configure tags - add additional tags here or comment out not-used ones
set tags+=~/.vim/tags/stl
set tags+=~/.vim/tags/gl
" build tags of your own project with CTRL+F12
"map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
"noremap <F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<cr>
"inoremap <F12> <Esc>:!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<cr>
" OmniCppComplete
let OmniCpp_NamespaceSearch = 1
let OmniCpp_GlobalScopeSearch = 1
let OmniCpp_ShowAccess = 1
let OmniCpp_MayCompleteDot = 1
let OmniCpp_MayCompleteArrow = 1
let OmniCpp_MayCompleteScope = 1
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
" automatically open and close the popup menu / preview window
au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
set completeopt=menuone,menu,longest,preview
colorscheme darkspectrum
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment