diff --git a/NEWS.md b/NEWS.md index eef7dd6f..2da0c0e0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +Version 0.7.5 + - enhancement: more accurate auto indent calculation + - change: remove "add indent" option in the editor general options widget ( It's merged with "auto indent" option) + Version 0.7.4 - fix: when debug a project, and have breakpoints that not in opened editors, dev-cpp will crash - fix: when a file is parsing in background, exit dev-cpp will crash diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index cd20d4f8..ae5e9a6c 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -3638,7 +3638,6 @@ void Editor::applySettings() eoRightMouseMovesCursor | eoScrollByOneLess | eoTabIndent | eoHideShowScrollbars; //options - options.setFlag(eoAddIndent,pSettings->editor().addIndent()); options.setFlag(eoAutoIndent,pSettings->editor().autoIndent()); options.setFlag(eoTabsToSpaces,pSettings->editor().tabToSpaces()); diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index 5c2a3623..7036430c 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -112,7 +112,7 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent) mBlockBegin.Char = 1; mBlockBegin.Line = 1; mBlockEnd = mBlockBegin; - mOptions = eoAutoIndent | eoAddIndent + mOptions = eoAutoIndent | eoDragDropEditing | eoEnhanceEndKey | eoTabIndent | eoGroupUndo | eoKeepCaretX | eoSelectWordByDblClick; @@ -1386,13 +1386,29 @@ int SynEdit::calcIndentSpaces(int line, const QString& lineText, bool addIndent) indentSpaces = leftSpaces(s); if (addIndent) { SynRangeState rangePreceeding = mLines->ranges(startLine-1); - if (!rangePreceeding.lastMatchingIndent.isNull()) { + if (!rangePreceeding.matchingIndents.isEmpty()) { // find the indent's start line, and use it's indent as the default indent; + QString matchingIndents = rangePreceeding.matchingIndents; int l = startLine-1; + int i = 0; + int len = matchingIndents.length(); while (l>=1) { SynRangeState range = mLines->ranges(l-1); - if (range.indents.mid(range.firstIndentThisLine).contains(rangePreceeding.lastMatchingIndent)) { + QString newIndents = range.indents.mid(range.firstIndentThisLine); + while (i=0) { + newIndents.truncate(idx); + } else { + break; + } + i++; + } + if (i>=len) { indentSpaces = leftSpaces(mLines->getString(l-1)); + if (newIndents.length()>0) + indentSpaces+=mTabWidth; break; } l--; @@ -1962,7 +1978,7 @@ void SynEdit::insertLine(bool moveCaret) mHighlighter->getRangeState().state); } int indentSpaces = calcIndentSpaces(mCaretY+1, - rightLineText,mOptions.testFlag(eoAddIndent) + rightLineText,mOptions.testFlag(eoAutoIndent) && notInComment); if (mOptions.testFlag(eoAutoIndent)) { rightLineText=TrimLeft(rightLineText); @@ -1976,7 +1992,7 @@ void SynEdit::insertLine(bool moveCaret) SynSelectionMode::smNormal); //insert new line in middle of "{" and "}" if (notInComment && leftLineText.endsWith('{') && rightLineText.startsWith('}')) { - indentSpaces = calcIndentSpaces(mCaretY+1, "" , mOptions.testFlag(eoAddIndent) + indentSpaces = calcIndentSpaces(mCaretY+1, "" , mOptions.testFlag(eoAutoIndent) && notInComment); indentSpacesForRightLineText = GetLeftSpacing(indentSpaces,true); mLines->insert(mCaretY, indentSpacesForRightLineText); @@ -2456,21 +2472,47 @@ void SynEdit::doAddChar(QChar AChar) } mUndoList->BeginBlock(); - if (mOptions.testFlag(eoAddIndent)) { + if (mOptions.testFlag(eoAutoIndent) && mHighlighter + && (oldCaretY<=mLines->count())) { + //unindent if '{' is after an statement like 'if' 'for' + if (AChar == '{') { + QString temp = mLines->getString(oldCaretY-1).mid(0,oldCaretX-1); + // and the first nonblank char is this new { + if (temp.trimmed().isEmpty()) { + int indentSpaces = calcIndentSpaces(oldCaretY,"{", true); + QString line = mLines->getString(oldCaretY-1); + if (indentSpaces != leftSpaces(line)) { + QString temp = GetLeftSpacing(indentSpaces,true); + int i = temp.length(); + mLines->putString(oldCaretY-1,temp); + internalSetCaretXY(BufferCoord{i+1,oldCaretY}); + mUndoList->AddChange( + SynChangeReason::crDelete, + BufferCoord{1, oldCaretY}, + BufferCoord{line.length()+1, oldCaretY}, + line, + SynSelectionMode::smNormal + ); + mUndoList->AddChange( + SynChangeReason::crInsert, + BufferCoord{1, oldCaretY}, + BufferCoord{temp.length()+1, oldCaretY}, + "", + SynSelectionMode::smNormal + ); + } + } + } // Remove TabWidth of indent of the current line when typing a } - if (AChar == '}' && (oldCaretY<=mLines->count())) { + if (AChar == '}') { QString temp = mLines->getString(oldCaretY-1).mid(0,oldCaretX-1); // and the first nonblank char is this new } if (temp.trimmed().isEmpty()) { - BufferCoord MatchBracketPos = getPreviousLeftBracket(oldCaretX, oldCaretY); - if (MatchBracketPos.Line > 0) { - int i = 0; - QString matchline = mLines->getString(MatchBracketPos.Line-1); - QString line = mLines->getString(oldCaretY-1); - while (igetString(oldCaretY-1); + if (indentSpaces != leftSpaces(line)) { + QString temp = GetLeftSpacing(indentSpaces,true); + int i = temp.length(); mLines->putString(oldCaretY-1,temp); internalSetCaretXY(BufferCoord{i+1,oldCaretY}); mUndoList->AddChange( @@ -2932,7 +2974,7 @@ int SynEdit::scanFrom(int Index, int canStopIndex) && mLines->ranges(Result).bracketLevel == iRange.bracketLevel ) { if (mUseCodeFolding) - rescan(); + rescanFolds(); return Result;// avoid the final Decrement } } @@ -2941,11 +2983,29 @@ int SynEdit::scanFrom(int Index, int canStopIndex) } while (Result < mLines->count()); Result--; if (mUseCodeFolding) - rescan(); + rescanFolds(); return Result; } -void SynEdit::scanRanges() +void SynEdit::rescanRange(int line) +{ + line--; + line = std::max(0,line); + if (line >= mLines->count()) + return; + + if (line == 0) { + mHighlighter->resetState(); + } else { + mHighlighter->setState(mLines->ranges(line-1)); + } + mHighlighter->setLine(mLines->getString(line), line); + mHighlighter->nextToEol(); + SynRangeState iRange = mHighlighter->getRangeState(); + mLines->setRange(line,iRange); +} + +void SynEdit::rescanRanges() { if (mHighlighter && !mLines->empty()) { mHighlighter->resetState(); @@ -2956,7 +3016,7 @@ void SynEdit::scanRanges() } } if (mUseCodeFolding) - rescan(); + rescanFolds(); } void SynEdit::uncollapse(PSynEditFoldRange FoldRange) @@ -3025,7 +3085,7 @@ void SynEdit::foldOnListCleared() mAllFoldRanges.clear(); } -void SynEdit::rescan() +void SynEdit::rescanFolds() { if (!mUseCodeFolding) return; @@ -4262,7 +4322,7 @@ void SynEdit::setHighlighter(const PSynHighlighter &highlighter) auto action=finally([this]{ mLines->endUpdate(); }); - scanRanges(); + rescanRanges(); } onSizeOrFontChanged(true); invalidate(); @@ -4776,7 +4836,7 @@ int SynEdit::insertTextByNormalMode(const QString &Value) int Start; int P; bool bChangeScroll; - int SpaceCount; +// int SpaceCount; int Result = 0; sLeftSide = lineText().mid(0, mCaretX - 1); if (mCaretX - 1 > sLeftSide.length()) { @@ -4786,22 +4846,23 @@ int SynEdit::insertTextByNormalMode(const QString &Value) sLeftSide += QString(mCaretX - 1 - sLeftSide.length(),' '); } sRightSide = lineText().mid(mCaretX-1); - if (mUndoing) { - SpaceCount = 0; - } else { - SpaceCount = leftSpaces(sLeftSide); - } +// if (mUndoing) { +// SpaceCount = 0; +// } else { +// SpaceCount = leftSpaces(sLeftSide); +// } // step1: insert the first line of Value into current line Start = 0; P = GetEOL(Value,Start); if (PinsertLines(mCaretY, CountLines(Value,P)); } else { Str = sLeftSide + Value + sRightSide; - properSetLine(mCaretY - 1, Str); + properSetLine(mCaretY - 1, Str); } + rescanRange(mCaretY); // step2: insert remaining lines of Value while (P < Value.length()) { if (Value[P] == '\r') @@ -4822,8 +4883,12 @@ int SynEdit::insertTextByNormalMode(const QString &Value) if (P>=Value.length()) Str += sRightSide; } - Str = GetLeftSpacing(SpaceCount, true)+Str; + if (mOptions.testFlag(eoAutoIndent)) { + int indentSpaces = calcIndentSpaces(mCaretY,Str,true); + Str = GetLeftSpacing(indentSpaces,true)+TrimLeft(Str); + } properSetLine(mCaretY - 1, Str); + rescanRange(mCaretY); Result++; } bChangeScroll = !mOptions.testFlag(eoScrollPastEol); diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index eff852f9..d573887f 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -65,8 +65,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(SynStateFlags) enum SynEditorOption { eoAltSetsColumnMode = 0x00000001, //Holding down the Alt Key will put the selection mode into columnar format - eoAutoIndent = 0x00000002, //Will indent the caret on new lines with the same amount of leading white space as the preceding line - eoAddIndent = 0x00000004, //Will add one tab width of indent when typing { and :, and remove the same amount when typing } + eoAutoIndent = 0x00000002, //Will auto calculate the indent when input +// eoAddIndent = 0x00000004, //Will add one tab width of indent when typing { and :, and remove the same amount when typing } eoDragDropEditing = 0x00000008, //Allows you to select a block of text and drag it within the document to another location eoDropFiles = 0x00000010, //Allows the editor accept OLE file drops eoEnhanceHomeKey = 0x00000020, //enhances home key positioning, similar to visual studio @@ -455,14 +455,15 @@ private: QString expandAtWideGlyphs(const QString& S); void updateModifiedStatus(); int scanFrom(int Index, int canStopIndex); - void scanRanges(); + void rescanRange(int line); + void rescanRanges(); void uncollapse(PSynEditFoldRange FoldRange); void collapse(PSynEditFoldRange FoldRange); void foldOnListInserted(int Line, int Count); void foldOnListDeleted(int Line, int Count); void foldOnListCleared(); - void rescan(); // rescan for folds + void rescanFolds(); // rescan for folds void rescanForFoldRanges(); void scanForFoldRanges(PSynEditFoldRanges TopFoldRanges); int lineHasChar(int Line, int startChar, QChar character, const QString& highlighterAttrName); diff --git a/RedPandaIDE/qsynedit/highlighter/base.h b/RedPandaIDE/qsynedit/highlighter/base.h index b778281f..22e7312b 100644 --- a/RedPandaIDE/qsynedit/highlighter/base.h +++ b/RedPandaIDE/qsynedit/highlighter/base.h @@ -26,7 +26,7 @@ struct SynRangeState { QString indents; // indents stack (each char represents an indent) (needed by auto indent) int firstIndentThisLine; /* index of first indent that appended to the indents * stack at this line ( need by auto indent) */ - QChar lastMatchingIndent; /* the last indent matched ( and removed ) + QString matchingIndents; /* the indent matched ( and removed ) but not started at this line (need by auto indent) */ bool operator==(const SynRangeState& s2); diff --git a/RedPandaIDE/qsynedit/highlighter/cpp.cpp b/RedPandaIDE/qsynedit/highlighter/cpp.cpp index 1e5cd80f..dcdd207e 100644 --- a/RedPandaIDE/qsynedit/highlighter/cpp.cpp +++ b/RedPandaIDE/qsynedit/highlighter/cpp.cpp @@ -389,7 +389,7 @@ void SynEditCppHighlighter::braceOpenProc() } mRange.braceLevel += 1; mRange.leftBraces++; - if (!mRange.indents.isEmpty() && mRange.indents.back() == StatementIndentType) { + if (mRange.getLastIndent() == StatementIndentType) { // if last indent is started by 'if' 'for' etc // just replace it popIndents(StatementIndentType); @@ -925,7 +925,7 @@ void SynEditCppHighlighter::semiColonProc() mExtTokenId = ExtTokenKind::SemiColon; if (mRange.state == RangeState::rsAsm) mRange.state = RangeState::rsUnknown; - if (mRange.indents.back() == StatementIndentType) { + if (mRange.getLastIndent() == StatementIndentType) { popIndents(StatementIndentType); } } @@ -1362,7 +1362,7 @@ void SynEditCppHighlighter::popIndents(QChar indentType) if (!mRange.indents.isEmpty()) { int idx = mRange.indents.length()-1; if (idx < mRange.firstIndentThisLine) { - mRange.lastMatchingIndent = mRange.indents[idx]; + mRange.matchingIndents.append(mRange.indents[idx]); } mRange.indents.remove(idx,1); } @@ -1531,7 +1531,7 @@ void SynEditCppHighlighter::setLine(const QString &newLine, int lineNumber) mRange.leftBraces = 0; mRange.rightBraces = 0; mRange.firstIndentThisLine = mRange.indents.length(); - mRange.lastMatchingIndent = QChar(); + mRange.matchingIndents = ""; next(); } @@ -1599,7 +1599,7 @@ void SynEditCppHighlighter::setState(const SynRangeState& rangeState) mRange.leftBraces = 0; mRange.rightBraces = 0; mRange.firstIndentThisLine = mRange.indents.length(); - mRange.lastMatchingIndent = QChar(); + mRange.matchingIndents = ""; } void SynEditCppHighlighter::resetState() @@ -1613,7 +1613,7 @@ void SynEditCppHighlighter::resetState() mRange.rightBraces = 0; mRange.indents = ""; mRange.firstIndentThisLine = 0; - mRange.lastMatchingIndent = QChar(); + mRange.matchingIndents = ""; mAsmStart = false; } diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index dcaa1a42..95ef811f 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -982,7 +982,6 @@ void Settings::Editor::doSave() // indents saveValue("auto_indent", mAutoIndent); - saveValue("add_indent", mAddIndent); saveValue("tab_to_spaces", mTabToSpaces); saveValue("tab_width", mTabWidth); saveValue("show_indent_lines", mShowIndentLines); @@ -1092,7 +1091,6 @@ void Settings::Editor::doLoad() // indents mAutoIndent = boolValue("auto_indent", true); - mAddIndent = boolValue("add_indent", true); mTabToSpaces = boolValue("tab_to_spaces",false); mTabWidth = intValue("tab_width",4); mShowIndentLines = boolValue("show_indent_lines",true); @@ -1281,16 +1279,6 @@ void Settings::Editor::setTabToSpaces(bool tabToSpaces) mTabToSpaces = tabToSpaces; } -bool Settings::Editor::addIndent() const -{ - return mAddIndent; -} - -void Settings::Editor::setAddIndent(bool addIndent) -{ - mAddIndent = addIndent; -} - Settings::CompilerSet::CompilerSet(const QString& compilerFolder): mAutoAddCharsetParams(true), mStaticLink(true) diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index c9f36283..1ee758b2 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -340,7 +340,6 @@ public: //General // indents bool mAutoIndent; - bool mAddIndent; bool mTabToSpaces; int mTabWidth; bool mShowIndentLines; diff --git a/RedPandaIDE/settingsdialog/editorgeneralwidget.cpp b/RedPandaIDE/settingsdialog/editorgeneralwidget.cpp index b7894ad9..c31c91c8 100644 --- a/RedPandaIDE/settingsdialog/editorgeneralwidget.cpp +++ b/RedPandaIDE/settingsdialog/editorgeneralwidget.cpp @@ -38,7 +38,6 @@ void EditorGeneralWidget::doLoad() { pSettings->editor().load(); //indents - ui->chkAddIndent->setChecked(pSettings->editor().addIndent()); ui->chkAutoIndent->setChecked(pSettings->editor().autoIndent()); ui->chkTabToSpaces->setChecked(pSettings->editor().tabToSpaces()); ui->spTabWidth->setValue(pSettings->editor().tabWidth()); @@ -70,7 +69,6 @@ void EditorGeneralWidget::doLoad() void EditorGeneralWidget::doSave() { //indents - pSettings->editor().setAddIndent(ui->chkAddIndent->isChecked()); pSettings->editor().setAutoIndent(ui->chkAutoIndent->isChecked()); pSettings->editor().setTabToSpaces(ui->chkTabToSpaces->isChecked()); pSettings->editor().setTabWidth(ui->spTabWidth->value()); diff --git a/RedPandaIDE/settingsdialog/editorgeneralwidget.ui b/RedPandaIDE/settingsdialog/editorgeneralwidget.ui index b142a55c..488070f8 100644 --- a/RedPandaIDE/settingsdialog/editorgeneralwidget.ui +++ b/RedPandaIDE/settingsdialog/editorgeneralwidget.ui @@ -27,13 +27,6 @@ - - - - Add Indent after { and : - - -