forked from qt-creator/qt-creator
Rework code folding
The new and cleaner foldingIndent in the block user data will make it easier to support other kinds of indentation for various other programming languages (like Python).
This commit is contained in:
@@ -44,6 +44,7 @@ Highlighter::Highlighter(QTextDocument *parent)
|
||||
{
|
||||
m_currentBlockParentheses.reserve(20);
|
||||
m_braceDepth = 0;
|
||||
m_foldingIndent = 0;
|
||||
}
|
||||
|
||||
Highlighter::~Highlighter()
|
||||
@@ -102,27 +103,27 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
break;
|
||||
|
||||
case Token::LeftParenthesis:
|
||||
onOpeningParenthesis('(', token.offset);
|
||||
onOpeningParenthesis('(', token.offset, index == 0);
|
||||
break;
|
||||
|
||||
case Token::RightParenthesis:
|
||||
onClosingParenthesis(')', token.offset);
|
||||
onClosingParenthesis(')', token.offset, index == tokens.size()-1);
|
||||
break;
|
||||
|
||||
case Token::LeftBrace:
|
||||
onOpeningParenthesis('{', token.offset);
|
||||
onOpeningParenthesis('{', token.offset, index == 0);
|
||||
break;
|
||||
|
||||
case Token::RightBrace:
|
||||
onClosingParenthesis('}', token.offset);
|
||||
onClosingParenthesis('}', token.offset, index == tokens.size()-1);
|
||||
break;
|
||||
|
||||
case Token::LeftBracket:
|
||||
onOpeningParenthesis('[', token.offset);
|
||||
onOpeningParenthesis('[', token.offset, index == 0);
|
||||
break;
|
||||
|
||||
case Token::RightBracket:
|
||||
onClosingParenthesis(']', token.offset);
|
||||
onClosingParenthesis(']', token.offset, index == tokens.size()-1);
|
||||
break;
|
||||
|
||||
case Token::Identifier: {
|
||||
@@ -232,12 +233,8 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
|
||||
setFormat(previousTokenEnd, text.length() - previousTokenEnd, m_formats[VisualWhitespace]);
|
||||
|
||||
int firstNonSpace = 0;
|
||||
if (! tokens.isEmpty())
|
||||
firstNonSpace = tokens.first().offset;
|
||||
|
||||
setCurrentBlockState(m_scanner.state());
|
||||
onBlockEnd(m_scanner.state(), firstNonSpace);
|
||||
onBlockEnd(m_scanner.state());
|
||||
}
|
||||
|
||||
bool Highlighter::maybeQmlKeyword(const QStringRef &text) const
|
||||
@@ -301,6 +298,12 @@ int Highlighter::onBlockStart()
|
||||
{
|
||||
m_currentBlockParentheses.clear();
|
||||
m_braceDepth = 0;
|
||||
m_foldingIndent = 0;
|
||||
if (TextEditor::TextBlockUserData *userData = TextEditor::BaseTextDocumentLayout::testUserData(currentBlock())) {
|
||||
userData->setFoldingIndent(0);
|
||||
userData->setFoldingStartIncluded(false);
|
||||
userData->setFoldingEndIncluded(false);
|
||||
}
|
||||
|
||||
int state = 0;
|
||||
int previousState = previousBlockState();
|
||||
@@ -308,56 +311,41 @@ int Highlighter::onBlockStart()
|
||||
state = previousState & 0xff;
|
||||
m_braceDepth = previousState >> 8;
|
||||
}
|
||||
m_foldingIndent = m_braceDepth;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void Highlighter::onBlockEnd(int state, int firstNonSpace)
|
||||
void Highlighter::onBlockEnd(int state)
|
||||
{
|
||||
typedef TextEditor::TextBlockUserData TextEditorBlockData;
|
||||
|
||||
setCurrentBlockState((m_braceDepth << 8) | state);
|
||||
|
||||
// Set block data parentheses. Force creation of block data unless empty
|
||||
TextEditorBlockData *blockData = 0;
|
||||
|
||||
if (QTextBlockUserData *userData = currentBlockUserData())
|
||||
blockData = static_cast<TextEditorBlockData *>(userData);
|
||||
|
||||
if (!blockData && !m_currentBlockParentheses.empty()) {
|
||||
blockData = new TextEditorBlockData;
|
||||
setCurrentBlockUserData(blockData);
|
||||
}
|
||||
if (blockData) {
|
||||
blockData->setParentheses(m_currentBlockParentheses);
|
||||
blockData->setClosingCollapseMode(TextEditor::TextBlockUserData::NoClosingCollapse);
|
||||
blockData->setCollapseMode(TextEditor::TextBlockUserData::NoCollapse);
|
||||
}
|
||||
if (!m_currentBlockParentheses.isEmpty()) {
|
||||
QTC_ASSERT(blockData, return);
|
||||
int collapse = Parenthesis::collapseAtPos(m_currentBlockParentheses);
|
||||
if (collapse >= 0) {
|
||||
if (collapse == firstNonSpace)
|
||||
blockData->setCollapseMode(TextEditor::TextBlockUserData::CollapseThis);
|
||||
else
|
||||
blockData->setCollapseMode(TextEditor::TextBlockUserData::CollapseAfter);
|
||||
}
|
||||
if (Parenthesis::hasClosingCollapse(m_currentBlockParentheses))
|
||||
blockData->setClosingCollapseMode(TextEditor::TextBlockUserData::NoClosingCollapse);
|
||||
}
|
||||
TextEditor::BaseTextDocumentLayout::setParentheses(currentBlock(), m_currentBlockParentheses);
|
||||
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), m_foldingIndent);
|
||||
}
|
||||
|
||||
void Highlighter::onOpeningParenthesis(QChar parenthesis, int pos)
|
||||
void Highlighter::onOpeningParenthesis(QChar parenthesis, int pos, bool atStart)
|
||||
{
|
||||
if (parenthesis == QLatin1Char('{') || parenthesis == QLatin1Char('['))
|
||||
if (parenthesis == QLatin1Char('{') || parenthesis == QLatin1Char('[')) {
|
||||
++m_braceDepth;
|
||||
// if a folding block opens at the beginning of a line, treat the entire line
|
||||
// as if it were inside the folding block
|
||||
if (atStart)
|
||||
TextEditor::BaseTextDocumentLayout::userData(currentBlock())->setFoldingStartIncluded(true);
|
||||
}
|
||||
m_currentBlockParentheses.push_back(Parenthesis(Parenthesis::Opened, parenthesis, pos));
|
||||
}
|
||||
|
||||
void Highlighter::onClosingParenthesis(QChar parenthesis, int pos)
|
||||
void Highlighter::onClosingParenthesis(QChar parenthesis, int pos, bool atEnd)
|
||||
{
|
||||
if (parenthesis == QLatin1Char('}') || parenthesis == QLatin1Char(']'))
|
||||
if (parenthesis == QLatin1Char('}') || parenthesis == QLatin1Char(']')) {
|
||||
--m_braceDepth;
|
||||
if (atEnd)
|
||||
TextEditor::BaseTextDocumentLayout::userData(currentBlock())->setFoldingEndIncluded(true);
|
||||
else
|
||||
m_foldingIndent = qMin(m_braceDepth, m_foldingIndent); // folding indent is the minimum brace depth of a block
|
||||
}
|
||||
m_currentBlockParentheses.push_back(Parenthesis(Parenthesis::Closed, parenthesis, pos));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user