From 177cd6e397d59de72a278418c28ce5d00ebb942b Mon Sep 17 00:00:00 2001 From: "royqh1979@gmail.com" Date: Thu, 18 Nov 2021 12:51:05 +0800 Subject: [PATCH] - enhancement: code completion suggestion for phrase after long/short/signed/unsigned --- NEWS.md | 1 + RedPandaIDE/editor.cpp | 29 +++-- RedPandaIDE/editor.h | 2 +- RedPandaIDE/parser/parserutils.cpp | 2 + RedPandaIDE/version.h | 2 +- RedPandaIDE/widgets/codecompletionpopup.cpp | 115 +++++++++++++------- RedPandaIDE/widgets/codecompletionpopup.h | 4 +- 7 files changed, 103 insertions(+), 52 deletions(-) diff --git a/NEWS.md b/NEWS.md index a28114e3..d73b17e5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ Version 0.9.1 For Dev-C++ 7 Beta - enhancement: code completion suggestion for "__func__" variable - fix: ide failed to start, if there are errors in the compiler set settings - fix: numpad's enter key doesn't work + - enhancement: code completion suggestion for phrase after long/short/signed/unsigned Version 0.9.0 For Dev-C++ 7 Beta - fix: control keys in the numpad doesn't work in the editor diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 904fa7ee..43287c3c 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -692,6 +692,16 @@ void Editor::keyPressEvent(QKeyEvent *event) QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY()); if (!lastWord.isEmpty()) { if (CppTypeKeywords.contains(lastWord)) { + if (lastWord == "long" || + lastWord == "short" || + lastWord == "signed" || + lastWord == "unsigned" + ) { + setSelText(ch); + showCompletion(lastWord,false); + handled=true; + return; + } //last word is a type keyword, this is a var or param define, and dont show suggestion // if devEditor.UseTabnine then // ShowTabnineCompletion; @@ -713,7 +723,7 @@ void Editor::keyPressEvent(QKeyEvent *event) } } setSelText(ch); - showCompletion(false); + showCompletion("",false); handled=true; return; } @@ -727,7 +737,7 @@ void Editor::keyPressEvent(QKeyEvent *event) && pSettings->codeCompletion().showCompletionWhileInput() ) { mLastIdCharPressed++; setSelText(ch); - showCompletion(false); + showCompletion("",false); handled=true; return; } @@ -739,7 +749,7 @@ void Editor::keyPressEvent(QKeyEvent *event) && pSettings->codeCompletion().showCompletionWhileInput() ) { mLastIdCharPressed++; setSelText(ch); - showCompletion(false); + showCompletion("",false); handled=true; return; } @@ -1139,7 +1149,7 @@ void Editor::inputMethodEvent(QInputMethodEvent *event) return; } } - showCompletion(false); + showCompletion("",false); return; } } @@ -1904,20 +1914,20 @@ bool Editor::handleCodeCompletion(QChar key) switch(key.unicode()) { case '.': setSelText(key); - showCompletion(false); + showCompletion("",false); return true; case '>': setSelText(key); if ((caretX() > 2) && (lineText().length() >= 2) && (lineText()[caretX() - 3] == '-')) - showCompletion(false); + showCompletion("",false); return true; case ':': ExecuteCommand(SynEditorCommand::ecChar,':',nullptr); //setSelText(key); if ((caretX() > 2) && (lineText().length() >= 2) && (lineText()[caretX() - 3] == ':')) - showCompletion(false); + showCompletion("",false); return true; case '/': case '\\': @@ -2260,7 +2270,7 @@ void Editor::exportAsHTML(const QString &htmlFilename) exporter.SaveToFile(htmlFilename); } -void Editor::showCompletion(bool autoComplete) +void Editor::showCompletion(const QString& preWord,bool autoComplete) { if (!pSettings->codeCompletion().enabled()) return; @@ -2337,8 +2347,7 @@ void Editor::showCompletion(bool autoComplete) if (word.isEmpty()) word=getWordAtPosition(this,caretXY(),pBeginPos,pEndPos, WordPurpose::wpCompletion); - //if not fCompletionBox.Visible then - mCompletionPopup->prepareSearch(word, mFilename, pBeginPos.Line); + mCompletionPopup->prepareSearch(preWord, word, mFilename, pBeginPos.Line); // Filter the whole statement list if (mCompletionPopup->search(word, autoComplete)) { //only one suggestion and it's not input while typing diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index 70e44cfb..05c11159 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -202,7 +202,7 @@ private: void undoSymbolCompletion(int pos); QuoteStatus getQuoteStatus(); - void showCompletion(bool autoComplete); + void showCompletion(const QString& preWord, bool autoComplete); void showHeaderCompletion(bool autoComplete); bool testInFunc(int x,int y); diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index 6ba40616..e6254b2b 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -154,6 +154,8 @@ void initParser() //CppTypeKeywords.insert("unsigned"); CppTypeKeywords.insert("void"); CppTypeKeywords.insert("wchar_t"); + CppTypeKeywords.insert("signed"); + CppTypeKeywords.insert("unsigned"); // it's part of type info CppKeywords.insert("const",SkipType::skNone); diff --git a/RedPandaIDE/version.h b/RedPandaIDE/version.h index 7e546268..fe8b2949 100644 --- a/RedPandaIDE/version.h +++ b/RedPandaIDE/version.h @@ -2,6 +2,6 @@ #define VERSION_H #include -#define DEVCPP_VERSION "beta.0.9.0" +#define DEVCPP_VERSION "beta.0.9.1" #endif // VERSION_H diff --git a/RedPandaIDE/widgets/codecompletionpopup.cpp b/RedPandaIDE/widgets/codecompletionpopup.cpp index 78dbc867..a37331d1 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.cpp +++ b/RedPandaIDE/widgets/codecompletionpopup.cpp @@ -59,7 +59,7 @@ void CodeCompletionPopup::setKeypressedCallback(const KeyPressedCallback &newKey mListView->setKeypressedCallback(newKeypressedCallback); } -void CodeCompletionPopup::prepareSearch(const QString &phrase, const QString &filename, int line) +void CodeCompletionPopup::prepareSearch(const QString& preWord,const QString &phrase, const QString &filename, int line) { QMutexLocker locker(&mMutex); if (!isEnabled()) @@ -69,19 +69,19 @@ void CodeCompletionPopup::prepareSearch(const QString &phrase, const QString &fi QCursor oldCursor = cursor(); setCursor(Qt::CursorShape::WaitCursor); - mIncludedFiles = mParser->getFileIncludes(filename); - getCompletionFor(filename,phrase,line); + if (preWord.isEmpty()) { + mIncludedFiles = mParser->getFileIncludes(filename); + getCompletionFor(filename,phrase,line); - if (mFullCompletionStatementList.isEmpty() && phrase.startsWith('~')) { - mPhrase = phrase.mid(1); - getCompletionFor(filename,mPhrase,line); + if (mFullCompletionStatementList.isEmpty() && phrase.startsWith('~')) { + mPhrase = phrase.mid(1); + getCompletionFor(filename,mPhrase,line); + } + } else { + mPhrase = phrase; + getFullCompletionListFor(preWord); } - //todo: notify model -//CodeComplForm.lbCompletion.Font.Size := FontSize; -//CodeComplForm.lbCompletion.ItemHeight := CodeComplForm.lbCompletion.Canvas.TextHeight('F')+6; -// Round(2 * FontSize); -//CodeComplForm.Update; setCursor(oldCursor); } @@ -453,13 +453,14 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin if (phrase.startsWith('#')) { if (mShowKeywords) { foreach (const QString& keyword, CppDirectives) { - PStatement statement = std::make_shared(); - statement->command = keyword; - statement->kind = StatementKind::skKeyword; - statement->fullName = keyword; - statement->usageCount = 0; - statement->freqTop = 0; - mFullCompletionStatementList.append(statement); + addKeyword(keyword); +// PStatement statement = std::make_shared(); +// statement->command = keyword; +// statement->kind = StatementKind::skKeyword; +// statement->fullName = keyword; +// statement->usageCount = 0; +// statement->freqTop = 0; +// mFullCompletionStatementList.append(statement); } } return; @@ -469,13 +470,14 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin if (phrase.startsWith('@')) { if (mShowKeywords) { foreach (const QString& keyword,JavadocTags) { - PStatement statement = std::make_shared(); - statement->command = keyword; - statement->kind = StatementKind::skKeyword; - statement->fullName = keyword; - statement->usageCount = 0; - statement->freqTop = 0; - mFullCompletionStatementList.append(statement); + addKeyword(keyword); +// PStatement statement = std::make_shared(); +// statement->command = keyword; +// statement->kind = StatementKind::skKeyword; +// statement->fullName = keyword; +// statement->usageCount = 0; +// statement->freqTop = 0; +// mFullCompletionStatementList.append(statement); } } return; @@ -506,23 +508,25 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin //add keywords if (mUseCppKeyword) { foreach (const QString& keyword,CppKeywords.keys()) { - PStatement statement = std::make_shared(); - statement->command = keyword; - statement->kind = StatementKind::skKeyword; - statement->fullName = keyword; - statement->usageCount = 0; - statement->freqTop = 0; - mFullCompletionStatementList.append(statement); + addKeyword(keyword); +// PStatement statement = std::make_shared(); +// statement->command = keyword; +// statement->kind = StatementKind::skKeyword; +// statement->fullName = keyword; +// statement->usageCount = 0; +// statement->freqTop = 0; +// mFullCompletionStatementList.append(statement); } } else { foreach (const QString& keyword,CKeywords) { - PStatement statement = std::make_shared(); - statement->command = keyword; - statement->kind = StatementKind::skKeyword; - statement->fullName = keyword; - statement->usageCount = 0; - statement->freqTop = 0; - mFullCompletionStatementList.append(statement); + addKeyword(keyword); +// PStatement statement = std::make_shared(); +// statement->command = keyword; +// statement->kind = StatementKind::skKeyword; +// statement->fullName = keyword; +// statement->usageCount = 0; +// statement->freqTop = 0; +// mFullCompletionStatementList.append(statement); } } } @@ -750,6 +754,39 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin } } +void CodeCompletionPopup::getFullCompletionListFor(const QString &preWord) +{ + mFullCompletionStatementList.clear(); + if (preWord == "long") { + addKeyword("long"); + addKeyword("double"); + addKeyword("int"); + } else if (preWord == "short") { + addKeyword("int"); + } else if (preWord == "signed") { + addKeyword("long"); + addKeyword("short"); + addKeyword("int"); + addKeyword("char"); + } else if (preWord == "unsigned") { + addKeyword("long"); + addKeyword("short"); + addKeyword("int"); + addKeyword("char"); + } +} + +void CodeCompletionPopup::addKeyword(const QString &keyword) +{ + PStatement statement = std::make_shared(); + statement->command = keyword; + statement->kind = StatementKind::skKeyword; + statement->fullName = keyword; + statement->usageCount = 0; + statement->freqTop = 0; + mFullCompletionStatementList.append(statement); +} + bool CodeCompletionPopup::isIncluded(const QString &fileName) { return mIncludedFiles.contains(fileName); diff --git a/RedPandaIDE/widgets/codecompletionpopup.h b/RedPandaIDE/widgets/codecompletionpopup.h index 1f94db9b..17284c09 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.h +++ b/RedPandaIDE/widgets/codecompletionpopup.h @@ -31,7 +31,7 @@ public: ~CodeCompletionPopup(); void setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback); - void prepareSearch(const QString& phrase, const QString& filename, int line); + void prepareSearch(const QString& preWord, const QString& phrase, const QString& filename, int line); bool search(const QString& phrase, bool autoHideOnSingleResult); PStatement selectedStatement(); @@ -74,6 +74,8 @@ private: void addStatement(PStatement statement, const QString& fileName, int line); void filterList(const QString& member); void getCompletionFor(const QString& fileName,const QString& phrase, int line); + void getFullCompletionListFor(const QString& preWord); + void addKeyword(const QString& keyword); bool isIncluded(const QString& fileName); private: CodeCompletionListView * mListView;