work save

This commit is contained in:
royqh1979@gmail.com 2021-08-28 09:01:40 +08:00
parent a8445dc039
commit 05f686d61e
10 changed files with 212 additions and 82 deletions

View File

@ -528,6 +528,47 @@ bool Editor::onGetSpecialLineColors(int Line, QColor &foreground, QColor &backgr
return false; return false;
} }
void Editor::onPreparePaintHighlightToken(int row, int column, const QString &token, PSynHighlighterAttribute attr, SynFontStyles &style, QColor &foreground, QColor &background)
{
if (token.isEmpty())
return;
//selection
if (selAvail() && highlighter()) {
if ((
(attr->name() == SYNS_AttrIdentifier)
|| (attr->name() == SYNS_AttrReservedWord)
|| (attr->name() == SYNS_AttrPreprocessor)
)
&& (token == selText())) {
foreground = selectedForeground();
background = selectedBackground();
return;
}
}
if (mParser && mCompletionPopup && (attr->name() == SYNS_AttrIdentifier)) {
BufferCoord p=displayToBufferPos(DisplayCoord{column+1,row});
BufferCoord pBeginPos,pEndPos;
QString s= getWordAtPosition(p, pBeginPos,pEndPos, WordPurpose::wpInformation);
PStatement statement = mParser->findStatementOf(mFilename,
s , p.Line);
StatementKind kind = mParser->getKindOfStatement(statement);
if (kind == StatementKind::skUnknown) {
if ((pEndPos.Line>=1)
&& (pEndPos.Char < lines()->getString(pEndPos.Line-1).length())
&& (lines()->getString(pEndPos.Line-1)[pEndPos.Char] == '(')) {
kind = StatementKind::skFunction;
} else {
kind = StatementKind::skVariable;
}
}
foreground = mCompletionPopup->colors().value(kind,
highlighter()->identifierAttribute()->foreground());
return;
}
}
void Editor::copyToClipboard() void Editor::copyToClipboard()
{ {
if (pSettings->editor().copySizeLimit()) { if (pSettings->editor().copySizeLimit()) {
@ -1452,8 +1493,8 @@ void Editor::completionInsert(bool appendFunc)
QString funcAddOn = ""; QString funcAddOn = "";
// delete the part of the word that's already been typed ... // delete the part of the word that's already been typed ...
BufferCoord p = wordEnd(); BufferCoord p = WordEnd();
setBlockBegin(wordStart()); setBlockBegin(WordStart());
setBlockEnd(p); setBlockEnd(p);
// if we are inserting a function, // if we are inserting a function,
@ -1970,6 +2011,11 @@ void Editor::applyColorScheme(const QString& schemeName)
if (item) { if (item) {
this->mSyntaxWarningColor = item->foreground(); this->mSyntaxWarningColor = item->foreground();
} }
item = pColorManager->getItem(schemeName,COLOR_SCHEME_SELECTION);
if (item) {
setSelectedForeground(item->foreground());
setSelectedBackground(item->background());
}
item = pColorManager->getItem(schemeName,COLOR_SCHEME_ACTIVE_BREAKPOINT); item = pColorManager->getItem(schemeName,COLOR_SCHEME_ACTIVE_BREAKPOINT);
if (item) { if (item) {
this->mActiveBreakpointForegroundColor = item->foreground(); this->mActiveBreakpointForegroundColor = item->foreground();
@ -1980,6 +2026,58 @@ void Editor::applyColorScheme(const QString& schemeName)
this->mBreakpointForegroundColor = item->foreground(); this->mBreakpointForegroundColor = item->foreground();
this->mBreakpointBackgroundColor = item->background(); this->mBreakpointBackgroundColor = item->background();
} }
//color for code completion popup
if (mCompletionPopup) {
item = pColorManager->getItem(schemeName, SYNS_AttrFunction);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skFunction,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skConstructor,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skDestructor,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrClass);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skClass,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skTypedef,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skAlias,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrIdentifier);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skEnumType,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skEnumClassType,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrVariable);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skVariable,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrLocalVariable);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skLocalVariable,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skParameter,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrGlobalVariable);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skGlobalVariable,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrGlobalVariable);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skGlobalVariable,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrPreprocessor);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skPreprocessor,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skEnum,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrReservedWord);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skKeyword,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skUserCodeIn,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrString);
if (item) {
mCompletionPopup->colors().insert(StatementKind::skNamespace,item->foreground());
mCompletionPopup->colors().insert(StatementKind::skNamespaceAlias,item->foreground());
}
}
this->invalidate(); this->invalidate();
} }

View File

@ -211,6 +211,10 @@ protected:
// SynEdit interface // SynEdit interface
protected: protected:
bool onGetSpecialLineColors(int Line, QColor &foreground, QColor &backgroundColor) override; bool onGetSpecialLineColors(int Line, QColor &foreground, QColor &backgroundColor) override;
// SynEdit interface
protected:
void onPreparePaintHighlightToken(int row, int column, const QString &token, PSynHighlighterAttribute attr, SynFontStyles &style, QColor &foreground, QColor &background) override;
}; };
#endif // EDITOR_H #endif // EDITOR_H

View File

@ -799,6 +799,7 @@ void CppParser::reset()
mPreprocessor.includesList().clear(); mPreprocessor.includesList().clear();
mNamespaces.clear(); mNamespaces.clear();
mInlineNamespaces.clear();
mPreprocessor.projectIncludePaths().clear(); mPreprocessor.projectIncludePaths().clear();
mPreprocessor.includePaths().clear(); mPreprocessor.includePaths().clear();
@ -2041,8 +2042,15 @@ void CppParser::handleNamespace()
//wrong namespace define, stop handling //wrong namespace define, stop handling
return; return;
QString command = mTokenizer[mIndex]->text; QString command = mTokenizer[mIndex]->text;
if (command.startsWith("__")) // hack for inline namespaces
isInline = true; QString fullName = getFullStatementName(command,getCurrentScope());
if (isInline) {
mInlineNamespaces.insert(fullName);
} else if (mInlineNamespaces.contains(fullName)) {
isInline = true;
}
// if (command.startsWith("__")) // hack for inline namespaces
// isInline = true;
mIndex++; mIndex++;
if (mIndex>=mTokenizer.tokenCount()) if (mIndex>=mTokenizer.tokenCount())
return; return;
@ -2954,15 +2962,15 @@ void CppParser::internalParse(const QString &fileName)
if (!handleStatement()) if (!handleStatement())
break; break;
} }
//#ifdef QT_DEBUG
StringsToFile(mPreprocessor.result(),"f:\\preprocess.txt");
mPreprocessor.dumpDefinesTo("f:\\defines.txt");
mPreprocessor.dumpIncludesListTo("f:\\includes.txt");
mStatementList.dump("f:\\stats.txt");
mTokenizer.dumpTokens("f:\\tokens.txt");
//#endif
#ifdef QT_DEBUG #ifdef QT_DEBUG
mStatementList.dumpAll("f:\\all-stats.txt"); // StringsToFile(mPreprocessor.result(),"f:\\preprocess.txt");
// mPreprocessor.dumpDefinesTo("f:\\defines.txt");
// mPreprocessor.dumpIncludesListTo("f:\\includes.txt");
// mStatementList.dump("f:\\stats.txt");
// mTokenizer.dumpTokens("f:\\tokens.txt");
#endif
#ifdef QT_DEBUG
// mStatementList.dumpAll("f:\\all-stats.txt");
#endif #endif
} }
} }

View File

@ -352,6 +352,7 @@ private:
int mLockCount; // lock(don't reparse) when we need to find statements in a batch int mLockCount; // lock(don't reparse) when we need to find statements in a batch
bool mParsing; bool mParsing;
QHash<QString,PStatementList> mNamespaces; //TStringList<String,List<Statement>> namespace and the statements in its scope QHash<QString,PStatementList> mNamespaces; //TStringList<String,List<Statement>> namespace and the statements in its scope
QSet<QString> mInlineNamespaces;
//fRemovedStatements: THashedStringList; //THashedStringList<String,PRemovedStatements> //fRemovedStatements: THashedStringList; //THashedStringList<String,PRemovedStatements>
QRecursiveMutex mMutex; QRecursiveMutex mMutex;

View File

@ -42,7 +42,7 @@ enum class SkipType {
skNone // It's a keyword but don't process here skNone // It's a keyword but don't process here
}; };
enum class StatementKind { enum StatementKind {
skUnknown, skUnknown,
skPreprocessor, skPreprocessor,
skEnumType, skEnumType,

View File

@ -1179,8 +1179,8 @@ BufferCoord SynEdit::WordStartEx(const BufferCoord &XY)
// valid line? // valid line?
if ((CY >= 1) && (CY <= mLines->count())) { if ((CY >= 1) && (CY <= mLines->count())) {
QString Line = mLines->getString(CY - 1); QString Line = mLines->getString(CY - 1);
CX = std::min(CX, Line.length()); CX = std::min(CX, Line.length()+1);
if (CX > 1) { if (CX-1 >= 0) {
if (!(Line[CX - 1].isSpace())) if (!(Line[CX - 1].isSpace()))
CX = StrRScanForNonWordChar(Line, CX - 1) + 1; CX = StrRScanForNonWordChar(Line, CX - 1) + 1;
else else
@ -3209,6 +3209,26 @@ void SynEdit::doScrolled(int)
invalidate(); invalidate();
} }
const QColor &SynEdit::selectedBackground() const
{
return mSelectedBackground;
}
void SynEdit::setSelectedBackground(const QColor &newSelectedBackground)
{
mSelectedBackground = newSelectedBackground;
}
const QColor &SynEdit::selectedForeground() const
{
return mSelectedForeground;
}
void SynEdit::setSelectedForeground(const QColor &newSelectedForeground)
{
mSelectedForeground = newSelectedForeground;
}
int SynEdit::textHeight() const int SynEdit::textHeight() const
{ {
return mTextHeight; return mTextHeight;
@ -4654,6 +4674,11 @@ void SynEdit::onPaint(QPainter &)
} }
void SynEdit::onPreparePaintHighlightToken(int row, int column, const QString &token, PSynHighlighterAttribute attr, SynFontStyles &style, QColor &foreground, QColor &background)
{
}
void SynEdit::onProcessCommand(SynEditorCommand , QChar , void *) void SynEdit::onProcessCommand(SynEditorCommand , QChar , void *)
{ {
@ -5668,56 +5693,6 @@ void SynEdit::setSelLength(int Value)
} }
} }
BufferCoord SynEdit::wordStart()
{
return wordStart(caretXY());
}
BufferCoord SynEdit::wordStart(const BufferCoord &value)
{
int cx = value.Char-1;
int cy = value.Line;
// valid line?
if ((cy <1) || (cy > lines()->count()))
return value;
QString line = lines()->getString(cy - 1);
if (cx>=line.length()) {
cx=line.length()-1;
}
while (cx>=0 && cx<line.length()) {
if (line[cx]==' ' || line[cx]=='\t')
break;
cx--;
}
if (cx != value.Char-1) {
cx++;
}
return BufferCoord{cx+1,cy};
}
BufferCoord SynEdit::wordEnd()
{
return wordEnd(caretXY());
}
BufferCoord SynEdit::wordEnd(const BufferCoord &value)
{
int cx = value.Char-1;
int cy = value.Line;
// valid line?
if ((cy <1) || (cy > lines()->count()))
return value;
QString line = lines()->getString(cy - 1);
while (cx>=0 && cx<line.length()) {
if (line[cx]==' ' || line[cx]=='\t')
break;
cx++;
}
return BufferCoord{cx+1,cy};
}
BufferCoord SynEdit::blockBegin() const BufferCoord SynEdit::blockBegin() const
{ {
if ((mBlockEnd.Line < mBlockBegin.Line) if ((mBlockEnd.Line < mBlockBegin.Line)

View File

@ -125,9 +125,9 @@ using SynPlaceMarkProc = std::function<void(PSynEditMark& Mark)>;
using SynProcessCommandProc = std::function<void(SynEditorCommand& command, QChar& AChar, void* data)>; using SynProcessCommandProc = std::function<void(SynEditorCommand& command, QChar& AChar, void* data)>;
using SynMouseCursorProc = std::function<void(const BufferCoord& aLineCharPos, QCursor & aCursor)>; using SynMouseCursorProc = std::function<void(const BufferCoord& aLineCharPos, QCursor & aCursor)>;
using SynPaintProc = std::function<void(const QPaintDevice& paintDevice )>; using SynPaintProc = std::function<void(const QPaintDevice& paintDevice )>;
using SynPreparePaintHighlightTokenProc = std::function<void(int row, //using SynPreparePaintHighlightTokenProc = std::function<void(int row,
int column, const QString& token, PSynHighlighterAttribute attr, // int column, const QString& token, PSynHighlighterAttribute attr,
SynFontStyles& style, QColor& foreground, QColor& background)>; // SynFontStyles& style, QColor& foreground, QColor& background)>;
using SynSearchMathedProc = std::function<SynSearchAction(const QString& sSearch, using SynSearchMathedProc = std::function<SynSearchAction(const QString& sSearch,
const QString& sReplace, int Line, int ch, int wordLen)>; const QString& sReplace, int Line, int ch, int wordLen)>;
@ -217,11 +217,6 @@ public:
void setSelText(const QString& Value); void setSelText(const QString& Value);
void setSelLength(int Value); void setSelLength(int Value);
BufferCoord wordStart();
BufferCoord wordStart(const BufferCoord& value);
BufferCoord wordEnd();
BufferCoord wordEnd(const BufferCoord& value);
int searchReplace(const QString& sSearch, const QString& sReplace, SynSearchOptions options, int searchReplace(const QString& sSearch, const QString& sReplace, SynSearchOptions options,
PSynSearchBase searchEngine, SynSearchMathedProc matchedCallback = nullptr); PSynSearchBase searchEngine, SynSearchMathedProc matchedCallback = nullptr);
@ -335,6 +330,12 @@ public:
int textHeight() const; int textHeight() const;
const QColor &selectedForeground() const;
void setSelectedForeground(const QColor &newSelectedForeground);
const QColor &selectedBackground() const;
void setSelectedBackground(const QColor &newSelectedBackground);
signals: signals:
void Changed(); void Changed();
@ -370,6 +371,9 @@ protected:
virtual void onGutterGetText(int aLine, QString& aText); virtual void onGutterGetText(int aLine, QString& aText);
virtual void onGutterPaint(QPainter& painter, int aLine, int X, int Y); virtual void onGutterPaint(QPainter& painter, int aLine, int X, int Y);
virtual void onPaint(QPainter& painter); virtual void onPaint(QPainter& painter);
virtual void onPreparePaintHighlightToken(int row,
int column, const QString& token, PSynHighlighterAttribute attr,
SynFontStyles& style, QColor& foreground, QColor& background);
virtual void onProcessCommand(SynEditorCommand Command, QChar AChar, void * pData); virtual void onProcessCommand(SynEditorCommand Command, QChar AChar, void * pData);
virtual void onCommandProcessed(SynEditorCommand Command, QChar AChar, void * pData); virtual void onCommandProcessed(SynEditorCommand Command, QChar AChar, void * pData);
virtual void ExecuteCommand(SynEditorCommand Command, QChar AChar, void * pData); virtual void ExecuteCommand(SynEditorCommand Command, QChar AChar, void * pData);
@ -605,7 +609,7 @@ private:
SynProcessCommandProc mOnCommandProcessed; SynProcessCommandProc mOnCommandProcessed;
SynMouseCursorProc mOnMouseCursor; SynMouseCursorProc mOnMouseCursor;
SynPaintProc mOnPaint; SynPaintProc mOnPaint;
SynPreparePaintHighlightTokenProc mOnPaintHighlightToken; // SynPreparePaintHighlightTokenProc mOnPaintHighlightToken;
SynPlaceMarkProc mOnPlaceMark; SynPlaceMarkProc mOnPlaceMark;
SynProcessCommandProc mOnProcessingCommand; SynProcessCommandProc mOnProcessingCommand;
SynProcessCommandProc mOnProcessingUserCommand; SynProcessCommandProc mOnProcessingUserCommand;

View File

@ -582,8 +582,7 @@ void SynEditTextPainter::AddHighlightToken(const QString &Token, int ColumnsBefo
} }
//todo : change char(getTokenPos) to column? //todo : change char(getTokenPos) to column?
if (edit->mOnPaintHighlightToken) edit->onPreparePaintHighlightToken(cLine,edit->mHighlighter->getTokenPos(),
edit->mOnPaintHighlightToken(cLine,edit->mHighlighter->getTokenPos(),
Token,p_Attri,Style,Foreground,Background); Token,p_Attri,Style,Foreground,Background);
// Do we have to paint the old chars first, or can we just append? // Do we have to paint the old chars first, or can we just append?

View File

@ -4,6 +4,7 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QDebug> #include <QDebug>
#include <QApplication>
CodeCompletionView::CodeCompletionView(QWidget *parent) : CodeCompletionView::CodeCompletionView(QWidget *parent) :
QWidget(parent) QWidget(parent)
@ -11,6 +12,15 @@ CodeCompletionView::CodeCompletionView(QWidget *parent) :
setWindowFlags(Qt::Popup); setWindowFlags(Qt::Popup);
mListView = new CodeCompletionListView(this); mListView = new CodeCompletionListView(this);
mModel=new CodeCompletionListModel(&mCompletionStatementList); mModel=new CodeCompletionListModel(&mCompletionStatementList);
mModel->setColorCallback([this](PStatement statement)->QColor{
StatementKind kind;
if (mParser) {
kind = mParser->getKindOfStatement(statement);
} else {
kind = statement->kind;
}
return mColors.value(kind,palette().color(QPalette::Text));
});
mListView->setModel(mModel); mListView->setModel(mModel);
setLayout(new QVBoxLayout()); setLayout(new QVBoxLayout());
layout()->addWidget(mListView); layout()->addWidget(mListView);
@ -213,9 +223,9 @@ static bool sortByScopeComparator(PStatement statement1,PStatement statement2){
} else if (statement2->kind == StatementKind::skKeyword) { } else if (statement2->kind == StatementKind::skKeyword) {
return false; return false;
// Show stuff from local headers first // Show stuff from local headers first
} else if (statement1->inSystemHeader && (!statement2->inSystemHeader)) { } else if (statement1->inSystemHeader && !(statement2->inSystemHeader)) {
return true; return true;
} else if ((!statement1->inSystemHeader) && statement2->inSystemHeader) { } else if (!(statement1->inSystemHeader) && statement2->inSystemHeader) {
return false; return false;
// Show local statements first // Show local statements first
} else if (statement1->scope != StatementScope::ssGlobal } else if (statement1->scope != StatementScope::ssGlobal
@ -277,9 +287,9 @@ static bool sortByScopeWithUsageComparator(PStatement statement1,PStatement stat
} else if (statement2->kind == StatementKind::skKeyword) { } else if (statement2->kind == StatementKind::skKeyword) {
return false; return false;
// Show stuff from local headers first // Show stuff from local headers first
} else if (statement1->inSystemHeader && ! statement2->inSystemHeader) { } else if (statement1->inSystemHeader && ! (statement2->inSystemHeader)) {
return true; return true;
} else if (!statement1->inSystemHeader && statement2->inSystemHeader) { } else if (!(statement1->inSystemHeader) && statement2->inSystemHeader) {
return false; return false;
// Show local statements first // Show local statements first
} else if (statement1->scope != StatementScope::ssGlobal } else if (statement1->scope != StatementScope::ssGlobal
@ -713,6 +723,11 @@ void CodeCompletionView::setCurrentStatement(const PStatement &newCurrentStateme
mCurrentStatement = newCurrentStatement; mCurrentStatement = newCurrentStatement;
} }
QHash<StatementKind, QColor> &CodeCompletionView::colors()
{
return mColors;
}
bool CodeCompletionView::useCppKeyword() const bool CodeCompletionView::useCppKeyword() const
{ {
return mUseCppKeyword; return mUseCppKeyword;
@ -870,9 +885,18 @@ QVariant CodeCompletionListModel::data(const QModelIndex &index, int role) const
if (index.row()>=mStatements->count()) if (index.row()>=mStatements->count())
return QVariant(); return QVariant();
if (role == Qt::DisplayRole) { switch(role) {
case Qt::DisplayRole: {
PStatement statement = mStatements->at(index.row()); PStatement statement = mStatements->at(index.row());
return statement->command; return statement->command;
}
case Qt::ForegroundRole: {
PStatement statement = mStatements->at(index.row());
if (mColorCallback)
return mColorCallback(statement);
QApplication *app = dynamic_cast<QApplication *>(QApplication::instance());
return app->palette().color(QPalette::Text);
}
} }
return QVariant(); return QVariant();
} }
@ -882,3 +906,13 @@ void CodeCompletionListModel::notifyUpdated()
beginResetModel(); beginResetModel();
endResetModel(); endResetModel();
} }
const ColorCallback &CodeCompletionListModel::colorCallback() const
{
return mColorCallback;
}
void CodeCompletionListModel::setColorCallback(const ColorCallback &newColorCallback)
{
mColorCallback = newColorCallback;
}

View File

@ -22,6 +22,8 @@ private:
KeyPressedCallback mKeypressedCallback; KeyPressedCallback mKeypressedCallback;
}; };
using ColorCallback = std::function<QColor (PStatement)>;
class CodeCompletionListModel : public QAbstractListModel { class CodeCompletionListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
public: public:
@ -29,9 +31,12 @@ public:
int rowCount(const QModelIndex &parent) const override; int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
void notifyUpdated(); void notifyUpdated();
const ColorCallback &colorCallback() const;
void setColorCallback(const ColorCallback &newColorCallback);
private: private:
const StatementList* mStatements; const StatementList* mStatements;
ColorCallback mColorCallback;
}; };
class CodeCompletionView : public QWidget class CodeCompletionView : public QWidget
@ -77,6 +82,7 @@ public:
const PStatement &currentStatement() const; const PStatement &currentStatement() const;
void setCurrentStatement(const PStatement &newCurrentStatement); void setCurrentStatement(const PStatement &newCurrentStatement);
QHash<StatementKind, QColor>& colors();
private: private:
void addChildren(PStatement scopeStatement, const QString& fileName, void addChildren(PStatement scopeStatement, const QString& fileName,
@ -98,6 +104,7 @@ private:
QString mPhrase; QString mPhrase;
QHash<QString,int> mSymbolUsage; QHash<QString,int> mSymbolUsage;
QRecursiveMutex mMutex; QRecursiveMutex mMutex;
QHash<StatementKind, QColor> mColors;
PCppParser mParser; PCppParser mParser;
PStatement mCurrentStatement; PStatement mCurrentStatement;