?? items.vim
字號:
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 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) let result = omni#cpp#utils#CreateTypeInfo(substitute(tagItem.typeref, '\w\+:', '', 'g')) endif else 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 endif endif return resultendfunc" Get the type info string from the returned type of functionfunction! 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 resultendfunc" Resolve a symbol, return a tagItem" Gets the first symbol found in the context stackfunction! 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 tagItemendfunc" Return if the tag item represent an unnamed typefunction! 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 bResultendfunc" Search the declaration of a variable and return the type infofunction! 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 searchdecl(a:szVariable, 0, 1)==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 resultendfunc" Search a declaration" @return" - tokens of the current instruction if success" - empty list if failurefunction! s:SearchDecl(szVariable) let result = {} let originalPos = getpos('.') let searchResult = searchdecl(a:szVariable, 0, 1) 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 resultendfunc" 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 instructionfunction! s:ExtractTypeInfoFromDecl(tokens) return omni#cpp#utils#ExtractTypeInfoFromTokens(a:tokens)endfunc" Convert tokens to stringfunction! 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 stringfunction! 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 stringfunction! 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 tokensfunction! 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -