work save

This commit is contained in:
royqh1979@gmail.com 2021-08-26 17:48:23 +08:00
parent bf4d12b89f
commit f8fae59dcc
8 changed files with 262 additions and 46 deletions

View File

@ -1422,6 +1422,131 @@ bool Editor::testInFunc(int x, int y)
return result; return result;
} }
void Editor::completionInsert(bool appendFunc)
{
PStatement statement = mCompletionPopup->selectedStatement();
if (!statement)
return;
// if devCodeCompletion.RecordUsage and (Statement^._Kind <> skUserCodeIn) then begin
// idx:=Utils.FastIndexOf(dmMain.SymbolUsage,Statement^._FullName);
// if idx = -1 then begin
// usageCount:=1;
// dmMain.SymbolUsage.AddObject(Statement^._FullName, pointer(1))
// end else begin
// usageCount := 1 + integer(dmMain.SymbolUsage.Objects[idx]);
// dmMain.SymbolUsage.Objects[idx] := pointer( usageCount );
// end;
// Statement^._UsageCount := usageCount;
// end;
QString funcAddOn = "";
// delete the part of the word that's already been typed ...
BufferCoord p = wordEnd();
setBlockBegin(wordStart());
setBlockEnd(p);
// if we are inserting a function,
if (appendFunc) {
if (statement->kind == StatementKind::skFunction
|| statement->kind == StatementKind::skConstructor
|| statement->kind == StatementKind::skDestructor) {
if ((p.Char >= lineText().length()) // it's the last char on line
|| (lineText()[p.Char] != '(')) { // it don't have '(' after it
if (statement->fullName!="std::endl")
funcAddOn = "()";
}
}
}
// ... by replacing the selection
if (statement->kind == StatementKind::skUserCodeIn) { // it's a user code template
//insertUserCodeIn(Statement->value);
} else {
if (
(statement->kind == StatementKind::skKeyword
|| statement->kind == StatementKind::skPreprocessor)
&& (statement->command.startsWith('#')
|| statement->command.startsWith('@'))
) {
setSelText(statement->command.mid(1));
} else
setSelText(statement->command + funcAddOn);
if (!funcAddOn.isEmpty())
mLastIdCharPressed = 0;
// Move caret inside the ()'s, only when the user has something to do there...
if (!funcAddOn.isEmpty()
&& (statement->args != "()")
&& (statement->args != "(void)")) {
setCaretX(caretX() - funcAddOn.length()+1);
//todo: function hint
// immediately activate function hint
// if devEditor.ShowFunctionTip and Assigned(fText.Highlighter) then begin
// fText.SetFocus;
// fFunctionTip.Parser := fParser;
// fFunctionTip.FileName := fFileName;
// fFunctionTip.Show;
// end;
}
}
mCompletionPopup->hide();
}
bool Editor::onCompletionKeyPressed(QKeyEvent *event)
{
bool processed = false;
if (!mCompletionPopup->isEnabled())
return false;
QString phrase;
BufferCoord pBeginPos,pEndPos;
switch (event->key()) {
case Qt::Key_Backspace:
ExecuteCommand(
SynEditorCommand::ecDeleteLastChar,
QChar(), nullptr); // Simulate backspace in editor
phrase = getWordAtPosition(caretXY(),
pBeginPos,pEndPos,
WordPurpose::wpCompletion);
mLastIdCharPressed = phrase.length();
mCompletionPopup->search(phrase, false);
return true;
case Qt::Key_Escape:
mCompletionPopup->hide();
return true;
case Qt::Key_Return:
case Qt::Key_Tab:
//CompletionInsert(devCodeCompletion.AppendFunc);
completionInsert(false);
return true;
default:
if (event->text().isEmpty()) {
//stop completion
mCompletionPopup->hide();
keyPressEvent(event);
return true;
}
}
QChar ch = event->text().front();
if (isIdentChar(ch)) {
setSelText(ch);
phrase = phrase = getWordAtPosition(caretXY(),
pBeginPos,pEndPos,
WordPurpose::wpCompletion);
mLastIdCharPressed = phrase.length();
mCompletionPopup->search(phrase, false);
return true;
} else {
//stop completion
mCompletionPopup->hide();
keyPressEvent(event);
return true;
}
return processed;
}
QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, BufferCoord &pWordEnd, WordPurpose purpose) QString Editor::getWordAtPosition(const BufferCoord &p, BufferCoord &pWordBegin, BufferCoord &pWordEnd, WordPurpose purpose)
{ {
QString result = ""; QString result = "";

View File

@ -167,6 +167,10 @@ private:
bool testInFunc(int x,int y); bool testInFunc(int x,int y);
void completionInsert(bool appendFunc=false);
bool onCompletionKeyPressed(QKeyEvent* event);
private: private:
static int newfileCount; static int newfileCount;
QByteArray mEncodingOption; // the encoding type set by the user QByteArray mEncodingOption; // the encoding type set by the user

View File

@ -2104,7 +2104,7 @@ void CppParser::handleOtherTypedefs()
while ((mIndex< mTokenizer.tokenCount()) && !mTokenizer[mIndex]->text.startsWith(';')) while ((mIndex< mTokenizer.tokenCount()) && !mTokenizer[mIndex]->text.startsWith(';'))
mIndex++; mIndex++;
//skip ; //skip ;
if ((mIndex< mTokenizer.tokenCount()) && !mTokenizer[mIndex]->text.startsWith(';')) if ((mIndex< mTokenizer.tokenCount()) && mTokenizer[mIndex]->text.startsWith(';'))
mIndex++; mIndex++;
return; return;
} }
@ -2186,7 +2186,7 @@ void CppParser::handleOtherTypedefs()
newType += mTokenizer[mIndex]->text + ' '; newType += mTokenizer[mIndex]->text + ' ';
mIndex++; mIndex++;
} }
if ((mIndex>= mTokenizer.tokenCount()) || (mTokenizer[mIndex]->text[1] == ';')) if ((mIndex>= mTokenizer.tokenCount()) || (mTokenizer[mIndex]->text[0] == ';'))
break; break;
else if (mTokenizer[mIndex]->text.front() == ',') else if (mTokenizer[mIndex]->text.front() == ',')
mIndex++; mIndex++;
@ -2528,14 +2528,14 @@ void CppParser::handleStructs(bool isTypedef)
if (!(mTokenizer[i]->text.front() == '{' if (!(mTokenizer[i]->text.front() == '{'
|| mTokenizer[i]->text.front() == ',' || mTokenizer[i]->text.front() == ','
|| mTokenizer[i]->text.front() == ';')) { || mTokenizer[i]->text.front() == ';')) {
if ((mTokenizer[i]->text.front() == '_') // if ((mTokenizer[i]->text.front() == '_')
&& (mTokenizer[i]->text.back() == '_')) { // && (mTokenizer[i]->text.back() == '_')) {
// skip possible gcc attributes // // skip possible gcc attributes
// start and end with 2 underscores (i.e. __attribute__) // // start and end with 2 underscores (i.e. __attribute__)
// so, to avoid slow checks of strings, we just check the first and last letter of the token // // so, to avoid slow checks of strings, we just check the first and last letter of the token
// if both are underscores, we split // // if both are underscores, we split
break; // break;
} else { // } else {
if (mTokenizer[i]->text.endsWith(']')) { // cut-off array brackets if (mTokenizer[i]->text.endsWith(']')) { // cut-off array brackets
int pos = mTokenizer[i]->text.indexOf('['); int pos = mTokenizer[i]->text.indexOf('[');
command += mTokenizer[i]->text.mid(0,pos) + ' '; command += mTokenizer[i]->text.mid(0,pos) + ' ';
@ -2546,7 +2546,7 @@ void CppParser::handleStructs(bool isTypedef)
} else { } else {
command += mTokenizer[i]->text + ' '; command += mTokenizer[i]->text + ' ';
} }
} // }
} else { } else {
command = command.trimmed(); command = command.trimmed();
if (!command.isEmpty() && if (!command.isEmpty() &&
@ -2873,9 +2873,9 @@ void CppParser::internalParse(const QString &fileName)
}); });
// Let the preprocessor augment the include records // Let the preprocessor augment the include records
// mPreprocessor.setIncludesList(mIncludesList); // mPreprocessor.setIncludesList(mIncludesList);
// mPreprocessor.setScannedFileList(mScannedFiles);
// mPreprocessor.setIncludePaths(mIncludePaths); // mPreprocessor.setIncludePaths(mIncludePaths);
// mPreprocessor.setProjectIncludePaths(mProjectIncludePaths); // mPreprocessor.setProjectIncludePaths(mProjectIncludePaths);
// mPreprocessor.setScannedFileList(mScannedFiles);
mPreprocessor.setScanOptions(mParseGlobalHeaders, mParseLocalHeaders); mPreprocessor.setScanOptions(mParseGlobalHeaders, mParseLocalHeaders);
mPreprocessor.preprocess(fileName, buffer); mPreprocessor.preprocess(fileName, buffer);
#ifdef QT_DEBUG #ifdef QT_DEBUG

View File

@ -336,9 +336,10 @@ void CppPreprocessor::handleInclude(const QString &line)
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
mCurrentIncludes->includeFiles.insert(fileName,true); //mCurrentIncludes->includeFiles.insert(fileName,true);
// And open a new entry // And open a new entry
openInclude(fileName); openInclude(fileName);
mCurrentIncludes->includeFiles.insert(fileName,true);
} }
void CppPreprocessor::handlePreprocessor(const QString &value) void CppPreprocessor::handlePreprocessor(const QString &value)
@ -396,7 +397,7 @@ QString CppPreprocessor::expandMacros(const QString &line, int depth)
} }
word = ""; word = "";
if (i< lenLine) { if (i< lenLine) {
newLine += ch; newLine += line[i];
} }
} }
i++; i++;
@ -410,7 +411,9 @@ QString CppPreprocessor::expandMacros(const QString &line, int depth)
void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString &word, int &i, int depth) void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString &word, int &i, int depth)
{ {
int lenLine = line.length(); int lenLine = line.length();
if (word == "__attribute__") { if (word.startsWith("__")
&& word.endsWith("__")) {
// if (word == "__attribute__") {
//skip gcc __attribute__ //skip gcc __attribute__
while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t')) while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t'))
i++; i++;
@ -487,7 +490,7 @@ QString CppPreprocessor::removeGCCAttributes(const QString &line)
removeGCCAttribute(line,newLine,i,word); removeGCCAttribute(line,newLine,i,word);
} }
word = ""; word = "";
if (i<=lenLine) { if (i<lenLine) {
newLine = newLine+line[i]; newLine = newLine+line[i];
} }
} }
@ -500,28 +503,29 @@ QString CppPreprocessor::removeGCCAttributes(const QString &line)
void CppPreprocessor::removeGCCAttribute(const QString &line, QString &newLine, int &i, const QString &word) void CppPreprocessor::removeGCCAttribute(const QString &line, QString &newLine, int &i, const QString &word)
{ {
int lenLine = line.length(); //no need it now
int level = 0; // int lenLine = line.length();
if (word=="__attribute__") { // int level = 0;
while ( (i<lenLine) && isSpaceChar(line[i])) // if (word=="__attribute__") {
i++; // while ( (i<lenLine) && isSpaceChar(line[i]))
if ((i<lenLine) && (line[i]=='(')) { // i++;
level=0; // if ((i<lenLine) && (line[i]=='(')) {
while (i<lenLine) { // level=0;
switch(line[i].unicode()) { // while (i<lenLine) {
case '(': level++; // switch(line[i].unicode()) {
break; // case '(': level++;
case ')': level--; // break;
break; // case ')': level--;
} // break;
i++; // }
if (level==0) // i++;
break; // if (level==0)
} // break;
} // }
} else { // }
newLine += word; // } else {
} // newLine += word;
// }
} }
PParsedFile CppPreprocessor::getInclude(int index) PParsedFile CppPreprocessor::getInclude(int index)
@ -865,18 +869,20 @@ QStringList CppPreprocessor::removeComments(const QStringList &text)
s+=ch; s+=ch;
break; break;
case '/': case '/':
switch(currentType) { if (currentType == ContentType::Other) {
case ContentType::Other:
if (pos+1<line.length() && line[pos+1]=='/') { if (pos+1<line.length() && line[pos+1]=='/') {
// line comment , skip all remainings of the current line // line comment , skip all remainings of the current line
stopProcess = true; stopProcess = true;
break;
} else if (pos+1<line.length() && line[pos+1]=='*') { } else if (pos+1<line.length() && line[pos+1]=='*') {
/* ansi c comment */ /* ansi c comment */
pos++; pos++;
currentType = ContentType::AnsiCComment; currentType = ContentType::AnsiCComment;
}
break; break;
} }
}
s+=ch;
break;
case '\\': case '\\':
switch (currentType) { switch (currentType) {
case ContentType::String: case ContentType::String:
@ -1032,7 +1038,7 @@ QString CppPreprocessor::expandDefines(QString line)
while (searchPos < line.length()) { while (searchPos < line.length()) {
// We have found an identifier. It is not a number suffix. Try to expand it // We have found an identifier. It is not a number suffix. Try to expand it
if (isMacroIdentChar(line[searchPos]) && ( if (isMacroIdentChar(line[searchPos]) && (
(searchPos == 1) || !isDigit(line[searchPos - 1]))) { (searchPos == 0) || !isDigit(line[searchPos - 1]))) {
int head = searchPos; int head = searchPos;
int tail = searchPos; int tail = searchPos;

View File

@ -5667,6 +5667,56 @@ 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

@ -215,6 +215,12 @@ public:
void uncollapseAroundLine(int line); void uncollapseAroundLine(int line);
PSynEditFoldRange foldHidesLine(int line); PSynEditFoldRange foldHidesLine(int line);
void setSelText(const QString& Value); void setSelText(const QString& 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);
@ -261,6 +267,8 @@ public:
BufferCoord blockBegin() const; BufferCoord blockBegin() const;
BufferCoord blockEnd() const; BufferCoord blockEnd() const;
void setBlockBegin(BufferCoord value);
void setBlockEnd(BufferCoord Value);
SynSelectionMode activeSelectionMode() const; SynSelectionMode activeSelectionMode() const;
void setActiveSelectionMode(const SynSelectionMode &Value); void setActiveSelectionMode(const SynSelectionMode &Value);
@ -491,10 +499,6 @@ private:
void doUncomment(); void doUncomment();
void doToggleComment(); void doToggleComment();
private:
void setBlockBegin(BufferCoord value);
void setBlockEnd(BufferCoord Value);
void setSelLength(int Value);
private slots: private slots:
void bookMarkOptionsChanged(); void bookMarkOptionsChanged();

View File

@ -105,6 +105,23 @@ bool CodeCompletionView::search(const QString &phrase, bool autoHideOnSingleResu
return false; return false;
} }
PStatement CodeCompletionView::selectedStatement()
{
if (isEnabled()) {
int index = mListView->currentIndex().row();
if (mListView->currentIndex().isValid()
&& (index<mCompletionStatementList.count()) ) {
return mCompletionStatementList[index];
} else {
if (!mCompletionStatementList.isEmpty())
return mCompletionStatementList.front();
else
return PStatement();
}
} else
return PStatement();
}
void CodeCompletionView::addChildren(PStatement scopeStatement, const QString &fileName, int line) void CodeCompletionView::addChildren(PStatement scopeStatement, const QString &fileName, int line)
{ {
if (scopeStatement && !isIncluded(scopeStatement->fileName) if (scopeStatement && !isIncluded(scopeStatement->fileName)
@ -669,6 +686,11 @@ bool CodeCompletionView::isIncluded(const QString &fileName)
return mIncludedFiles.contains(fileName); return mIncludedFiles.contains(fileName);
} }
void CodeCompletionView::showEvent(QShowEvent *)
{
mListView->setFocus();
}
const PStatement &CodeCompletionView::currentStatement() const const PStatement &CodeCompletionView::currentStatement() const
{ {
return mCurrentStatement; return mCurrentStatement;
@ -819,6 +841,9 @@ QVariant CodeCompletionListModel::data(const QModelIndex &index, int role) const
{ {
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
if (index.row()>=mStatements->count())
return QVariant();
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
PStatement statement = mStatements->at(index.row()); PStatement statement = mStatements->at(index.row());
return statement->command; return statement->command;

View File

@ -46,6 +46,7 @@ public:
void prepareSearch(const QString& phrase, const QString& filename, int line); void prepareSearch(const QString& phrase, const QString& filename, int line);
bool search(const QString& phrase, bool autoHideOnSingleResult); bool search(const QString& phrase, bool autoHideOnSingleResult);
PStatement selectedStatement();
const PCppParser &parser() const; const PCppParser &parser() const;
void setParser(const PCppParser &newParser); void setParser(const PCppParser &newParser);
@ -111,6 +112,7 @@ private:
// QWidget interface // QWidget interface
protected: protected:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override; void hideEvent(QHideEvent *event) override;
}; };