From 19e7143efcc939f08c5afd1e839c269574efcd9e Mon Sep 17 00:00:00 2001 From: "royqh1979@gmail.com" Date: Thu, 28 Oct 2021 23:46:54 +0800 Subject: [PATCH] work save --- RedPandaIDE/qsynedit/SynEdit.cpp | 42 ++++++++++---------- RedPandaIDE/qsynedit/highlighter/base.cpp | 10 ++++- RedPandaIDE/qsynedit/highlighter/base.h | 7 ++++ RedPandaIDE/qsynedit/highlighter/cpp.cpp | 48 +++++++++++++++++++++++ RedPandaIDE/qsynedit/highlighter/cpp.h | 1 + 5 files changed, 87 insertions(+), 21 deletions(-) diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index 3cc6271b..f9d469fa 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -1368,7 +1368,7 @@ int SynEdit::calcIndentSpaces(int line, const QString& lineText, bool addIndent) { if (!mHighlighter) return 0; - line = std::min(line, line = mLines->count()+1); + line = std::min(line, mLines->count()+1); if (line<=1) return 0; int startLine = line-1; @@ -1382,20 +1382,24 @@ int SynEdit::calcIndentSpaces(int line, const QString& lineText, bool addIndent) startLine -- ; } if (startLine>=1) { - SynRangeState range = mLines->ranges(startLine-1); indentSpaces = leftSpaces(s); if (addIndent) { - int left = range.leftBraces+range.leftBrackets+range.leftParenthesis; - indentSpaces+=left*mTabWidth; - mHighlighter->setState(range); - mHighlighter->setLine(lineText,line); - mHighlighter->nextToEol(); - range = mHighlighter->getRangeState(); - //todo: if line ends with unclosed comment or string - if (s.trimmed().endsWith(':')) + SynRangeState range = mLines->ranges(startLine-1); + if ((!range.indentStartLines.isEmpty() + && range.indentStartLines.back() == startLine-1) + || (s.trimmed().endsWith(':')) + ) { indentSpaces += mTabWidth; - int right = range.rightBraces+range.rightBrackets+range.leftParenthesis; - indentSpaces-=right*mTabWidth; + } + mHighlighter->setState(range); + mHighlighter->setLine(lineText,line-1); + mHighlighter->nextToEol(); + SynRangeState newRange = mHighlighter->getRangeState(); + while (!newRange.indentStartLines.isEmpty() && newRange.indentStartLines.back()==line-1) { + newRange.indentStartLines.pop_back(); + } + if (newRange.indentStartLines.length() < range.indentStartLines.length()) + indentSpaces-=mTabWidth; } } return std::max(0,indentSpaces); @@ -1921,20 +1925,14 @@ void SynEdit::insertLine(bool moveCaret) QString Temp = lineText(); QString Temp2 = Temp; QString Temp3; - int SpaceCount2; PSynHighlighterAttribute Attr; // This is sloppy, but the Right Thing would be to track the column of markers // too, so they could be moved depending on whether they are after the caret... int InsDelta = (mCaretX == 1)?1:0; - int Len = Temp.length(); QString leftLineText = lineText().mid(0, mCaretX - 1); QString rightLineText = lineText().mid(mCaretX-1); bool notInComment=true; - if (getHighlighterAttriAtRowCol(BufferCoord{leftLineText.length(), mCaretY}, - leftLineText, Attr)) { - notInComment = (Attr != mHighlighter->commentAttribute()); - } properSetLine(mCaretY-1,leftLineText); //update range stated for line mCaretY if (mHighlighter) { @@ -1946,8 +1944,12 @@ void SynEdit::insertLine(bool moveCaret) mHighlighter->setLine(leftLineText, mCaretY-1); mHighlighter->nextToEol(); mLines->setRange(mCaretY-1,mHighlighter->getRangeState()); + notInComment = !mHighlighter->isLastLineCommentNotFinished( + mHighlighter->getRangeState().state) + && !mHighlighter->isLastLineStringNotFinished( + mHighlighter->getRangeState().state); } - int indentSpaces = calcIndentSpaces(mCaretY, + int indentSpaces = calcIndentSpaces(mCaretY+1, rightLineText,mOptions.testFlag(eoAddIndent) && notInComment); if (mOptions.testFlag(eoAutoIndent)) { @@ -1962,7 +1964,7 @@ void SynEdit::insertLine(bool moveCaret) SynSelectionMode::smNormal); //insert new line in middle of "{" and "}" if (notInComment && leftLineText.endsWith('{') && rightLineText.startsWith('}')) { - indentSpaces = calcIndentSpaces(mCaretY, "" , mOptions.testFlag(eoAddIndent) + indentSpaces = calcIndentSpaces(mCaretY+1, "" , mOptions.testFlag(eoAddIndent) && notInComment); indentSpacesForRightLineText = GetLeftSpacing(indentSpaces,true); mLines->insert(mCaretY, indentSpacesForRightLineText); diff --git a/RedPandaIDE/qsynedit/highlighter/base.cpp b/RedPandaIDE/qsynedit/highlighter/base.cpp index f3c0c957..ca92d70b 100644 --- a/RedPandaIDE/qsynedit/highlighter/base.cpp +++ b/RedPandaIDE/qsynedit/highlighter/base.cpp @@ -215,5 +215,13 @@ bool SynRangeState::operator==(const SynRangeState &s2) && (spaceState == s2.spaceState) && (braceLevel == s2.braceLevel) && (bracketLevel == s2.bracketLevel) - && (parenthesisLevel == s2.parenthesisLevel); + && (parenthesisLevel == s2.parenthesisLevel) + && (leftBraces == s2.leftBraces) + && (leftParenthesis = s2.leftParenthesis) + && (leftBrackets == s2.leftBrackets) + && (rightBraces == s2.rightBraces) + && (rightParenthesis = s2.rightParenthesis) + && (rightBrackets == s2.rightBrackets) + && (indents == s2.indents) + ; } diff --git a/RedPandaIDE/qsynedit/highlighter/base.h b/RedPandaIDE/qsynedit/highlighter/base.h index 4bff7b11..b55351ab 100644 --- a/RedPandaIDE/qsynedit/highlighter/base.h +++ b/RedPandaIDE/qsynedit/highlighter/base.h @@ -10,6 +10,11 @@ #include #include "../Types.h" +constexpr QChar BraceIndentType('{'); +constexpr QChar ParenthesisIndentType('('); +constexpr QChar BracketIndentType('['); +constexpr QChar StatementIndentType('K'); + struct SynRangeState { int state; int spaceState; @@ -22,6 +27,8 @@ struct SynRangeState { int rightBrackets; int leftParenthesis; int rightParenthesis; + QString indents; + QVector indentStartLines; bool operator==(const SynRangeState& s2); }; diff --git a/RedPandaIDE/qsynedit/highlighter/cpp.cpp b/RedPandaIDE/qsynedit/highlighter/cpp.cpp index bcbaf8e5..3a6adcf6 100644 --- a/RedPandaIDE/qsynedit/highlighter/cpp.cpp +++ b/RedPandaIDE/qsynedit/highlighter/cpp.cpp @@ -3,6 +3,15 @@ #include +static const QSet StatementKeyWords { + "if", + "for", + "try", + "catch" +}; + + + const QSet SynEditCppHighlighter::Keywords { "and", "and_eq", @@ -366,6 +375,7 @@ void SynEditCppHighlighter::braceCloseProc() } else { mRange.rightBraces++ ; } + popIndentsByType(BraceIndentType); } void SynEditCppHighlighter::braceOpenProc() @@ -379,6 +389,15 @@ void SynEditCppHighlighter::braceOpenProc() } mRange.braceLevel += 1; mRange.leftBraces++; + if (!mRange.indents.isEmpty() && mRange.indents.back() == StatementIndentType) { + // if last indent is started by 'if' 'for' etc + // just replace it + mRange.indents.replace(mRange.indents.length()-1,1,BraceIndentType); + mRange.indentStartLines.replace(mRange.indents.length()-1,mLineNumber); + } else { + mRange.indents.append(BraceIndentType); + mRange.indentStartLines.append(mLineNumber); + } } void SynEditCppHighlighter::colonProc() @@ -520,6 +539,10 @@ void SynEditCppHighlighter::identProc() mRun=wordEnd; if (isKeyword(word)) { mTokenId = TokenKind::Key; + if (StatementKeyWords.contains(word)) { + mRange.indents.append(StatementIndentType); + mRange.indentStartLines.append(mLineNumber); + } } else { mTokenId = TokenKind::Identifier; } @@ -885,6 +908,7 @@ void SynEditCppHighlighter::roundCloseProc() } else { mRange.rightParenthesis++ ; } + popIndentsByType(ParenthesisIndentType); } void SynEditCppHighlighter::roundOpenProc() @@ -894,6 +918,8 @@ void SynEditCppHighlighter::roundOpenProc() mExtTokenId = ExtTokenKind::RoundOpen; mRange.parenthesisLevel++; mRange.leftParenthesis++; + mRange.indents.append(ParenthesisIndentType); + mRange.indentStartLines.append(mLineNumber); } void SynEditCppHighlighter::semiColonProc() @@ -903,6 +929,10 @@ void SynEditCppHighlighter::semiColonProc() mExtTokenId = ExtTokenKind::SemiColon; if (mRange.state == RangeState::rsAsm) mRange.state = RangeState::rsUnknown; + if (mRange.indents.back() == StatementIndentType) { + mRange.indents.remove(mRange.indents.length()-1,1); + mRange.indentStartLines.pop_back(); + } } void SynEditCppHighlighter::slashProc() @@ -961,6 +991,7 @@ void SynEditCppHighlighter::squareCloseProc() } else { mRange.rightBrackets++ ; } + popIndentsByType(BracketIndentType); } void SynEditCppHighlighter::squareOpenProc() @@ -970,6 +1001,8 @@ void SynEditCppHighlighter::squareOpenProc() mExtTokenId = ExtTokenKind::SquareOpen; mRange.bracketLevel++; mRange.leftBrackets++; + mRange.indents.append(BracketIndentType); + mRange.indentStartLines.append(mLineNumber); } void SynEditCppHighlighter::starProc() @@ -1333,6 +1366,19 @@ void SynEditCppHighlighter::processChar() } } +void SynEditCppHighlighter::popIndentsByType(QChar indentType) +{ + while (!mRange.indents.isEmpty() && mRange.indents.back()!=indentType) { + mRange.indents.remove(mRange.indents.length()-1,1); + mRange.indentStartLines.pop_back(); + } + if (!mRange.indents.isEmpty()) { + mRange.indents.remove(mRange.indents.length()-1,1); + mRange.indentStartLines.pop_back(); + } + +} + bool SynEditCppHighlighter::getTokenFinished() const { if (mTokenId == TokenKind::Comment @@ -1576,6 +1622,8 @@ void SynEditCppHighlighter::resetState() mRange.rightBraces = 0; mRange.rightBrackets = 0; mRange.rightParenthesis = 0; + mRange.indents = ""; + mRange.indentStartLines.clear(); mAsmStart = false; } diff --git a/RedPandaIDE/qsynedit/highlighter/cpp.h b/RedPandaIDE/qsynedit/highlighter/cpp.h index 88ef6066..8fa45a8f 100644 --- a/RedPandaIDE/qsynedit/highlighter/cpp.h +++ b/RedPandaIDE/qsynedit/highlighter/cpp.h @@ -125,6 +125,7 @@ private: void unknownProc(); void xorSymbolProc(); void processChar(); + void popIndentsByType(QChar indentType); private: bool mAsmStart;