Commit 83dba068 authored by Thorbjørn Lindeijer's avatar Thorbjørn Lindeijer
Browse files

Avoid triggering indent for electric characters in comments and strings

In comments and strings, electric characters have no syntactical
significance and the unnecessary automatic reindent can be annoying.

Reviewed-by: Erik Verbruggen
parent a6e52985
......@@ -1588,6 +1588,38 @@ bool CPPEditor::contextAllowsAutoParentheses(const QTextCursor &cursor,
return true;
}
bool CPPEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{
CPlusPlus::TokenUnderCursor tokenUnderCursor;
const SimpleToken tk = tokenUnderCursor(cursor);
// XXX Duplicated from CPPEditor::isInComment to avoid tokenizing twice
if (tk.isComment()) {
const int pos = cursor.selectionEnd() - cursor.block().position();
if (pos == tk.end()) {
if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))
return false;
const int state = cursor.block().userState() & 0xFF;
if (state > 0)
return false;
}
if (pos < tk.end())
return false;
}
else if (tk.is(T_STRING_LITERAL) || tk.is(T_WIDE_STRING_LITERAL)
|| tk.is(T_CHAR_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL)) {
const int pos = cursor.selectionEnd() - cursor.block().position();
if (pos <= tk.end())
return false;
}
return true;
}
bool CPPEditor::isInComment(const QTextCursor &cursor) const
{
CPlusPlus::TokenUnderCursor tokenUnderCursor;
......@@ -1729,7 +1761,7 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
// ### enable
// updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource()));
QMenu *menu = new QMenu();
QMenu *menu = new QMenu;
Core::ActionManager *am = Core::ICore::instance()->actionManager();
Core::ActionContainer *mcontext = am->actionContainer(CppEditor::Constants::M_CONTEXT);
......
......@@ -221,6 +221,7 @@ protected:
virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert = QString()) const;
virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
virtual bool isInComment(const QTextCursor &cursor) const;
......
......@@ -1096,6 +1096,34 @@ static bool isCompleteStringLiteral(const QStringRef &text)
return false;
}
static Token tokenUnderCursor(const QTextCursor &cursor)
{
const QString blockText = cursor.block().text();
const int blockState = blockStartState(cursor.block());
Scanner tokenize;
const QList<Token> tokens = tokenize(blockText, blockState);
const int pos = cursor.positionInBlock();
int tokenIndex = 0;
for (; tokenIndex < tokens.size(); ++tokenIndex) {
const Token &token = tokens.at(tokenIndex);
if (token.is(Token::Comment) || token.is(Token::String)) {
if (pos > token.begin() && pos <= token.end())
break;
} else {
if (pos >= token.begin() && pos < token.end())
break;
}
}
if (tokenIndex != tokens.size())
return tokens.at(tokenIndex);
return Token();
}
bool QmlJSTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert) const
{
QChar ch;
......@@ -1125,56 +1153,45 @@ bool QmlJSTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor, co
return false;
} // end of switch
const QString blockText = cursor.block().text();
const int blockState = blockStartState(cursor.block());
const Token token = tokenUnderCursor(cursor);
switch (token.kind) {
case Token::Comment:
return false;
Scanner tokenize;
const QList<Token> tokens = tokenize(blockText, blockState);
const int pos = cursor.positionInBlock();
case Token::String: {
const QString blockText = cursor.block().text();
const QStringRef tokenText = blockText.midRef(token.offset, token.length);
const QChar quote = tokenText.at(0);
int tokenIndex = 0;
for (; tokenIndex < tokens.size(); ++tokenIndex) {
const Token &token = tokens.at(tokenIndex);
if (pos >= token.begin()) {
if (pos < token.end())
break;
if (ch != quote || isCompleteStringLiteral(tokenText))
break;
else if (pos == token.end() && (token.is(Token::Comment) ||
token.is(Token::String)))
break;
}
return false;
}
if (tokenIndex != tokens.size()) {
const Token &token = tokens.at(tokenIndex);
switch (token.kind) {
case Token::Comment:
return false;
case Token::String: {
const QStringRef tokenText = blockText.midRef(token.offset, token.length);
const QChar quote = tokenText.at(0);
if (ch != quote || isCompleteStringLiteral(tokenText))
break;
default:
break;
} // end of switch
return false;
}
return true;
}
default:
break;
} // end of switch
bool QmlJSTextEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{
Token token = tokenUnderCursor(cursor);
qDebug() << cursor.positionInBlock() << token.begin() << token.end();
switch (token.kind) {
case Token::Comment:
case Token::String:
return false;
default:
return true;
}
return true;
}
bool QmlJSTextEditor::isInComment(const QTextCursor &) const
bool QmlJSTextEditor::isInComment(const QTextCursor &cursor) const
{
// ### implement me
return false;
return tokenUnderCursor(cursor).is(Token::Comment);
}
QString QmlJSTextEditor::insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar, int *skippedChars) const
......
......@@ -245,6 +245,7 @@ protected:
//// brace matching
virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert = QString()) const;
virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
virtual bool isInComment(const QTextCursor &cursor) const;
virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar la, int *skippedChars) const;
virtual QString insertParagraphSeparator(const QTextCursor &tc) const;
......
......@@ -1332,7 +1332,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
cursor.insertText(autoText);
cursor.setPosition(pos);
}
if (!electricChar.isNull())
if (!electricChar.isNull() && contextAllowsElectricCharacters(cursor))
indent(document(), cursor, electricChar);
if (doEditBlock)
......@@ -3856,6 +3856,11 @@ bool BaseTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor,
return false;
}
bool BaseTextEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{
return contextAllowsAutoParentheses(cursor);
}
bool BaseTextEditor::isInComment(const QTextCursor &cursor) const
{
Q_UNUSED(cursor);
......
......@@ -403,6 +403,7 @@ protected:
virtual void reindent(QTextDocument *doc, const QTextCursor &cursor);
virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert = QString()) const;
virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
// Returns true if the cursor is inside a comment.
virtual bool isInComment(const QTextCursor &cursor) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment