summaryrefslogtreecommitdiff
path: root/.config/vim/autoload/omni/cpp/utils.vim
diff options
context:
space:
mode:
Diffstat (limited to '.config/vim/autoload/omni/cpp/utils.vim')
-rw-r--r--.config/vim/autoload/omni/cpp/utils.vim587
1 files changed, 0 insertions, 587 deletions
diff --git a/.config/vim/autoload/omni/cpp/utils.vim b/.config/vim/autoload/omni/cpp/utils.vim
deleted file mode 100644
index 5d74d34..0000000
--- a/.config/vim/autoload/omni/cpp/utils.vim
+++ /dev/null
@@ -1,587 +0,0 @@
-" 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