diff --git a/NEWS.md b/NEWS.md index b1cdf96e..68586972 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ Red Panda C++ Version 2.12 - fix: Can't correctly load project's custom compile options, if it contains more than one line contents. - fix: Crash when create or open txt files in project. + - enhancement: Code folding for #if/#endif + - enhancement: When folding "if", don't fold "else"; Red Panda C++ Version 2.11 diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 4e34a4f9..2f9d4b08 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -4797,6 +4797,7 @@ void Editor::checkSyntaxInBack() pMainWindow->checkSyntaxInBack(this); } + const PCppParser &Editor::parser() const { return mParser; diff --git a/libs/qsynedit/qsynedit/painter.cpp b/libs/qsynedit/qsynedit/painter.cpp index ae0a6538..76c6bd5b 100644 --- a/libs/qsynedit/qsynedit/painter.cpp +++ b/libs/qsynedit/qsynedit/painter.cpp @@ -195,10 +195,10 @@ void QSynEditPainter::paintGutter(const QRect& clip) rcFold.top() + rcFold.height() / 2); } // Any fold ranges beginning on this line? - PCodeFoldingRange FoldRange = edit->foldStartAtLine(vLine); - if (FoldRange) { + PCodeFoldingRange foldRange = edit->foldStartAtLine(vLine); + if (foldRange) { // Draw the bottom part of a line - if (!FoldRange->collapsed) { + if (!foldRange->collapsed) { x = rcFold.left() + (rcFold.width() / 2); painter->drawLine(x, rcFold.top() + rcFold.height() / 2, x, rcFold.bottom()); @@ -220,7 +220,7 @@ void QSynEditPainter::paintGutter(const QRect& clip) rcFold.left() + 2, rcFold.top() + (rcFold.height() / 2 ), rcFold.right() - 2, rcFold.top() + (rcFold.height() / 2 )); // Paint vertical line of plus sign - if (FoldRange->collapsed) { + if (foldRange->collapsed) { x = rcFold.left() + (rcFold.width() / 2); painter->drawLine(x, rcFold.top() + 2, x, rcFold.bottom() - 2); @@ -1047,7 +1047,7 @@ void QSynEditPainter::paintLines() // Paint folding foldRange = edit->foldStartAtLine(vLine); if ((foldRange) && foldRange->collapsed) { - sFold = edit->syntaxer()->foldString(); + sFold = edit->syntaxer()->foldString(""); nFold = edit->stringColumns(sFold,edit->mDocument->lineColumns(vLine-1)); attr = edit->mSyntaxer->symbolAttribute(); getBraceColorAttr(edit->mSyntaxer->getState().braceLevel,attr); diff --git a/libs/qsynedit/qsynedit/qsynedit.cpp b/libs/qsynedit/qsynedit/qsynedit.cpp index 3b9adfca..d4f43bf9 100644 --- a/libs/qsynedit/qsynedit/qsynedit.cpp +++ b/libs/qsynedit/qsynedit/qsynedit.cpp @@ -349,7 +349,7 @@ int QSynEdit::maxScrollWidth() const { int maxLen = mDocument->lengthOfLongestLine(); if (syntaxer()) - maxLen = maxLen+stringColumns(syntaxer()->foldString(),maxLen); + maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen); if (mOptions.testFlag(eoScrollPastEol)) return std::max(maxLen ,1); else @@ -1921,7 +1921,7 @@ QString QSynEdit::getDisplayStringAtLine(int line) const QString s = mDocument->getLine(line-1); PCodeFoldingRange foldRange = foldStartAtLine(line); if ((foldRange) && foldRange->collapsed) { - return s+syntaxer()->foldString(); + return s+syntaxer()->foldString(""); } return s; } @@ -2332,7 +2332,7 @@ void QSynEdit::insertLine(bool moveCaret) if (mCaretX>lineText().length()+1) { PCodeFoldingRange foldRange = foldStartAtLine(mCaretY); if ((foldRange) && foldRange->collapsed) { - QString s = Temp+syntaxer()->foldString(); + QString s = Temp+syntaxer()->foldString(""); if (mCaretX > s.length()) { if (!mUndoing) { addCaretToUndo(); @@ -3575,7 +3575,10 @@ void QSynEdit::findSubFoldRange(PCodeFoldingRanges topFoldRanges, PCodeFoldingRa for (int i=0; iblockEnded(line);i++) { // Stop the recursion if we find a closing char, and return to our parent if (parent) { - parent->toLine = line + 1; + if (mDocument->blockStarted(line)>0) + parent->toLine = line; + else + parent->toLine = line + 1; parent = parent->parent.lock(); if (!parent) { parentFoldRanges = topFoldRanges; @@ -4547,7 +4550,7 @@ QString QSynEdit::selText() const PCodeFoldingRange foldRange = foldStartAtLine(blockEnd().line); QString s = mDocument->getLine(Last); if ((foldRange) && foldRange->collapsed && ColTo>s.length()) { - s=s+syntaxer()->foldString(); + s=s+syntaxer()->foldString(""); if (ColTo>s.length()) { Last = foldRange->toLine-1; ColTo = mDocument->getLine(Last).length()+1; @@ -4626,7 +4629,7 @@ QStringList QSynEdit::getContent(BufferCoord startPos, BufferCoord endPos, Selec PCodeFoldingRange foldRange = foldStartAtLine(endPos.line); QString s = mDocument->getLine(Last); if ((foldRange) && foldRange->collapsed && ColTo>s.length()) { - s=s+syntaxer()->foldString(); + s=s+syntaxer()->foldString(""); if (ColTo>s.length()) { Last = foldRange->toLine-1; ColTo = mDocument->getLine(Last).length()+1; @@ -4701,7 +4704,7 @@ QString QSynEdit::displayLineText() QString s= mDocument->getLine(mCaretY - 1); PCodeFoldingRange foldRange = foldStartAtLine(mCaretY); if ((foldRange) && foldRange->collapsed) { - return s+syntaxer()->foldString(); + return s+syntaxer()->foldString(""); } return s; } @@ -5293,7 +5296,7 @@ void QSynEdit::doDeleteText(BufferCoord startPos, BufferCoord endPos, SelectionM PCodeFoldingRange foldRange = foldStartAtLine(endPos.line); QString s = mDocument->getLine(endPos.line-1); if ((foldRange) && foldRange->collapsed && endPos.ch>s.length()) { - QString newS=s+syntaxer()->foldString(); + QString newS=s+syntaxer()->foldString(""); if ((startPos.ch<=s.length() || startPos.linenewS.length() ) { //selection has whole block @@ -6690,7 +6693,7 @@ void QSynEdit::setBlockEnd(BufferCoord value) } else { int maxLen = mDocument->lengthOfLongestLine(); if (syntaxer()) - maxLen = maxLen+stringColumns(syntaxer()->foldString(),maxLen); + maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen); value.ch = minMax(value.ch, 1, maxLen+1); } if (value.ch != mBlockEnd.ch || value.line != mBlockEnd.line) { @@ -6798,7 +6801,7 @@ void QSynEdit::setBlockBegin(BufferCoord value) } else { int maxLen = mDocument->lengthOfLongestLine(); if (syntaxer()) - maxLen = maxLen+stringColumns(syntaxer()->foldString(),maxLen); + maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen); value.ch = minMax(value.ch, 1, maxLen+1); } if (selAvail()) { diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp index 189b2965..97c8a86d 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp @@ -373,7 +373,8 @@ void CppSyntaxer::braceCloseProc() mTokenId = TokenId::Symbol; if (mRange.state == RangeState::rsAsmBlock) { mRange.state = rsUnknown; - } + } else if (mRange.state == RangeState::rsDefineRemaining) + return; mRange.braceLevel -= 1; mRange.blockLevel -= 1; @@ -396,7 +397,9 @@ void CppSyntaxer::braceOpenProc() if (mRange.state == RangeState::rsAsm) { mRange.state = RangeState::rsAsmBlock; mAsmStart = true; - } + } else if (mRange.state == RangeState::rsDefineRemaining) + return; + mRange.braceLevel += 1; mRange.blockLevel += 1; mRange.blockStarted++; @@ -451,8 +454,25 @@ void CppSyntaxer::directiveProc() } if (directive == "define") { mRange.state = RangeState::rsDefineIdentifier; - } else + } else { mRange.state = RangeState::rsUnknown; + if (directive=="if" + || directive=="ifdef" + || directive=="ifndef" + ) { + mRange.blockLevel++; + mRange.blockStarted=1; + } else if (directive=="else" + || directive=="elif" + || directive=="elifdef" + || directive=="elifndef") { + mRange.blockStarted=1; + mRange.blockEnded=1; + } else if (directive=="endif") { + mRange.blockLevel--; + mRange.blockEnded=1; + } + } } void CppSyntaxer::defineIdentProc() @@ -1638,8 +1658,10 @@ QSet CppSyntaxer::keywords() const return set; } -QString CppSyntaxer::foldString() +QString CppSyntaxer::foldString(QString endLine) { + if (endLine.trimmed().startsWith("#")) + return "..."; return "...}"; } diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.h b/libs/qsynedit/qsynedit/syntaxer/cpp.h index 6ce7f9b9..20281428 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.h +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.h @@ -201,7 +201,7 @@ public: // SynHighlighter interface public: - QString foldString() override; + QString foldString(QString startLine) override; const QSet &customTypeKeywords() const; void setCustomTypeKeywords(const QSet &newCustomTypeKeywords); diff --git a/libs/qsynedit/qsynedit/syntaxer/syntaxer.cpp b/libs/qsynedit/qsynedit/syntaxer/syntaxer.cpp index b054fa80..5610fcc3 100644 --- a/libs/qsynedit/qsynedit/syntaxer/syntaxer.cpp +++ b/libs/qsynedit/qsynedit/syntaxer/syntaxer.cpp @@ -98,7 +98,7 @@ QSet Syntaxer::keywords() const return QSet(); } -QString Syntaxer::foldString() +QString Syntaxer::foldString(QString startLine) { return " ... }"; } diff --git a/libs/qsynedit/qsynedit/syntaxer/syntaxer.h b/libs/qsynedit/qsynedit/syntaxer/syntaxer.h index a128c65e..54c6324a 100644 --- a/libs/qsynedit/qsynedit/syntaxer/syntaxer.h +++ b/libs/qsynedit/qsynedit/syntaxer/syntaxer.h @@ -173,7 +173,7 @@ public: virtual QString languageName() = 0; virtual ProgrammingLanguage language() = 0; - virtual QString foldString(); + virtual QString foldString(QString startLine); virtual bool supportBraceLevel(); virtual bool isSpaceChar(const QChar& ch);