- 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. - enhancement: Support compile asm files using nasm in the project.
- fix: Project parser should not parse non-c/cpp files. - fix: Project parser should not parse non-c/cpp files.
- enhancement: Add "assembler" tab in the project options dialog's custom compiler parameters. - 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 Red Panda C++ Version 2.10

View File

@ -31,6 +31,7 @@
#include <QMimeData> #include <QMimeData>
#include <QTemporaryFile> #include <QTemporaryFile>
#include "qsynedit/syntaxer/cpp.h" #include "qsynedit/syntaxer/cpp.h"
#include "qsynedit/syntaxer/asm.h"
#include "syntaxermanager.h" #include "syntaxermanager.h"
#include "qsynedit/exporter/rtfexporter.h" #include "qsynedit/exporter/rtfexporter.h"
#include "qsynedit/exporter/htmlexporter.h" #include "qsynedit/exporter/htmlexporter.h"
@ -119,7 +120,8 @@ Editor::Editor(QWidget *parent, const QString& filename,
} }
if (mProject) { if (mProject) {
mParser = mProject->cppParser(); if (syntaxer->language() == QSynedit::ProgrammingLanguage::CPP)
mParser = mProject->cppParser();
} else { } else {
initParser(); initParser();
} }
@ -832,65 +834,84 @@ void Editor::keyPressEvent(QKeyEvent *event)
if (isIdentChar(ch)) { if (isIdentChar(ch)) {
mLastIdCharPressed++; mLastIdCharPressed++;
if (pSettings->codeCompletion().enabled() if (pSettings->codeCompletion().enabled()
&& pSettings->codeCompletion().showCompletionWhileInput() ) { && pSettings->codeCompletion().showCompletionWhileInput()
if (mParser && mParser->isIncludeLine(lineText()) && mLastIdCharPressed==pSettings->codeCompletion().minCharRequired()) {
&& mLastIdCharPressed==pSettings->codeCompletion().minCharRequired()) { if (mParser) {
// is a #include line if (mParser->isIncludeLine(lineText())) {
processCommand(QSynedit::EditCommand::Char,ch,nullptr); // is a #include line
showHeaderCompletion(false); processCommand(QSynedit::EditCommand::Char,ch,nullptr);
handled=true; showHeaderCompletion(false);
return; handled=true;
} else if (mLastIdCharPressed==pSettings->codeCompletion().minCharRequired()){ return;
QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY()); } else {
if (mParser && !lastWord.isEmpty()) { QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY());
if (lastWord == "using") { if (mParser && !lastWord.isEmpty()) {
processCommand(QSynedit::EditCommand::Char,ch,nullptr); if (lastWord == "using") {
showCompletion(lastWord,false, CodeCompletionType::ComplexKeyword);
handled=true;
return;
} else if (lastWord == "namespace") {
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false, CodeCompletionType::Namespaces);
handled=true;
return;
} else if (CppTypeKeywords.contains(lastWord)) {
PStatement currentScope = mParser->findScopeStatement(mFilename,caretY());
while(currentScope && currentScope->kind==StatementKind::skBlock) {
currentScope = currentScope->parentScope.lock();
}
if (!currentScope || currentScope->kind == StatementKind::skNamespace
|| currentScope->kind == StatementKind::skClass) {
//may define a function
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false,CodeCompletionType::FunctionWithoutDefinition);
handled=true;
return;
}
if (lastWord == "long" ||
lastWord == "short" ||
lastWord == "signed" ||
lastWord == "unsigned"
) {
processCommand(QSynedit::EditCommand::Char,ch,nullptr); processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false, CodeCompletionType::ComplexKeyword); showCompletion(lastWord,false, CodeCompletionType::ComplexKeyword);
handled=true; handled=true;
return; return;
} else if (lastWord == "namespace") {
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false, CodeCompletionType::Namespaces);
handled=true;
return;
} else if (CppTypeKeywords.contains(lastWord)) {
PStatement currentScope = mParser->findScopeStatement(mFilename,caretY());
while(currentScope && currentScope->kind==StatementKind::skBlock) {
currentScope = currentScope->parentScope.lock();
}
if (!currentScope || currentScope->kind == StatementKind::skNamespace
|| currentScope->kind == StatementKind::skClass) {
//may define a function
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false,CodeCompletionType::FunctionWithoutDefinition);
handled=true;
return;
}
if (lastWord == "long" ||
lastWord == "short" ||
lastWord == "signed" ||
lastWord == "unsigned"
) {
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false, CodeCompletionType::ComplexKeyword);
handled=true;
return;
}
//last word is a type keyword, this is a var or param define, and dont show suggestion
return;
} }
PStatement statement = mParser->findStatementOf(
mFilename,
lastWord,
caretY());
StatementKind kind = getKindOfStatement(statement);
if (kind == StatementKind::skClass
|| kind == StatementKind::skEnumClassType
|| kind == StatementKind::skEnumType
|| kind == StatementKind::skTypedef) {
PStatement currentScope = mParser->findScopeStatement(mFilename,caretY());
while(currentScope && currentScope->kind==StatementKind::skBlock) {
currentScope = currentScope->parentScope.lock();
}
if (!currentScope || currentScope->kind == StatementKind::skNamespace) {
//may define a function
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion("",false,CodeCompletionType::FunctionWithoutDefinition);
handled=true;
return;
}
//last word is a type keyword, this is a var or param define, and dont show suggestion //last word is a typedef/class/struct, this is a var or param define, and dont show suggestion
return; return;
}
} }
PStatement statement = mParser->findStatementOf( lastWord = getPreviousWordAtPositionForCompleteFunctionDefinition(caretXY());
mFilename, if (mParser && !lastWord.isEmpty()) {
lastWord,
caretY());
StatementKind kind = getKindOfStatement(statement);
if (kind == StatementKind::skClass
|| kind == StatementKind::skEnumClassType
|| kind == StatementKind::skEnumType
|| kind == StatementKind::skTypedef) {
PStatement currentScope = mParser->findScopeStatement(mFilename,caretY()); PStatement currentScope = mParser->findScopeStatement(mFilename,caretY());
while(currentScope && currentScope->kind==StatementKind::skBlock) { while(currentScope && currentScope->kind==StatementKind::skBlock) {
currentScope = currentScope->parentScope.lock(); currentScope = currentScope->parentScope.lock();
@ -902,53 +923,38 @@ void Editor::keyPressEvent(QKeyEvent *event)
handled=true; handled=true;
return; return;
} }
//last word is a typedef/class/struct, this is a var or param define, and dont show suggestion
return;
} }
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion("",false,CodeCompletionType::Normal);
handled=true;
return;
} }
lastWord = getPreviousWordAtPositionForCompleteFunctionDefinition(caretXY()); } else if (syntaxer()) {
if (mParser && !lastWord.isEmpty()) { //show keywords
PStatement currentScope = mParser->findScopeStatement(mFilename,caretY()); showCompletion("",false,CodeCompletionType::KeywordsOnly);
while(currentScope && currentScope->kind==StatementKind::skBlock) {
currentScope = currentScope->parentScope.lock();
}
if (!currentScope || currentScope->kind == StatementKind::skNamespace) {
//may define a function
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion("",false,CodeCompletionType::FunctionWithoutDefinition);
handled=true;
return;
}
}
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion("",false,CodeCompletionType::Normal);
handled=true;
return;
} }
} }
} else { } else {
//preprocessor ? if (pSettings->codeCompletion().enabled()
if (mParser && (mLastIdCharPressed=0) && (ch=='#') && lineText().isEmpty()) { && pSettings->codeCompletion().showCompletionWhileInput() ) {
if (pSettings->codeCompletion().enabled() if (mParser) {
&& pSettings->codeCompletion().showCompletionWhileInput() ) { //preprocessor ?
mLastIdCharPressed++; if ((mLastIdCharPressed==0) && (ch=='#') && lineText().isEmpty()) {
processCommand(QSynedit::EditCommand::Char,ch,nullptr); mLastIdCharPressed++;
showCompletion("",false,CodeCompletionType::Normal); processCommand(QSynedit::EditCommand::Char,ch,nullptr);
handled=true; showCompletion("",false,CodeCompletionType::Normal);
return; handled=true;
} return;
} }
//javadoc directive? //javadoc directive?
if (mParser && (mLastIdCharPressed=0) && (ch=='#') && if ((mLastIdCharPressed==0) && (ch=='@') &&
lineText().trimmed().startsWith('*')) { lineText().trimmed().startsWith('*')) {
if (pSettings->codeCompletion().enabled() mLastIdCharPressed++;
&& pSettings->codeCompletion().showCompletionWhileInput() ) { processCommand(QSynedit::EditCommand::Char,ch,nullptr);
mLastIdCharPressed++; showCompletion("",false,CodeCompletionType::Normal);
processCommand(QSynedit::EditCommand::Char,ch,nullptr); handled=true;
showCompletion("",false,CodeCompletionType::Normal); return;
handled=true; }
return;
} }
} }
mLastIdCharPressed = 0; mLastIdCharPressed = 0;
@ -3183,11 +3189,16 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
} }
if (!pSettings->codeCompletion().enabled()) if (!pSettings->codeCompletion().enabled())
return; return;
if (!mParser || !mParser->enabled()) if (type==CodeCompletionType::KeywordsOnly) {
return; if (!syntaxer())
return;
} else {
if (!mParser || !mParser->enabled())
return;
if (!syntaxer()) if (!syntaxer())
return; return;
}
if (mCompletionPopup->isVisible()) // already in search, don't do it again if (mCompletionPopup->isVisible()) // already in search, don't do it again
return; return;
@ -3229,12 +3240,16 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
mCompletionPopup->setRecordUsage(pSettings->codeCompletion().recordUsage()); mCompletionPopup->setRecordUsage(pSettings->codeCompletion().recordUsage());
mCompletionPopup->setSortByScope(pSettings->codeCompletion().sortByScope()); mCompletionPopup->setSortByScope(pSettings->codeCompletion().sortByScope());
mCompletionPopup->setShowKeywords(pSettings->codeCompletion().showKeywords()); mCompletionPopup->setShowKeywords(pSettings->codeCompletion().showKeywords());
mCompletionPopup->setShowCodeSnippets(pSettings->codeCompletion().showCodeIns()); if (type!=CodeCompletionType::Normal)
mCompletionPopup->setShowCodeSnippets(false);
else {
mCompletionPopup->setShowCodeSnippets(pSettings->codeCompletion().showCodeIns());
if (pSettings->codeCompletion().showCodeIns()) {
mCompletionPopup->setCodeSnippets(pMainWindow->codeSnippetManager()->snippets());
}
}
mCompletionPopup->setHideSymbolsStartWithUnderline(pSettings->codeCompletion().hideSymbolsStartsWithUnderLine()); mCompletionPopup->setHideSymbolsStartWithUnderline(pSettings->codeCompletion().hideSymbolsStartsWithUnderLine());
mCompletionPopup->setHideSymbolsStartWithTwoUnderline(pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine()); mCompletionPopup->setHideSymbolsStartWithTwoUnderline(pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine());
if (pSettings->codeCompletion().showCodeIns()) {
mCompletionPopup->setCodeSnippets(pMainWindow->codeSnippetManager()->snippets());
}
mCompletionPopup->setIgnoreCase(pSettings->codeCompletion().ignoreCase()); mCompletionPopup->setIgnoreCase(pSettings->codeCompletion().ignoreCase());
mCompletionPopup->resize(pSettings->codeCompletion().width(), mCompletionPopup->resize(pSettings->codeCompletion().width(),
pSettings->codeCompletion().height()); pSettings->codeCompletion().height());
@ -3249,18 +3264,30 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
return onCompletionKeyPressed(event); return onCompletionKeyPressed(event);
}); });
mCompletionPopup->setParser(mParser); mCompletionPopup->setParser(mParser);
if (mParser) {
mCompletionPopup->setCurrentScope(
mParser->findScopeStatement(mFilename, caretY())
);
}
pMainWindow->functionTip()->hide(); pMainWindow->functionTip()->hide();
mCompletionPopup->show(); mCompletionPopup->show();
// Scan the current function body // Scan the current function body
mCompletionPopup->setCurrentScope(
mParser->findScopeStatement(mFilename, caretY())
);
QSet<QString> keywords; QSet<QString> keywords;
if (syntaxer()) { if (syntaxer()) {
if (syntaxer()->language() != QSynedit::ProgrammingLanguage::CPP ) { if (syntaxer()->language() != QSynedit::ProgrammingLanguage::CPP ) {
keywords = syntaxer()->keywords(); 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 { } else {
if (mUseCppSyntax) { if (mUseCppSyntax) {
foreach (const QString& keyword, CppKeywords.keys()) { foreach (const QString& keyword, CppKeywords.keys()) {
@ -4289,15 +4316,17 @@ void Editor::setProject(Project *pProject)
return; return;
mProject = pProject; mProject = pProject;
if (mProject) { if (mProject) {
mParser = mProject->cppParser(); if (syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP) {
if (isVisible()) { mParser = mProject->cppParser();
if (mParser && mParser->parsing()) { if (isVisible()) {
connect(mParser.get(), if (mParser && mParser->parsing()) {
&CppParser::onEndParsing, connect(mParser.get(),
this, &CppParser::onEndParsing,
&QSynedit::QSynEdit::invalidate); this,
} else { &QSynedit::QSynEdit::invalidate);
invalidate(); } else {
invalidate();
}
} }
} }
} else { } else {

View File

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

View File

@ -104,6 +104,10 @@ void CodeCompletionPopup::prepareSearch(
mIncludedFiles = mParser->getFileIncludes(filename); mIncludedFiles = mParser->getFileIncludes(filename);
getCompletionListForNamespaces(preWord,filename,line); getCompletionListForNamespaces(preWord,filename,line);
break; break;
case CodeCompletionType::KeywordsOnly:
mIncludedFiles.clear();
getKeywordCompletionFor(customKeywords);
break;
default: default:
mIncludedFiles = mParser->getFileIncludes(filename); mIncludedFiles = mParser->getFileIncludes(filename);
getCompletionFor(ownerExpression,memberOperator,memberExpression, filename,line, customKeywords); getCompletionFor(ownerExpression,memberOperator,memberExpression, filename,line, customKeywords);
@ -419,21 +423,12 @@ void CodeCompletionPopup::filterList(const QString &member)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
mCompletionStatementList.clear(); mCompletionStatementList.clear();
if (!mParser) // if (!mParser)
return; // return;
if (!mParser->enabled()) // if (!mParser->enabled())
return; // return;
//we don't need to freeze here since we use smart pointers //we don't need to freeze here since we use smart pointers
// and data have been retrieved from the parser // 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.clear();
mCompletionStatementList.reserve(mFullCompletionStatementList.size()); 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( void CodeCompletionPopup::getCompletionFor(
QStringList ownerExpression, QStringList ownerExpression,
const QString& memberOperator, const QString& memberOperator,
@ -547,18 +552,58 @@ void CodeCompletionPopup::getCompletionFor(
int line, int line,
const QSet<QString>& customKeywords) const QSet<QString>& customKeywords)
{ {
if(!mParser) {
if (memberOperator.isEmpty() && ownerExpression.isEmpty() && memberExpression.isEmpty())
return;
if (memberOperator.isEmpty()) {
//C++ preprocessor directives
if (mMemberPhrase.startsWith('#')) {
if (mShowKeywords) {
foreach (const QString& keyword, CppDirectives) {
addKeyword(keyword);
}
}
return;
}
//docstring tags (javadoc style)
if (mMemberPhrase.startsWith('@')) {
if (mShowKeywords) {
foreach (const QString& keyword,JavadocTags) {
addKeyword(keyword);
}
}
return;
}
//the identifier to be completed is not a member of variable/class
if (mShowCodeSnippets) {
//add custom code templates
foreach (const PCodeSnippet& codeIn,mCodeSnippets) {
if (!codeIn->code.isEmpty()) {
PStatement statement = std::make_shared<Statement>();
statement->command = codeIn->prefix;
statement->value = codeIn->code;
statement->kind = StatementKind::skUserCodeSnippet;
statement->fullName = codeIn->prefix;
statement->usageCount = 0;
mFullCompletionStatementList.append(statement);
}
}
}
if (mShowKeywords) { if (mShowKeywords) {
//add keywords //add keywords
if (!customKeywords.isEmpty()) {
foreach (const QString& keyword,customKeywords) { foreach (const QString& keyword,customKeywords) {
addKeyword(keyword); addKeyword(keyword);
} }
}
} }
return;
} }
if (!mParser->enabled())
return; if (!mParser || !mParser->enabled())
if (memberOperator.isEmpty() && ownerExpression.isEmpty() && memberExpression.isEmpty())
return; return;
if (!mParser->freeze()) if (!mParser->freeze())
@ -569,51 +614,6 @@ void CodeCompletionPopup::getCompletionFor(
}); });
if (memberOperator.isEmpty()) { if (memberOperator.isEmpty()) {
//C++ preprocessor directives
if (mMemberPhrase.startsWith('#')) {
if (mShowKeywords) {
foreach (const QString& keyword, CppDirectives) {
addKeyword(keyword);
}
}
return;
}
//docstring tags (javadoc style)
if (mMemberPhrase.startsWith('@')) {
if (mShowKeywords) {
foreach (const QString& keyword,JavadocTags) {
addKeyword(keyword);
}
}
return;
}
//the identifier to be completed is not a member of variable/class
if (mShowCodeSnippets) {
//add custom code templates
foreach (const PCodeSnippet& codeIn,mCodeSnippets) {
if (!codeIn->code.isEmpty()) {
PStatement statement = std::make_shared<Statement>();
statement->command = codeIn->prefix;
statement->value = codeIn->code;
statement->kind = StatementKind::skUserCodeSnippet;
statement->fullName = codeIn->prefix;
statement->usageCount = 0;
mFullCompletionStatementList.append(statement);
}
}
}
if (mShowKeywords) {
//add keywords
if (!customKeywords.isEmpty()) {
foreach (const QString& keyword,customKeywords) {
addKeyword(keyword);
}
}
}
PStatement scopeStatement = mCurrentScope; PStatement scopeStatement = mCurrentScope;
// repeat until reach global // repeat until reach global
while (scopeStatement) { while (scopeStatement) {

View File

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

View File

@ -37,7 +37,7 @@ const QSet<QString> ASMSyntaxer::Registers {
"r15h","r15l","r15w","r15d" "r15h","r15l","r15w","r15d"
}; };
const QSet<QString> ASMSyntaxer::Keywords { const QSet<QString> ASMSyntaxer::Instructions {
"movb","movw","movl","movq", "movb","movw","movl","movq",
"leab","leaw","leal","leaq", "leab","leaw","leal","leaq",
"incb","incw","incl","incq", "incb","incw","incl","incq",
@ -76,7 +76,7 @@ const QSet<QString> ASMSyntaxer::Keywords {
"ja","jae","jb","jbe","jc","jcxz","je","jecxz","jg","jge","jl","jle","jmp","jna","jnae","jnb","jnbe","jnc", "ja","jae","jb","jbe","jc","jcxz","je","jecxz","jg","jge","jl","jle","jmp","jna","jnae","jnb","jnbe","jnc",
"jne","jng","jnge","jnl","jnle","jno","jnp","jns","jnz","jo","jp","jpe","jpo","js","jz","lahf","lar","lds", "jne","jng","jnge","jnl","jnle","jno","jnp","jns","jnz","jo","jp","jpe","jpo","js","jz","lahf","lar","lds",
"lea","leave","les","lfs","lgdt","lgs","lidt","lldt","lmsw","lock","lods","lodsb","lodsd","lodsw", "lea","leave","les","lfs","lgdt","lgs","lidt","lldt","lmsw","lock","lods","lodsb","lodsd","lodsw",
"loop","loope","loopne","loopnz","loopz","lsl","lss","ltr","mov","movd","movq"," movs","movsb", "loop","loope","loopne","loopnz","loopz","lsl","lss","ltr","mov","movd","movq","movs","movsb",
"movsd","movsw","movsx","movzx","mul","neg","nop","not","or","out","outs","outsb","outsd","outsw", "movsd","movsw","movsx","movzx","mul","neg","nop","not","or","out","outs","outsb","outsd","outsw",
"packssdw","packsswb","packuswb","paddb","paddd","paddsb","paddsw","paddusb","paddusw", "packssdw","packsswb","packuswb","paddb","paddd","paddsb","paddsw","paddusb","paddusw",
"paddw","pand","pandn","pavgusb","pcmpeqb","pcmpeqd","pcmpeqw","pcmpgtb","pcmpgtd","pcmpgtw", "paddw","pand","pandn","pavgusb","pcmpeqb","pcmpeqd","pcmpeqw","pcmpgtb","pcmpgtd","pcmpgtw",
@ -91,7 +91,13 @@ const QSet<QString> ASMSyntaxer::Keywords {
"setna","setnae","setnb","setnbe","setnc","setne","setng","setnge","setnl","setnle","setno", "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", "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", "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; mTokenID = TokenId::Directive;
break; break;
default: default:
if (Keywords.contains(s)) if (Instructions.contains(s))
mTokenID = TokenId::Instruction; mTokenID = TokenId::Instruction;
else if (Registers.contains(s)) else if (Registers.contains(s))
mTokenID = TokenId::Register; mTokenID = TokenId::Register;
else if (Directives.contains(s))
mTokenID = TokenId::Directive;
else if (mLine[mRun]==':') else if (mLine[mRun]==':')
mTokenID = TokenId::Label; mTokenID = TokenId::Label;
else else
@ -460,7 +468,10 @@ void ASMSyntaxer::resetState()
QSet<QString> ASMSyntaxer::keywords() const QSet<QString> ASMSyntaxer::keywords() const
{ {
return Keywords; QSet<QString> result=Instructions;
result.unite(Directives);
result.unite(Registers);
return result;
} }
const PTokenAttribute &ASMSyntaxer::directiveAttribute() const const PTokenAttribute &ASMSyntaxer::directiveAttribute() const

View File

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