diff options
Diffstat (limited to '.config/vim')
61 files changed, 7446 insertions, 0 deletions
diff --git a/.config/vim/after/ftplugin/c.vim b/.config/vim/after/ftplugin/c.vim new file mode 100644 index 0000000..66dfc5e --- /dev/null +++ b/.config/vim/after/ftplugin/c.vim @@ -0,0 +1,2 @@ +" OmniCppComplete initialization +call omni#cpp#complete#Init() diff --git a/.config/vim/after/ftplugin/cpp.vim b/.config/vim/after/ftplugin/cpp.vim new file mode 100644 index 0000000..66dfc5e --- /dev/null +++ b/.config/vim/after/ftplugin/cpp.vim @@ -0,0 +1,2 @@ +" OmniCppComplete initialization +call omni#cpp#complete#Init() diff --git a/.config/vim/autoload/omni/common/debug.vim b/.config/vim/autoload/omni/common/debug.vim new file mode 100644 index 0000000..eded649 --- /dev/null +++ b/.config/vim/autoload/omni/common/debug.vim @@ -0,0 +1,32 @@ +" 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 diff --git a/.config/vim/autoload/omni/common/utils.vim b/.config/vim/autoload/omni/common/utils.vim new file mode 100644 index 0000000..c880ad2 --- /dev/null +++ b/.config/vim/autoload/omni/common/utils.vim @@ -0,0 +1,67 @@ +" 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 diff --git a/.config/vim/autoload/omni/cpp/complete.vim b/.config/vim/autoload/omni/cpp/complete.vim new file mode 100644 index 0000000..a7e4edc --- /dev/null +++ b/.config/vim/autoload/omni/cpp/complete.vim @@ -0,0 +1,569 @@ +" 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 diff --git a/.config/vim/autoload/omni/cpp/includes.vim b/.config/vim/autoload/omni/cpp/includes.vim new file mode 100644 index 0000000..10a89bc --- /dev/null +++ b/.config/vim/autoload/omni/cpp/includes.vim @@ -0,0 +1,126 @@ +" 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 + + diff --git a/.config/vim/autoload/omni/cpp/items.vim b/.config/vim/autoload/omni/cpp/items.vim new file mode 100644 index 0000000..b943ad4 --- /dev/null +++ b/.config/vim/autoload/omni/cpp/items.vim @@ -0,0 +1,660 @@ +" 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 diff --git a/.config/vim/autoload/omni/cpp/maycomplete.vim b/.config/vim/autoload/omni/cpp/maycomplete.vim new file mode 100644 index 0000000..610526b --- /dev/null +++ b/.config/vim/autoload/omni/cpp/maycomplete.vim @@ -0,0 +1,82 @@ +" 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 diff --git a/.config/vim/autoload/omni/cpp/namespaces.vim b/.config/vim/autoload/omni/cpp/namespaces.vim new file mode 100644 index 0000000..386b3f9 --- /dev/null +++ b/.config/vim/autoload/omni/cpp/namespaces.vim @@ -0,0 +1,838 @@ +" 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 diff --git a/.config/vim/autoload/omni/cpp/settings.vim b/.config/vim/autoload/omni/cpp/settings.vim new file mode 100644 index 0000000..6683d3a --- /dev/null +++ b/.config/vim/autoload/omni/cpp/settings.vim @@ -0,0 +1,96 @@ +" 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 diff --git a/.config/vim/autoload/omni/cpp/tokenizer.vim b/.config/vim/autoload/omni/cpp/tokenizer.vim new file mode 100644 index 0000000..16e0be2 --- /dev/null +++ b/.config/vim/autoload/omni/cpp/tokenizer.vim @@ -0,0 +1,93 @@ +" 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 diff --git a/.config/vim/autoload/omni/cpp/utils.vim b/.config/vim/autoload/omni/cpp/utils.vim new file mode 100644 index 0000000..5d74d34 --- /dev/null +++ b/.config/vim/autoload/omni/cpp/utils.vim @@ -0,0 +1,587 @@ +" 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 diff --git a/.config/vim/colors/desert256.vim b/.config/vim/colors/desert256.vim new file mode 100644 index 0000000..7a97742 --- /dev/null +++ b/.config/vim/colors/desert256.vim @@ -0,0 +1,338 @@ +" Vim color file +" Maintainer: Henry So, Jr. <henryso@panix.com> + +" These are the colors of the "desert" theme by Hans Fugal with a few small +" modifications (namely that I lowered the intensity of the normal white and +" made the normal and nontext backgrounds black), modified to work with 88- +" and 256-color xterms. +" +" The original "desert" theme is available as part of the vim distribution or +" at http://hans.fugal.net/vim/colors/. +" +" The real feature of this color scheme, with a wink to the "inkpot" theme, is +" the programmatic approximation of the gui colors to the palettes of 88- and +" 256- color xterms. The functions that do this (folded away, for +" readability) are calibrated to the colors used for Thomas E. Dickey's xterm +" (version 200), which is available at http://dickey.his.com/xterm/xterm.html. +" +" I struggled with trying to parse the rgb.txt file to avoid the necessity of +" converting color names to #rrggbb form, but decided it was just not worth +" the effort. Maybe someone seeing this may decide otherwise... + +set background=dark +if version > 580 + " no guarantees for version 5.8 and below, but this makes it stop + " complaining + hi clear + if exists("syntax_on") + syntax reset + endif +endif +let g:colors_name="desert256" + +if has("gui_running") || &t_Co == 88 || &t_Co == 256 + " functions {{{ + " returns an approximate grey index for the given grey level + fun <SID>grey_number(x) + if &t_Co == 88 + if a:x < 23 + return 0 + elseif a:x < 69 + return 1 + elseif a:x < 103 + return 2 + elseif a:x < 127 + return 3 + elseif a:x < 150 + return 4 + elseif a:x < 173 + return 5 + elseif a:x < 196 + return 6 + elseif a:x < 219 + return 7 + elseif a:x < 243 + return 8 + else + return 9 + endif + else + if a:x < 14 + return 0 + else + let l:n = (a:x - 8) / 10 + let l:m = (a:x - 8) % 10 + if l:m < 5 + return l:n + else + return l:n + 1 + endif + endif + endif + endfun + + " returns the actual grey level represented by the grey index + fun <SID>grey_level(n) + if &t_Co == 88 + if a:n == 0 + return 0 + elseif a:n == 1 + return 46 + elseif a:n == 2 + return 92 + elseif a:n == 3 + return 115 + elseif a:n == 4 + return 139 + elseif a:n == 5 + return 162 + elseif a:n == 6 + return 185 + elseif a:n == 7 + return 208 + elseif a:n == 8 + return 231 + else + return 255 + endif + else + if a:n == 0 + return 0 + else + return 8 + (a:n * 10) + endif + endif + endfun + + " returns the palette index for the given grey index + fun <SID>grey_color(n) + if &t_Co == 88 + if a:n == 0 + return 16 + elseif a:n == 9 + return 79 + else + return 79 + a:n + endif + else + if a:n == 0 + return 16 + elseif a:n == 25 + return 231 + else + return 231 + a:n + endif + endif + endfun + + " returns an approximate color index for the given color level + fun <SID>rgb_number(x) + if &t_Co == 88 + if a:x < 69 + return 0 + elseif a:x < 172 + return 1 + elseif a:x < 230 + return 2 + else + return 3 + endif + else + if a:x < 75 + return 0 + else + let l:n = (a:x - 55) / 40 + let l:m = (a:x - 55) % 40 + if l:m < 20 + return l:n + else + return l:n + 1 + endif + endif + endif + endfun + + " returns the actual color level for the given color index + fun <SID>rgb_level(n) + if &t_Co == 88 + if a:n == 0 + return 0 + elseif a:n == 1 + return 139 + elseif a:n == 2 + return 205 + else + return 255 + endif + else + if a:n == 0 + return 0 + else + return 55 + (a:n * 40) + endif + endif + endfun + + " returns the palette index for the given R/G/B color indices + fun <SID>rgb_color(x, y, z) + if &t_Co == 88 + return 16 + (a:x * 16) + (a:y * 4) + a:z + else + return 16 + (a:x * 36) + (a:y * 6) + a:z + endif + endfun + + " returns the palette index to approximate the given R/G/B color levels + fun <SID>color(r, g, b) + " get the closest grey + let l:gx = <SID>grey_number(a:r) + let l:gy = <SID>grey_number(a:g) + let l:gz = <SID>grey_number(a:b) + + " get the closest color + let l:x = <SID>rgb_number(a:r) + let l:y = <SID>rgb_number(a:g) + let l:z = <SID>rgb_number(a:b) + + if l:gx == l:gy && l:gy == l:gz + " there are two possibilities + let l:dgr = <SID>grey_level(l:gx) - a:r + let l:dgg = <SID>grey_level(l:gy) - a:g + let l:dgb = <SID>grey_level(l:gz) - a:b + let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb) + let l:dr = <SID>rgb_level(l:gx) - a:r + let l:dg = <SID>rgb_level(l:gy) - a:g + let l:db = <SID>rgb_level(l:gz) - a:b + let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db) + if l:dgrey < l:drgb + " use the grey + return <SID>grey_color(l:gx) + else + " use the color + return <SID>rgb_color(l:x, l:y, l:z) + endif + else + " only one possibility + return <SID>rgb_color(l:x, l:y, l:z) + endif + endfun + + " returns the palette index to approximate the 'rrggbb' hex string + fun <SID>rgb(rgb) + let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0 + let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0 + let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0 + + return <SID>color(l:r, l:g, l:b) + endfun + + " sets the highlighting for the given group + fun <SID>X(group, fg, bg, attr) + if a:fg != "" + exec "hi " . a:group . " guifg=#" . a:fg . " ctermfg=" . <SID>rgb(a:fg) + endif + if a:bg != "" + exec "hi " . a:group . " guibg=#" . a:bg . " ctermbg=" . <SID>rgb(a:bg) + endif + if a:attr != "" + exec "hi " . a:group . " gui=" . a:attr . " cterm=" . a:attr + endif + endfun + " }}} + + call <SID>X("Normal", "cccccc", "000000", "") + + " highlight groups + call <SID>X("Cursor", "708090", "f0e68c", "") + "CursorIM + "Directory + "DiffAdd + "DiffChange + "DiffDelete + "DiffText + "ErrorMsg + call <SID>X("VertSplit", "c2bfa5", "7f7f7f", "reverse") + call <SID>X("Folded", "ffd700", "4d4d4d", "") + call <SID>X("FoldColumn", "d2b48c", "4d4d4d", "") + call <SID>X("IncSearch", "708090", "f0e68c", "") + "LineNr + call <SID>X("ModeMsg", "daa520", "", "") + call <SID>X("MoreMsg", "2e8b57", "", "") + call <SID>X("NonText", "addbe7", "000000", "bold") + call <SID>X("Question", "00ff7f", "", "") + call <SID>X("Search", "f5deb3", "cd853f", "") + call <SID>X("SpecialKey", "9acd32", "", "") + call <SID>X("StatusLine", "c2bfa5", "000000", "reverse") + call <SID>X("StatusLineNC", "c2bfa5", "7f7f7f", "reverse") + call <SID>X("Title", "cd5c5c", "", "") + call <SID>X("Visual", "6b8e23", "f0e68c", "reverse") + "VisualNOS + call <SID>X("WarningMsg", "fa8072", "", "") + "WildMenu + "Menu + "Scrollbar + "Tooltip + + " syntax highlighting groups + call <SID>X("Comment", "87ceeb", "", "") + call <SID>X("Constant", "ffa0a0", "", "") + call <SID>X("Identifier", "98fb98", "", "none") + call <SID>X("Statement", "f0e68c", "", "bold") + call <SID>X("PreProc", "cd5c5c", "", "") + call <SID>X("Type", "bdb76b", "", "bold") + call <SID>X("Special", "ffdead", "", "") + "Underlined + call <SID>X("Ignore", "666666", "", "") + "Error + call <SID>X("Todo", "ff4500", "eeee00", "") + + " delete functions {{{ + delf <SID>X + delf <SID>rgb + delf <SID>color + delf <SID>rgb_color + delf <SID>rgb_level + delf <SID>rgb_number + delf <SID>grey_color + delf <SID>grey_level + delf <SID>grey_number + " }}} +else + " color terminal definitions + hi SpecialKey ctermfg=darkgreen + hi NonText cterm=bold ctermfg=darkblue + hi Directory ctermfg=darkcyan + hi ErrorMsg cterm=bold ctermfg=7 ctermbg=1 + hi IncSearch cterm=NONE ctermfg=yellow ctermbg=green + hi Search cterm=NONE ctermfg=grey ctermbg=blue + hi MoreMsg ctermfg=darkgreen + hi ModeMsg cterm=NONE ctermfg=brown + hi LineNr ctermfg=3 + hi Question ctermfg=green + hi StatusLine cterm=bold,reverse + hi StatusLineNC cterm=reverse + hi VertSplit cterm=reverse + hi Title ctermfg=5 + hi Visual cterm=reverse + hi VisualNOS cterm=bold,underline + hi WarningMsg ctermfg=1 + hi WildMenu ctermfg=0 ctermbg=3 + hi Folded ctermfg=darkgrey ctermbg=NONE + hi FoldColumn ctermfg=darkgrey ctermbg=NONE + hi DiffAdd ctermbg=4 + hi DiffChange ctermbg=5 + hi DiffDelete cterm=bold ctermfg=4 ctermbg=6 + hi DiffText cterm=bold ctermbg=1 + hi Comment ctermfg=darkcyan + hi Constant ctermfg=brown + hi Special ctermfg=5 + hi Identifier ctermfg=6 + hi Statement ctermfg=3 + hi PreProc ctermfg=5 + hi Type ctermfg=2 + hi Underlined cterm=underline ctermfg=5 + hi Ignore ctermfg=darkgrey + hi Error cterm=bold ctermfg=7 ctermbg=1 +endif + +" vim: set fdl=0 fdm=marker: diff --git a/.config/vim/colors/inkpot.vim b/.config/vim/colors/inkpot.vim new file mode 100644 index 0000000..a062248 --- /dev/null +++ b/.config/vim/colors/inkpot.vim @@ -0,0 +1,212 @@ +" Vim color file +" Name: inkpot.vim +" Maintainer: Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk> +" This should work in the GUI, rxvt-unicode (88 colour mode) and xterm (256 +" colour mode). It won't work in 8/16 colour terminals. +" +" To use a black background, :let g:inkpot_black_background = 1 + +set background=dark +hi clear +if exists("syntax_on") + syntax reset +endif + +let colors_name = "inkpot" + +" map a urxvt cube number to an xterm-256 cube number +fun! <SID>M(a) + return strpart("0135", a:a, 1) + 0 +endfun + +" map a urxvt colour to an xterm-256 colour +fun! <SID>X(a) + if &t_Co == 88 + return a:a + else + if a:a == 8 + return 237 + elseif a:a < 16 + return a:a + elseif a:a > 79 + return 232 + (3 * (a:a - 80)) + else + let l:b = a:a - 16 + let l:x = l:b % 4 + let l:y = (l:b / 4) % 4 + let l:z = (l:b / 16) + return 16 + <SID>M(l:x) + (6 * <SID>M(l:y)) + (36 * <SID>M(l:z)) + endif + endif +endfun + +if ! exists("g:inkpot_black_background") + let g:inkpot_black_background = 0 +endif + +if has("gui_running") + if ! g:inkpot_black_background + hi Normal gui=NONE guifg=#cfbfad guibg=#1e1e27 + else + hi Normal gui=NONE guifg=#cfbfad guibg=#000000 + endif + + hi IncSearch gui=BOLD guifg=#303030 guibg=#cd8b60 + hi Search gui=NONE guifg=#303030 guibg=#cd8b60 + hi ErrorMsg gui=BOLD guifg=#ffffff guibg=#ce4e4e + hi WarningMsg gui=BOLD guifg=#ffffff guibg=#ce8e4e + hi ModeMsg gui=BOLD guifg=#7e7eae guibg=NONE + hi MoreMsg gui=BOLD guifg=#7e7eae guibg=NONE + hi Question gui=BOLD guifg=#ffcd00 guibg=NONE + + hi StatusLine gui=BOLD guifg=#b9b9b9 guibg=#3e3e5e + hi User1 gui=BOLD guifg=#00ff8b guibg=#3e3e5e + hi User2 gui=BOLD guifg=#7070a0 guibg=#3e3e5e + hi StatusLineNC gui=NONE guifg=#b9b9b9 guibg=#3e3e5e + hi VertSplit gui=NONE guifg=#b9b9b9 guibg=#3e3e5e + + hi WildMenu gui=BOLD guifg=#eeeeee guibg=#6e6eaf + + hi MBENormal guifg=#cfbfad guibg=#2e2e3f + hi MBEChanged guifg=#eeeeee guibg=#2e2e3f + hi MBEVisibleNormal guifg=#cfcfcd guibg=#4e4e8f + hi MBEVisibleChanged guifg=#eeeeee guibg=#4e4e8f + + hi DiffText gui=NONE guifg=#ffffcd guibg=#4a2a4a + hi DiffChange gui=NONE guifg=#ffffcd guibg=#306b8f + hi DiffDelete gui=NONE guifg=#ffffcd guibg=#6d3030 + hi DiffAdd gui=NONE guifg=#ffffcd guibg=#306d30 + + hi Cursor gui=NONE guifg=#404040 guibg=#8b8bff + hi lCursor gui=NONE guifg=#404040 guibg=#8fff8b + hi CursorIM gui=NONE guifg=#404040 guibg=#8b8bff + + hi Folded gui=NONE guifg=#cfcfcd guibg=#4b208f + hi FoldColumn gui=NONE guifg=#8b8bcd guibg=#2e2e2e + + hi Directory gui=NONE guifg=#00ff8b guibg=NONE + hi LineNr gui=NONE guifg=#8b8bcd guibg=#2e2e2e + hi NonText gui=BOLD guifg=#8b8bcd guibg=NONE + hi SpecialKey gui=BOLD guifg=#ab60ed guibg=NONE + hi Title gui=BOLD guifg=#af4f4b guibg=NONE + hi Visual gui=NONE guifg=#eeeeee guibg=#4e4e8f + + hi Comment gui=NONE guifg=#cd8b00 guibg=NONE + hi Constant gui=NONE guifg=#ffcd8b guibg=NONE + hi String gui=NONE guifg=#ffcd8b guibg=#404040 + hi Error gui=NONE guifg=#ffffff guibg=#6e2e2e + hi Identifier gui=NONE guifg=#ff8bff guibg=NONE + hi Ignore gui=NONE + hi Number gui=NONE guifg=#f0ad6d guibg=NONE + hi PreProc gui=NONE guifg=#409090 guibg=NONE + hi Special gui=NONE guifg=#c080d0 guibg=NONE + hi SpecialChar gui=NONE guifg=#c080d0 guibg=#404040 + hi Statement gui=NONE guifg=#808bed guibg=NONE + hi Todo gui=BOLD guifg=#303030 guibg=#d0a060 + hi Type gui=NONE guifg=#ff8bff guibg=NONE + hi Underlined gui=BOLD guifg=#df9f2d guibg=NONE + hi TaglistTagName gui=BOLD guifg=#808bed guibg=NONE + + hi perlSpecialMatch gui=NONE guifg=#c080d0 guibg=#404040 + hi perlSpecialString gui=NONE guifg=#c080d0 guibg=#404040 + + hi cSpecialCharacter gui=NONE guifg=#c080d0 guibg=#404040 + hi cFormat gui=NONE guifg=#c080d0 guibg=#404040 + + hi doxygenBrief gui=NONE guifg=#fdab60 guibg=NONE + hi doxygenParam gui=NONE guifg=#fdd090 guibg=NONE + hi doxygenPrev gui=NONE guifg=#fdd090 guibg=NONE + hi doxygenSmallSpecial gui=NONE guifg=#fdd090 guibg=NONE + hi doxygenSpecial gui=NONE guifg=#fdd090 guibg=NONE + hi doxygenComment gui=NONE guifg=#ad7b20 guibg=NONE + hi doxygenSpecial gui=NONE guifg=#fdab60 guibg=NONE + hi doxygenSpecialMultilineDesc gui=NONE guifg=#ad600b guibg=NONE + hi doxygenSpecialOnelineDesc gui=NONE guifg=#ad600b guibg=NONE + + if v:version >= 700 + hi Pmenu gui=NONE guifg=#eeeeee guibg=#4e4e8f + hi PmenuSel gui=BOLD guifg=#eeeeee guibg=#2e2e3f + hi PmenuSbar gui=BOLD guifg=#eeeeee guibg=#6e6eaf + hi PmenuThumb gui=BOLD guifg=#eeeeee guibg=#6e6eaf + + hi SpellBad gui=undercurl guisp=#cc6666 + hi SpellRare gui=undercurl guisp=#cc66cc + hi SpellLocal gui=undercurl guisp=#cccc66 + hi SpellCap gui=undercurl guisp=#66cccc + + hi MatchParen gui=NONE guifg=#404040 guibg=#8fff8b + endif +else + if ! g:inkpot_black_background + exec "hi Normal cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(80) + else + exec "hi Normal cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(16) + endif + + exec "hi IncSearch cterm=BOLD ctermfg=" . <SID>X(80) . " ctermbg=" . <SID>X(73) + exec "hi Search cterm=NONE ctermfg=" . <SID>X(80) . " ctermbg=" . <SID>X(73) + exec "hi ErrorMsg cterm=BOLD ctermfg=" . <SID>X(16) . " ctermbg=" . <SID>X(48) + exec "hi WarningMsg cterm=BOLD ctermfg=" . <SID>X(16) . " ctermbg=" . <SID>X(68) + exec "hi ModeMsg cterm=BOLD ctermfg=" . <SID>X(38) . " ctermbg=" . "NONE" + exec "hi MoreMsg cterm=BOLD ctermfg=" . <SID>X(38) . " ctermbg=" . "NONE" + exec "hi Question cterm=BOLD ctermfg=" . <SID>X(52) . " ctermbg=" . "NONE" + + exec "hi StatusLine cterm=BOLD ctermfg=" . <SID>X(85) . " ctermbg=" . <SID>X(81) + exec "hi User1 cterm=BOLD ctermfg=" . <SID>X(28) . " ctermbg=" . <SID>X(81) + exec "hi User2 cterm=BOLD ctermfg=" . <SID>X(39) . " ctermbg=" . <SID>X(81) + exec "hi StatusLineNC cterm=NONE ctermfg=" . <SID>X(84) . " ctermbg=" . <SID>X(81) + exec "hi VertSplit cterm=NONE ctermfg=" . <SID>X(84) . " ctermbg=" . <SID>X(81) + + exec "hi WildMenu cterm=BOLD ctermfg=" . <SID>X(87) . " ctermbg=" . <SID>X(38) + + exec "hi MBENormal ctermfg=" . <SID>X(85) . " ctermbg=" . <SID>X(81) + exec "hi MBEChanged ctermfg=" . <SID>X(87) . " ctermbg=" . <SID>X(81) + exec "hi MBEVisibleNormal ctermfg=" . <SID>X(85) . " ctermbg=" . <SID>X(82) + exec "hi MBEVisibleChanged ctermfg=" . <SID>X(87) . " ctermbg=" . <SID>X(82) + + exec "hi DiffText cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(34) + exec "hi DiffChange cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(17) + exec "hi DiffDelete cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(32) + exec "hi DiffAdd cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(20) + + exec "hi Folded cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(35) + exec "hi FoldColumn cterm=NONE ctermfg=" . <SID>X(39) . " ctermbg=" . <SID>X(80) + + exec "hi Directory cterm=NONE ctermfg=" . <SID>X(28) . " ctermbg=" . "NONE" + exec "hi LineNr cterm=NONE ctermfg=" . <SID>X(39) . " ctermbg=" . <SID>X(80) + exec "hi NonText cterm=BOLD ctermfg=" . <SID>X(39) . " ctermbg=" . "NONE" + exec "hi SpecialKey cterm=BOLD ctermfg=" . <SID>X(55) . " ctermbg=" . "NONE" + exec "hi Title cterm=BOLD ctermfg=" . <SID>X(48) . " ctermbg=" . "NONE" + exec "hi Visual cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(38) + + exec "hi Comment cterm=NONE ctermfg=" . <SID>X(52) . " ctermbg=" . "NONE" + exec "hi Constant cterm=NONE ctermfg=" . <SID>X(73) . " ctermbg=" . "NONE" + exec "hi String cterm=NONE ctermfg=" . <SID>X(73) . " ctermbg=" . <SID>X(81) + exec "hi Error cterm=NONE ctermfg=" . <SID>X(79) . " ctermbg=" . <SID>X(32) + exec "hi Identifier cterm=NONE ctermfg=" . <SID>X(53) . " ctermbg=" . "NONE" + exec "hi Ignore cterm=NONE" + exec "hi Number cterm=NONE ctermfg=" . <SID>X(69) . " ctermbg=" . "NONE" + exec "hi PreProc cterm=NONE ctermfg=" . <SID>X(25) . " ctermbg=" . "NONE" + exec "hi Special cterm=NONE ctermfg=" . <SID>X(55) . " ctermbg=" . "NONE" + exec "hi SpecialChar cterm=NONE ctermfg=" . <SID>X(55) . " ctermbg=" . <SID>X(81) + exec "hi Statement cterm=NONE ctermfg=" . <SID>X(27) . " ctermbg=" . "NONE" + exec "hi Todo cterm=BOLD ctermfg=" . <SID>X(16) . " ctermbg=" . <SID>X(57) + exec "hi Type cterm=NONE ctermfg=" . <SID>X(71) . " ctermbg=" . "NONE" + exec "hi Underlined cterm=BOLD ctermfg=" . <SID>X(77) . " ctermbg=" . "NONE" + exec "hi TaglistTagName cterm=BOLD ctermfg=" . <SID>X(39) . " ctermbg=" . "NONE" + + if v:version >= 700 + exec "hi Pmenu cterm=NONE ctermfg=" . <SID>X(87) . " ctermbg=" . <SID>X(82) + exec "hi PmenuSel cterm=BOLD ctermfg=" . <SID>X(87) . " ctermbg=" . <SID>X(38) + exec "hi PmenuSbar cterm=BOLD ctermfg=" . <SID>X(87) . " ctermbg=" . <SID>X(39) + exec "hi PmenuThumb cterm=BOLD ctermfg=" . <SID>X(87) . " ctermbg=" . <SID>X(39) + + exec "hi SpellBad cterm=NONE ctermbg=" . <SID>X(32) + exec "hi SpellRare cterm=NONE ctermbg=" . <SID>X(33) + exec "hi SpellLocal cterm=NONE ctermbg=" . <SID>X(36) + exec "hi SpellCap cterm=NONE ctermbg=" . <SID>X(21) + exec "hi MatchParen cterm=NONE ctermbg=" . <SID>X(14) . "ctermfg=" . <SID>X(25) + endif +endif + +" vim: set et : diff --git a/.config/vim/colors/tango.vim b/.config/vim/colors/tango.vim new file mode 100644 index 0000000..859a6c3 --- /dev/null +++ b/.config/vim/colors/tango.vim @@ -0,0 +1,81 @@ +" +" Tango Vim Color Scheme +" ======================= +" +" For best results, set up your terminal with a Tango palette. +" Instructions for GNOME Terminal: +" http://uwstopia.nl/blog/2006/07/tango-terminal +" +" author: Michele Campeotto <micampe@micampe.it> +" +set background=dark + +hi clear +if exists("syntax_on") + syntax reset +endif + +let colors_name = "tango" + +" Default Colors +hi Normal guifg=#eeeeec guibg=#000000 +hi Normal ctermfg=grey ctermbg=black +"hi Normal ctermfg=white ctermbg=black +hi NonText guifg=#555753 guibg=#000000 gui=none +hi NonText ctermfg=darkgray +hi Cursor guibg=#d3d7cf +hi lCursor guibg=#d3d7cf + +" Search +hi Search guifg=#eeeeec guibg=#c4a000 +hi Search cterm=none ctermfg=grey ctermbg=blue +hi IncSearch guibg=#eeeeec guifg=#729fcf +hi IncSearch cterm=none ctermfg=yellow ctermbg=green + +" Window Elements +hi StatusLine guifg=#eeeeec guibg=#4e9a06 gui=bold +hi StatusLine ctermfg=white ctermbg=green cterm=bold +hi StatusLineNC guifg=#d3d7df guibg=#4e9a06 +hi StatusLineNC ctermfg=lightgray ctermbg=darkgreen +hi VertSplit guifg=#eeeeec guibg=#eeeeec +hi Folded guifg=#eeeeec guibg=#75507b +hi Folded ctermfg=white ctermbg=magenta +hi Visual guifg=#d3d7cf guibg=#4e9a06 +hi Visual ctermbg=white ctermfg=lightgreen cterm=reverse + +" Specials +hi Todo guifg=#8ae234 guibg=#4e9a06 gui=bold +hi Todo ctermfg=white ctermbg=green +hi Title guifg=#eeeeec gui=bold +hi Title ctermfg=white cterm=bold + +" Syntax +hi Constant guifg=#c4a000 +hi Constant ctermfg=darkyellow +hi Number guifg=#729fcf +hi Number ctermfg=darkblue +hi Statement guifg=#4e9a06 gui=bold +hi Statement ctermfg=green +hi Identifier guifg=#8ae234 +hi Identifier ctermfg=darkgreen +hi PreProc guifg=#cc0000 +hi PreProc ctermfg=darkred +hi Comment guifg=#06989a gui=italic +hi Comment ctermfg=cyan cterm=none +hi Type guifg=#d3d7cf gui=bold +hi Type ctermfg=gray cterm=bold +hi Special guifg=#75507b +hi Special ctermfg=magenta cterm=none +hi Error guifg=#eeeeec guibg=#ef2929 +hi Error ctermfg=white ctermbg=red + +" Diff +hi DiffAdd guifg=fg guibg=#3465a4 gui=none +hi DiffAdd ctermfg=gray ctermbg=blue cterm=none +hi DiffChange guifg=fg guibg=#555753 gui=none +hi DiffChange ctermfg=gray ctermbg=darkgray cterm=none +hi DiffDelete guibg=bg +hi DiffDelete ctermfg=gray ctermbg=none cterm=none +hi DiffText guifg=fg guibg=#c4a000 gui=none +hi DiffText ctermfg=gray ctermbg=yellow cterm=none + diff --git a/.config/vim/colors/wombat.vim b/.config/vim/colors/wombat.vim new file mode 100644 index 0000000..9ad1e56 --- /dev/null +++ b/.config/vim/colors/wombat.vim @@ -0,0 +1,51 @@ +" Maintainer: Lars H. Nielsen (dengmao@gmail.com) +" Last Change: January 22 2007 + +set background=dark + +hi clear + +if exists("syntax_on") + syntax reset +endif + +let colors_name = "wombat" + + +" Vim >= 7.0 specific colors +if version >= 700 + hi CursorLine guibg=#2d2d2d + hi CursorColumn guibg=#2d2d2d + hi MatchParen guifg=#f6f3e8 guibg=#857b6f gui=bold + hi Pmenu guifg=#f6f3e8 guibg=#444444 + hi PmenuSel guifg=#000000 guibg=#cae682 +endif + +" General colors +hi Cursor guifg=NONE guibg=#656565 gui=none +hi Normal guifg=#f6f3e8 guibg=#242424 gui=none +hi NonText guifg=#808080 guibg=#303030 gui=none +hi LineNr guifg=#857b6f guibg=#000000 gui=none +hi StatusLine guifg=#f6f3e8 guibg=#444444 gui=italic +hi StatusLineNC guifg=#857b6f guibg=#444444 gui=none +hi VertSplit guifg=#444444 guibg=#444444 gui=none +hi Folded guibg=#384048 guifg=#a0a8b0 gui=none +hi Title guifg=#f6f3e8 guibg=NONE gui=bold +hi Visual guifg=#f6f3e8 guibg=#444444 gui=none +hi SpecialKey guifg=#808080 guibg=#343434 gui=none + +" Syntax highlighting +hi Comment guifg=#99968b gui=italic +hi Todo guifg=#8f8f8f gui=italic +hi Constant guifg=#e5786d gui=none +hi String guifg=#95e454 gui=italic +hi Identifier guifg=#cae682 gui=none +hi Function guifg=#cae682 gui=none +hi Type guifg=#cae682 gui=none +hi Statement guifg=#8ac6f2 gui=none +hi Keyword guifg=#8ac6f2 gui=none +hi PreProc guifg=#e5786d gui=none +hi Number guifg=#e5786d gui=none +hi Special guifg=#e7f6da gui=none + + diff --git a/.config/vim/compiler/mlint.vim b/.config/vim/compiler/mlint.vim new file mode 100644 index 0000000..f9e9c6d --- /dev/null +++ b/.config/vim/compiler/mlint.vim @@ -0,0 +1,44 @@ +" Vim compiler file +" Compiler: Matlab mlint code checker +" Maintainer: Fabrice Guy <fabrice.guy at gmail dot com> +" Latest Revision: 2008 Oct 16 +" Comment: mlint messages are either +" - L x (C y): message (where x and y are line number and +" column number) +" - L x (C y-z): message (where x is the line number, y and +" z the column numbers where the error comes from) + + +if exists("current_compiler") + finish +endif +let current_compiler = "mlint" + +if exists(":CompilerSet") != 2 " older Vim always used :setlocal + command -nargs=* CompilerSet setlocal <args> +endif + +" mlint doesn't provide filename information except if multiple +" filenames are given +" With the following command : +" mlint <filename> <filename without extension> +" mlint produces an output like that : +" ========== <filename> ========== +" L x (C y): ID : Message +" L x (C y): ID : Message +" .. +" .. +" ========== <filename without extension> ========== +" L 0 (C 0): MDOTM :Filename 'filename' must end in .m or .M +" +" The filename can then be parsed +CompilerSet makeprg=mlint\ -id\ %\ %< + +CompilerSet errorformat= + \%-P==========\ %f\ ==========, + \%-G%>==========\ %s\ ==========, + \%-G%>L\ %l\ (C\ %c):\ MDOTM%m, + \L\ %l\ (C\ %c):\ %m, + \L\ %l\ (C\ %c-%*[0-9]):\ %m, + \%-Q + diff --git a/.config/vim/doc/omnicppcomplete.txt b/.config/vim/doc/omnicppcomplete.txt new file mode 100644 index 0000000..b11e006 --- /dev/null +++ b/.config/vim/doc/omnicppcomplete.txt @@ -0,0 +1,1078 @@ +*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: diff --git a/.config/vim/doc/tags b/.config/vim/doc/tags new file mode 100644 index 0000000..6feb038 --- /dev/null +++ b/.config/vim/doc/tags @@ -0,0 +1,25 @@ +OmniCpp_DefaultNamespaces omnicppcomplete.txt /*OmniCpp_DefaultNamespaces* +OmniCpp_DisplayMode omnicppcomplete.txt /*OmniCpp_DisplayMode* +OmniCpp_GlobalScopeSearch omnicppcomplete.txt /*OmniCpp_GlobalScopeSearch* +OmniCpp_LocalSearchDecl omnicppcomplete.txt /*OmniCpp_LocalSearchDecl* +OmniCpp_MayCompleteArrow omnicppcomplete.txt /*OmniCpp_MayCompleteArrow* +OmniCpp_MayCompleteDot omnicppcomplete.txt /*OmniCpp_MayCompleteDot* +OmniCpp_MayCompleteScope omnicppcomplete.txt /*OmniCpp_MayCompleteScope* +OmniCpp_NamespaceSearch omnicppcomplete.txt /*OmniCpp_NamespaceSearch* +OmniCpp_SelectFirstItem omnicppcomplete.txt /*OmniCpp_SelectFirstItem* +OmniCpp_ShowAccess omnicppcomplete.txt /*OmniCpp_ShowAccess* +OmniCpp_ShowPrototypeInAbbr omnicppcomplete.txt /*OmniCpp_ShowPrototypeInAbbr* +OmniCpp_ShowScopeInAbbr omnicppcomplete.txt /*OmniCpp_ShowScopeInAbbr* +omnicpp-download omnicppcomplete.txt /*omnicpp-download* +omnicpp-faq omnicppcomplete.txt /*omnicpp-faq* +omnicpp-features omnicppcomplete.txt /*omnicpp-features* +omnicpp-history omnicppcomplete.txt /*omnicpp-history* +omnicpp-installation omnicppcomplete.txt /*omnicpp-installation* +omnicpp-limitations omnicppcomplete.txt /*omnicpp-limitations* +omnicpp-may-complete omnicppcomplete.txt /*omnicpp-may-complete* +omnicpp-options omnicppcomplete.txt /*omnicpp-options* +omnicpp-overview omnicppcomplete.txt /*omnicpp-overview* +omnicpp-popup omnicppcomplete.txt /*omnicpp-popup* +omnicpp-thanks omnicppcomplete.txt /*omnicpp-thanks* +omnicppcomplete omnicppcomplete.txt /*omnicppcomplete* +omnicppcomplete.txt omnicppcomplete.txt /*omnicppcomplete.txt* diff --git a/.config/vim/ftplugin/matlab.vim b/.config/vim/ftplugin/matlab.vim new file mode 100644 index 0000000..4ae257f --- /dev/null +++ b/.config/vim/ftplugin/matlab.vim @@ -0,0 +1,31 @@ +" Vim filetype plugin file +" Language: matlab +" Maintainer: Fabrice Guy <fabrice.guy at gmail dot com> +" Last Changed: 2008 Oct 16 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:save_cpo = &cpo +set cpo-=C + +if exists("loaded_matchit") + let s:conditionalEnd = '\(([^()]*\)\@!\<end\>\([^()]*)\)\@!' + let b:match_words = '\<classdef\>\|\<methods\>\|\<events\>\|\<properties\>\|\<if\>\|\<while\>\|\<for\>\|\<switch\>\|\<try\>\|\<function\>:' . s:conditionalEnd +endif + +setlocal suffixesadd=.m +setlocal suffixes+=.asv +" Change the :browse e filter to primarily show M-files +if has("gui_win32") && !exists("b:browsefilter") + let b:browsefilter="M-files (*.m)\t*.m\n" . + \ "All files (*.*)\t*.*\n" +endif + +let b:undo_ftplugin = "setlocal suffixesadd< suffixes< " + \ . "| unlet! b:browsefilter" + \ . "| unlet! b:match_words" + +let &cpo = s:save_cpo diff --git a/.config/vim/indent/matlab.vim b/.config/vim/indent/matlab.vim new file mode 100644 index 0000000..936ac7c --- /dev/null +++ b/.config/vim/indent/matlab.vim @@ -0,0 +1,136 @@ +" Matlab indent file +" Language: Matlab +" Maintainer: Fabrice Guy <fabrice.guy at gmail dot com> +" Last Change: 2008 Oct 15 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 +let s:onlySubfunctionExists = 0 + +setlocal indentexpr=GetMatlabIndent() +setlocal indentkeys=!,o,O=end,=case,=else,=elseif,=otherwise,=catch + +" Only define the function once. +if exists("*GetMatlabIndent") + finish +endif + +function! s:IsMatlabContinuationLine(lnum) + let continuationLine = 0 + if a:lnum > 0 + let pnbline = getline(prevnonblank(a:lnum)) + " if we have the line continuation operator (... at the end of a line or + " ... followed by a comment) it may be a line continuation + if pnbline =~ '\.\.\.\s*$' || pnbline =~ '\.\.\.\s*%.*$' + let continuationLine = 1 + " but if the ... are part of a string or a comment, it is not a + " continuation line + let col = match(pnbline, '\.\.\.\s*$') + if col == -1 + let col = match(pnbline, '\.\.\.\s*%.*$') + endif + if has('syntax_items') + if synIDattr(synID(prevnonblank(a:lnum), col + 1, 1), "name") =~ "matlabString" || + \ synIDattr(synID(prevnonblank(a:lnum), col + 1, 1), "name") =~ "matlabComment" + let continuationLine = 0 + endif + endif + endif + endif + return continuationLine +endfunction + +function GetMatlabIndent() + " Find a non-blank line above the current line. + let plnum = prevnonblank(v:lnum - 1) + + " If the previous line is a continuation line, get the beginning of the block to + " use the indent of that line + if s:IsMatlabContinuationLine(plnum - 1) + while s:IsMatlabContinuationLine(plnum - 1) + let plnum = plnum - 1 + endwhile + endif + + " At the start of the file use zero indent. + if plnum == 0 + return 0 + endif + + let curind = indent(plnum) + if s:IsMatlabContinuationLine(v:lnum - 1) + let curind = curind + &sw + endif + " Add a 'shiftwidth' after classdef, properties, switch, methods, events, + " function, if, while, for, otherwise, case, tic, try, catch, else, elseif + if getline(plnum) =~ '^\s*\(classdef\|properties\|switch\|methods\|events\|function\|if\|while\|for\|otherwise\|case\|tic\|try\|catch\|else\|elseif\)\>' + let curind = curind + &sw + " In Matlab we have different kind of functions + " - the main function (the function with the same name than the filename) + " - the nested functions + " - the functions defined in methods (for classes) + " - subfunctions + " For the moment the main function (located line 1) doesn't produce any indentation in the + " code (default behavior in the Matlab editor) and the other kind of + " functions indent the code + if getline(plnum) =~ '^\s*\function\>' + " If it is the main function + if plnum == 1 + " look for a matching end : + " - if we find a matching end everything is fine + " - if not, then all other functions are subfunctions + normal % + if getline(line('.')) =~ '^\s*end' + let s:onlySubfunctionExists = 0 + else + let s:onlySubfunctionExists = 1 + endif + normal % + let curind = curind - &sw + else + " it is a subfunction without matching end : dedent + if s:onlySubfunctionExists + let curind = curind - &sw + endif + endif + endif + endif + + " Subtract a 'shiftwidth' on a else, elseif, end, catch, otherwise, case, + " toc + if getline(v:lnum) =~ '^\s*\(else\|elseif\|end\|catch\|otherwise\|case\|toc\)\>' + let curind = curind - &sw + endif + " No indentation in a subfunction + if getline(v:lnum) =~ '^\s*\function\>' && s:onlySubfunctionExists + let curind = curind - &sw + endif + + " First case after a switch : indent + if getline(v:lnum) =~ '^\s*case' + while plnum > 0 && (getline(plnum) =~ '^\s*%' || getline(plnum) =~ '^\s*$') + let plnum = plnum - 1 + endwhile + if getline(plnum) =~ '^\s*switch' + let curind = indent(plnum) + &sw + endif + endif + + " end in a switch / end block : dedent twice + " we use the matchit script to know if this end is the end of a switch block + if exists("b:match_words") + if getline(v:lnum) =~ '^\s*end' + normal % + if getline(line('.')) =~ "switch" + let curind = curind - &sw + endif + normal % + end + end + return curind +endfunction + +" vim:sw=2 diff --git a/.config/vim/omnicppcomplete-0.41.zip b/.config/vim/omnicppcomplete-0.41.zip Binary files differnew file mode 100644 index 0000000..b888ac5 --- /dev/null +++ b/.config/vim/omnicppcomplete-0.41.zip diff --git a/.config/vim/plugin/SeeTab.vim b/.config/vim/plugin/SeeTab.vim new file mode 100644 index 0000000..6291f9b --- /dev/null +++ b/.config/vim/plugin/SeeTab.vim @@ -0,0 +1,116 @@ +" SeeTab: displays a bar for each tab +" Author: Charles E. Campbell, Jr. +" Date: Aug 26, 2004 +" Version: 3 +" +" GetLatestVimScripts: :AutoInstall: 628 1 SeeTab.vim +" Usage: :SeeTab (toggles tab-bars) {{{1 +" +" Variables: +" g:SeeTabFG : nominal foreground color (default: magenta) +" g:SeeTabBG : nominal background color (default: black) + +" allow user to bypass loading, also implements only-load-once +" +" GetLatestVimScripts: 628 1 :AutoInstall: SeeTab.vim + +" --------------------------------------------------------------------- +" One Loading Only: {{{1 +if exists("g:loaded_SeeTab") + finish +endif +let g:loaded_SeeTab= "v3" + +" --------------------------------------------------------------------- +" Highlighting Overrides: {{{1 +" user may override either or both of these colors in his/her <.vimrc> +if &bg == "dark" + if !exists("g:SeeTabCtermFG") + let g:SeeTabCtermFG="magenta" + endif + if !exists("g:SeeTabCtermBG") + let g:SeeTabCtermBG="black" + endif + if !exists("g:SeeTabGuiFG") + let g:SeeTabGuiFG="magenta" + endif + if !exists("g:SeeTabGuiBG") + let g:SeeTabGuiBG="black" + endif +else + if !exists("g:SeeTabCtermFG") + let g:SeeTabCtermFG="black" + endif + if !exists("g:SeeTabCtermBG") + let g:SeeTabCtermBG="magenta" + endif + if !exists("g:SeeTabGuiFG") + let g:SeeTabGuiFG="black" + endif + if !exists("g:SeeTabGuiBG") + let g:SeeTabGuiBG="magenta" + endif +endif + +" --------------------------------------------------------------------- +" Public Interface: {{{1 +com! -nargs=0 SeeTab :call <SID>SeeTab() + +" --------------------------------------------------------------------- +" SeeTab: toggles between showing tabs and using standard listchars {{{1 +fun! s:SeeTab() +" call Dfunc("SeeTab()") + + if !exists("g:SeeTabEnabled") +" call Decho("make tab bars visible (et=".&et.")") + " ----------------------- + " Make tab bar(s) visible + " ----------------------- + let g:SeeTabEnabled= 1 + + " record original SpecialKey, change SpecialKey + let regA= @a + redir @a + silent! hi SpecialKey + redir END + let s:SeeTabSpecialKey= @a + let @a = regA + hi clear SpecialKey + + if &et + syn clear + syn match SeeTabMatch /^\s\+/ contains=SeeTabBar + let tsm1= &ts - 1 + exe 'syn match SeeTabBar / \{'.tsm1.'}/hs=s,he=s+1 contained' + hi link SeeTabBar SpecialKey +" call Decho('et: exe silent! hi SpecialKey ctermfg='.g:SeeTabCtermBG.' ctermbg='.g:SeeTabCtermFG.' guifg=.'g:SeeTabGuiBG.' guibg='.g:SeeTabGuiFG) + exe 'silent! hi SpecialKey ctermfg='.g:SeeTabCtermBG.' ctermbg='.g:SeeTabCtermFG.' guifg=.'g:SeeTabGuiBG.' guibg='.g:SeeTabGuiFG + else + let s:SeeTab_list = &list + let s:SeeTab_listchars = &listchars + + " note that list uses SpecialKey highlighting + set list + set listchars=tab:\|\ + exe 'silent! hi SpecialKey ctermfg='.g:SeeTabCtermFG.' ctermbg='.g:SeeTabCtermBG.' guifg='.g:SeeTabGuiFG.' guibg=.'g:SeeTabGuiBG + endif + + else +" call Decho("remove tab bars from display") + " ------------------------- + " restore display to normal + " ------------------------- + silent! exe "hi ".substitute(s:SeeTabSpecialKey,'xxx','','e') + if &et + syn clear SeeTabMatch SeeTabBar + unlet g:SeeTabEnabled + else + let &list = s:SeeTab_list + let &listchars = &listchars + " restore SpecialKey + unlet g:SeeTabEnabled s:SeeTab_list s:SeeTab_listchars + endif + endif +endfun +" --------------------------------------------------------------------- +" vim: ts=4 fdm=marker diff --git a/.config/vim/plugin/imaps.vim b/.config/vim/plugin/imaps.vim new file mode 100644 index 0000000..9738936 --- /dev/null +++ b/.config/vim/plugin/imaps.vim @@ -0,0 +1,822 @@ +" File: imaps.vim +" Authors: Srinath Avadhanula <srinath AT fastmail.fm> +" Benji Fisher <benji AT member.AMS.org> +" +" WWW: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/vim-latex/vimfiles/plugin/imaps.vim?only_with_tag=MAIN +" +" Description: insert mode template expander with cursor placement +" while preserving filetype indentation. +" +" $Id: imaps.vim,v 1.39 2004/05/30 07:35:40 srinathava Exp $ +" +" Documentation: {{{ +" +" Motivation: +" this script provides a way to generate insert mode mappings which do not +" suffer from some of the problem of mappings and abbreviations while allowing +" cursor placement after the expansion. It can alternatively be thought of as +" a template expander. +" +" Consider an example. If you do +" +" imap lhs something +" +" then a mapping is set up. However, there will be the following problems: +" 1. the 'ttimeout' option will generally limit how easily you can type the +" lhs. if you type the left hand side too slowly, then the mapping will not +" be activated. +" 2. if you mistype one of the letters of the lhs, then the mapping is +" deactivated as soon as you backspace to correct the mistake. +" +" If, in order to take care of the above problems, you do instead +" +" iab lhs something +" +" then the timeout problem is solved and so is the problem of mistyping. +" however, abbreviations are only expanded after typing a non-word character. +" which causes problems of cursor placement after the expansion and invariably +" spurious spaces are inserted. +" +" Usage Example: +" this script attempts to solve all these problems by providing an emulation +" of imaps wchich does not suffer from its attendant problems. Because maps +" are activated without having to press additional characters, therefore +" cursor placement is possible. furthermore, file-type specific indentation is +" preserved, because the rhs is expanded as if the rhs is typed in literally +" by the user. +" +" The script already provides some default mappings. each "mapping" is of the +" form: +" +" call IMAP (lhs, rhs, ft) +" +" Some characters in the RHS have special meaning which help in cursor +" placement. +" +" Example One: +" +" call IMAP ("bit`", "\\begin{itemize}\<cr>\\item <++>\<cr>\\end{itemize}<++>", "tex") +" +" This effectively sets up the map for "bit`" whenever you edit a latex file. +" When you type in this sequence of letters, the following text is inserted: +" +" \begin{itemize} +" \item * +" \end{itemize}<++> +" +" where * shows the cursor position. The cursor position after inserting the +" text is decided by the position of the first "place-holder". Place holders +" are special characters which decide cursor placement and movement. In the +" example above, the place holder characters are <+ and +>. After you have typed +" in the item, press <C-j> and you will be taken to the next set of <++>'s. +" Therefore by placing the <++> characters appropriately, you can minimize the +" use of movement keys. +" +" NOTE: Set g:Imap_UsePlaceHolders to 0 to disable placeholders altogether. +" Set +" g:Imap_PlaceHolderStart and g:Imap_PlaceHolderEnd +" to something else if you want different place holder characters. +" Also, b:Imap_PlaceHolderStart and b:Imap_PlaceHolderEnd override the values +" of g:Imap_PlaceHolderStart and g:Imap_PlaceHolderEnd respectively. This is +" useful for setting buffer specific place hoders. +" +" Example Two: +" You can use the <C-r> command to insert dynamic elements such as dates. +" call IMAP ('date`', "\<c-r>=strftime('%b %d %Y')\<cr>", '') +" +" sets up the map for date` to insert the current date. +" +"--------------------------------------%<-------------------------------------- +" Bonus: This script also provides a command Snip which puts tearoff strings, +" '----%<----' above and below the visually selected range of lines. The +" length of the string is chosen to be equal to the longest line in the range. +" Recommended Usage: +" '<,'>Snip +"--------------------------------------%<-------------------------------------- +" }}} + +" ============================================================================== +" Script Options / Variables +" ============================================================================== +" Options {{{ +if !exists('g:Imap_StickyPlaceHolders') + let g:Imap_StickyPlaceHolders = 1 +endif +if !exists('g:Imap_DeleteEmptyPlaceHolders') + let g:Imap_DeleteEmptyPlaceHolders = 1 +endif +" }}} +" Variables {{{ +" s:LHS_{ft}_{char} will be generated automatically. It will look like +" s:LHS_tex_o = 'fo\|foo\|boo' and contain all mapped sequences ending in "o". +" s:Map_{ft}_{lhs} will be generated automatically. It will look like +" s:Map_c_foo = 'for(<++>; <++>; <++>)', the mapping for "foo". +" +" }}} + +" ============================================================================== +" functions for easy insert mode mappings. +" ============================================================================== +" IMAP: Adds a "fake" insert mode mapping. {{{ +" For example, doing +" IMAP('abc', 'def' ft) +" will mean that if the letters abc are pressed in insert mode, then +" they will be replaced by def. If ft != '', then the "mapping" will be +" specific to the files of type ft. +" +" Using IMAP has a few advantages over simply doing: +" imap abc def +" 1. with imap, if you begin typing abc, the cursor will not advance and +" long as there is a possible completion, the letters a, b, c will be +" displayed on on top of the other. using this function avoids that. +" 2. with imap, if a backspace or arrow key is pressed before completing +" the word, then the mapping is lost. this function allows movement. +" (this ofcourse means that this function is only limited to +" left-hand-sides which do not have movement keys or unprintable +" characters) +" It works by only mapping the last character of the left-hand side. +" when this character is typed in, then a reverse lookup is done and if +" the previous characters consititute the left hand side of the mapping, +" the previously typed characters and erased and the right hand side is +" inserted + +" IMAP: set up a filetype specific mapping. +" Description: +" "maps" the lhs to rhs in files of type 'ft'. If supplied with 2 +" additional arguments, then those are assumed to be the placeholder +" characters in rhs. If unspecified, then the placeholder characters +" are assumed to be '<+' and '+>' These placeholder characters in +" a:rhs are replaced with the users setting of +" [bg]:Imap_PlaceHolderStart and [bg]:Imap_PlaceHolderEnd settings. +" +function! IMAP(lhs, rhs, ft, ...) + + " Find the place holders to save for IMAP_PutTextWithMovement() . + if a:0 < 2 + let phs = '<+' + let phe = '+>' + else + let phs = a:1 + let phe = a:2 + endif + + let hash = s:Hash(a:lhs) + let s:Map_{a:ft}_{hash} = a:rhs + let s:phs_{a:ft}_{hash} = phs + let s:phe_{a:ft}_{hash} = phe + + " Add a:lhs to the list of left-hand sides that end with lastLHSChar: + let lastLHSChar = a:lhs[strlen(a:lhs)-1] + let hash = s:Hash(lastLHSChar) + if !exists("s:LHS_" . a:ft . "_" . hash) + let s:LHS_{a:ft}_{hash} = escape(a:lhs, '\') + else + let s:LHS_{a:ft}_{hash} = escape(a:lhs, '\') .'\|'. s:LHS_{a:ft}_{hash} + endif + + " map only the last character of the left-hand side. + if lastLHSChar == ' ' + let lastLHSChar = '<space>' + end + exe 'inoremap <silent>' + \ escape(lastLHSChar, '|') + \ '<C-r>=<SID>LookupCharacter("' . + \ escape(lastLHSChar, '\|"') . + \ '")<CR>' +endfunction + +" }}} +" IMAP_list: list the rhs and place holders corresponding to a:lhs {{{ +" +" Added mainly for debugging purposes, but maybe worth keeping. +function! IMAP_list(lhs) + let char = a:lhs[strlen(a:lhs)-1] + let charHash = s:Hash(char) + if exists("s:LHS_" . &ft ."_". charHash) && a:lhs =~ s:LHS_{&ft}_{charHash} + let ft = &ft + elseif exists("s:LHS__" . charHash) && a:lhs =~ s:LHS__{charHash} + let ft = "" + else + return "" + endif + let hash = s:Hash(a:lhs) + return "rhs = " . s:Map_{ft}_{hash} . " place holders = " . + \ s:phs_{ft}_{hash} . " and " . s:phe_{ft}_{hash} +endfunction +" }}} +" LookupCharacter: inserts mapping corresponding to this character {{{ +" +" This function extracts from s:LHS_{&ft}_{a:char} or s:LHS__{a:char} +" the longest lhs matching the current text. Then it replaces lhs with the +" corresponding rhs saved in s:Map_{ft}_{lhs} . +" The place-holder variables are passed to IMAP_PutTextWithMovement() . +function! s:LookupCharacter(char) + if IMAP_GetVal('Imap_FreezeImap', 0) == 1 + return a:char + endif + let charHash = s:Hash(a:char) + + " The line so far, including the character that triggered this function: + let text = strpart(getline("."), 0, col(".")-1) . a:char + " Prefer a local map to a global one, even if the local map is shorter. + " Is this what we want? Do we care? + " Use '\V' (very no-magic) so that only '\' is special, and it was already + " escaped when building up s:LHS_{&ft}_{charHash} . + if exists("s:LHS_" . &ft . "_" . charHash) + \ && text =~ "\\C\\V\\(" . s:LHS_{&ft}_{charHash} . "\\)\\$" + let ft = &ft + elseif exists("s:LHS__" . charHash) + \ && text =~ "\\C\\V\\(" . s:LHS__{charHash} . "\\)\\$" + let ft = "" + else + " If this is a character which could have been used to trigger an + " abbreviation, check if an abbreviation exists. + if a:char !~ '\k' + let lastword = matchstr(getline('.'), '\k\+$', '') + if lastword != '' + " An extremeley wierd way to get around the fact that vim + " doesn't have the equivalent of the :mapcheck() function for + " abbreviations. + let _a = @a + exec "redir @a | silent! iab ".lastword." | redir END" + let abbreviationRHS = matchstr(@a."\n", "\n".'i\s\+'.lastword.'\+\s\+@\?\zs.*\ze'."\n") + + if @a =~ "No abbreviation found" || abbreviationRHS == "" + let @a = _a + return a:char + endif + + let @a = _a + let abbreviationRHS = escape(abbreviationRHS, '\<"') + exec 'let abbreviationRHS = "'.abbreviationRHS.'"' + + let lhs = lastword.a:char + let rhs = abbreviationRHS.a:char + let phs = IMAP_GetPlaceHolderStart() + let phe = IMAP_GetPlaceHolderEnd() + else + return a:char + endif + else + return a:char + endif + endif + " Find the longest left-hand side that matches the line so far. + " matchstr() returns the match that starts first. This automatically + " ensures that the longest LHS is used for the mapping. + if !exists('lhs') || !exists('rhs') + let lhs = matchstr(text, "\\C\\V\\(" . s:LHS_{ft}_{charHash} . "\\)\\$") + let hash = s:Hash(lhs) + let rhs = s:Map_{ft}_{hash} + let phs = s:phs_{ft}_{hash} + let phe = s:phe_{ft}_{hash} + endif + + if strlen(lhs) == 0 + return a:char + endif + " enough back-spaces to erase the left-hand side; -1 for the last + " character typed: + let bs = substitute(strpart(lhs, 1), ".", "\<bs>", "g") + return bs . IMAP_PutTextWithMovement(rhs, phs, phe) +endfunction + +" }}} +" IMAP_PutTextWithMovement: returns the string with movement appended {{{ +" Description: +" If a:str contains "placeholders", then appends movement commands to +" str in a way that the user moves to the first placeholder and enters +" insert or select mode. If supplied with 2 additional arguments, then +" they are assumed to be the placeholder specs. Otherwise, they are +" assumed to be '<+' and '+>'. These placeholder chars are replaced +" with the users settings of [bg]:Imap_PlaceHolderStart and +" [bg]:Imap_PlaceHolderEnd. +function! IMAP_PutTextWithMovement(str, ...) + + " The placeholders used in the particular input string. These can be + " different from what the user wants to use. + if a:0 < 2 + let phs = '<+' + let phe = '+>' + else + let phs = escape(a:1, '\') + let phe = escape(a:2, '\') + endif + + let text = a:str + + " The user's placeholder settings. + let phsUser = IMAP_GetPlaceHolderStart() + let pheUser = IMAP_GetPlaceHolderEnd() + + " Problem: depending on the setting of the 'encoding' option, a character + " such as "\xab" may not match itself. We try to get around this by + " changing the encoding of all our strings. At the end, we have to + " convert text back. + let phsEnc = s:Iconv(phs, "encode") + let pheEnc = s:Iconv(phe, "encode") + let phsUserEnc = s:Iconv(phsUser, "encode") + let pheUserEnc = s:Iconv(pheUser, "encode") + let textEnc = s:Iconv(text, "encode") + if textEnc != text + let textEncoded = 1 + else + let textEncoded = 0 + endif + + let pattern = '\V\(\.\{-}\)' .phs. '\(\.\{-}\)' .phe. '\(\.\*\)' + " If there are no placeholders, just return the text. + if textEnc !~ pattern + call IMAP_Debug('Not getting '.phs.' and '.phe.' in '.textEnc, 'imap') + return text + endif + " Break text up into "initial <+template+> final"; any piece may be empty. + let initialEnc = substitute(textEnc, pattern, '\1', '') + let templateEnc = substitute(textEnc, pattern, '\2', '') + let finalEnc = substitute(textEnc, pattern, '\3', '') + + " If the user does not want to use placeholders, then remove all but the + " first placeholder. + " Otherwise, replace all occurences of the placeholders here with the + " user's choice of placeholder settings. + if exists('g:Imap_UsePlaceHolders') && !g:Imap_UsePlaceHolders + let finalEnc = substitute(finalEnc, '\V'.phs.'\.\{-}'.phe, '', 'g') + else + let finalEnc = substitute(finalEnc, '\V'.phs.'\(\.\{-}\)'.phe, + \ phsUserEnc.'\1'.pheUserEnc, 'g') + endif + + " The substitutions are done, so convert back, if necessary. + if textEncoded + let initial = s:Iconv(initialEnc, "decode") + let template = s:Iconv(templateEnc, "decode") + let final = s:Iconv(finalEnc, "decode") + else + let initial = initialEnc + let template = templateEnc + let final = finalEnc + endif + + " Build up the text to insert: + " 1. the initial text plus an extra character; + " 2. go to Normal mode with <C-\><C-N>, so it works even if 'insertmode' + " is set, and mark the position; + " 3. replace the extra character with tamplate and final; + " 4. back to Normal mode and restore the cursor position; + " 5. call IMAP_Jumpfunc(). + let template = phsUser . template . pheUser + " Old trick: insert and delete a character to get the same behavior at + " start, middle, or end of line and on empty lines. + let text = initial . "X\<C-\>\<C-N>:call IMAP_Mark('set')\<CR>\"_s" + let text = text . template . final + let text = text . "\<C-\>\<C-N>:call IMAP_Mark('go')\<CR>" + let text = text . "i\<C-r>=IMAP_Jumpfunc('', 1)\<CR>" + + call IMAP_Debug('IMAP_PutTextWithMovement: text = ['.text.']', 'imap') + return text +endfunction + +" }}} +" IMAP_Jumpfunc: takes user to next <+place-holder+> {{{ +" Author: Luc Hermitte +" Arguments: +" direction: flag for the search() function. If set to '', search forwards, +" if 'b', then search backwards. See the {flags} argument of the +" |search()| function for valid values. +" inclusive: In vim, the search() function is 'exclusive', i.e we always goto +" next cursor match even if there is a match starting from the +" current cursor position. Setting this argument to 1 makes +" IMAP_Jumpfunc() also respect a match at the current cursor +" position. 'inclusive'ness is necessary for IMAP() because a +" placeholder string can occur at the very beginning of a map which +" we want to select. +" We use a non-zero value only in special conditions. Most mappings +" should use a zero value. +function! IMAP_Jumpfunc(direction, inclusive) + + " The user's placeholder settings. + let phsUser = IMAP_GetPlaceHolderStart() + let pheUser = IMAP_GetPlaceHolderEnd() + + let searchString = '' + " If this is not an inclusive search or if it is inclusive, but the + " current cursor position does not contain a placeholder character, then + " search for the placeholder characters. + if !a:inclusive || strpart(getline('.'), col('.')-1) !~ '\V\^'.phsUser + let searchString = '\V'.phsUser.'\_.\{-}'.pheUser + endif + + " If we didn't find any placeholders return quietly. + if searchString != '' && !search(searchString, a:direction) + return '' + endif + + " Open any closed folds and make this part of the text visible. + silent! foldopen! + + " Calculate if we have an empty placeholder or if it contains some + " description. + let template = + \ matchstr(strpart(getline('.'), col('.')-1), + \ '\V\^'.phsUser.'\zs\.\{-}\ze\('.pheUser.'\|\$\)') + let placeHolderEmpty = !strlen(template) + + " If we are selecting in exclusive mode, then we need to move one step to + " the right + let extramove = '' + if &selection == 'exclusive' + let extramove = 'l' + endif + + " Select till the end placeholder character. + let movement = "\<C-o>v/\\V".pheUser."/e\<CR>".extramove + + " First remember what the search pattern was. s:RemoveLastHistoryItem will + " reset @/ to this pattern so we do not create new highlighting. + let g:Tex_LastSearchPattern = @/ + + " Now either goto insert mode or select mode. + if placeHolderEmpty && g:Imap_DeleteEmptyPlaceHolders + " delete the empty placeholder into the blackhole. + return movement."\"_c\<C-o>:".s:RemoveLastHistoryItem."\<CR>" + else + return movement."\<C-\>\<C-N>:".s:RemoveLastHistoryItem."\<CR>gv\<C-g>" + endif + +endfunction + +" }}} +" Maps for IMAP_Jumpfunc {{{ +" +" These mappings use <Plug> and thus provide for easy user customization. When +" the user wants to map some other key to jump forward, he can do for +" instance: +" nmap ,f <plug>IMAP_JumpForward +" etc. + +" jumping forward and back in insert mode. +imap <silent> <Plug>IMAP_JumpForward <c-r>=IMAP_Jumpfunc('', 0)<CR> +imap <silent> <Plug>IMAP_JumpBack <c-r>=IMAP_Jumpfunc('b', 0)<CR> + +" jumping in normal mode +nmap <silent> <Plug>IMAP_JumpForward i<c-r>=IMAP_Jumpfunc('', 0)<CR> +nmap <silent> <Plug>IMAP_JumpBack i<c-r>=IMAP_Jumpfunc('b', 0)<CR> + +" deleting the present selection and then jumping forward. +vmap <silent> <Plug>IMAP_DeleteAndJumpForward "_<Del>i<c-r>=IMAP_Jumpfunc('', 0)<CR> +vmap <silent> <Plug>IMAP_DeleteAndJumpBack "_<Del>i<c-r>=IMAP_Jumpfunc('b', 0)<CR> + +" jumping forward without deleting present selection. +vmap <silent> <Plug>IMAP_JumpForward <C-\><C-N>i<c-r>=IMAP_Jumpfunc('', 0)<CR> +vmap <silent> <Plug>IMAP_JumpBack <C-\><C-N>`<i<c-r>=IMAP_Jumpfunc('b', 0)<CR> + +" }}} +" Default maps for IMAP_Jumpfunc {{{ +" map only if there is no mapping already. allows for user customization. +" NOTE: Default mappings for jumping to the previous placeholder are not +" provided. It is assumed that if the user will create such mappings +" hself if e so desires. +if !hasmapto('<Plug>IMAP_JumpForward', 'i') + imap <C-J> <Plug>IMAP_JumpForward +endif +if !hasmapto('<Plug>IMAP_JumpForward', 'n') + nmap <C-J> <Plug>IMAP_JumpForward +endif +if exists('g:Imap_StickyPlaceHolders') && g:Imap_StickyPlaceHolders + if !hasmapto('<Plug>IMAP_JumpForward', 'v') + vmap <C-J> <Plug>IMAP_JumpForward + endif +else + if !hasmapto('<Plug>IMAP_DeleteAndJumpForward', 'v') + vmap <C-J> <Plug>IMAP_DeleteAndJumpForward + endif +endif +" }}} + +nmap <silent> <script> <plug><+SelectRegion+> `<v`> + +" ============================================================================== +" enclosing selected region. +" ============================================================================== +" VEnclose: encloses the visually selected region with given arguments {{{ +" Description: allows for differing action based on visual line wise +" selection or visual characterwise selection. preserves the +" marks and search history. +function! VEnclose(vstart, vend, VStart, VEnd) + + " its characterwise if + " 1. characterwise selection and valid values for vstart and vend. + " OR + " 2. linewise selection and invalid values for VStart and VEnd + if (visualmode() == 'v' && (a:vstart != '' || a:vend != '')) || (a:VStart == '' && a:VEnd == '') + + let newline = "" + let _r = @r + + let normcmd = "normal! \<C-\>\<C-n>`<v`>\"_s" + + exe "normal! \<C-\>\<C-n>`<v`>\"ry" + if @r =~ "\n$" + let newline = "\n" + let @r = substitute(@r, "\n$", '', '') + endif + + " In exclusive selection, we need to select an extra character. + if &selection == 'exclusive' + let movement = 8 + else + let movement = 7 + endif + let normcmd = normcmd. + \ a:vstart."!!mark!!".a:vend.newline. + \ "\<C-\>\<C-N>?!!mark!!\<CR>v".movement."l\"_s\<C-r>r\<C-\>\<C-n>" + + " this little if statement is because till very recently, vim used to + " report col("'>") > length of selected line when `> is $. on some + " systems it reports a -ve number. + if col("'>") < 0 || col("'>") > strlen(getline("'>")) + let lastcol = strlen(getline("'>")) + else + let lastcol = col("'>") + endif + if lastcol - col("'<") != 0 + let len = lastcol - col("'<") + else + let len = '' + endif + + " the next normal! is for restoring the marks. + let normcmd = normcmd."`<v".len."l\<C-\>\<C-N>" + + " First remember what the search pattern was. s:RemoveLastHistoryItem + " will reset @/ to this pattern so we do not create new highlighting. + let g:Tex_LastSearchPattern = @/ + + silent! exe normcmd + " this is to restore the r register. + let @r = _r + " and finally, this is to restore the search history. + execute s:RemoveLastHistoryItem + + else + + exec 'normal! `<O'.a:VStart."\<C-\>\<C-n>" + exec 'normal! `>o'.a:VEnd."\<C-\>\<C-n>" + if &indentexpr != '' + silent! normal! `<kV`>j= + endif + silent! normal! `> + endif +endfunction + +" }}} +" ExecMap: adds the ability to correct an normal/visual mode mapping. {{{ +" Author: Hari Krishna Dara <hari_vim@yahoo.com> +" Reads a normal mode mapping at the command line and executes it with the +" given prefix. Press <BS> to correct and <Esc> to cancel. +function! ExecMap(prefix, mode) + " Temporarily remove the mapping, otherwise it will interfere with the + " mapcheck call below: + let myMap = maparg(a:prefix, a:mode) + exec a:mode."unmap ".a:prefix + + " Generate a line with spaces to clear the previous message. + let i = 1 + let clearLine = "\r" + while i < &columns + let clearLine = clearLine . ' ' + let i = i + 1 + endwhile + + let mapCmd = a:prefix + let foundMap = 0 + let breakLoop = 0 + echon "\rEnter Map: " . mapCmd + while !breakLoop + let char = getchar() + if char !~ '^\d\+$' + if char == "\<BS>" + let mapCmd = strpart(mapCmd, 0, strlen(mapCmd) - 1) + endif + else " It is the ascii code. + let char = nr2char(char) + if char == "\<Esc>" + let breakLoop = 1 + else + let mapCmd = mapCmd . char + if maparg(mapCmd, a:mode) != "" + let foundMap = 1 + let breakLoop = 1 + elseif mapcheck(mapCmd, a:mode) == "" + let mapCmd = strpart(mapCmd, 0, strlen(mapCmd) - 1) + endif + endif + endif + echon clearLine + echon "\rEnter Map: " . mapCmd + endwhile + if foundMap + if a:mode == 'v' + " use a plug to select the region instead of using something like + " `<v`> to avoid problems caused by some of the characters in + " '`<v`>' being mapped. + let gotoc = "\<plug><+SelectRegion+>" + else + let gotoc = '' + endif + exec "normal ".gotoc.mapCmd + endif + exec a:mode.'noremap '.a:prefix.' '.myMap +endfunction + +" }}} + +" ============================================================================== +" helper functions +" ============================================================================== +" Strntok: extract the n^th token from a list {{{ +" example: Strntok('1,23,3', ',', 2) = 23 +fun! <SID>Strntok(s, tok, n) + return matchstr( a:s.a:tok[0], '\v(\zs([^'.a:tok.']*)\ze['.a:tok.']){'.a:n.'}') +endfun + +" }}} +" s:RemoveLastHistoryItem: removes last search item from search history {{{ +" Description: Execute this string to clean up the search history. +let s:RemoveLastHistoryItem = ':call histdel("/", -1)|let @/=g:Tex_LastSearchPattern' + +" }}} +" s:Hash: Return a version of a string that can be used as part of a variable" {{{ +" name. +" Converts every non alphanumeric character into _{ascii}_ where {ascii} is +" the ASCII code for that character... +fun! s:Hash(text) + return substitute(a:text, '\([^[:alnum:]]\)', + \ '\="_".char2nr(submatch(1))."_"', 'g') +endfun +"" }}} +" IMAP_GetPlaceHolderStart and IMAP_GetPlaceHolderEnd: "{{{ +" return the buffer local placeholder variables, or the global one, or the default. +function! IMAP_GetPlaceHolderStart() + if exists("b:Imap_PlaceHolderStart") && strlen(b:Imap_PlaceHolderEnd) + return b:Imap_PlaceHolderStart + elseif exists("g:Imap_PlaceHolderStart") && strlen(g:Imap_PlaceHolderEnd) + return g:Imap_PlaceHolderStart + else + return "<+" +endfun +function! IMAP_GetPlaceHolderEnd() + if exists("b:Imap_PlaceHolderEnd") && strlen(b:Imap_PlaceHolderEnd) + return b:Imap_PlaceHolderEnd + elseif exists("g:Imap_PlaceHolderEnd") && strlen(g:Imap_PlaceHolderEnd) + return g:Imap_PlaceHolderEnd + else + return "+>" +endfun +" }}} +" s:Iconv: a wrapper for iconv()" {{{ +" Problem: after +" let text = "\xab" +" (or using the raw 8-bit ASCII character in a file with 'fenc' set to +" "latin1") if 'encoding' is set to utf-8, then text does not match itself: +" echo text =~ text +" returns 0. +" Solution: When this happens, a re-encoded version of text does match text: +" echo iconv(text, "latin1", "utf8") =~ text +" returns 1. In this case, convert text to utf-8 with iconv(). +" TODO: Is it better to use &encoding instead of "utf8"? Internally, vim +" uses utf-8, and can convert between latin1 and utf-8 even when compiled with +" -iconv, so let's try using utf-8. +" Arguments: +" a:text = text to be encoded or decoded +" a:mode = "encode" (latin1 to utf8) or "decode" (utf8 to latin1) +" Caution: do not encode and then decode without checking whether the text +" has changed, becuase of the :if clause in encoding! +function! s:Iconv(text, mode) + if a:mode == "decode" + return iconv(a:text, "utf8", "latin1") + endif + if a:text =~ '\V\^' . escape(a:text, '\') . '\$' + return a:text + endif + let textEnc = iconv(a:text, "latin1", "utf8") + if textEnc !~ '\V\^' . escape(a:text, '\') . '\$' + call IMAP_Debug('Encoding problems with text '.a:text.' ', 'imap') + endif + return textEnc +endfun +"" }}} +" IMAP_Debug: interface to Tex_Debug if available, otherwise emulate it {{{ +" Description: +" Do not want a memory leak! Set this to zero so that imaps always +" starts out in a non-debugging mode. +if !exists('g:Imap_Debug') + let g:Imap_Debug = 0 +endif +function! IMAP_Debug(string, pattern) + if !g:Imap_Debug + return + endif + if exists('*Tex_Debug') + call Tex_Debug(a:string, a:pattern) + else + if !exists('s:debug_'.a:pattern) + let s:debug_{a:pattern} = a:string + else + let s:debug_{a:pattern} = s:debug_{a:pattern}.a:string + endif + endif +endfunction " }}} +" IMAP_DebugClear: interface to Tex_DebugClear if avaialable, otherwise emulate it {{{ +" Description: +function! IMAP_DebugClear(pattern) + if exists('*Tex_DebugClear') + call Tex_DebugClear(a:pattern) + else + let s:debug_{a:pattern} = '' + endif +endfunction " }}} +" IMAP_PrintDebug: interface to Tex_DebugPrint if avaialable, otherwise emulate it {{{ +" Description: +function! IMAP_PrintDebug(pattern) + if exists('*Tex_PrintDebug') + call Tex_PrintDebug(a:pattern) + else + if exists('s:debug_'.a:pattern) + echo s:debug_{a:pattern} + endif + endif +endfunction " }}} +" IMAP_Mark: Save the cursor position (if a:action == 'set') in a" {{{ +" script-local variable; restore this position if a:action == 'go'. +let s:Mark = "(0,0)" +let s:initBlanks = '' +function! IMAP_Mark(action) + if a:action == 'set' + let s:Mark = "(" . line(".") . "," . col(".") . ")" + let s:initBlanks = matchstr(getline('.'), '^\s*') + elseif a:action == 'go' + execute "call cursor" s:Mark + let blanksNow = matchstr(getline('.'), '^\s*') + if strlen(blanksNow) > strlen(s:initBlanks) + execute 'silent! normal! '.(strlen(blanksNow) - strlen(s:initBlanks)).'l' + elseif strlen(blanksNow) < strlen(s:initBlanks) + execute 'silent! normal! '.(strlen(s:initBlanks) - strlen(blanksNow)).'h' + endif + endif +endfunction "" }}} +" IMAP_GetVal: gets the value of a variable {{{ +" Description: first checks window local, then buffer local etc. +function! IMAP_GetVal(name, ...) + if a:0 > 0 + let default = a:1 + else + let default = '' + endif + if exists('w:'.a:name) + return w:{a:name} + elseif exists('b:'.a:name) + return b:{a:name} + elseif exists('g:'.a:name) + return g:{a:name} + else + return default + endif +endfunction " }}} + +" ============================================================================== +" A bonus function: Snip() +" ============================================================================== +" Snip: puts a scissor string above and below block of text {{{ +" Desciption: +"-------------------------------------%<------------------------------------- +" this puts a the string "--------%<---------" above and below the visually +" selected block of lines. the length of the 'tearoff' string depends on the +" maximum string length in the selected range. this is an aesthetically more +" pleasing alternative instead of hardcoding a length. +"-------------------------------------%<------------------------------------- +function! <SID>Snip() range + let i = a:firstline + let maxlen = -2 + " find out the maximum virtual length of each line. + while i <= a:lastline + exe i + let length = virtcol('$') + let maxlen = (length > maxlen ? length : maxlen) + let i = i + 1 + endwhile + let maxlen = (maxlen > &tw && &tw != 0 ? &tw : maxlen) + let half = maxlen/2 + exe a:lastline + " put a string below + exe "norm! o\<esc>".(half - 1)."a-\<esc>A%<\<esc>".(half - 1)."a-" + " and above. its necessary to put the string below the block of lines + " first because that way the first line number doesnt change... + exe a:firstline + exe "norm! O\<esc>".(half - 1)."a-\<esc>A%<\<esc>".(half - 1)."a-" +endfunction + +com! -nargs=0 -range Snip :<line1>,<line2>call <SID>Snip() +" }}} + +" vim:ft=vim:ts=4:sw=4:noet:fdm=marker:commentstring=\"\ %s:nowrap diff --git a/.config/vim/plugin/jad.vim b/.config/vim/plugin/jad.vim new file mode 100644 index 0000000..f6e7741 --- /dev/null +++ b/.config/vim/plugin/jad.vim @@ -0,0 +1,66 @@ +" File: jad.vim +" Purpose: Vim plugin for viewing decompiled class files using 'jad' decompiler. +" Ideas: Allow for a default to be set in the vimrc +" - map a keystroke to decompile and edit, or decompile and view in split window +" Date Created: 10-14-2002 +" Last Modified:10-22-2002 +" Version: 1.3 + +if exists("loaded_jad") || &cp || exists("#BufReadPre#*.class") + finish +endif +let loaded_jad = 1 + +augroup class + " Remove all jad autocommands + au! + " Enable editing of jaded files + " set binary mode before reading the file + " add your preferable flags after "jad" (for instance "jad -f -dead -ff -a") + autocmd BufReadPre,FileReadPre *.class set bin + autocmd BufReadPost,FileReadPost *.class call s:read("jad") +augroup END + +" Function to check that executing "cmd [-f]" works. +" The result is cached in s:have_"cmd" for speed. +fun s:check(cmd) + let name = substitute(a:cmd, '\(\S*\).*', '\1', '') + if !exists("s:have_" . name) + let e = executable(name) + if e < 0 + let r = system(name . " --version") + let e = (r !~ "not found" && r != "") + endif + exe "let s:have_" . name . "=" . e + endif + exe "return s:have_" . name +endfun + +" After reading decompiled file: Decompiled text in buffer with "cmd" +fun s:read(cmd) + " don't do anything if the cmd is not supported + if !s:check(a:cmd) + return + endif + " make 'patchmode' empty, we don't want a copy of the written file + let pm_save = &pm + set pm = + " set 'modifiable' + set ma + " when filtering the whole buffer, it will become empty + let empty = line("'[") == 1 && line("']") == line("$") + let jadfile = expand("<afile>:r") . ".jad" + let orig = expand("<afile>") + " now we have no binary file, so set 'nobinary' + set nobin + "Split and show code in a new window + g/.*/d + execute "silent r !" a:cmd . " -p " . orig + 1 + " set file name, type and file syntax to java + execute ":file " . jadfile + set ft =java + set syntax =java + " recover global variables + let &pm = pm_save +endfun diff --git a/.config/vim/plugin/lodgeit.vim b/.config/vim/plugin/lodgeit.vim new file mode 100644 index 0000000..4053b0b --- /dev/null +++ b/.config/vim/plugin/lodgeit.vim @@ -0,0 +1,134 @@ +" lodgeit.vim: Vim plugin for paste.pocoo.org +" Maintainer: Armin Ronacher <armin.ronacher@active-4.com> +" Version: 0.1.5 + +" Usage: +" :Lodgeit create a paste from the current buffer of selection +" :e <url> download a paste. If you then use :Lodgeit you can +" reply to that paste. +" +" If you want to paste on ctrl + p just add this to your vimrc: +" map ^P :Lodgeit<CR> +" (where ^P is entered using ctrl + v, ctrl + p in vim) + +function! s:LodgeitInit() +python << EOF + +import vim +import re +from xmlrpclib import ServerProxy +srv = ServerProxy('http://paste.pocoo.org/xmlrpc/', allow_none=True) + +new_paste = srv.pastes.newPaste +get_paste = srv.pastes.getPaste + +language_mapping = { + 'python': 'python', + 'php': 'html+php', + 'smarty': 'smarty', + 'tex': 'tex', + 'rst': 'rst', + 'cs': 'csharp', + 'haskell': 'haskell', + 'xml': 'xml', + 'html': 'html', + 'xhtml': 'html', + 'htmldjango': 'html+django', + 'django': 'html+django', + 'htmljinja': 'html+django', + 'jinja': 'html+django', + 'lua': 'lua', + 'scheme': 'scheme', + 'mako': 'html+mako', + 'c': 'c', + 'cpp': 'cpp', + 'javascript': 'js', + 'jsp': 'jsp', + 'ruby': 'ruby', + 'bash': 'bash', + 'bat': 'bat', + 'd': 'd', + 'genshi': 'html+genshi' +} + +language_reverse_mapping = {} +for key, value in language_mapping.iteritems(): + language_reverse_mapping[value] = key + +def paste_id_from_url(url): + regex = re.compile(r'^http://paste.pocoo.org/show/(\d+)/?$') + m = regex.match(url) + if m is not None: + return int(m.group(1)) + +def make_utf8(code): + enc = vim.eval('&fenc') or vim.eval('&enc') + return code.decode(enc, 'ignore').encode('utf-8') + +EOF +endfunction + + +function! s:Lodgeit(line1,line2,count,...) +call s:LodgeitInit() +python << endpython + +# download paste +if vim.eval('a:0') == '1': + paste = paste_id = None + arg = vim.eval('a:1') + + if arg.startswith('#'): + try: + paste_id = int(arg[1:]) + except: + pass + if paste_id is None: + paste_id = paste_id_from_url(vim.eval('a:1')) + if paste_id is not None: + paste = get_paste(paste_id) + + if paste: + vim.command('tabnew') + vim.command('file Lodgeit\ Paste\ \#%d"' % paste_id) + vim.current.buffer[:] = paste['code'].splitlines() + vim.command('setlocal ft=' + language_reverse_mapping. + get(paste['language'], 'text')) + vim.command('setlocal nomodified') + vim.command('let b:lodgeit_paste_id=%d' % paste_id) + else: + print 'Paste not Found' + +# new paste or reply +else: + rng_start = int(vim.eval('a:line1')) - 1 + rng_end = int(vim.eval('a:line2')) + if int(vim.eval('a:count')): + code = '\n'.join(vim.current.buffer[rng_start:rng_end]) + else: + code = '\n'.join(vim.current.buffer) + code = make_utf8(code) + + parent = None + update_buffer_info = False + if vim.eval('exists("b:lodgeit_paste_id")') == '1': + parent = int(vim.eval('b:lodgeit_paste_id')) + update_buffer_info = True + + lng_code = language_mapping.get(vim.eval('&ft'), 'text') + paste_id = new_paste(lng_code, code, parent) + url = 'http://paste.pocoo.org/show/%d' % paste_id + + print 'Pasted #%d to %s' % (paste_id, url) + vim.command(':call setreg(\'+\', %r)' % url) + + if update_buffer_info: + vim.command('file Lodgeit\ Paste\ \#%d"' % paste_id) + vim.command('setlocal nomodified') + vim.command('let b:lodgeit_paste_id=%d' % paste_id) + +endpython +endfunction + + +command! -range=0 -nargs=* Lodgeit :call s:Lodgeit(<line1>,<line2>,<count>,<f-args>) diff --git a/.config/vim/plugin/pastie.vim b/.config/vim/plugin/pastie.vim new file mode 100644 index 0000000..b001508 --- /dev/null +++ b/.config/vim/plugin/pastie.vim @@ -0,0 +1,537 @@ +" pastie.vim: Vim plugin for pastie.caboo.se +" Maintainer: Tim Pope <vimNOSPAM@tpope.info> +" URL: http://www.vim.org/scripts/script.php?script_id=1624 +" GetLatestVimScripts: 1624 1 +" $Id: pastie.vim,v 1.15 2007-12-13 16:44:26 tpope Exp $ + +" Installation: +" Place in ~/.vim/plugin or vimfiles/plugin +" A working ruby install is required (Vim interface not necessary). + +" Usage: +" :Pastie creates a new paste (example arguments shown below). Use :w to save +" it by posting it to the server (the parser used is derived from the Vim +" filetype). This updates the filename and stores the new url in the primary +" selection/clipboard when successful. :Pastie! creates a paste, saves, and +" closes the buffer, except when loading an existing paste. + +" :Pastie Create a paste from all open windows +" :Pastie! Create a paste from all open windows and paste it +" :1,10Pastie Create a paste from the specified range +" :%Pastie Use the entire current file to create a new paste +" :Pastie foo.txt bar.txt Create a paste from foo.txt and bar.txt +" :Pastie! foo.txt Paste directly from foo.txt +" :Pastie a Create a paste from the "a register +" :Pastie @ Create a paste from the default (unnamed) register +" :Pastie * Create a paste from the primary selection/clipboard +" :Pastie _ Create a new, blank paste +" :768Pastie Load existing paste 768 +" :0Pastie Load the newest paste +" :Pastie http://pastie.caboo.se/768 Load existing paste 768 +" :Pastie http://pastie.caboo.se/123456?key=... Use login from pastie bot + +" Regardless of the command used, on the first write, this script will create +" a new paste, and on subsequent writes, it will update the existing paste. +" If a bang is passed to a command that load an existing paste (:768), the +" first write will update as well. If the loaded paste was not created in the +" same vim session, or with an account extracted from your Firefox cookies, +" updates will almost certainly silently fail. (Advanced users can muck +" around with g:pastie_session_id if desired). + +" As hinted at earlier, pastie.vim will snoop around in your Firefox cookies, +" and use an account cookie if one is found. The only way to create one of +" these account cookies is by talking to pastie on IRC. + +" At the shell you can directly create a new pastie with a command like +" $ vim +Pastie +" or, assuming no other plugins conflict +" $ vim +Pa +" And, to read an existing paste +" $ vim +768Pa +" You could even paste a file directly +" $ vim '+Pa!~/.irbrc' +q +" You can even edit a pastie URL directly, but this is not recommended because +" netrw can sometimes interfere. + +" Lines ending in #!! will be sent as lines beginning with !!. This alternate +" format is easier to read and is less likely to interfere with code +" execution. In Vim 7 highlighting is done with :2match (use ":2match none" +" to disable it) and in previous versions, :match (use ":match none" to +" disable). +" +" Known Issues: +" URL sometimes disappears with the bang (:Pastie!) variant. You can still +" retrieve it from the clipboard. + +if exists("g:loaded_pastie") || &cp + finish +endif +let g:loaded_pastie = 1 + +augroup pastie + autocmd! + autocmd BufReadPre http://pastie.caboo.se/*[0-9]?key=* call s:extractcookies(expand("<amatch>")) + autocmd BufReadPost http://pastie.caboo.se/*[0-9]?key=* call s:PastieSwapout(expand("<amatch>")) + autocmd BufReadPost http://pastie.caboo.se/*[0-9] call s:PastieSwapout(expand("<amatch>")) + autocmd BufReadPost http://pastie.caboo.se/pastes/*[0-9]/download call s:PastieRead(expand("<amatch>")) + autocmd BufReadPost http://pastie.caboo.se/*[0-9].* call s:PastieRead(expand("<amatch>")) + autocmd BufWriteCmd http://pastie.caboo.se/pastes/*[0-9]/download call s:PastieWrite(expand("<amatch>")) + autocmd BufWriteCmd http://pastie.caboo.se/*[0-9].* call s:PastieWrite(expand("<amatch>")) + autocmd BufWriteCmd http://pastie.caboo.se/pastes/ call s:PastieWrite(expand("<amatch>")) +augroup END + +let s:domain = "pastie.caboo.se" + +let s:dl_suffix = ".txt" " Used only for :file + +if !exists("g:pastie_destination") + if version >= 700 + let g:pastie_destination = 'tab' + else + let g:pastie_destination = 'window' + endif + "let g:pastie_destination = 'buffer' +endif + +command! -bar -bang -nargs=* -range=0 -complete=file Pastie :call s:Pastie(<bang>0,<line1>,<line2>,<count>,<f-args>) + +function! s:Pastie(bang,line1,line2,count,...) + if exists(":tab") + let tabnr = tabpagenr() + endif + let newfile = "http://".s:domain."/pastes/" + let loggedin = 0 + let ft = &ft + let num = 0 + if a:0 == 0 && a:count == a:line1 && a:count > line('$') + let num = a:count + elseif a:0 == 0 && a:line1 == 0 && a:line2 == 0 + let num = s:latestid() + if num == 0 + return s:error("Could not determine latest paste") + endif + elseif !a:count && a:0 == 1 + if a:1 == '*' + let numcheck = @* + elseif a:1 == '+' + let numcheck = @+ + elseif a:1 == '@' + let numcheck = @@ + else + let numcheck = a:1 + endif + let numcheck = substitute(numcheck,'\n\+$','','') + let numcheck = substitute(numcheck,'^\n\+','','g') + if numcheck =~ '\n' + let numcheck = '' + endif + if numcheck =~ '^\d\d+$' + let num = numcheck + elseif numcheck =~ '\%(^\|/\)\d\+?key=\x\{8,\}' + if exists("b:pastie_fake_login") + unlet b:pastie_fake_login + else + call s:extractcookies('/'.matchstr(numcheck,'\%(^\|/\)\zs\d\+?.*')) + endif + if exists("g:pastie_account") + let loggedin = 1 + endif + let num = matchstr(numcheck,'\%(^\|/\)\zs\d\+\ze?') + elseif numcheck =~ '\%(^\|^/\|^http://.*\)\d\+\%([/?]\|$\)' + let num = matchstr(numcheck,'\%(^\|/\)\zs\d\+') + endif + endif + if num + call s:newwindow() + let file = "http://".s:domain."/".num.s:dl_suffix + silent exe 'doautocmd BufReadPre '.file + silent exe 'read !ruby -rnet/http -e "r = Net::HTTP.get_response(\%{'.s:domain.'}, \%{/pastes/'.num.'/download}); if r.code == \%{200} then print r.body else exit 10+r.code.to_i/100 end"' + if v:shell_error && v:shell_error != 14 && v:shell_error !=15 + return s:error("Something went wrong: shell returned ".v:shell_error) + else + let err = v:shell_error + silent exe "file ".file + 1d_ + set nomodified + call s:dobufreadpost() + if err + if loggedin + let b:pastie_update = 1 + else + echohl WarningMsg + echo "Warning: Failed to retrieve existing paste" + echohl None + endif + endif + "call s:PastieRead(file) + if a:bang + " Instead of saving an identical paste, take ! to mean "do not + " create a new paste on first save" + let b:pastie_update = 1 + endif + return + endif + elseif a:0 == 0 && !a:count && a:bang && expand("%") =~ '^http://'.s:domain.'/\d\+' + " If the :Pastie! form is used in an existing paste, switch to + " updating instead of creating. + "echohl Question + echo "Will update, not create" + echohl None + let b:pastie_update = 1 + return + elseif a:0 == 1 && !a:count && a:1 =~ '^[&?]\x\{32,\}' + " Set session id with :Pastie&deadbeefcafebabe + let g:pastie_session_id = strpart(a:1,1) + elseif a:0 == 1 && !a:count && (a:1 == '&' || a:1 == '?') + " Extract session id with :Pastie& + call s:cookies() + if exists("g:pastie_session_id") + echo g:pastie_session_id + "silent! let @* = g:pastie_session_id + endif + elseif a:0 == 0 && !a:count && a:line1 + let ft = 'conf' + let sum = "" + let cnt = 0 + let keep = @" + windo let tmp = s:grabwin() | if tmp != "" | let cnt = cnt + 1 | let sum = sum . tmp | end + let sum = substitute(sum,'\n\+$',"\n",'') + if cnt == 1 + let ft = matchstr(sum,'^##.\{-\} \[\zs\w*\ze\]') + if ft != "" + let sum = substitute(sum,'^##.\{-\} \[\w*\]\n','','') + endif + endif + call s:newwindow() + silent exe "file ".newfile + "silent exe "doautocmd BufReadPre ".newfile + if sum != "" + let @" = sum + silent $put + 1d _ + endif + if ft == 'plaintext' || ft == 'plain_text' + "set ft=conf + elseif ft != '' && sum != "" + let &ft = ft + endif + let @" = keep + call s:dobufreadpost() + else + let keep = @" + let args = "" + if a:0 > 0 && a:1 =~ '^[-"@0-9a-zA-Z:.%#*+~_/]$' + let i = 1 + let register = a:1 + else + let i = 0 + let register = "" + endif + while i < a:0 + let i = i+1 + if strlen(a:{i}) + let file = fnamemodify(expand(a:{i}),':~:.') + let args = args . file . "\n" + endif + endwhile + let range = "" + if a:count + silent exe a:line1.",".a:line2."yank" + let range = @" + let @" = keep + endif + call s:newwindow() + silent exe "file ".newfile + "silent exe "doautocmd BufReadPre ".newfile + if range != "" + let &ft = ft + let @" = range + silent $put + endif + if register != '' && register != '_' + "exe "let regvalue = @".register + silent exe "$put ".(register =~ '^[@"]$' ? '' : register) + endif + while args != '' + let file = matchstr(args,'^.\{-\}\ze\n') + let args = substitute(args,'^.\{-\}\n','','') + let @" = "## ".file." [".s:parser(file)."]\n" + if a:0 != 1 || a:count + silent $put + else + let &ft = s:filetype(file) + endif + silent exe "$read ".substitute(file,' ','\ ','g') + endwhile + let @" = keep + 1d_ + call s:dobufreadpost() + if (a:0 + (a:count > 0)) > 1 + set ft=conf + endif + endif + 1 + call s:afterload() + if a:bang + write + let name = bufname('%') + " TODO: re-echo the URL in a way that doesn't disappear. Stupid Vim. + silent! bdel + if exists("tabnr") + silent exe "norm! ".tabnr."gt" + endif + endif +endfunction + +function! s:dobufreadpost() + if expand("%") =~ '/\d\+\.\@!' + silent exe "doautocmd BufReadPost ".expand("%") + else + silent exe "doautocmd BufNewFile ".expand("%") + endif +endfunction + +function! s:PastieSwapout(file) + if a:file =~ '?key=' + let b:pastie_fake_login = 1 + endif + exe "Pastie ".a:file +endfunction + +function! s:PastieRead(file) + let lnum = line(".") + silent %s/^!!\(.*\)/\1 #!!/e + exe lnum + set nomodified + let num = matchstr(a:file,'/\@<!/\zs\d\+') + let url = "http://".s:domain."/pastes/".num + "let url = substitute(a:file,'\c/\%(download/\=\|text/\=\)\=$','','') + let url = url."/download" + let result = system('ruby -rnet/http -e "puts Net::HTTP.get_response(URI.parse(%{'.url.'}))[%{Content-Disposition}]"') + let fn = matchstr(result,'filename="\zs.*\ze"') + let &ft = s:filetype(fn) + if &ft =~ '^\%(html\|ruby\)$' && getline(1).getline(2).getline(3) =~ '<%' + set ft=eruby + endif + call s:afterload() +endfunction + +function! s:afterload() + set commentstring=%s\ #!! " + hi def link pastieIgnore Ignore + hi def link pastieNonText NonText + if exists(":match") + hi def link pastieHighlight MatchParen + if version >= 700 + 2match pastieHighlight /^!!\s*.*\|^.\{-\}\ze\s*#!!\s*$/ + else + match pastieHighlight /^!!\s*.*\|^.\{-\}\ze\s*#!!\s*$/ + endif + else + hi def link pastieHighlight Search + syn match pastieHighlight '^.\{-\}\ze\s*#!!\s*$' nextgroup=pastieIgnore skipwhite + syn region pastieHighlight start='^!!\s*' end='$' contains=pastieNonText + endif + syn match pastieIgnore '#!!\ze\s*$' containedin=rubyComment,rubyString + syn match pastieNonText '^!!' containedin=rubyString +endfunction + +function! s:PastieWrite(file) + let parser = s:parser(&ft) + let tmp = tempname() + let num = matchstr(a:file,'/\@<!/\zs\d\+') + if num == '' + let num = 'pastes' + endif + if exists("b:pastie_update") && s:cookies() != '' && num != "" + let url = "/pastes/".num + let method = "_method=put&" + else + let url = "/pastes" + let method = "" + endif + if exists("b:pastie_display_name") + let pdn = "&paste[display_name]=".s:urlencode(b:pastie_display_name) + elseif exists("g:pastie_display_name") + let pdn = "&paste[display_name]=".s:urlencode(g:pastie_display_name) + else + let pdn = "" + endif + silent exe "write ".tmp + let result = "" + let rubycmd = 'obj = Net::HTTP.start(%{'.s:domain.'}){|h|h.post(%{'.url.'}, %q{'.method.'paste[parser]='.parser.pdn.'&paste[authorization]=burger&paste[key]=&paste[body]=} + File.read(%q{'.tmp.'}).gsub(/^(.*?) *#\!\! *#{36.chr}/,%{!\!}+92.chr+%{1}).gsub(/[^a-zA-Z0-9_.-]/n) {|s| %{%%%02x} % s[0]},{%{Cookie} => %{'.s:cookies().'}})}; print obj[%{Location}].to_s+%{ }+obj[%{Set-Cookie}].to_s' + let result = system('ruby -rnet/http -e "'.rubycmd.'"') + let redirect = matchstr(result,'^[^ ]*') + let cookies = matchstr(result,'^[^ ]* \zs.*') + call s:extractcookiesfromheader(cookies) + call delete(tmp) + if redirect =~ '^\w\+://' + set nomodified + let b:pastie_update = 1 + "silent! let @+ = result + silent! let @* = redirect + silent exe "file ".redirect.s:dl_suffix + " TODO: make a proper status message + echo '"'.redirect.'" written' + silent exe "doautocmd BufWritePost ".redirect.s:dl_suffix + else + if redirect == '' + let redirect = "Could not post to ".url + endif + let redirect = substitute(redirect,'^-e:1:\s*','','') + call s:error(redirect) + endif +endfunction + +function! s:error(msg) + echohl Error + echo a:msg + echohl NONE + let v:errmsg = a:msg +endfunction + +function! s:filetype(type) + " Accepts a filename, extension, pastie parser, or vim filetype + let type = tolower(substitute(a:type,'.*\.','','')) + if type =~ '^\%(x\=html\|asp\w*\)$' + return 'html' + elseif type =~ '^\%(eruby\|erb\|rhtml\)$' + return 'eruby' + elseif type =~ '^\%(ruby\|ruby_on_rails\|rb\|rake\|builder\|rjs\|irbrc\)' + return 'ruby' + elseif type == 'js' || type == 'javascript' + return 'javascript' + elseif type == 'c' || type == 'cpp' || type == 'c++' + return 'cpp' + elseif type =~ '^\%(css\|diff\|java\|php\|python\|sql\|sh\|shell-unix-generic\)$' + return type + else + return '' + endif +endfunction + +function! s:parser(type) + let type = s:filetype(a:type) + if type == 'text' || type == '' + return 'plain_text' + elseif type == 'eruby' + return 'html_rails' + elseif type == 'ruby' + return 'ruby_on_rails' + elseif type == 'sh' + return 'shell-unix-generic' + elseif type == 'cpp' + return 'c++' + else + return type + endif +endfunction + +function! s:grabwin() + let ft = (&ft == '' ? expand("%:e") : &ft) + let top = "## ".expand("%:~:.")." [".s:parser(ft)."]\n" + let keep = @" + silent %yank + let file = @" + let @" = keep + if file == "" || file == "\n" + return "" + else + return top.file."\n" + endif +endfunction + +function! s:cookies() + if exists("g:pastie_session_id") + let cookies = "_pastie_session_id=".g:pastie_session_id + else + call s:extractcookies('/') + if !exists("g:pastie_session_id") + if !exists("s:session_warning") + echohl WarningMsg + echo "Warning: could not extract session id" + let s:session_warning = 1 + echohl NONE + endif + let cookies = "" + else + let cookies = "_pastie_session_id=".g:pastie_session_id + endif + endif + if !exists("g:pastie_account") + let rubycmd = '%w(~/.mozilla/firefox ~/.firefox/default ~/.phoenix/default ~/Application\ Data/Mozilla/Firefox/Profiles ~/Library/Application\ Support/Firefox/Profiles)' + let rubycmd = rubycmd . '.each {|dir| Dir[File.join(File.expand_path(dir),%{*})].select {|p| File.exists?(File.join(p,%{cookies.txt}))}.each {|p| File.open(File.join(p,%{cookies.txt})).each_line { |l| a=l.split(9.chr); puts [a[4],a[6]].join(%{ }) if a[0] =~ /pastie\.caboo\.se#{36.chr}/ && Time.now.to_i < a[4].to_i && a[5] == %{account} }}}' + let output = '' + let output = system('ruby -e "'.rubycmd.'"') + if output =~ '\n' && output !~ '-e:' + let output = substitute(output,'\n.*','','') + let g:pastie_account = matchstr(output,' \zs.*') + let g:pastie_account_expires = matchstr(output,'.\{-\}\ze ') + else + let g:pastie_account = '' + endif + endif + if exists("g:pastie_account") && g:pastie_account != "" + " You cannot set this arbitrarily, it must be a valid cookie + let cookies = cookies . (cookies == "" ? "" : "; ") + let cookies = cookies . 'account='.substitute(g:pastie_account,':','%3A','g') + endif + return cookies +endfunction + +function! s:extractcookies(path) + let path = substitute(a:path,'\c^http://'.s:domain,'','') + if path !~ '^/' + let path = '/'.path + endif + let cookie = system('ruby -rnet/http -e "print Net::HTTP.get_response(%{'.s:domain.'},%{'.path.'})[%{Set-Cookie}]"') + if exists("g:pastie_debug") + let g:pastie_cookies_path = path + let g:pastie_cookies = cookie + endif + return s:extractcookiesfromheader(cookie) +endfunction + +function! s:extractcookiesfromheader(cookie) + let cookie = a:cookie + if cookie !~ '-e:' + let session_id = matchstr(cookie,'\<_pastie_session_id=\zs.\{-\}\ze\%([;,]\|$\)') + let account = matchstr(cookie,'\<account=\zs.\{-\}\ze\%([;,]\|$\)') + if session_id != "" + let g:pastie_session_id = session_id + endif + if account != "" + let g:pastie_account = account + let time = matchstr(cookie,'\<[Ee]xpires=\zs\w\w\w,.\{-\}\ze\%([;,]\|$\)') + if time != "" + let g:pastie_account_expires = system('ruby -e "print Time.parse(%{'.time.'}).to_i"') + endif + endif + endif +endfunction + +function! s:latestid() + return system('ruby -rnet/http -e "print Net::HTTP.get_response(URI.parse(%{http://'.s:domain.'/all})).body.match(%r{<a href=.http://'.s:domain.'/(\d+).>View})[1]"') +endfunction + +function! s:urlencode(str) + " Vim 6.2, how did we ever live with you? + return substitute(substitute(a:str,"[\001-\037%&?=\\\\]",'\="%".printf("%02X",char2nr(submatch(0)))','g'),' ','%20','g') +endfunction + +function! s:newwindow() + if !(&modified) && (expand("%") == '' || (version >= 700 && winnr("$") == 1 && tabpagenr("$") == 1)) + enew + else + if g:pastie_destination == 'tab' + tabnew + elseif g:pastie_destination == 'window' + new + else + enew + endif + endif + setlocal noswapfile +endfunction + +" vim:set sw=4 sts=4 et: diff --git a/.config/vim/plugin/templates.vim b/.config/vim/plugin/templates.vim new file mode 100755 index 0000000..b24dfb5 --- /dev/null +++ b/.config/vim/plugin/templates.vim @@ -0,0 +1,105 @@ +" vim:fileencoding=iso-8859-1 +if has("python") +py <<EOF +""" + Templates for VIM + by Phillip Berndt, www.pberndt.com + + + Phillip Berndt, Sat Apr 14 22:20:31 CEST 2007: + Nihil (nihil <at> jabber.ccc.de) reported some problems in his + VIM environment, which inserts a CR after the first character + in templates. He came up with a workaround. Replace the + imap command in the end with + command('imap <unique> ^D ^[:py template_complete()<CR>a') + to make it work. + +""" +import sys +#sys.path.remove("") +from vim import * +from cStringIO import StringIO +import re, os +template_buffer = {} + +def template_complete(): + global template_buffer + + # Check for a template + currentPos = current.window.cursor[1] + template = "" + while currentPos >= 0 and len(current.line) > 0 and not current.line[currentPos].isspace(): + template = current.line[currentPos] + template + currentPos = currentPos - 1 + currentPos = currentPos + 1 + + if template is "": + return + + # Search for that template + fileType = eval("&ft") + if fileType not in template_buffer or template not in template_buffer[fileType]: + if fileType not in template_buffer: + template_buffer[fileType] = {} + searchPath = eval("g:templatePath") + + searchPaths = [ + "%s/%s/%s" % (searchPath, fileType, template), + "%s/%s" % (searchPath, template), + "%s/%s/%s.py" % (searchPath, fileType, template), + "%s/%s.py" % (searchPath, template) + ] + for templateFile in searchPaths: + if not os.access(templateFile, os.F_OK): + continue + try: + if templateFile[-3:] == ".py": + template_buffer[fileType][template] = open(templateFile, "r").read() + else: + template_buffer[fileType][template] = open(templateFile, "r").readlines() + break + except: + continue + else: + template_buffer[fileType][template] = False + if template_buffer[fileType][template] is not False: + # Insert template + indention = re.search("^\s+", current.line) + if indention is None: + indention = "" + else: + indention = indention.group(0) + endOfLine = current.line[current.window.cursor[1] + 1:] + current.line = current.line[:currentPos] + range = current.buffer.range(current.window.cursor[0], current.window.cursor[0]) + + if type(template_buffer[fileType][template]) == str: + # Execute as python code + backup = sys.stdout + sys.stdout = StringIO() + code = template_buffer[fileType][template] + exec code in {}, {"_vim": current, "_command": command} + insert = sys.stdout.getvalue().split("\n") + sys.stdout = backup + else: + insert = template_buffer[fileType][template] + + firstLine = True + sentVar = False + for line in insert: + if line.find("<++>") is not -1: + sentVar = True + if firstLine: + range.append(line) + else: + range.append(indention + line) + firstLine = False + if sentVar: + range.append(endOfLine) + else: + range.append("<++>%s" % endOfLine) + command('normal J') + +command('imap <unique> :py template_complete()<CR>a<C-J>') +EOF +endif diff --git a/.config/vim/syntax/matlab.vim b/.config/vim/syntax/matlab.vim new file mode 100644 index 0000000..4fdce0a --- /dev/null +++ b/.config/vim/syntax/matlab.vim @@ -0,0 +1,359 @@ +" Vim syntax file +" Language: Matlab +" Maintainer: Fabrice Guy <fabrice.guy at gmail dot com> +" Original authors: Mario Eusebio and Preben Guldberg +" Last Change: 2008 Oct 16 : added try/catch/rethrow and class statements +" 2008 Oct 28 : added highlighting for most of Matlab functions + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +syn keyword matlabStatement return function +syn keyword matlabConditional switch case else elseif end if otherwise break continue +syn keyword matlabRepeat do for while +syn keyword matlabStorageClass classdef methods properties events persistent global +syn keyword matlabExceptions try catch rethrow throw + +syn keyword matlabTodo contained TODO NOTE FIXME XXX +syn keyword matlabImport import +" If you do not want these operators lit, uncommment them and the "hi link" below +syn match matlabRelationalOperator "\(==\|\~=\|>=\|<=\|=\~\|>\|<\|=\)" +syn match matlabArithmeticOperator "[-+]" +syn match matlabArithmeticOperator "\.\=[*/\\^]" +syn match matlabLogicalOperator "[&|~]" +syn keyword matlabBoolean true false + +syn match matlabLineContinuation "\.\{3}" + +" String +syn region matlabString start=+'+ end=+'+ oneline + +" If you don't like tabs +syn match matlabTab "\t" + +" Standard numbers +syn match matlabNumber "\<\d\+[ij]\=\>" +" floating point number, with dot, optional exponent +syn match matlabFloat "\<\d\+\(\.\d*\)\=\([edED][-+]\=\d\+\)\=[ij]\=\>" +" floating point number, starting with a dot, optional exponent +syn match matlabFloat "\.\d\+\([edED][-+]\=\d\+\)\=[ij]\=\>" +syn keyword matlabConstant eps Inf NaN pi + + +" Transpose character and delimiters: Either use just [...] or (...) aswell +syn match matlabDelimiter "[][]" +"syn match matlabDelimiter "[][()]" +syn match matlabTransposeOperator "[])a-zA-Z0-9.]'"lc=1 + +syn match matlabSemicolon ";" + +syn match matlabComment "%.*$" contains=matlabTodo,matlabTab +syn region matlabBlockComment start=+%{+ end=+%}+ + + +" trigonometric +syn keyword matlabFunc acos acosd acosh acot acotd acoth acsc acscd acsch asec asecd asech asin asind asinh +syn keyword matlabFunc atan atan2 atand atanh cos cosd cosh cot cotd coth csc cscd csch hypot sec secd +syn keyword matlabFunc sech sin sind sinh tan tand tanh +" exponential +syn keyword matlabFunc exp expm1 log log10 log1p log2 nextpow2 nthroot pow2 reallog realpow realsqrt sqrt +" Complex +syn keyword matlabFunc abs angle complex conj cplxpair imag real sign unwrap +" Rounding and Remainder +syn keyword matlabFunc ceil fix floor idivide mod rem round +"Discrete Math (e.g., Prime Factors) +syn keyword matlabFunc factor factorial gcd isprime lcm nchoosek perms primes rat rats +"Polynomials +syn keyword matlabFunc conv deconv poly polyder polyeig polyfit polyint polyval polyvalm residue roots +"Numeric Types +syn keyword matlabFunc arrayfun cast cat class find intmax intmin intwarning ipermute isa isequal isequalwithequalnans isfinite isinf isnan isnumeric isreal isscalar isvector permute realmax realmin reshape squeeze zeros +"Characters and Strings +syn keyword matlabFunc cellstr char eval findstr isstr regexp sprintf sscanf strcat strcmp strcmpi strings strjust strmatch strread strrep strtrim strvcat +"Structures +syn keyword matlabFunc cell2struct deal fieldnames getfield isfield isstruct orderfields rmfield setfield struct struct2cell structfun +"Cell Arrays +syn keyword matlabFunc cell cell2mat celldisp cellfun cellplot iscell iscellstr mat2cell num2cell +"Function Handles +syn keyword matlabFunc feval func2str functions str2func +"Java Classes and Objects +syn keyword matlabFunc clear depfun exist im2java inmem javaaddpath javaArray javachk Generate javaclasspath javaMethod javaObject javarmpath methodsview usejava which +"Data Type Identification +syn keyword matlabFunc ischar isfloat isinteger isjava islogical isobject validateattributes who whos +"Data type conversion +"Numeric +syn keyword matlabFunc double int8 int16 int32 int64 single typecast uint8 uint16 uint32 uint64 +"String to Numeric +syn keyword matlabFunc base2dec bin2dec hex2dec hex2num str2double str2num unicode2native +"Numeric to String +syn keyword matlabFunc dec2base dec2bin dec2hex int2str mat2str native2unicode num2str +"Other Conversions +syn keyword matlabFunc datestr logical num2hex str2mat +"String Creation +syn keyword matlabFunc blanks +"String Identification +syn keyword matlabFunc isletter isspace isstrprop validatestring +"String Manipulation +syn keyword matlabFunc deblank lower upper +"String Parsing +syn keyword matlabFunc regexpi regexprep regexptranslate strfind strtok +"String Evaluation +syn keyword matlabFunc evalc evalin +"String Comparison +syn keyword matlabFunc strncmp strncmpi +"Bit-wise Functions +syn keyword matlabFunc bitand bitcmp bitget bitmax bitor bitset bitshift bitxor swapbytes +"Logical Functions +syn keyword matlabFunc all and any iskeyword isvarname not or xor +"Predefined Dialog Boxes +syn keyword matlabFunc dialog errordlg export2wsdlg helpdlg inputdlg listdlg msgbox printdlg printpreview questdlg uigetdir uigetfile uigetpref uiopen uiputfile uisave uisetcolor uisetfont waitbar warndlg +"Deploying User Interfaces +syn keyword matlabFunc guidata guihandles movegui openfig +"Developing User Interfaces +syn keyword matlabFunc addpref getappdata getpref ginput guide inspect isappdata ispref rmappdata rmpref setappdata setpref uisetpref waitfor waitforbuttonpress +"User Interface Objects +syn keyword matlabFunc uibuttongroup uicontextmenu uicontrol uimenu uipanel uipushtool uitoggletool uitoolbar menu +"Finding Objects from Callbacks +syn keyword matlabFunc findall findfigs findobj gcbf gcbo +"GUI Utility Functions +syn keyword matlabFunc align getpixelposition listfonts selectmoveresize setpixelposition textwrap uistack +"Controlling Program Execution +syn keyword matlabFunc uiresume uiwait +"Basic Plots and Graphs +syn keyword matlabFunc box errorbar hold loglog plot plot3 plotyy polar semilogx semilogy subplot +"Plotting Tools +syn keyword matlabFunc figurepalette pan plotbrowser plotedit plottools propertyeditor rotate3d showplottool zoom + +"Annotating Plots +syn keyword matlabFunc annotation clabel datacursormode datetick gtext legend line rectangle texlabel title xlabel ylabel zlabel +"Area, Bar, and Pie Plots +syn keyword matlabFunc area bar barh bar3 bar3h pareto pie pie3 +"Contour Plots +syn keyword matlabFunc contour contour3 contourc contourf ezcontour ezcontourf +"Direction and Velocity Plots +syn keyword matlabFunc comet comet3 compass feather quiver quiver3 +"Discrete Data Plots +syn keyword matlabFunc stairs stem stem3 +"Function Plots +syn keyword matlabFunc ezmesh ezmeshc ezplot ezplot3 ezpolar ezsurf ezsurfc fplot +"Histograms +syn keyword matlabFunc hist histc rose +"Polygons and Surfaces +syn keyword matlabFunc convhull cylinder delaunay delaunay3 delaunayn dsearch dsearchn ellipsoid fill fill3 inpolygon pcolor polyarea rectint ribbon slice sphere tsearch tsearchn voronoi waterfall +"Scatter/Bubble Plots +syn keyword matlabFunc plotmatrix scatter scatter3 +"Animation +syn keyword matlabFunc getframe im2frame movie noanimate +"Bit-Mapped Images +syn keyword matlabFunc frame2im image imagesc imfinfo imformats imread imwrite ind2rgb +"Printing +syn keyword matlabFunc frameedit hgexport orient print printopt saveas +"Handle Graphics +syn keyword matlabFunc allchild ancestor copyobj delete gca gco get ishandle propedit set +"Object +syn keyword matlabFunc axes figure hggroup hgtransform light patch +"root object +syn keyword matlabFunc surface text +"Plot Objects +syn keyword matlabFunc clf close closereq drawnow gcf hgload hgsave newplot opengl refresh +"Axes Operations +syn keyword matlabFunc axis cla grid ishold makehgtform +"Operating on Object Properties +syn keyword matlabFunc linkaxes linkprop refreshdata +"Data analysis +"Basic Operations +syn keyword matlabFunc brush cumprod cumsum linkdata prod sort sortrows sum +"Descriptive Statistics +syn keyword matlabFunc corrcoef cov max mean median min mode std var +"Filtering and Convolution +syn keyword matlabFunc conv2 convn detrend filter filter2 +"Interpolation and Regression +syn keyword matlabFunc interp1 interp2 interp3 interpn mldivide mrdivide +"Fourier Transforms +syn keyword matlabFunc fft fft2 fftn fftshift fftw ifft ifft2 ifftn ifftshift +"Derivatives and Integrals +syn keyword matlabFunc cumtrapz del2 diff gradient trapz +"File Operations +syn keyword matlabFunc cd copyfile dir fileattrib filebrowser isdir lookfor ls matlabroot mkdir movefile pwd recycle rehash rmdir toolboxdir type what +"Operating System Interface +syn keyword matlabFunc clipboard computer dos getenv hostid maxNumCompThreads perl setenv system unix winqueryreg +"MATLAB Version and License +syn keyword matlabFunc ismac ispc isstudent isunix javachk license prefdir usejava ver verLessThan version +"Basic Information +syn keyword matlabFunc disp display isempty issparse length ndims numel size +"Elementary Matrices and Arrays +syn keyword matlabFunc blkdiag diag eye freqspace ind2sub linspace logspace meshgrid ndgrid ones rand randn sub2ind +"Array Operations +syn keyword matlabFunc accumarray bsxfun cross dot kron tril triu +"Array Manipulation +syn keyword matlabFunc circshift flipdim fliplr flipud horzcat inline repmat rot90 shiftdim vectorize vertcat +"Specialized Matrices +syn keyword matlabFunc compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson +"Matrix Analysis +syn keyword matlabFunc cond condeig det norm normest null orth rank rcond rref subspace trace +"Linear Equations +syn keyword matlabFunc chol cholinc condest funm ilu inv linsolve lscov lsqnonneg lu luinc pinv qr +"Eigenvalues and Singular Values +syn keyword matlabFunc balance cdf2rdf eig eigs gsvd hess ordeig ordqz ordschur rsf2csf schur sqrtm ss2tf svd svds +"Matrix Logarithms and Exponentials +syn keyword matlabFunc expm logm +"Factorization +syn keyword matlabFunc cholupdate planerot qrdelete qrinsert qrupdate qz +"Interpolation +syn keyword matlabFunc griddata griddata3 griddatan interp1q interpft mkpp padecoef pchip ppval spline unmkpp +"Delaunay Triangulation and Tessellation +syn keyword matlabFunc tetramesh trimesh triplot trisurf +"Convex Hull +syn keyword matlabFunc convhulln +"Voronoi Diagrams +syn keyword matlabFunc voronoin +"Cartesian Coordinate System Conversion +syn keyword matlabFunc cart2pol cart2sph pol2cart sph2cart +"Ordinary Differential Equations (IVP) +syn keyword matlabFunc decic deval ode15i ode23 ode45 ode113 ode15s ode23s ode23t ode23tb odefile odeget odeset odextend +"Delay Differential Equations +syn keyword matlabFunc dde23 ddeget ddesd ddeset +"Boundary Value Problems +syn keyword matlabFunc bvp4c bvp5c bvpget bvpinit bvpset bvpxtend +"Partial Differential Equations +syn keyword matlabFunc pdepe pdeval +"Optimization +syn keyword matlabFunc fminbnd fminsearch fzero optimget optimset +"Numerical Integration (Quadrature) +syn keyword matlabFunc dblquad quad quadgk quadl quadv triplequad +"Specialized Math +syn keyword matlabFunc airy besselh besseli besselj besselk bessely beta betainc betaln ellipj ellipke erf erfc erfcx erfinv erfcinv expint gamma gammainc gammaln legendre psi +"Elementary Sparse Matrices +syn keyword matlabFunc spdiags speye sprand sprandn sprandsym +"Full to Sparse Conversion +syn keyword matlabFunc full sparse spconvert +"Working with Sparse Matrices +syn keyword matlabFunc nnz nonzeros nzmax spalloc spfun spones spparms spy +"Reordering Algorithms +syn keyword matlabFunc amd colamd colperm dmperm ldl randperm symamd symrcm +"Linear Algebra +syn keyword matlabFunc spaugment sprank +"Linear Equations (Iterative Methods) +syn keyword matlabFunc bicg bicgstab cgs gmres lsqr minres pcg qmr symmlq +"Tree Operations +syn keyword matlabFunc etree etreeplot gplot symbfact treelayout treeplot +"Timeseries +"General Purpose +syn keyword matlabFunc getdatasamplesize getqualitydesc timeseries tsprops tstool +"Data Manipulation +syn keyword matlabFunc addsample ctranspose delsample getabstime getinterpmethod getsampleusingtime idealfilter resample setabstime setinterpmethod synchronize transpose +"Event Data +syn keyword matlabFunc addevent delevent gettsafteratevent gettsafterevent gettsatevent gettsbeforeatevent gettsbeforeevent gettsbetweenevents +"Descriptive Statistics +syn keyword matlabFunc iqr + +"Time Series Collections +"General Purpose +syn keyword matlabFunc tscollection +"Data Manipulation +syn keyword matlabFunc addsampletocollection addts delsamplefromcollection gettimeseriesnames removets settimeseriesnames +"Set Functions +syn keyword matlabFunc intersect ismember issorted setdiff setxor union unique +"Date and Time Functions +syn keyword matlabFunc addtodate calendar clock cputime date datenum datevec eomday etime now weekday +"M-File Functions and Scripts +syn keyword matlabFunc addOptional addParamValue addRequired createCopy depdir echo input inputname inputParser mfilename namelengthmax nargchk nargin nargout nargoutchk parse pcode +"script Script M-file description +syn keyword matlabFunc varargin varargout +"Evaluation of Expressions and Functions +syn keyword matlabFunc ans assert builtin pause run script symvar +"Timer Functions +syn keyword matlabFunc isvalid start startat stop timer timerfind timerfindall wait +"Variables and Functions in Memory +syn keyword matlabFunc assignin datatipinfo genvarname isglobal memory mislocked mlock munlock pack +"Control Flow +syn keyword matlabFunc parfor +"Error Handling +syn keyword matlabFunc addCause error ferror getReport last lasterr lasterror lastwarn warning +"Classes and Objects +syn keyword matlabFunc addlistener addprop dynamicprops +"events Display class event names +syn keyword matlabFunc findprop getdisp handle hgsetget inferiorto loadobj metaclass notify saveobj setdisp subsasgn subsindex subsref substruct superiorto +"File Name Construction +syn keyword matlabFunc filemarker fileparts filesep fullfile tempdir tempname +"Opening, Loading, Saving Files +syn keyword matlabFunc daqread filehandle importdata load open save uiimport winopen +"Memory Mapping +syn keyword matlabFunc memmapfile +"Low-Level File I/O +syn keyword matlabFunc fclose feof fgetl fgets fopen fprintf fread frewind fscanf fseek ftell fwrite + +"Text Files +syn keyword matlabFunc csvread csvwrite dlmread dlmwrite textread textscan +"XML Documents +syn keyword matlabFunc xmlread xmlwrite xslt +"Microsoft Excel Functions +syn keyword matlabFunc xlsfinfo xlsread xlswrite +"Lotus 1-2-3 Functions +syn keyword matlabFunc wk1finfo wk1read wk1write +"Common Data Format (CDF) +syn keyword matlabFunc cdfepoch cdfinfo cdfread cdfwrite todatenum +"Flexible Image Transport System +syn keyword matlabFunc fitsinfo fitsread +"Hierarchical Data Format (HDF) +syn keyword matlabFunc hdf hdf5 hdf5info hdf5read hdf5write hdfinfo hdfread hdftool +"Band-Interleaved Data +syn keyword matlabFunc multibandread multibandwrite + + +syn match matlabError "-\=\<\d\+\.\d\+\.[^*/\\^]" +syn match matlabError "-\=\<\d\+\.\d\+[eEdD][-+]\=\d\+\.\([^*/\\^]\)" + +" Define the default highlighting. +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_matlab_syntax_inits") + if version < 508 + let did_matlab_syntax_inits = 1 + command -nargs=+ HiLink hi link <args> + else + command -nargs=+ HiLink hi def link <args> + endif + + HiLink matlabTransposeOperator matlabOperator + HiLink matlabLineContinuation Special + HiLink matlabLabel Label + HiLink matlabConditional Conditional + HiLink matlabRepeat Repeat + HiLink matlabTodo Todo + HiLink matlabString String + HiLink matlabDelimiter Identifier + HiLink matlabTransposeOther Identifier + HiLink matlabNumber Number + HiLink matlabFloat Float + HiLink matlabConstant Constant + HiLink matlabError Error + HiLink matlabImplicit matlabStatement + HiLink matlabStatement Statement + HiLink matlabSemicolon SpecialChar + HiLink matlabComment Comment + HiLink matlabBlockComment Comment + HiLink matlabImport Include + HiLink matlabBoolean Boolean + HiLink matlabStorageClass StorageClass + + HiLink matlabArithmeticOperator matlabOperator + HiLink matlabRelationalOperator matlabOperator + HiLink matlabLogicalOperator matlabOperator + HiLink matlabOperator Operator + HiLink matlabExceptions Exception + HiLink matlabFunc Function + +"optional highlighting + "HiLink matlabIdentifier Identifier + "HiLink matlabTab Error + delcommand HiLink +endif + +let b:current_syntax = "matlab" + +"EOF vim: ts=8 noet tw=100 sw=8 sts=0 diff --git a/.config/vim/templates/changelog/change.py b/.config/vim/templates/changelog/change.py new file mode 100755 index 0000000..ea0e7ca --- /dev/null +++ b/.config/vim/templates/changelog/change.py @@ -0,0 +1,3 @@ +import datetime +print " %s; Phillip Berndt <phillip.berndt@gmail.com>:" % datetime.date.today().strftime("%d. %b %Y") +print " <++>" diff --git a/.config/vim/templates/changelog/rel b/.config/vim/templates/changelog/rel new file mode 100755 index 0000000..4a4c644 --- /dev/null +++ b/.config/vim/templates/changelog/rel @@ -0,0 +1,2 @@ +* <++> +<++> diff --git a/.config/vim/templates/html/$ b/.config/vim/templates/html/$ new file mode 100755 index 0000000..86f8609 --- /dev/null +++ b/.config/vim/templates/html/$ @@ -0,0 +1 @@ +document.getElementById("<++>").<++> diff --git a/.config/vim/templates/html/dl b/.config/vim/templates/html/dl new file mode 100755 index 0000000..c7bff2e --- /dev/null +++ b/.config/vim/templates/html/dl @@ -0,0 +1,6 @@ +<dl> + <dt><++></dt> + <dd><++></dd> + <++> +</dl> +<++> diff --git a/.config/vim/templates/html/dt b/.config/vim/templates/html/dt new file mode 100755 index 0000000..eee603e --- /dev/null +++ b/.config/vim/templates/html/dt @@ -0,0 +1,3 @@ +<dt><++></dt> +<dd><++></dd> +<++> diff --git a/.config/vim/templates/html/em b/.config/vim/templates/html/em new file mode 100755 index 0000000..53f4852 --- /dev/null +++ b/.config/vim/templates/html/em @@ -0,0 +1 @@ +<em><++></em><++> diff --git a/.config/vim/templates/html/form b/.config/vim/templates/html/form new file mode 100755 index 0000000..5985979 --- /dev/null +++ b/.config/vim/templates/html/form @@ -0,0 +1,6 @@ +<form method="<++>" action="<++>"> +<p> + <++> +</p> +</form> +<++> diff --git a/.config/vim/templates/html/html b/.config/vim/templates/html/html new file mode 100755 index 0000000..618a876 --- /dev/null +++ b/.config/vim/templates/html/html @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC + "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title><+title+></title> + <style type="text/css"> + </style> + </head> + <body> + <h1><+title+></h1> + <++> + </body> +</html> diff --git a/.config/vim/templates/html/input b/.config/vim/templates/html/input new file mode 100755 index 0000000..670e334 --- /dev/null +++ b/.config/vim/templates/html/input @@ -0,0 +1,2 @@ +<input type="<++>" name="<++>" /> +<++> diff --git a/.config/vim/templates/html/li b/.config/vim/templates/html/li new file mode 100755 index 0000000..b04522c --- /dev/null +++ b/.config/vim/templates/html/li @@ -0,0 +1,2 @@ +<li><++></li> +<++> diff --git a/.config/vim/templates/html/ol b/.config/vim/templates/html/ol new file mode 100755 index 0000000..119e490 --- /dev/null +++ b/.config/vim/templates/html/ol @@ -0,0 +1,5 @@ +<ol> + <li><++></li> + <++> +</ol> +<++> diff --git a/.config/vim/templates/html/p b/.config/vim/templates/html/p new file mode 100755 index 0000000..92cd897 --- /dev/null +++ b/.config/vim/templates/html/p @@ -0,0 +1,4 @@ +<p> + <++> +</p> +<++> diff --git a/.config/vim/templates/html/script b/.config/vim/templates/html/script new file mode 100755 index 0000000..61aab67 --- /dev/null +++ b/.config/vim/templates/html/script @@ -0,0 +1,4 @@ +<script type="text/javascript"> + <++> +</script> +<++> diff --git a/.config/vim/templates/html/ul b/.config/vim/templates/html/ul new file mode 100755 index 0000000..f65ab78 --- /dev/null +++ b/.config/vim/templates/html/ul @@ -0,0 +1,5 @@ +<ul> + <li><++></li> + <++> +</ul> +<++> diff --git a/.config/vim/templates/php/$ b/.config/vim/templates/php/$ new file mode 100755 index 0000000..86f8609 --- /dev/null +++ b/.config/vim/templates/php/$ @@ -0,0 +1 @@ +document.getElementById("<++>").<++> diff --git a/.config/vim/templates/php/dl b/.config/vim/templates/php/dl new file mode 100755 index 0000000..c7bff2e --- /dev/null +++ b/.config/vim/templates/php/dl @@ -0,0 +1,6 @@ +<dl> + <dt><++></dt> + <dd><++></dd> + <++> +</dl> +<++> diff --git a/.config/vim/templates/php/dt b/.config/vim/templates/php/dt new file mode 100755 index 0000000..eee603e --- /dev/null +++ b/.config/vim/templates/php/dt @@ -0,0 +1,3 @@ +<dt><++></dt> +<dd><++></dd> +<++> diff --git a/.config/vim/templates/php/em b/.config/vim/templates/php/em new file mode 100755 index 0000000..53f4852 --- /dev/null +++ b/.config/vim/templates/php/em @@ -0,0 +1 @@ +<em><++></em><++> diff --git a/.config/vim/templates/php/fore b/.config/vim/templates/php/fore new file mode 100755 index 0000000..5816e79 --- /dev/null +++ b/.config/vim/templates/php/fore @@ -0,0 +1,4 @@ +foreach(<++> as <++> => <++>) +{ + <++> +} diff --git a/.config/vim/templates/php/form b/.config/vim/templates/php/form new file mode 100755 index 0000000..5985979 --- /dev/null +++ b/.config/vim/templates/php/form @@ -0,0 +1,6 @@ +<form method="<++>" action="<++>"> +<p> + <++> +</p> +</form> +<++> diff --git a/.config/vim/templates/php/html b/.config/vim/templates/php/html new file mode 100755 index 0000000..618a876 --- /dev/null +++ b/.config/vim/templates/php/html @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC + "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title><+title+></title> + <style type="text/css"> + </style> + </head> + <body> + <h1><+title+></h1> + <++> + </body> +</html> diff --git a/.config/vim/templates/php/input b/.config/vim/templates/php/input new file mode 100755 index 0000000..670e334 --- /dev/null +++ b/.config/vim/templates/php/input @@ -0,0 +1,2 @@ +<input type="<++>" name="<++>" /> +<++> diff --git a/.config/vim/templates/php/li b/.config/vim/templates/php/li new file mode 100755 index 0000000..b04522c --- /dev/null +++ b/.config/vim/templates/php/li @@ -0,0 +1,2 @@ +<li><++></li> +<++> diff --git a/.config/vim/templates/php/ol b/.config/vim/templates/php/ol new file mode 100755 index 0000000..119e490 --- /dev/null +++ b/.config/vim/templates/php/ol @@ -0,0 +1,5 @@ +<ol> + <li><++></li> + <++> +</ol> +<++> diff --git a/.config/vim/templates/php/p b/.config/vim/templates/php/p new file mode 100755 index 0000000..92cd897 --- /dev/null +++ b/.config/vim/templates/php/p @@ -0,0 +1,4 @@ +<p> + <++> +</p> +<++> diff --git a/.config/vim/templates/php/script b/.config/vim/templates/php/script new file mode 100755 index 0000000..61aab67 --- /dev/null +++ b/.config/vim/templates/php/script @@ -0,0 +1,4 @@ +<script type="text/javascript"> + <++> +</script> +<++> diff --git a/.config/vim/templates/php/ul b/.config/vim/templates/php/ul new file mode 100755 index 0000000..f65ab78 --- /dev/null +++ b/.config/vim/templates/php/ul @@ -0,0 +1,5 @@ +<ul> + <li><++></li> + <++> +</ul> +<++> diff --git a/.config/vim/templates/php/while b/.config/vim/templates/php/while new file mode 100755 index 0000000..0e6e202 --- /dev/null +++ b/.config/vim/templates/php/while @@ -0,0 +1,4 @@ +while(<++>) +{ + <++> +} diff --git a/.config/vim/templates/python/fori b/.config/vim/templates/python/fori new file mode 100755 index 0000000..4fb67c9 --- /dev/null +++ b/.config/vim/templates/python/fori @@ -0,0 +1,2 @@ +for <++> in <++>: + <++> diff --git a/.config/vim/templates/python/gtkt b/.config/vim/templates/python/gtkt new file mode 100755 index 0000000..c8a62c1 --- /dev/null +++ b/.config/vim/templates/python/gtkt @@ -0,0 +1,3 @@ +gtk.threads_enter() +<++> +gtk.threads_leave() diff --git a/.config/vim/templates/python/head b/.config/vim/templates/python/head new file mode 100755 index 0000000..5567fe9 --- /dev/null +++ b/.config/vim/templates/python/head @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# vim:fileencoding=utf-8:ft=python +# + diff --git a/.config/vim/templates/tex/head b/.config/vim/templates/tex/head new file mode 100644 index 0000000..572c2d0 --- /dev/null +++ b/.config/vim/templates/tex/head @@ -0,0 +1,23 @@ +\documentclass{scrartcl} +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage[ngerman]{babel} +\usepackage[automark]{scrpage2} +\pagestyle{scrheadings} + +\ihead{<+links+>} +\chead{\pagemark} +\ohead{\headmark} +\author{Phillip Berndt} +\date{\today{}} +\title{<++>} + + +\begin{document} +\maketitle +\tableofcontents +\newpage + +\section{<++>} + +\end{document} |