- enhancement: Greatly reduce time to open/edit big files.

This commit is contained in:
Roy Qu 2023-02-17 23:56:13 +08:00
parent 766bf62c04
commit f4b239e15d
9 changed files with 95 additions and 216 deletions

View File

@ -36,6 +36,7 @@ Red Panda C++ Version 2.12
- change: Remove "Compile & Run" menu item. It's replaced by "Run".
- enhancement: Show "..." instead of "...}" when folding #if/#endif
- enhancement: Correctly handle high-precision mouse wheel / touchpad in editors.
- enhancement: Greatly reduce time to open/edit big files.
Red Panda C++ Version 2.11

View File

@ -246,6 +246,7 @@ void Editor::loadFile(QString filename) {
unit->setRealEncoding(mFileEncoding);
}
}
//this->setModified(false);
updateCaption();
if (mParentPageControl)
@ -267,6 +268,7 @@ void Editor::loadFile(QString filename) {
}
reparseTodo();
}
mLastIdCharPressed = 0;
saveAutoBackup();
}
@ -355,6 +357,7 @@ bool Editor::save(bool force, bool doReparse) {
checkSyntaxInBack();
reparseTodo();
}
return true;
}
@ -3273,7 +3276,6 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
}
pMainWindow->functionTip()->hide();
mCompletionPopup->show();
// Scan the current function body
QSet<QString> keywords;
if (syntaxer()) {

View File

@ -58,14 +58,13 @@ CodeFoldingRange::CodeFoldingRange(PCodeFoldingRange parent,
toLine(toLine),
linesCollapsed(0),
collapsed(false),
hintMarkLeft(0),
parent(parent)
{
subFoldRanges = std::make_shared<CodeFoldingRanges>();
}
PCodeFoldingRange CodeFoldingRanges::range(int index)
PCodeFoldingRange CodeFoldingRanges::range(int index) const
{
return mRanges[index];
}
@ -118,4 +117,9 @@ PCodeFoldingRange CodeFoldingRanges::operator[](int index) const
return mRanges[index];
}
const QVector<PCodeFoldingRange> &CodeFoldingRanges::ranges() const
{
return mRanges;
}
}

View File

@ -44,7 +44,7 @@ public:
explicit CodeFoldingRanges();
CodeFoldingRanges& operator=(const CodeFoldingRanges&)=delete;
PCodeFoldingRange range(int index);
PCodeFoldingRange range(int index) const;
void clear();
int count() const;
PCodeFoldingRange addByParts(PCodeFoldingRange parent, PCodeFoldingRanges allFold,
@ -54,6 +54,8 @@ public:
void remove(int index);
void add(PCodeFoldingRange foldRange);
PCodeFoldingRange operator[](int index) const;
const QVector<PCodeFoldingRange> &ranges() const;
private:
QVector<PCodeFoldingRange> mRanges;
};
@ -69,7 +71,6 @@ public:
int linesCollapsed; // Number of collapsed lines
PCodeFoldingRanges subFoldRanges; // Sub fold ranges
bool collapsed; // Is collapsed?
int hintMarkLeft;
std::weak_ptr<CodeFoldingRange> parent;
bool parentCollapsed();
void move(int count);

View File

@ -206,9 +206,9 @@ void Document::setSyntaxState(int Index, const SyntaxState& range)
if (Index<0 || Index>=mLines.count()) {
ListIndexOutOfBounds(Index);
}
beginUpdate();
//beginUpdate();
mLines[Index]->syntaxState = range;
endUpdate();
//endUpdate();
}
QString Document::getLine(int Index)
@ -581,6 +581,7 @@ void Document::setTabWidth(int newTabWidth)
resetColumns();
}
}
void Document::loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding)
{
QMutexLocker locker(&mMutex);

View File

@ -3377,12 +3377,16 @@ void QSynEdit::reparseLine(int line)
void QSynEdit::reparseDocument()
{
if (mSyntaxer && !mDocument->empty()) {
// qint64 begin=QDateTime::currentMSecsSinceEpoch();
mSyntaxer->resetState();
for (int i =0;i<mDocument->count();i++) {
mSyntaxer->setLine(mDocument->getLine(i), i);
mSyntaxer->nextToEol();
mDocument->setSyntaxState(i, mSyntaxer->getState());
}
// qint64 diff= QDateTime::currentMSecsSinceEpoch() - begin;
// qDebug()<<diff<<mDocument->count();
}
if (mUseCodeFolding)
rescanFolds();
@ -3461,7 +3465,11 @@ void QSynEdit::rescanFolds()
//qDebug()<<QDateTime::currentDateTime();
if (!mUseCodeFolding)
return;
// qint64 begin=QDateTime::currentMSecsSinceEpoch();
rescanForFoldRanges();
// qint64 diff= QDateTime::currentMSecsSinceEpoch() - begin;
// qDebug()<<"-"<<diff;
invalidateGutter();
}
@ -3478,35 +3486,30 @@ void QSynEdit::rescanForFoldRanges()
// Did we leave any collapsed folds and are we viewing a code file?
if (mAllFoldRanges.count() > 0) {
CodeFoldingRanges ranges{mAllFoldRanges};
QMap<QString,PCodeFoldingRange> rangeIndexes;
foreach(const PCodeFoldingRange& r, mAllFoldRanges.ranges()) {
if (r->collapsed)
rangeIndexes.insert(QString("%1-%2").arg(r->fromLine).arg(r->toLine),r);
}
mAllFoldRanges.clear();
// Add folds to a separate list
PCodeFoldingRanges temporaryAllFoldRanges = std::make_shared<CodeFoldingRanges>();
scanForFoldRanges(temporaryAllFoldRanges);
PCodeFoldingRange tempFoldRange;
PCodeFoldingRange r2;
// Combine new with old folds, preserve parent order
for (int i = 0; i< temporaryAllFoldRanges->count();i++) {
PCodeFoldingRange tempFoldRange=temporaryAllFoldRanges->range(i);
int j=0;
while (j <ranges.count()) {
PCodeFoldingRange foldRange = ranges[j];
//qDebug()<<TemporaryAllFoldRanges->range(i)->fromLine<<ranges[j]->fromLine;
if (tempFoldRange->fromLine == foldRange->fromLine
&& tempFoldRange->toLine == foldRange->toLine) {
//qDebug()<<"-"<<foldRange->fromLine;
mAllFoldRanges.add(foldRange);
break;
}
j++;
}
if (j>=ranges.count()) {
//qDebug()<<"--"<<tempFoldRange->fromLine;
mAllFoldRanges.add(tempFoldRange);
tempFoldRange=temporaryAllFoldRanges->range(i);
r2=rangeIndexes.value(QString("%1-%2").arg(tempFoldRange->fromLine).arg(tempFoldRange->toLine),
PCodeFoldingRange());
if (r2) {
tempFoldRange->collapsed=true;
tempFoldRange->linesCollapsed=r2->linesCollapsed;
}
mAllFoldRanges.add(tempFoldRange);
}
} else {
// We ended up with no folds after deleting, just pass standard data...
PCodeFoldingRanges temp(&mAllFoldRanges, null_deleter);
scanForFoldRanges(temp);
@ -3516,7 +3519,11 @@ void QSynEdit::rescanForFoldRanges()
void QSynEdit::scanForFoldRanges(PCodeFoldingRanges topFoldRanges)
{
PCodeFoldingRanges parentFoldRanges = topFoldRanges;
// qint64 begin=QDateTime::currentMSecsSinceEpoch();
findSubFoldRange(topFoldRanges, parentFoldRanges,PCodeFoldingRange());
// qint64 diff= QDateTime::currentMSecsSinceEpoch() - begin;
// qDebug()<<"?"<<diff;
}
//this func should only be used in findSubFoldRange
@ -3559,19 +3566,21 @@ void QSynEdit::findSubFoldRange(PCodeFoldingRanges topFoldRanges, PCodeFoldingRa
while (line < mDocument->count()) { // index is valid for LinesToScan and fLines
// If there is a collapsed fold over here, skip it
collapsedFold = collapsedFoldStartAtLine(line + 1); // only collapsed folds remain
if (collapsedFold) {
line = collapsedFold->toLine;
continue;
}
// collapsedFold = collapsedFoldStartAtLine(line + 1); // only collapsed folds remain
// if (collapsedFold) {
// line = collapsedFold->toLine;
// continue;
// }
// Find an opening character on this line
curLine = mDocument->getLine(line);
if (mDocument->blockEnded(line)>0) {
for (int i=0; i<mDocument->blockEnded(line);i++) {
int blockEnded=mDocument->blockEnded(line);
int blockStarted=mDocument->blockStarted(line);
if (blockEnded>0) {
for (int i=0; i<blockEnded;i++) {
// Stop the recursion if we find a closing char, and return to our parent
if (parent) {
if (mDocument->blockStarted(line)>0)
if (blockStarted>0)
parent->toLine = line;
else
parent->toLine = line + 1;
@ -3584,8 +3593,8 @@ void QSynEdit::findSubFoldRange(PCodeFoldingRanges topFoldRanges, PCodeFoldingRa
}
}
}
if (mDocument->blockStarted(line)>0) {
for (int i=0; i<mDocument->blockStarted(line);i++) {
if (blockStarted>0) {
for (int i=0; i<blockStarted;i++) {
// Add it to the top list of folds
parent = parentFoldRanges->addByParts(
parent,
@ -3604,7 +3613,7 @@ void QSynEdit::findSubFoldRange(PCodeFoldingRanges topFoldRanges, PCodeFoldingRa
PCodeFoldingRange QSynEdit::collapsedFoldStartAtLine(int Line)
{
for (int i = 0; i< mAllFoldRanges.count() - 1; i++ ) {
if (mAllFoldRanges[i]->fromLine == Line && mAllFoldRanges[i]->collapsed) {
if (mAllFoldRanges[i]->collapsed && mAllFoldRanges[i]->fromLine == Line) {
return mAllFoldRanges[i];
} else if (mAllFoldRanges[i]->fromLine > Line) {
break; // sorted by line. don't bother scanning further

View File

@ -469,6 +469,8 @@ protected:
virtual void onBeginFirstPaintLock();
private:
void beginEditingWithoutUndo();
void endEditingWithoutUndo();
void clearAreaList(EditingAreaList areaList);
void computeCaret();
void computeScroll(bool isDragging);
@ -500,8 +502,8 @@ private:
QString expandAtWideGlyphs(const QString& S);
void updateModifiedStatus();
void scanFrom(int index);
void rescanRange(int line);
void rescanRanges();
void reparseLine(int line);
void reparseDocument();
void uncollapse(PCodeFoldingRange FoldRange);
void collapse(PCodeFoldingRange FoldRange);

View File

@ -361,12 +361,6 @@ void CppSyntaxer::asciiCharProc()
mRange.state = RangeState::rsUnknown;
}
void CppSyntaxer::atSymbolProc()
{
mTokenId = TokenId::Unknown;
mRun+=1;
}
void CppSyntaxer::braceCloseProc()
{
mRun += 1;
@ -673,43 +667,32 @@ void CppSyntaxer::nullProc()
void CppSyntaxer::numberProc()
{
int idx1; // token[1]
idx1 = mRun;
mRun+=1;
mTokenId = TokenId::Number;
bool shouldExit = false;
if (mRun+1<mLineSize && mLine[mRun]=='0') {
if (mLine[mRun+1]=='x' || mLine[mRun+1]=='X') {
mTokenId=TokenId::Hex;
mRun+=2;
} else if (mLine[mRun+1]>='0' && mLine[mRun+1]<='7') {
mTokenId=TokenId::Octal;
mRun+=2;
}
} else
mRun+=1;
while (mRun<mLineSize) {
switch(mLine[mRun].unicode()) {
case '\'':
if (mTokenId != TokenId::Number) {
mTokenId = TokenId::Symbol;
return;
}
break;
case '.':
if (mRun+1<mLineSize && mLine[mRun+1] == '.') {
mRun+=2;
mTokenId = TokenId::Unknown;
return;
} else if (mTokenId != TokenId::Hex) {
if (mTokenId != TokenId::Hex && mTokenId != TokenId::Octal) {
mTokenId = TokenId::Float;
} else {
mTokenId = TokenId::Unknown;
return;
}
break;
case '-':
case '+':
if (mTokenId != TokenId::Float) // number <> float. an arithmetic operator
return;
if (mRun-1>=0 && mLine[mRun-1]!= 'e' && mLine[mRun-1]!='E') // number = float, but no exponent. an arithmetic operator
return;
if (mRun+1<mLineSize && (mLine[mRun+1]<'0' || mLine[mRun+1]>'9')) {// invalid
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
break;
case '0':
case '1':
case '2':
@ -718,15 +701,8 @@ void CppSyntaxer::numberProc()
case '5':
case '6':
case '7':
if ((mRun == idx1+1) && (mLine[idx1] == '0')) { // octal number
mTokenId = TokenId::Octal;
}
break;
case '8':
case '9':
if ( (mLine[idx1]=='0') && (mTokenId != TokenId::Hex) && (mTokenId != TokenId::Float) ) // invalid octal char
mTokenId = TokenId::Unknown; // we must continue parse, it may be an float number
break;
case 'a':
case 'b':
case 'c':
@ -735,110 +711,31 @@ void CppSyntaxer::numberProc()
case 'B':
case 'C':
case 'D':
if (mTokenId!=TokenId::Hex) { //invalid
mTokenId = TokenId::Unknown;
return;
}
break;
case 'e':
case 'E':
if (mTokenId==TokenId::Number) {
mTokenId = TokenId::Float;
mRun++;
if (mRun < mLineSize && (mLine[mRun]== '+' || mLine[mRun]== '-')) // number = float, but no exponent. an arithmetic operator
mRun++;
break;
}
break;
case 'p':
case 'P':
if (mTokenId!=TokenId::Hex) {
if (mRun-1>=0 && (mLine[mRun-1]>='0' || mLine[mRun-1]<='9') ) {//exponent
for (int i=idx1;i<mRun;i++) {
if (mLine[i] == 'e' || mLine[i]=='E') { // too many exponents
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
}
if (mRun+1<mLineSize && mLine[mRun+1]!='+' && mLine[mRun+1]!='-' && !(mLine[mRun+1]>='0' && mLine[mRun+1]<='9')) {
return;
} else {
mTokenId = TokenId::Float;
}
} else {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
}
mTokenId = TokenId::Float;
mRun++;
if (mRun < mLineSize && (mLine[mRun]== '+' || mLine[mRun]== '-')) // number = float, but no exponent. an arithmetic operator
mRun++;
break;
case 'f':
case 'F':
if (mTokenId!=TokenId::Hex) {
for (int i=idx1;i<mRun;i++) {
if (mLine[i] == 'f' || mLine[i]=='F') {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
}
if (mTokenId == TokenId::Float) {
if (mRun-1>=0 && (mLine[mRun-1]=='l' || mLine[mRun-1]=='L')) {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
} else {
mTokenId = TokenId::Float;
}
}
break;
case 'l':
case 'L':
for (int i=idx1;i<=mRun-2;i++) {
if (mLine[i] == 'l' && mLine[i]=='L') {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
}
if (mTokenId == TokenId::Float && (mLine[mRun-1]=='f' || mLine[mRun-1]=='F')) {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
break;
case 'u':
case 'U':
if (mTokenId == TokenId::Float) {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
} else {
for (int i=idx1;i<mRun;i++) {
if (mLine[i] == 'u' || mLine[i]=='U') {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
}
}
break;
case 'x':
case 'X':
if ((mRun == idx1+1) && (mLine[idx1]=='0') &&
mRun+1<mLineSize &&
((mLine[mRun+1]>='0' && mLine[mRun+1]<='9')
|| (mLine[mRun+1]>='a' && mLine[mRun+1]<='f')
|| (mLine[mRun+1]>='A' && mLine[mRun+1]<='F')) ) {
mTokenId = TokenId::Hex;
} else {
mRun+=1;
mTokenId = TokenId::Unknown;
return;
}
break;
default:
shouldExit=true;
return;
}
if (shouldExit) {
break;
}
mRun+=1;
}
if (mRun-1>=0 && mLine[mRun-1] == '\'') {
mTokenId = TokenId::Unknown;
mRun+=1;
}
}
@ -1123,11 +1020,7 @@ void CppSyntaxer::stringEscapeSeqProc()
case '5':
case '6':
case '7':
for (int i=0;i<3;i++) {
if (mRun>=mLineSize || mLine[mRun]<'0' || mLine[mRun]>'7')
break;
mRun+=1;
}
mRun+=3;
break;
case '8':
case '9':
@ -1136,49 +1029,19 @@ void CppSyntaxer::stringEscapeSeqProc()
break;
case 'x':
mRun+=1;
if (mRun>=mLineSize || !(
(mLine[mRun]>='0' && mLine[mRun]<='9')
|| (mLine[mRun]>='a' && mLine[mRun]<='f')
|| (mLine[mRun]>='A' && mLine[mRun]<='F')
)) {
mTokenId = TokenId::Unknown;
} else {
while (mRun<mLineSize && (
(mLine[mRun]>='0' && mLine[mRun]<='9')
|| (mLine[mRun]>='a' && mLine[mRun]<='f')
|| (mLine[mRun]>='A' && mLine[mRun]<='F')
)) {
mRun+=1;
}
while (mRun<mLineSize && (
(mLine[mRun]>='0' && mLine[mRun]<='9')
|| (mLine[mRun]>='a' && mLine[mRun]<='f')
|| (mLine[mRun]>='A' && mLine[mRun]<='F')
)) {
mRun+=1;
}
break;
case 'u':
mRun+=1;
for (int i=0;i<4;i++) {
if (mRun>=mLineSize || !(
(mLine[mRun]>='0' && mLine[mRun]<='9')
|| (mLine[mRun]>='a' && mLine[mRun]<='f')
|| (mLine[mRun]>='A' && mLine[mRun]<='F')
)) {
mTokenId = TokenId::Unknown;
return;
}
mRun+=1;
}
mRun+=5;
break;
case 'U':
mRun+=1;
for (int i=0;i<8;i++) {
if (mRun>=mLineSize || !(
(mLine[mRun]>='0' && mLine[mRun]<='9')
|| (mLine[mRun]>='a' && mLine[mRun]<='f')
|| (mLine[mRun]>='A' && mLine[mRun]<='F')
)) {
mTokenId = TokenId::Unknown;
return;
}
mRun+=1;
}
mRun+=9;
break;
}
}
@ -1283,9 +1146,6 @@ void CppSyntaxer::processChar()
case '\'':
asciiCharProc();
break;
case '@':
atSymbolProc();
break;
case '}':
braceCloseProc();
break;

View File

@ -94,7 +94,6 @@ private:
void ansiCppProc();
void ansiCProc();
void asciiCharProc();
void atSymbolProc();
void braceCloseProc();
void braceOpenProc();
void colonProc();