forked from qt-creator/qt-creator
fix auto braces with preprocessor directives
We now exclude brace in ifdefed out sections when calculating, whether or not the braces match. This requires adjust the brace levels whenever sections get ifdef'd out or ifdef'd in again.
This commit is contained in:
@@ -52,12 +52,13 @@ void CppHighlighter::highlightBlock(const QString &text)
|
|||||||
QTextCharFormat emptyFormat;
|
QTextCharFormat emptyFormat;
|
||||||
|
|
||||||
const int previousState = previousBlockState();
|
const int previousState = previousBlockState();
|
||||||
int state = 0, braceDepth = 0;
|
int state = 0, initialBraceDepth = 0;
|
||||||
if (previousState != -1) {
|
if (previousState != -1) {
|
||||||
state = previousState & 0xff;
|
state = previousState & 0xff;
|
||||||
braceDepth = previousState >> 8;
|
initialBraceDepth = previousState >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int braceDepth = initialBraceDepth;
|
||||||
|
|
||||||
SimpleLexer tokenize;
|
SimpleLexer tokenize;
|
||||||
tokenize.setQtMocRunEnabled(false);
|
tokenize.setQtMocRunEnabled(false);
|
||||||
@@ -211,6 +212,10 @@ void CppHighlighter::highlightBlock(const QString &text)
|
|||||||
|
|
||||||
TextEditDocumentLayout::setParentheses(currentBlock(), parentheses);
|
TextEditDocumentLayout::setParentheses(currentBlock(), parentheses);
|
||||||
|
|
||||||
|
// if the block is ifdefed out, we only store the parentheses, but
|
||||||
|
// do not adjust the brace depth.
|
||||||
|
if (TextEditDocumentLayout::ifdefedOut(currentBlock()))
|
||||||
|
braceDepth = initialBraceDepth;
|
||||||
|
|
||||||
// optimization: if only the brace depth changes, we adjust subsequent blocks
|
// optimization: if only the brace depth changes, we adjust subsequent blocks
|
||||||
// to have QSyntaxHighlighter stop the rehighlighting
|
// to have QSyntaxHighlighter stop the rehighlighting
|
||||||
@@ -222,12 +227,7 @@ void CppHighlighter::highlightBlock(const QString &text)
|
|||||||
int delta = braceDepth - oldBraceDepth;
|
int delta = braceDepth - oldBraceDepth;
|
||||||
QTextBlock block = currentBlock().next();
|
QTextBlock block = currentBlock().next();
|
||||||
while (block.isValid()) {
|
while (block.isValid()) {
|
||||||
currentState = block.userState();
|
TextEditDocumentLayout::changeBraceDepth(block, delta);
|
||||||
if (currentState != -1) {
|
|
||||||
oldState = currentState & 0xff;
|
|
||||||
oldBraceDepth = currentState >> 8;
|
|
||||||
block.setUserState(((oldBraceDepth + delta) << 8 ) | oldState);
|
|
||||||
}
|
|
||||||
block = block.next();
|
block = block.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1528,6 +1528,18 @@ int TextBlockUserData::collapseAtPos() const
|
|||||||
return Parenthesis::collapseAtPos(m_parentheses);
|
return Parenthesis::collapseAtPos(m_parentheses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TextBlockUserData::braceDepthDelta() const
|
||||||
|
{
|
||||||
|
int delta = 0;
|
||||||
|
for (int i = 0; i < m_parentheses.size(); ++i) {
|
||||||
|
switch (m_parentheses.at(i).chr.unicode()) {
|
||||||
|
case '{': case '+': ++delta; break;
|
||||||
|
case '}': case '-': --delta; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
void TextEditDocumentLayout::setParentheses(const QTextBlock &block, const Parentheses &parentheses)
|
void TextEditDocumentLayout::setParentheses(const QTextBlock &block, const Parentheses &parentheses)
|
||||||
{
|
{
|
||||||
@@ -1553,6 +1565,35 @@ bool TextEditDocumentLayout::hasParentheses(const QTextBlock &block)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TextEditDocumentLayout::braceDepthDelta(const QTextBlock &block)
|
||||||
|
{
|
||||||
|
if (TextBlockUserData *userData = testUserData(block))
|
||||||
|
return userData->braceDepthDelta();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextEditDocumentLayout::braceDepth(const QTextBlock &block)
|
||||||
|
{
|
||||||
|
int state = block.userState();
|
||||||
|
if (state == -1)
|
||||||
|
return 0;
|
||||||
|
return state >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditDocumentLayout::setBraceDepth(QTextBlock &block, int depth)
|
||||||
|
{
|
||||||
|
int state = block.userState();
|
||||||
|
if (state == -1)
|
||||||
|
state = 0;
|
||||||
|
state = state & 0xff;
|
||||||
|
block.setUserState((depth << 8) | state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditDocumentLayout::changeBraceDepth(QTextBlock &block, int delta)
|
||||||
|
{
|
||||||
|
if (delta)
|
||||||
|
setBraceDepth(block, braceDepth(block) + delta);
|
||||||
|
}
|
||||||
|
|
||||||
bool TextEditDocumentLayout::setIfdefedOut(const QTextBlock &block)
|
bool TextEditDocumentLayout::setIfdefedOut(const QTextBlock &block)
|
||||||
{
|
{
|
||||||
@@ -2683,6 +2724,11 @@ void BaseTextEditor::updateCurrentLineHighlight()
|
|||||||
|
|
||||||
void BaseTextEditor::slotCursorPositionChanged()
|
void BaseTextEditor::slotCursorPositionChanged()
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
qDebug() << "block" << textCursor().blockNumber()+1
|
||||||
|
<< "depth:" << TextEditDocumentLayout::braceDepth(textCursor().block())
|
||||||
|
<< "/" << TextEditDocumentLayout::braceDepth(document()->lastBlock());
|
||||||
|
#endif
|
||||||
if (!d->m_contentsChanged && d->m_lastCursorChangeWasInteresting) {
|
if (!d->m_contentsChanged && d->m_lastCursorChangeWasInteresting) {
|
||||||
Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(editableInterface(), d->m_tempNavigationState);
|
Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(editableInterface(), d->m_tempNavigationState);
|
||||||
d->m_lastCursorChangeWasInteresting = false;
|
d->m_lastCursorChangeWasInteresting = false;
|
||||||
@@ -4026,21 +4072,36 @@ void BaseTextEditor::setIfdefedOutBlocks(const QList<BaseTextEditor::BlockRange>
|
|||||||
QTextBlock block = doc->firstBlock();
|
QTextBlock block = doc->firstBlock();
|
||||||
|
|
||||||
int rangeNumber = 0;
|
int rangeNumber = 0;
|
||||||
|
int braceDepthDelta = 0;
|
||||||
while (block.isValid()) {
|
while (block.isValid()) {
|
||||||
|
bool cleared = false;
|
||||||
|
bool set = false;
|
||||||
if (rangeNumber < blocks.size()) {
|
if (rangeNumber < blocks.size()) {
|
||||||
const BlockRange &range = blocks.at(rangeNumber);
|
const BlockRange &range = blocks.at(rangeNumber);
|
||||||
|
|
||||||
if (block.position() >= range.first && (block.position() <= range.last || !range.last)) {
|
if (block.position() >= range.first && (block.position() <= range.last || !range.last)) {
|
||||||
needUpdate |= TextEditDocumentLayout::setIfdefedOut(block);
|
set = TextEditDocumentLayout::setIfdefedOut(block);
|
||||||
} else {
|
} else {
|
||||||
needUpdate |= TextEditDocumentLayout::clearIfdefedOut(block);
|
cleared = TextEditDocumentLayout::clearIfdefedOut(block);
|
||||||
}
|
}
|
||||||
if (block.contains(range.last))
|
if (block.contains(range.last))
|
||||||
++rangeNumber;
|
++rangeNumber;
|
||||||
} else {
|
} else {
|
||||||
needUpdate |= TextEditDocumentLayout::clearIfdefedOut(block);
|
cleared = TextEditDocumentLayout::clearIfdefedOut(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cleared || set) {
|
||||||
|
needUpdate = true;
|
||||||
|
int delta = TextEditDocumentLayout::braceDepthDelta(block);
|
||||||
|
if (cleared)
|
||||||
|
braceDepthDelta += delta;
|
||||||
|
else if (set)
|
||||||
|
braceDepthDelta -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (braceDepthDelta)
|
||||||
|
TextEditDocumentLayout::changeBraceDepth(block,braceDepthDelta);
|
||||||
|
|
||||||
block = block.next();
|
block = block.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ public:
|
|||||||
inline void clearParentheses() { m_parentheses.clear(); }
|
inline void clearParentheses() { m_parentheses.clear(); }
|
||||||
inline const Parentheses &parentheses() const { return m_parentheses; }
|
inline const Parentheses &parentheses() const { return m_parentheses; }
|
||||||
inline bool hasParentheses() const { return !m_parentheses.isEmpty(); }
|
inline bool hasParentheses() const { return !m_parentheses.isEmpty(); }
|
||||||
|
int braceDepthDelta() const;
|
||||||
|
|
||||||
inline bool setIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = true; return !result; }
|
inline bool setIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = true; return !result; }
|
||||||
inline bool clearIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = false; return result;}
|
inline bool clearIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = false; return result;}
|
||||||
@@ -215,6 +216,10 @@ public:
|
|||||||
static bool setIfdefedOut(const QTextBlock &block);
|
static bool setIfdefedOut(const QTextBlock &block);
|
||||||
static bool clearIfdefedOut(const QTextBlock &block);
|
static bool clearIfdefedOut(const QTextBlock &block);
|
||||||
static bool ifdefedOut(const QTextBlock &block);
|
static bool ifdefedOut(const QTextBlock &block);
|
||||||
|
static int braceDepthDelta(const QTextBlock &block);
|
||||||
|
static int braceDepth(const QTextBlock &block);
|
||||||
|
static void setBraceDepth(QTextBlock &block, int depth);
|
||||||
|
static void changeBraceDepth(QTextBlock &block, int delta);
|
||||||
|
|
||||||
static TextBlockUserData *testUserData(const QTextBlock &block) {
|
static TextBlockUserData *testUserData(const QTextBlock &block) {
|
||||||
return static_cast<TextBlockUserData*>(block.userData());
|
return static_cast<TextBlockUserData*>(block.userData());
|
||||||
|
|||||||
Reference in New Issue
Block a user