work save

This commit is contained in:
royqh1979@gmail.com 2021-10-28 23:46:54 +08:00
parent 317a798cce
commit 19e7143efc
5 changed files with 87 additions and 21 deletions

View File

@ -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);

View File

@ -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)
;
}

View File

@ -10,6 +10,11 @@
#include <QVector>
#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<int> indentStartLines;
bool operator==(const SynRangeState& s2);
};

View File

@ -3,6 +3,15 @@
#include <QFont>
static const QSet<QString> StatementKeyWords {
"if",
"for",
"try",
"catch"
};
const QSet<QString> 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;
}

View File

@ -125,6 +125,7 @@ private:
void unknownProc();
void xorSymbolProc();
void processChar();
void popIndentsByType(QChar indentType);
private:
bool mAsmStart;