refactor: Check string/rawstring/character status while completing symbols in c/c++ file
This commit is contained in:
parent
417c33a8dc
commit
f7514e424e
|
@ -732,15 +732,8 @@ void Editor::keyPressEvent(QKeyEvent *event)
|
|||
clearUserCodeInTabStops();
|
||||
} else {
|
||||
QString s = lineText().mid(0,caretX()-1).trimmed();
|
||||
if (caretY()==1) {
|
||||
syntaxer()->resetState();
|
||||
} else {
|
||||
syntaxer()->setState(document()->getSyntaxState(caretY()-2));
|
||||
}
|
||||
syntaxer()->setLine(s,caretY());
|
||||
syntaxer()->nextToEol();
|
||||
int state = syntaxer()->getState().state;
|
||||
if (syntaxer()->isCommentNotFinished(state)) {
|
||||
QSynedit::SyntaxState state = calcSyntaxStateAtLine(caretY()-1, s);
|
||||
if (syntaxer()->isCommentNotFinished(state.state)) {
|
||||
if (s=="/**") { //javadoc style docstring
|
||||
s = lineText().mid(caretX()-1).trimmed();
|
||||
if (s=="*/") {
|
||||
|
@ -2961,7 +2954,7 @@ bool Editor::handleDoubleQuoteCompletion()
|
|||
QuoteStatus status = getQuoteStatus();
|
||||
QChar ch = getCurrentChar();
|
||||
if (ch == '"') {
|
||||
if ((status == QuoteStatus::DoubleQuote || status == QuoteStatus::RawString)
|
||||
if ((status == QuoteStatus::DoubleQuote || status == QuoteStatus::RawStringEnd)
|
||||
&& !selAvail()) {
|
||||
setCaretXY( QSynedit::BufferCoord{caretX() + 1, caretY()}); // skip over
|
||||
return true;
|
||||
|
@ -3100,118 +3093,31 @@ ParserLanguage Editor::calcParserLanguage()
|
|||
Editor::QuoteStatus Editor::getQuoteStatus()
|
||||
{
|
||||
QuoteStatus Result = QuoteStatus::NotQuote;
|
||||
if ((caretY()>1) && syntaxer()->isStringNotFinished(document()->getSyntaxState(caretY() - 2).state))
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
|
||||
QString Line = document()->getLine(caretY()-1);
|
||||
int posX = caretX()-1;
|
||||
if (posX >= Line.length()) {
|
||||
posX = Line.length()-1;
|
||||
}
|
||||
for (int i=0; i<posX;i++) {
|
||||
if (i+1<Line.length() && (Line[i] == 'R') && (Line[i+1] == '"') && (Result == QuoteStatus::NotQuote)) {
|
||||
Result = QuoteStatus::RawString;
|
||||
i++; // skip R
|
||||
} else if (Line[i] == '(') {
|
||||
switch(Result) {
|
||||
case QuoteStatus::RawString:
|
||||
Result=QuoteStatus::RawStringNoEscape;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (Line[i] == ')') {
|
||||
switch(Result) {
|
||||
case QuoteStatus::RawStringNoEscape:
|
||||
Result=QuoteStatus::RawString;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (Line[i] == '"') {
|
||||
switch(Result) {
|
||||
case QuoteStatus::NotQuote:
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
break;
|
||||
case QuoteStatus::SingleQuote:
|
||||
Result = QuoteStatus::SingleQuote;
|
||||
break;
|
||||
case QuoteStatus::SingleQuoteEscape:
|
||||
Result = QuoteStatus::SingleQuote;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuote:
|
||||
Result = QuoteStatus::NotQuote;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuoteEscape:
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
break;
|
||||
case QuoteStatus::RawString:
|
||||
Result=QuoteStatus::NotQuote;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (Line[i] == '\'') {
|
||||
switch(Result) {
|
||||
case QuoteStatus::NotQuote:
|
||||
Result = QuoteStatus::SingleQuote;
|
||||
break;
|
||||
case QuoteStatus::SingleQuote:
|
||||
Result = QuoteStatus::NotQuote;
|
||||
break;
|
||||
case QuoteStatus::SingleQuoteEscape:
|
||||
Result = QuoteStatus::SingleQuote;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuote:
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuoteEscape:
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (Line[i] == '\\') {
|
||||
switch(Result) {
|
||||
case QuoteStatus::NotQuote:
|
||||
Result = QuoteStatus::NotQuote;
|
||||
break;
|
||||
case QuoteStatus::SingleQuote:
|
||||
Result = QuoteStatus::SingleQuoteEscape;
|
||||
break;
|
||||
case QuoteStatus::SingleQuoteEscape:
|
||||
Result = QuoteStatus::SingleQuote;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuote:
|
||||
Result = QuoteStatus::DoubleQuoteEscape;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuoteEscape:
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(Result) {
|
||||
case QuoteStatus::NotQuote:
|
||||
Result = QuoteStatus::NotQuote;
|
||||
break;
|
||||
case QuoteStatus::SingleQuote:
|
||||
Result = QuoteStatus::SingleQuote;
|
||||
break;
|
||||
case QuoteStatus::SingleQuoteEscape:
|
||||
Result = QuoteStatus::SingleQuote;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuote:
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
break;
|
||||
case QuoteStatus::DoubleQuoteEscape:
|
||||
Result = QuoteStatus::DoubleQuote;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (syntaxer()->language()==QSynedit::ProgrammingLanguage::CPP) {
|
||||
QString s = lineText().mid(0,caretX()-1);
|
||||
QSynedit::SyntaxState state = calcSyntaxStateAtLine(caretY()-1, s);
|
||||
std::shared_ptr<QSynedit::CppSyntaxer> cppSyntaxer = std::dynamic_pointer_cast<QSynedit::CppSyntaxer>(syntaxer());
|
||||
if (syntaxer()->isStringNotFinished(state.state)) {
|
||||
if (cppSyntaxer->isStringToNextLine(state.state))
|
||||
return QuoteStatus::DoubleQuoteEscape;
|
||||
else
|
||||
return QuoteStatus::DoubleQuote;
|
||||
}
|
||||
if (cppSyntaxer->isCharNotFinished(state.state)) {
|
||||
if (cppSyntaxer->isCharEscaping(state.state))
|
||||
return QuoteStatus::SingleQuoteEscape;
|
||||
else
|
||||
return QuoteStatus::SingleQuote;
|
||||
}
|
||||
if (cppSyntaxer->isRawStringNoEscape(state.state))
|
||||
return QuoteStatus::RawStringNoEscape;
|
||||
if (cppSyntaxer->isRawStringStart(state.state))
|
||||
return QuoteStatus::RawString;
|
||||
if (cppSyntaxer->isRawStringEnd(state.state))
|
||||
return QuoteStatus::RawStringEnd;
|
||||
return QuoteStatus::NotQuote;
|
||||
} else {
|
||||
return QuoteStatus::NotQuote;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,8 @@ public:
|
|||
DoubleQuote,
|
||||
DoubleQuoteEscape,
|
||||
RawString,
|
||||
RawStringNoEscape
|
||||
RawStringNoEscape,
|
||||
RawStringEnd
|
||||
};
|
||||
|
||||
enum class WordPurpose {
|
||||
|
|
|
@ -2985,6 +2985,18 @@ void QSynEdit::decPaintLock()
|
|||
}
|
||||
}
|
||||
|
||||
SyntaxState QSynEdit::calcSyntaxStateAtLine(int line, const QString &newLineText)
|
||||
{
|
||||
if (line == 0) {
|
||||
syntaxer()->resetState();
|
||||
} else {
|
||||
syntaxer()->setState(mDocument->getSyntaxState(line-1));
|
||||
}
|
||||
syntaxer()->setLine(newLineText,line);
|
||||
syntaxer()->nextToEol();
|
||||
return syntaxer()->getState();
|
||||
}
|
||||
|
||||
int QSynEdit::clientWidth() const
|
||||
{
|
||||
return viewport()->size().width();
|
||||
|
|
|
@ -504,6 +504,7 @@ protected:
|
|||
void doSelectLine();
|
||||
void incPaintLock();
|
||||
void decPaintLock();
|
||||
SyntaxState calcSyntaxStateAtLine(int line, const QString &newLineText);
|
||||
private:
|
||||
BufferCoord ensureBufferCoordValid(const BufferCoord& coord);
|
||||
void beginEditingWithoutUndo();
|
||||
|
|
|
@ -263,6 +263,36 @@ const PTokenAttribute &CppSyntaxer::localVarAttribute() const
|
|||
return mLocalVarAttribute;
|
||||
}
|
||||
|
||||
bool CppSyntaxer::isStringToNextLine(int state)
|
||||
{
|
||||
return state == RangeState::rsStringNextLine;
|
||||
}
|
||||
|
||||
bool CppSyntaxer::isRawStringStart(int state)
|
||||
{
|
||||
return state == RangeState::rsRawString;
|
||||
}
|
||||
|
||||
bool CppSyntaxer::isRawStringNoEscape(int state)
|
||||
{
|
||||
return state == RangeState::rsRawStringNotEscaping;
|
||||
}
|
||||
|
||||
bool CppSyntaxer::isRawStringEnd(int state)
|
||||
{
|
||||
return state == RangeState::rsRawStringEnd;
|
||||
}
|
||||
|
||||
bool CppSyntaxer::isCharNotFinished(int state)
|
||||
{
|
||||
return state == RangeState::rsChar || state == RangeState::rsCharEscaping;
|
||||
}
|
||||
|
||||
bool CppSyntaxer::isCharEscaping(int state)
|
||||
{
|
||||
return state == RangeState::rsCharEscaping;
|
||||
}
|
||||
|
||||
CppSyntaxer::TokenId CppSyntaxer::getTokenId()
|
||||
{
|
||||
return mTokenId;
|
||||
|
@ -370,17 +400,25 @@ void CppSyntaxer::procAnsiCStyleComment()
|
|||
void CppSyntaxer::procAsciiChar()
|
||||
{
|
||||
mTokenId = TokenId::Char;
|
||||
do {
|
||||
if (mLine[mRun] == '\\') {
|
||||
if (mRun+1<mLineSize && (mLine[mRun+1] == '\'' || mLine[mRun+1] == '\\')) {
|
||||
while (mRun < mLineSize) {
|
||||
if (mLine[mRun] =='\'') {
|
||||
mRun++;
|
||||
break;
|
||||
} if (mLine[mRun] == '\\') {
|
||||
if (mRun+1>=mLineSize) {
|
||||
mRun++;
|
||||
mRange.state = RangeState::rsCharEscaping;
|
||||
return;
|
||||
} else if (mLine[mRun+1] == '\'' || mLine[mRun+1] == '\\') {
|
||||
mRun+=1;
|
||||
}
|
||||
} else if (isSpaceChar(mLine[mRun])) {
|
||||
return;
|
||||
}
|
||||
mRun+=1;
|
||||
} while (mRun < mLineSize && mLine[mRun]!='\'');
|
||||
if (mRun<mLineSize && mLine[mRun] == '\'')
|
||||
mRun+=1;
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
}
|
||||
if (mRun<mLineSize)
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
}
|
||||
|
||||
void CppSyntaxer::procBraceClose()
|
||||
|
@ -968,8 +1006,7 @@ void CppSyntaxer::procRawString()
|
|||
mRange.extraData = std::make_shared<QVariant>("");
|
||||
while (mRun<mLineSize) {
|
||||
if (mRange.state!=RangeState::rsRawStringNotEscaping &&
|
||||
(mLine[mRun]=='"'
|
||||
|| mLine[mRun].isSpace()
|
||||
(mLine[mRun].isSpace()
|
||||
|| mLine[mRun].unicode()>127
|
||||
|| mLine[mRun].unicode()<=32)) {
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
|
@ -983,7 +1020,6 @@ void CppSyntaxer::procRawString()
|
|||
case '(':
|
||||
if (mRange.state==RangeState::rsRawString) {
|
||||
mRange.state = RangeState::rsRawStringNotEscaping;
|
||||
rawStringInitialDCharSeq += "\"";
|
||||
mRange.extraData = std::make_shared<QVariant>(rawStringInitialDCharSeq);
|
||||
}
|
||||
break;
|
||||
|
@ -991,20 +1027,24 @@ void CppSyntaxer::procRawString()
|
|||
if (mRange.state == RangeState::rsRawStringNotEscaping) {
|
||||
rawStringInitialDCharSeq = mRange.extraData->toString();
|
||||
if ( mLine.mid(mRun+1,rawStringInitialDCharSeq.length()) == rawStringInitialDCharSeq) {
|
||||
mRun = mRun+1+rawStringInitialDCharSeq.length();
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
mRun = mRun+rawStringInitialDCharSeq.length();
|
||||
mRange.state = RangeState::rsRawStringEnd;
|
||||
mRange.extraData = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\"':
|
||||
if (mRange.state == RangeState::rsRawStringEnd) {
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
mRun++;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (mRange.state == RangeState::rsRawString)
|
||||
rawStringInitialDCharSeq += mLine[mRun];
|
||||
mRun+=1;
|
||||
mRun++;
|
||||
}
|
||||
if (mRun>=mLineSize && mRange.state != RangeState::rsRawStringNotEscaping)
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
}
|
||||
|
||||
void CppSyntaxer::procRoundClose()
|
||||
|
@ -1253,7 +1293,7 @@ void CppSyntaxer::procStringEscapeSeq()
|
|||
void CppSyntaxer::procString()
|
||||
{
|
||||
if (mRun >= mLineSize) {
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
mRange.state = RangeState::rsStringUnfinished;
|
||||
return;
|
||||
}
|
||||
mTokenId = TokenId::String;
|
||||
|
@ -1266,7 +1306,7 @@ void CppSyntaxer::procString()
|
|||
} else if (mLine[mRun]=='\\') {
|
||||
if (mRun == mLineSize-1) {
|
||||
mRun++;
|
||||
mRange.state = RangeState::rsString;
|
||||
mRange.state = RangeState::rsStringNextLine;
|
||||
return;
|
||||
}
|
||||
if (mRun+1<mLineSize) {
|
||||
|
@ -1302,7 +1342,10 @@ void CppSyntaxer::procString()
|
|||
}
|
||||
mRun+=1;
|
||||
}
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
if (mRun>=mLineSize)
|
||||
mRange.state = RangeState::rsStringUnfinished;
|
||||
else
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
}
|
||||
|
||||
void CppSyntaxer::procStringStart()
|
||||
|
@ -1311,7 +1354,7 @@ void CppSyntaxer::procStringStart()
|
|||
mRange.state = RangeState::rsString;
|
||||
mRun += 1;
|
||||
if (mRun>=mLineSize) {
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
mRange.state = RangeState::rsStringUnfinished;
|
||||
return;
|
||||
}
|
||||
//procString();
|
||||
|
@ -1349,6 +1392,9 @@ void CppSyntaxer::processChar()
|
|||
procAndSymbol();
|
||||
break;
|
||||
case '\'':
|
||||
mTokenId = TokenId::Char;
|
||||
mRange.state = RangeState::rsChar;
|
||||
mRun++;
|
||||
procAsciiChar();
|
||||
break;
|
||||
case '}':
|
||||
|
@ -1525,7 +1571,7 @@ bool CppSyntaxer::isCommentNotFinished(int state) const
|
|||
|
||||
bool CppSyntaxer::isStringNotFinished(int state) const
|
||||
{
|
||||
return state == RangeState::rsString;
|
||||
return state == RangeState::rsString || state==RangeState::rsStringNextLine || state==RangeState::rsStringUnfinished;
|
||||
}
|
||||
|
||||
bool CppSyntaxer::isDocstringNotFinished(int state) const
|
||||
|
@ -1591,6 +1637,13 @@ int CppSyntaxer::getTokenPos()
|
|||
|
||||
void CppSyntaxer::next()
|
||||
{
|
||||
if (mRun==0) {
|
||||
switch(mRange.state) {
|
||||
case RangeState::rsString:
|
||||
case RangeState::rsChar:
|
||||
mRange.state = RangeState::rsUnknown;
|
||||
}
|
||||
}
|
||||
mTokenPos = mRun;
|
||||
if (mLineSize == 0 && mRange.state == RangeState::rsString)
|
||||
mRange.state=RangeState::rsUnknown;
|
||||
|
@ -1613,6 +1666,7 @@ void CppSyntaxer::next()
|
|||
procDocstring();
|
||||
break;
|
||||
case RangeState::rsString:
|
||||
case RangeState::rsStringNextLine:
|
||||
//qDebug()<<"*1-0-0*";
|
||||
procString();
|
||||
break;
|
||||
|
@ -1633,16 +1687,7 @@ void CppSyntaxer::next()
|
|||
procStringEscapeSeq();
|
||||
break;
|
||||
case RangeState::rsChar:
|
||||
//qDebug()<<"*7-0-0*";
|
||||
if (mRun>=mLineSize) {
|
||||
procNull();
|
||||
} else if (mLine[mRun]=='\'') {
|
||||
mRange.state = rsUnknown;
|
||||
mTokenId = TokenId::Char;
|
||||
mRun+=1;
|
||||
} else {
|
||||
procAsciiChar();
|
||||
}
|
||||
procAsciiChar();
|
||||
break;
|
||||
case RangeState::rsDefineIdentifier:
|
||||
//qDebug()<<"*8-0-0*";
|
||||
|
@ -1654,7 +1699,6 @@ void CppSyntaxer::next()
|
|||
break;
|
||||
case RangeState::rsRawStringNotEscaping:
|
||||
case RangeState::rsRawString:
|
||||
case RangeState::rsRawStringEnd:
|
||||
//qDebug()<<"*9-0-0*";
|
||||
procRawString();
|
||||
break;
|
||||
|
|
|
@ -46,11 +46,13 @@ public:
|
|||
};
|
||||
|
||||
enum RangeState {
|
||||
rsUnknown, rsAnsiC, rsDirective, rsDirectiveComment, rsString,
|
||||
rsUnknown, rsAnsiC, rsDirective, rsDirectiveComment,
|
||||
rsString, rsStringNextLine, rsStringUnfinished,
|
||||
rsMultiLineString, rsMultiLineDirective, rsCppComment,
|
||||
rsDocstring,
|
||||
rsStringEscapeSeq,
|
||||
rsRawString, rsSpace,rsRawStringNotEscaping,rsRawStringEnd,rsChar,
|
||||
rsRawString, rsSpace,rsRawStringNotEscaping,rsRawStringEnd,
|
||||
rsChar, rsCharEscaping,
|
||||
rsDefineIdentifier, rsDefineRemaining,
|
||||
};
|
||||
|
||||
|
@ -88,6 +90,13 @@ public:
|
|||
|
||||
static const QSet<QString> ValidIntegerSuffixes;
|
||||
|
||||
bool isStringToNextLine(int state);
|
||||
bool isRawStringStart(int state);
|
||||
bool isRawStringNoEscape(int state);
|
||||
bool isRawStringEnd(int state);
|
||||
bool isCharNotFinished(int state);
|
||||
bool isCharEscaping(int state);
|
||||
|
||||
TokenId getTokenId();
|
||||
private:
|
||||
void procAndSymbol();
|
||||
|
|
Loading…
Reference in New Issue