diff --git a/NEWS.md b/NEWS.md index c511e888..dbeeb519 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,7 @@ Red Panda C++ Version 0.13.3 - fix: If project's compiler set is not the same with the default compiler set, auto openned project's file will use wrong compiler set to do syntax check. - change: symbols that exactly match are sorted to the front in the code suggestion popup list - fix: symbols defind locally should be sorted to the front in the code suggestion popup list + - fix: when show function tips, can't correctly calcuate the current position in the function param list Red Panda C++ Version 0.13.2 - fix: "delete and exit" button in the environtment / folder option page doesn't work correctly diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 2f626896..1ed45bcb 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -3182,152 +3182,128 @@ void Editor::updateFunctionTip() pMainWindow->functionTip()->hide(); return; } - BufferCoord caretPos = caretXY(); - ContentsCoord curPos = fromBufferCoord(caretPos); - ContentsCoord cursorPos = curPos; - int nBraces = 0; - int nCommas = 0; - int FMaxScanLength = 500; - // Find out where the function ends... - for (int i=0;ifunctionTip()->hide(); - return; - // Opening brace, increase count - } - QChar nextCh = *(curPos+1); - if (ch == '(') { - nBraces++; - // Ending brace, decrease count or success (found ending)! - } else if (ch == ')') { - nBraces--; - if (nBraces == -1) + }); + const int maxLines=20; + BufferCoord caretPos = caretXY(); + int currentLine = caretPos.Line-1; + int currentChar = caretPos.Char-1; + BufferCoord functionNamePos{-1,-1}; + bool foundFunctionStart = false; + int parenthesisLevel = 0; + int braceLevel = 0; + int bracketLevel = 0; + int paramsCount = 1; + int currentParamPos = 1; + if (currentLine>=lines()->count()) + return; + while (currentLine>=0) { + QString line = lines()->getString(currentLine); + if (currentLine!=caretPos.Line-1) + currentChar = line.length(); + QStringList tokens; + QList positions; + if (currentLine==0) + highlighter()->resetState(); + else + highlighter()->setState( + lines()->ranges(currentLine-1)); + highlighter()->setLine(line,currentLine); + while(!highlighter()->eol()) { + int start = highlighter()->getTokenPos(); + QString token = highlighter()->getToken(); + PSynHighlighterAttribute attr = highlighter()->getTokenAttribute(); + if (start>=currentChar) break; - // Single line comments - } else if ((ch == '/') && (nextCh == '/')) { - // Walk up to an enter sequence - while (ch!='\0' && ch!='\n') { - curPos+=1; - ch = *curPos; - } - - - // Skip linebreak; - if (ch == '\n') { - curPos += 1; - } - } else if ((ch == '/') && (nextCh == '*')) { - - // Walk up to "*/" - while (ch!='\0' && !(ch=='*' && nextCh=='/')) { - curPos += 1; - ch = *curPos; - nextCh = *(curPos+1); - } - - // Step over - if (ch!='\0') { - curPos+=1; - } - } else - curPos += 1; - } - - //qDebug()<<"first pass:"<functionTip()->hide(); - return; - } - - //ContentsCoord FFunctionEnd = curPos; - - int paramPos = 0; - bool paramPosFounded = false; - // We've stopped at the ending ), start walking backwards )*here* with nBraces = -1 - for (int i=0;ifunctionTip()->hide(); - return; - } - if (prevCh == '/' && ch == '*' ) { - curPos -= 1; + if (attr != highlighter()->commentAttribute() + && attr!=highlighter()->whitespaceAttribute()) { + if (foundFunctionStart) { + if (attr!=highlighter()->identifierAttribute()) + return; // not a function + functionNamePos.Line = currentLine+1; + functionNamePos.Char = start+1; break; } + tokens.append(token); + positions.append(start); + } else if (attr == highlighter()->commentAttribute() + && currentLine == caretPos.Line-1 && start=caretPos.Char) { + return; // in comment, do nothing } - } else if (ch == ')') { - nBraces++ ; - } else if (ch == '(') { - nBraces--; - if (nBraces == -1) // found it! - break;; - } else if (ch == ',') { - if (nBraces == 0) { - if (curPos <= cursorPos && !paramPosFounded) { - paramPos = nCommas; - paramPosFounded = true; + highlighter()->next(); + } + if (!foundFunctionStart) { + for (int i=tokens.length()-1;i>=0;i--) { + if (braceLevel>0) { + if (tokens[i]=="{") { + braceLevel--; + } else if (tokens[i]=="}") { + braceLevel++; + } + } else if (bracketLevel>0) { + if (tokens[i]=="[") { + braceLevel--; + } else if (tokens[i]=="]") { + braceLevel++; + } + }else if (parenthesisLevel>0){ + if (tokens[i]==")") { + parenthesisLevel++; + } else if (tokens[i]=="(") { + parenthesisLevel--; + } + } else { + qDebug()<0) { + functionNamePos.Line = currentLine+1; + functionNamePos.Char = positions[i-1]+1; + } + break; + } else if (tokens[i]=="[") { + //we are not in a function call + return; + } else if (tokens[i]=="{") { + //we are not in a function call + return; + } else if (tokens[i]==";") { + //we are not in a function call + return; + } else if (tokens[i]==")") { + parenthesisLevel++; + } else if (tokens[i]=="}") { + braceLevel++; + } else if (tokens[i]=="}") { + bracketLevel++; + } else if (tokens[i]==",") { + paramsCount++; + } } - nCommas++; } } - curPos -= 1; - if (curPos.atStart()) + if (functionNamePos.Char>=0) + break; + currentLine--; + if (caretPos.Line-currentLine>maxLines) break; } - if (paramPosFounded) - paramPos = nCommas - paramPos; - - //qDebug()<<"second pass:"<functionTip()->hide(); + isFunction = functionNamePos.Char>=0; + currentParamPos = paramsCount-1; + if (!isFunction) return; - } - - //ContentsCoord FFunctionStart = curPos; - - // Skip blanks - while (!curPos.atStart()) { - QChar prevCh = *(curPos-1); - if (prevCh == '\t' || prevCh == ' ' - || prevCh == '\n') { - curPos-=1; - } else { - break; - } - } - - ContentsCoord prevPos = curPos-1; - if (prevPos.atStart()) { - pMainWindow->functionTip()->hide(); - return; - } - // Get the name of the function we're about to show - BufferCoord FuncStartXY = prevPos.toBufferCoord(); - QString token; - PSynHighlighterAttribute HLAttr; - if (!getHighlighterAttriAtRowCol(FuncStartXY,token,HLAttr)) { - pMainWindow->functionTip()->hide(); - return; - } - if (HLAttr != highlighter()->identifierAttribute()) { - pMainWindow->functionTip()->hide(); - return; - } - BufferCoord pWordBegin, pWordEnd; - QString s = getWordAtPosition(this, FuncStartXY, pWordBegin,pWordEnd, WordPurpose::wpInformation); + QString s = getWordAtPosition(this, functionNamePos, pWordBegin,pWordEnd, WordPurpose::wpInformation); // qDebug()<functionTip()->clearTips(); QList statements=mParser->getListOfFunctions(mFilename, s, - FuncStartXY.Line); + functionNamePos.Line); foreach (const PStatement statement, statements) { pMainWindow->functionTip()->addTip( @@ -3365,9 +3341,9 @@ void Editor::updateFunctionTip() pMainWindow->functionTip()->move(mapToGlobal(p)); pMainWindow->functionTip()->setFunctioFullName(s); - pMainWindow->functionTip()->guessFunction(nCommas); + pMainWindow->functionTip()->guessFunction(paramsCount-1); pMainWindow->functionTip()->setParamIndex( - paramPos + currentParamPos ); cancelHint(); pMainWindow->functionTip()->show();