- fix: preprocessors is not correctly suggested.

- fix: javadoc-style docstring is not correctly suggested
  - enhancement: Better syntax color for asm files.
This commit is contained in:
Roy Qu 2023-02-09 21:01:01 +08:00
parent cc1e42193d
commit f91e35192f
7 changed files with 260 additions and 214 deletions

View File

@ -15,6 +15,9 @@ Red Panda C++ Version 2.11
- enhancement: Support compile asm files using nasm in the project.
- fix: Project parser should not parse non-c/cpp files.
- enhancement: Add "assembler" tab in the project options dialog's custom compiler parameters.
- fix: preprocessors is not correctly suggested.
- fix: javadoc-style docstring is not correctly suggested
- enhancement: Better syntax color for asm files.
Red Panda C++ Version 2.10

View File

@ -31,6 +31,7 @@
#include <QMimeData>
#include <QTemporaryFile>
#include "qsynedit/syntaxer/cpp.h"
#include "qsynedit/syntaxer/asm.h"
#include "syntaxermanager.h"
#include "qsynedit/exporter/rtfexporter.h"
#include "qsynedit/exporter/htmlexporter.h"
@ -119,6 +120,7 @@ Editor::Editor(QWidget *parent, const QString& filename,
}
if (mProject) {
if (syntaxer->language() == QSynedit::ProgrammingLanguage::CPP)
mParser = mProject->cppParser();
} else {
initParser();
@ -832,15 +834,16 @@ void Editor::keyPressEvent(QKeyEvent *event)
if (isIdentChar(ch)) {
mLastIdCharPressed++;
if (pSettings->codeCompletion().enabled()
&& pSettings->codeCompletion().showCompletionWhileInput() ) {
if (mParser && mParser->isIncludeLine(lineText())
&& pSettings->codeCompletion().showCompletionWhileInput()
&& mLastIdCharPressed==pSettings->codeCompletion().minCharRequired()) {
if (mParser) {
if (mParser->isIncludeLine(lineText())) {
// is a #include line
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showHeaderCompletion(false);
handled=true;
return;
} else if (mLastIdCharPressed==pSettings->codeCompletion().minCharRequired()){
} else {
QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY());
if (mParser && !lastWord.isEmpty()) {
if (lastWord == "using") {
@ -926,24 +929,26 @@ void Editor::keyPressEvent(QKeyEvent *event)
handled=true;
return;
}
} else if (syntaxer()) {
//show keywords
showCompletion("",false,CodeCompletionType::KeywordsOnly);
}
}
} else {
//preprocessor ?
if (mParser && (mLastIdCharPressed=0) && (ch=='#') && lineText().isEmpty()) {
if (pSettings->codeCompletion().enabled()
&& pSettings->codeCompletion().showCompletionWhileInput() ) {
if (mParser) {
//preprocessor ?
if ((mLastIdCharPressed==0) && (ch=='#') && lineText().isEmpty()) {
mLastIdCharPressed++;
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion("",false,CodeCompletionType::Normal);
handled=true;
return;
}
}
//javadoc directive?
if (mParser && (mLastIdCharPressed=0) && (ch=='#') &&
if ((mLastIdCharPressed==0) && (ch=='@') &&
lineText().trimmed().startsWith('*')) {
if (pSettings->codeCompletion().enabled()
&& pSettings->codeCompletion().showCompletionWhileInput() ) {
mLastIdCharPressed++;
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion("",false,CodeCompletionType::Normal);
@ -951,6 +956,7 @@ void Editor::keyPressEvent(QKeyEvent *event)
return;
}
}
}
mLastIdCharPressed = 0;
switch (ch.unicode()) {
case '"':
@ -3183,11 +3189,16 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
}
if (!pSettings->codeCompletion().enabled())
return;
if (type==CodeCompletionType::KeywordsOnly) {
if (!syntaxer())
return;
} else {
if (!mParser || !mParser->enabled())
return;
if (!syntaxer())
return;
}
if (mCompletionPopup->isVisible()) // already in search, don't do it again
return;
@ -3229,12 +3240,16 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
mCompletionPopup->setRecordUsage(pSettings->codeCompletion().recordUsage());
mCompletionPopup->setSortByScope(pSettings->codeCompletion().sortByScope());
mCompletionPopup->setShowKeywords(pSettings->codeCompletion().showKeywords());
if (type!=CodeCompletionType::Normal)
mCompletionPopup->setShowCodeSnippets(false);
else {
mCompletionPopup->setShowCodeSnippets(pSettings->codeCompletion().showCodeIns());
mCompletionPopup->setHideSymbolsStartWithUnderline(pSettings->codeCompletion().hideSymbolsStartsWithUnderLine());
mCompletionPopup->setHideSymbolsStartWithTwoUnderline(pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine());
if (pSettings->codeCompletion().showCodeIns()) {
mCompletionPopup->setCodeSnippets(pMainWindow->codeSnippetManager()->snippets());
}
}
mCompletionPopup->setHideSymbolsStartWithUnderline(pSettings->codeCompletion().hideSymbolsStartsWithUnderLine());
mCompletionPopup->setHideSymbolsStartWithTwoUnderline(pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine());
mCompletionPopup->setIgnoreCase(pSettings->codeCompletion().ignoreCase());
mCompletionPopup->resize(pSettings->codeCompletion().width(),
pSettings->codeCompletion().height());
@ -3249,18 +3264,30 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
return onCompletionKeyPressed(event);
});
mCompletionPopup->setParser(mParser);
if (mParser) {
mCompletionPopup->setCurrentScope(
mParser->findScopeStatement(mFilename, caretY())
);
}
pMainWindow->functionTip()->hide();
mCompletionPopup->show();
// Scan the current function body
mCompletionPopup->setCurrentScope(
mParser->findScopeStatement(mFilename, caretY())
);
QSet<QString> keywords;
if (syntaxer()) {
if (syntaxer()->language() != QSynedit::ProgrammingLanguage::CPP ) {
if (syntaxer()->language()==QSynedit::ProgrammingLanguage::Assembly) {
keywords = QSynedit::ASMSyntaxer::Directives;
foreach(const QString& keyword, QSynedit::ASMSyntaxer::Registers) {
keywords.insert(keyword);
}
foreach(const QString& keyword, QSynedit::ASMSyntaxer::Instructions) {
keywords.insert(keyword);
}
} else {
keywords = syntaxer()->keywords();
}
} else {
if (mUseCppSyntax) {
foreach (const QString& keyword, CppKeywords.keys()) {
@ -4289,6 +4316,7 @@ void Editor::setProject(Project *pProject)
return;
mProject = pProject;
if (mProject) {
if (syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP) {
mParser = mProject->cppParser();
if (isVisible()) {
if (mParser && mParser->parsing()) {
@ -4300,6 +4328,7 @@ void Editor::setProject(Project *pProject)
invalidate();
}
}
}
} else {
initParser();
}

View File

@ -849,7 +849,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../settingsdialog/compilersetoptionwidget.ui" line="426"/>
<source>Assembler</source>
<translation type="unfinished"></translation>
<translation>(NASM)</translation>
</message>
<message>
<location filename="../settingsdialog/compilersetoptionwidget.ui" line="464"/>
@ -1084,7 +1084,7 @@ Are you really want to continue?</oldsource>
<message>
<location filename="../settingsdialog/compilersetoptionwidget.cpp" line="456"/>
<source>Locate nasm</source>
<translation type="unfinished"></translation>
<translation>nasm程序</translation>
</message>
</context>
<context>
@ -1111,12 +1111,12 @@ Are you really want to continue?</oldsource>
<location filename="../cpprefacter.cpp" line="187"/>
<location filename="../cpprefacter.cpp" line="198"/>
<source>Searching...</source>
<translation type="unfinished">...</translation>
<translation>...</translation>
</message>
<message>
<location filename="../cpprefacter.cpp" line="188"/>
<source>Abort</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
</context>
<context>
@ -1402,13 +1402,13 @@ Are you really want to continue?</oldsource>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../editor.cpp" line="343"/>
<location filename="../editor.cpp" line="429"/>
<location filename="../editor.cpp" line="458"/>
<location filename="../editor.cpp" line="1550"/>
<location filename="../editor.cpp" line="1555"/>
<location filename="../editor.cpp" line="1575"/>
<location filename="../editor.cpp" line="1580"/>
<location filename="../editor.cpp" line="345"/>
<location filename="../editor.cpp" line="431"/>
<location filename="../editor.cpp" line="460"/>
<location filename="../editor.cpp" line="1556"/>
<location filename="../editor.cpp" line="1561"/>
<location filename="../editor.cpp" line="1581"/>
<location filename="../editor.cpp" line="1586"/>
<source>Error</source>
<translation></translation>
</message>
@ -1417,8 +1417,8 @@ Are you really want to continue?</oldsource>
<translation type="vanished">&quot;%1&quot;</translation>
</message>
<message>
<location filename="../editor.cpp" line="106"/>
<location filename="../editor.cpp" line="532"/>
<location filename="../editor.cpp" line="107"/>
<location filename="../editor.cpp" line="534"/>
<source>Error Load File</source>
<translation></translation>
</message>
@ -1447,44 +1447,44 @@ Are you really want to continue?</oldsource>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../editor.cpp" line="373"/>
<location filename="../editor.cpp" line="375"/>
<source>Save As</source>
<translation></translation>
</message>
<message>
<location filename="../editor.cpp" line="430"/>
<location filename="../editor.cpp" line="432"/>
<source>File %1 already openned!</source>
<translation>%1</translation>
</message>
<message>
<location filename="../editor.cpp" line="1551"/>
<location filename="../editor.cpp" line="1557"/>
<source>The text to be copied exceeds count limit!</source>
<translation></translation>
</message>
<message>
<location filename="../editor.cpp" line="1556"/>
<location filename="../editor.cpp" line="1562"/>
<source>The text to be copied exceeds character limit!</source>
<translation></translation>
</message>
<message>
<location filename="../editor.cpp" line="1576"/>
<location filename="../editor.cpp" line="1582"/>
<source>The text to be cut exceeds count limit!</source>
<translation></translation>
</message>
<message>
<location filename="../editor.cpp" line="1581"/>
<location filename="../editor.cpp" line="1587"/>
<source>The text to be cut exceeds character limit!</source>
<translation></translation>
</message>
<message>
<location filename="../editor.cpp" line="3086"/>
<location filename="../editor.cpp" line="3092"/>
<source>Print Document</source>
<translation></translation>
</message>
<message>
<location filename="../editor.cpp" line="3778"/>
<location filename="../editor.cpp" line="3825"/>
<location filename="../editor.cpp" line="3870"/>
<location filename="../editor.cpp" line="3805"/>
<location filename="../editor.cpp" line="3852"/>
<location filename="../editor.cpp" line="3897"/>
<source>Ctrl+click for more info</source>
<translation>Ctrl+</translation>
</message>
@ -1493,27 +1493,27 @@ Are you really want to continue?</oldsource>
<translation type="vanished">&apos;%1&apos;!</translation>
</message>
<message>
<location filename="../editor.cpp" line="4709"/>
<location filename="../editor.cpp" line="4738"/>
<source>astyle not found</source>
<translation>astyle程序</translation>
</message>
<message>
<location filename="../editor.cpp" line="4710"/>
<location filename="../editor.cpp" line="4739"/>
<source>Can&apos;t find astyle in &quot;%1&quot;.</source>
<translation>astyle程序&quot;%1&quot;.</translation>
</message>
<message>
<location filename="../editor.cpp" line="4869"/>
<location filename="../editor.cpp" line="4898"/>
<source>Break point condition</source>
<translation></translation>
</message>
<message>
<location filename="../editor.cpp" line="4870"/>
<location filename="../editor.cpp" line="4899"/>
<source>Enter the condition of the breakpoint:</source>
<translation>:</translation>
</message>
<message>
<location filename="../editor.cpp" line="5115"/>
<location filename="../editor.cpp" line="5144"/>
<source>Readonly</source>
<translation></translation>
</message>
@ -7346,7 +7346,7 @@ Are you really want to continue?</oldsource>
<message>
<location filename="../settingsdialog/projectcompileparamaterswidget.ui" line="186"/>
<source>Assembler</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog/projectcompileparamaterswidget.cpp" line="75"/>

View File

@ -104,6 +104,10 @@ void CodeCompletionPopup::prepareSearch(
mIncludedFiles = mParser->getFileIncludes(filename);
getCompletionListForNamespaces(preWord,filename,line);
break;
case CodeCompletionType::KeywordsOnly:
mIncludedFiles.clear();
getKeywordCompletionFor(customKeywords);
break;
default:
mIncludedFiles = mParser->getFileIncludes(filename);
getCompletionFor(ownerExpression,memberOperator,memberExpression, filename,line, customKeywords);
@ -419,21 +423,12 @@ void CodeCompletionPopup::filterList(const QString &member)
{
QMutexLocker locker(&mMutex);
mCompletionStatementList.clear();
if (!mParser)
return;
if (!mParser->enabled())
return;
// if (!mParser)
// return;
// if (!mParser->enabled())
// return;
//we don't need to freeze here since we use smart pointers
// and data have been retrieved from the parser
// if (!mParser->freeze())
// return;
// {
// auto action = finally([this]{
// mParser->unFreeze();
// });
// if (mParserSerialId!=mParser->serialId()) {
// return;
// }
mCompletionStatementList.clear();
mCompletionStatementList.reserve(mFullCompletionStatementList.size());
@ -539,6 +534,16 @@ void CodeCompletionPopup::filterList(const QString &member)
// }
}
void CodeCompletionPopup::getKeywordCompletionFor(const QSet<QString> &customKeywords)
{
//add keywords
if (!customKeywords.isEmpty()) {
foreach (const QString& keyword,customKeywords) {
addKeyword(keyword);
}
}
}
void CodeCompletionPopup::getCompletionFor(
QStringList ownerExpression,
const QString& memberOperator,
@ -547,27 +552,10 @@ void CodeCompletionPopup::getCompletionFor(
int line,
const QSet<QString>& customKeywords)
{
if(!mParser) {
if (mShowKeywords) {
//add keywords
foreach (const QString& keyword,customKeywords) {
addKeyword(keyword);
}
}
return;
}
if (!mParser->enabled())
return;
if (memberOperator.isEmpty() && ownerExpression.isEmpty() && memberExpression.isEmpty())
return;
if (!mParser->freeze())
return;
{
auto action = finally([this]{
mParser->unFreeze();
});
if (memberOperator.isEmpty()) {
//C++ preprocessor directives
if (mMemberPhrase.startsWith('#')) {
@ -613,7 +601,19 @@ void CodeCompletionPopup::getCompletionFor(
}
}
}
}
if (!mParser || !mParser->enabled())
return;
if (!mParser->freeze())
return;
{
auto action = finally([this]{
mParser->unFreeze();
});
if (memberOperator.isEmpty()) {
PStatement scopeStatement = mCurrentScope;
// repeat until reach global
while (scopeStatement) {

View File

@ -41,7 +41,8 @@ enum class CodeCompletionType {
Normal,
ComplexKeyword,
FunctionWithoutDefinition,
Namespaces
Namespaces,
KeywordsOnly
};
class CodeCompletionListItemDelegate: public QStyledItemDelegate {
@ -133,6 +134,7 @@ private:
int line);
void addStatement(const PStatement& statement, const QString& fileName, int line);
void filterList(const QString& member);
void getKeywordCompletionFor(const QSet<QString>& customKeywords);
void getCompletionFor(
QStringList ownerExpression,
const QString& memberOperator,

View File

@ -37,7 +37,7 @@ const QSet<QString> ASMSyntaxer::Registers {
"r15h","r15l","r15w","r15d"
};
const QSet<QString> ASMSyntaxer::Keywords {
const QSet<QString> ASMSyntaxer::Instructions {
"movb","movw","movl","movq",
"leab","leaw","leal","leaq",
"incb","incw","incl","incq",
@ -91,7 +91,13 @@ const QSet<QString> ASMSyntaxer::Keywords {
"setna","setnae","setnb","setnbe","setnc","setne","setng","setnge","setnl","setnle","setno",
"setnp","setns","setnz","seto","setp","setpo","sets","setz","sgdt","shl","shld","shr","shrd","sidt",
"sldt","smsw","stc","std","sti","stos","stosb","stosd","stosw","str","sub","test","verr","verw",
"wait","wbinvd","xadd","xchg","xlat","xlatb","xor"
"wait","wbinvd","xadd","xchg","xlat","xlatb","xor",
};
const QSet<QString> ASMSyntaxer::Directives {
"section","global","extern","segment",
"db","dw","dd","dq","dt","do","dy","dz",
"resb","resw","resd","resq","rest","reso","resy","resz",
};
@ -160,10 +166,12 @@ void ASMSyntaxer::IdentProc(IdentPrefix prefix)
mTokenID = TokenId::Directive;
break;
default:
if (Keywords.contains(s))
if (Instructions.contains(s))
mTokenID = TokenId::Instruction;
else if (Registers.contains(s))
mTokenID = TokenId::Register;
else if (Directives.contains(s))
mTokenID = TokenId::Directive;
else if (mLine[mRun]==':')
mTokenID = TokenId::Label;
else
@ -460,7 +468,10 @@ void ASMSyntaxer::resetState()
QSet<QString> ASMSyntaxer::keywords() const
{
return Keywords;
QSet<QString> result=Instructions;
result.unite(Directives);
result.unite(Registers);
return result;
}
const PTokenAttribute &ASMSyntaxer::directiveAttribute() const

View File

@ -53,8 +53,9 @@ public:
const PTokenAttribute &labelAttribute() const;
const PTokenAttribute &registerAttribute() const;
static const QSet<QString> Keywords;
static const QSet<QString> Instructions;
static const QSet<QString> Registers;
static const QSet<QString> Directives;
private:
QChar* mLine;
QString mLineString;