diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp index 9f1088ada6b..5b3b19db5ad 100644 --- a/src/plugins/cppeditor/cppautocompleter.cpp +++ b/src/plugins/cppeditor/cppautocompleter.cpp @@ -48,8 +48,8 @@ CppAutoCompleter::CppAutoCompleter() CppAutoCompleter::~CppAutoCompleter() {} -bool CppAutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +bool CppAutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) const { QChar ch; @@ -66,7 +66,7 @@ bool CppAutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, return true; } -bool CppAutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool CppAutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -98,7 +98,7 @@ bool CppAutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &curs return true; } -bool CppAutoCompleter::doIsInComment(const QTextCursor &cursor) const +bool CppAutoCompleter::isInComment(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -122,7 +122,7 @@ bool CppAutoCompleter::doIsInComment(const QTextCursor &cursor) const return false; } -QString CppAutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, +QString CppAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text, QChar la, int *skippedChars) const @@ -131,7 +131,7 @@ QString CppAutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, return m.insertMatchingBrace(cursor, text, la, skippedChars); } -QString CppAutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString CppAutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { MatchingText m; return m.insertParagraphSeparator(cursor); diff --git a/src/plugins/cppeditor/cppautocompleter.h b/src/plugins/cppeditor/cppautocompleter.h index 0a80679a9c5..b9ba066e64c 100644 --- a/src/plugins/cppeditor/cppautocompleter.h +++ b/src/plugins/cppeditor/cppautocompleter.h @@ -41,16 +41,15 @@ public: CppAutoCompleter(); virtual ~CppAutoCompleter(); -private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const; - virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; + 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 &cursor, + const QString &text, + QChar la, + int *skippedChars) const; + virtual QString insertParagraphSeparator(const QTextCursor &cursor) const; }; } // Internal diff --git a/src/plugins/cppeditor/cppqtstyleindenter.cpp b/src/plugins/cppeditor/cppqtstyleindenter.cpp index 796165c2ae1..778a8c22916 100644 --- a/src/plugins/cppeditor/cppqtstyleindenter.cpp +++ b/src/plugins/cppeditor/cppqtstyleindenter.cpp @@ -47,7 +47,7 @@ CppQtStyleIndenter::CppQtStyleIndenter() CppQtStyleIndenter::~CppQtStyleIndenter() {} -bool CppQtStyleIndenter::doIsElectricalCharacter(const QChar &ch) const +bool CppQtStyleIndenter::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('{') || ch == QLatin1Char('}') || @@ -58,10 +58,10 @@ bool CppQtStyleIndenter::doIsElectricalCharacter(const QChar &ch) const return false; } -void CppQtStyleIndenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void CppQtStyleIndenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { Q_UNUSED(doc) @@ -86,10 +86,10 @@ void CppQtStyleIndenter::doIndentBlock(QTextDocument *doc, ts.indentLine(block, indent + padding, padding); } -void CppQtStyleIndenter::doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void CppQtStyleIndenter::indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); diff --git a/src/plugins/cppeditor/cppqtstyleindenter.h b/src/plugins/cppeditor/cppqtstyleindenter.h index 4c91a1aa374..f1864793124 100644 --- a/src/plugins/cppeditor/cppqtstyleindenter.h +++ b/src/plugins/cppeditor/cppqtstyleindenter.h @@ -41,17 +41,16 @@ public: CppQtStyleIndenter(); virtual ~CppQtStyleIndenter(); -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual bool isElectricCharacter(const QChar &ch) const; + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); - virtual void doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual void indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); }; } // Internal diff --git a/src/plugins/glsleditor/glslautocompleter.cpp b/src/plugins/glsleditor/glslautocompleter.cpp index acb30446413..dc29d26c903 100644 --- a/src/plugins/glsleditor/glslautocompleter.cpp +++ b/src/plugins/glsleditor/glslautocompleter.cpp @@ -47,8 +47,8 @@ GLSLCompleter::GLSLCompleter() GLSLCompleter::~GLSLCompleter() {} -bool GLSLCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +bool GLSLCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) const { QChar ch; @@ -65,7 +65,7 @@ bool GLSLCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, return true; } -bool GLSLCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool GLSLCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -97,7 +97,7 @@ bool GLSLCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) return true; } -bool GLSLCompleter::doIsInComment(const QTextCursor &cursor) const +bool GLSLCompleter::isInComment(const QTextCursor &cursor) const { const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block())); @@ -121,16 +121,16 @@ bool GLSLCompleter::doIsInComment(const QTextCursor &cursor) const return false; } -QString GLSLCompleter::doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const +QString GLSLCompleter::insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar la, + int *skippedChars) const { MatchingText m; return m.insertMatchingBrace(cursor, text, la, skippedChars); } -QString GLSLCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString GLSLCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { MatchingText m; return m.insertParagraphSeparator(cursor); diff --git a/src/plugins/glsleditor/glslautocompleter.h b/src/plugins/glsleditor/glslautocompleter.h index 1fb01991caf..3976883c2e4 100644 --- a/src/plugins/glsleditor/glslautocompleter.h +++ b/src/plugins/glsleditor/glslautocompleter.h @@ -41,16 +41,15 @@ public: GLSLCompleter(); virtual ~GLSLCompleter(); -private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const; - virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; + 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 &cursor, + const QString &text, + QChar la, + int *skippedChars) const; + virtual QString insertParagraphSeparator(const QTextCursor &cursor) const; }; } // Internal diff --git a/src/plugins/glsleditor/glslindenter.cpp b/src/plugins/glsleditor/glslindenter.cpp index 8fecc7e2d3b..86a216164ee 100644 --- a/src/plugins/glsleditor/glslindenter.cpp +++ b/src/plugins/glsleditor/glslindenter.cpp @@ -47,7 +47,7 @@ GLSLIndenter::GLSLIndenter() GLSLIndenter::~GLSLIndenter() {} -bool GLSLIndenter::doIsElectricalCharacter(const QChar &ch) const +bool GLSLIndenter::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('{') || ch == QLatin1Char('}') || @@ -58,10 +58,10 @@ bool GLSLIndenter::doIsElectricalCharacter(const QChar &ch) const return false; } -void GLSLIndenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void GLSLIndenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { Q_UNUSED(doc) @@ -86,10 +86,10 @@ void GLSLIndenter::doIndentBlock(QTextDocument *doc, ts.indentLine(block, indent + padding, padding); } -void GLSLIndenter::doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void GLSLIndenter::indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); diff --git a/src/plugins/glsleditor/glslindenter.h b/src/plugins/glsleditor/glslindenter.h index 03af9f378ce..816044ed2b3 100644 --- a/src/plugins/glsleditor/glslindenter.h +++ b/src/plugins/glsleditor/glslindenter.h @@ -41,17 +41,16 @@ public: GLSLIndenter(); virtual ~GLSLIndenter(); -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual bool isElectricCharacter(const QChar &ch) const; + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); - virtual void doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual void indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); }; } // Internal diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp index 836e5e0ef97..845e54e010d 100644 --- a/src/plugins/qmljseditor/qmljsautocompleter.cpp +++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp @@ -143,8 +143,8 @@ AutoCompleter::AutoCompleter() AutoCompleter::~AutoCompleter() {} -bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const +bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) const { QChar ch; @@ -200,7 +200,7 @@ bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, return true; } -bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { Token token = tokenUnderCursor(cursor); switch (token.kind) { @@ -212,15 +212,15 @@ bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) } } -bool AutoCompleter::doIsInComment(const QTextCursor &cursor) const +bool AutoCompleter::isInComment(const QTextCursor &cursor) const { return tokenUnderCursor(cursor).is(Token::Comment); } -QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar, - int *skippedChars) const +QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar, + int *skippedChars) const { if (text.length() != 1) return QString(); @@ -268,7 +268,7 @@ QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, return QString(); } -QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { if (shouldInsertNewline(cursor)) { QTextCursor cursor = cursor; diff --git a/src/plugins/qmljseditor/qmljsautocompleter.h b/src/plugins/qmljseditor/qmljsautocompleter.h index 7e6b2bab03f..003a01994b3 100644 --- a/src/plugins/qmljseditor/qmljsautocompleter.h +++ b/src/plugins/qmljseditor/qmljsautocompleter.h @@ -41,16 +41,15 @@ public: AutoCompleter(); virtual ~AutoCompleter(); -private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &tc, + 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 doInsertParagraphSeparator(const QTextCursor &tc) const; + virtual QString insertParagraphSeparator(const QTextCursor &tc) const; }; } // Internal diff --git a/src/plugins/qmljseditor/qmljsindenter.cpp b/src/plugins/qmljseditor/qmljsindenter.cpp index 81374504ea4..ac288f236de 100644 --- a/src/plugins/qmljseditor/qmljsindenter.cpp +++ b/src/plugins/qmljseditor/qmljsindenter.cpp @@ -47,7 +47,7 @@ Indenter::Indenter() Indenter::~Indenter() {} -bool Indenter::doIsElectricalCharacter(const QChar &ch) const +bool Indenter::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('}') || ch == QLatin1Char(']') @@ -56,10 +56,10 @@ bool Indenter::doIsElectricalCharacter(const QChar &ch) const return false; } -void Indenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor) +void Indenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor) { Q_UNUSED(doc) Q_UNUSED(typedChar) diff --git a/src/plugins/qmljseditor/qmljsindenter.h b/src/plugins/qmljseditor/qmljsindenter.h index 82ad7114421..cf23112b733 100644 --- a/src/plugins/qmljseditor/qmljsindenter.h +++ b/src/plugins/qmljseditor/qmljsindenter.h @@ -41,12 +41,11 @@ public: Indenter(); virtual ~Indenter(); -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - TextEditor::BaseTextEditor *editor); + virtual bool isElectricCharacter(const QChar &ch) const; + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + TextEditor::BaseTextEditor *editor); }; } // Internal diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp index 92ce3161a40..5f04201436c 100644 --- a/src/plugins/texteditor/autocompleter.cpp +++ b/src/plugins/texteditor/autocompleter.cpp @@ -28,69 +28,310 @@ **************************************************************************/ #include "autocompleter.h" +#include "basetextdocumentlayout.h" +#include "texteditorsettings.h" +#include "tabsettings.h" #include using namespace TextEditor; -AutoCompleter::AutoCompleter() +AutoCompleter::AutoCompleter() : + m_allowSkippingOfBlockEnd(false), + m_surroundWithEnabled(true), + m_autoParenthesesEnabled(true) {} AutoCompleter::~AutoCompleter() {} +void AutoCompleter::setAutoParenthesesEnabled(bool b) +{ + m_autoParenthesesEnabled = b; +} + +bool AutoCompleter::isAutoParenthesesEnabled() const +{ + return m_autoParenthesesEnabled; +} + +void AutoCompleter::setSurroundWithEnabled(bool b) +{ + m_surroundWithEnabled = b; +} + +bool AutoCompleter::isSurroundWithEnabled() const +{ + return m_surroundWithEnabled; +} + +void AutoCompleter::countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen) +{ + if (c == open) + ++*stillopen; + else if (c == close) + --*stillopen; + + if (*stillopen < 0) { + *errors += -1 * (*stillopen); + *stillopen = 0; + } +} + +void AutoCompleter::countBrackets(QTextCursor cursor, + int from, + int end, + QChar open, + QChar close, + int *errors, + int *stillopen) +{ + cursor.setPosition(from); + QTextBlock block = cursor.block(); + while (block.isValid() && block.position() < end) { + TextEditor::Parentheses parenList = TextEditor::BaseTextDocumentLayout::parentheses(block); + if (!parenList.isEmpty() && !TextEditor::BaseTextDocumentLayout::ifdefedOut(block)) { + for (int i = 0; i < parenList.count(); ++i) { + TextEditor::Parenthesis paren = parenList.at(i); + int position = block.position() + paren.pos; + if (position < from || position >= end) + continue; + countBracket(open, close, paren.chr, errors, stillopen); + } + } + block = block.next(); + } +} + +QString AutoCompleter::autoComplete(QTextCursor &cursor, const QString &textToInsert) const +{ + const bool checkBlockEnd = m_allowSkippingOfBlockEnd; + m_allowSkippingOfBlockEnd = false; // consume blockEnd. + + if (m_surroundWithEnabled && cursor.hasSelection()) { + if (textToInsert == QLatin1String("(")) + return cursor.selectedText() + QLatin1String(")"); + if (textToInsert == QLatin1String("{")) { + //If the text span multiple lines, insert on different lines + QString str = cursor.selectedText(); + if (str.contains(QChar::ParagraphSeparator)) { + //Also, try to simulate auto-indent + str = (str.startsWith(QChar::ParagraphSeparator) ? QString() : QString(QChar::ParagraphSeparator)) + + str; + if (str.endsWith(QChar::ParagraphSeparator)) + str += QLatin1String("}") + QString(QChar::ParagraphSeparator); + else + str += QString(QChar::ParagraphSeparator) + QLatin1String("}"); + } + else { + str += QLatin1String("}"); + } + return str; + } + if (textToInsert == QLatin1String("[")) + return cursor.selectedText() + QLatin1String("]"); + if (textToInsert == QLatin1String("\"")) + return cursor.selectedText() + QLatin1String("\""); + if (textToInsert == QLatin1String("'")) + return cursor.selectedText() + QLatin1String("'"); + } + + if (!m_autoParenthesesEnabled) + return QString(); + + if (!contextAllowsAutoParentheses(cursor, textToInsert)) + return QString(); + + QTextDocument *doc = cursor.document(); + const QString text = textToInsert; + const QChar lookAhead = doc->characterAt(cursor.selectionEnd()); + + const QChar character = textToInsert.at(0); + const QString parentheses = QLatin1String("()"); + const QString brackets = QLatin1String("[]"); + if (parentheses.contains(character) || brackets.contains(character)) { + QTextCursor tmp= cursor; + bool foundBlockStart = TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); + int blockStart = foundBlockStart ? tmp.position() : 0; + tmp = cursor; + bool foundBlockEnd = TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); + int blockEnd = foundBlockEnd ? tmp.position() : (cursor.document()->characterCount() - 1); + const QChar openChar = parentheses.contains(character) ? QLatin1Char('(') : QLatin1Char('['); + const QChar closeChar = parentheses.contains(character) ? QLatin1Char(')') : QLatin1Char(']'); + + int errors = 0; + int stillopen = 0; + countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsBeforeInsertion = errors + stillopen; + errors = 0; + stillopen = 0; + countBrackets(cursor, blockStart, cursor.position(), openChar, closeChar, &errors, &stillopen); + countBracket(openChar, closeChar, character, &errors, &stillopen); + countBrackets(cursor, cursor.position(), blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsAfterInsertion = errors + stillopen; + if (errorsAfterInsertion < errorsBeforeInsertion) + return QString(); // insertion fixes parentheses or bracket errors, do not auto complete + } + + int skippedChars = 0; + const QString autoText = insertMatchingBrace(cursor, text, lookAhead, &skippedChars); + + if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) { + if (textToInsert.length() > 1) + qWarning() << "*** handle event compression"; + + int startPos = cursor.selectionEnd(), pos = startPos; + while (doc->characterAt(pos).isSpace()) + ++pos; + + if (doc->characterAt(pos) == QLatin1Char('}')) + skippedChars += (pos - startPos) + 1; + } + + if (skippedChars) { + const int pos = cursor.position(); + cursor.setPosition(pos + skippedChars); + cursor.setPosition(pos, QTextCursor::KeepAnchor); + } + + return autoText; +} + +bool AutoCompleter::autoBackspace(QTextCursor &cursor) +{ + m_allowSkippingOfBlockEnd = false; + + if (!m_autoParenthesesEnabled) + return false; + + int pos = cursor.position(); + if (pos == 0) + return false; + QTextCursor c = cursor; + c.setPosition(pos - 1); + + QTextDocument *doc = cursor.document(); + const QChar lookAhead = doc->characterAt(pos); + const QChar lookBehind = doc->characterAt(pos - 1); + const QChar lookFurtherBehind = doc->characterAt(pos - 2); + + const QChar character = lookBehind; + if (character == QLatin1Char('(') || character == QLatin1Char('[')) { + QTextCursor tmp = cursor; + TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); + int blockStart = tmp.isNull() ? 0 : tmp.position(); + tmp = cursor; + TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); + int blockEnd = tmp.isNull() ? (cursor.document()->characterCount()-1) : tmp.position(); + QChar openChar = character; + QChar closeChar = (character == QLatin1Char('(')) ? QLatin1Char(')') : QLatin1Char(']'); + + int errors = 0; + int stillopen = 0; + countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsBeforeDeletion = errors + stillopen; + errors = 0; + stillopen = 0; + countBrackets(cursor, blockStart, pos - 1, openChar, closeChar, &errors, &stillopen); + countBrackets(cursor, pos, blockEnd, openChar, closeChar, &errors, &stillopen); + int errorsAfterDeletion = errors + stillopen; + + if (errorsAfterDeletion < errorsBeforeDeletion) + return false; // insertion fixes parentheses or bracket errors, do not auto complete + } + + // ### this code needs to be generalized + if ((lookBehind == QLatin1Char('(') && lookAhead == QLatin1Char(')')) + || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']')) + || (lookBehind == QLatin1Char('"') && lookAhead == QLatin1Char('"') + && lookFurtherBehind != QLatin1Char('\\')) + || (lookBehind == QLatin1Char('\'') && lookAhead == QLatin1Char('\'') + && lookFurtherBehind != QLatin1Char('\\'))) { + if (! isInComment(c)) { + cursor.beginEditBlock(); + cursor.deleteChar(); + cursor.deletePreviousChar(); + cursor.endEditBlock(); + return true; + } + } + return false; +} + +int AutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor) +{ + if (!m_autoParenthesesEnabled) + return 0; + + QTextDocument *doc = cursor.document(); + if (doc->characterAt(cursor.position() - 1) != QLatin1Char('{')) + return 0; + + if (!contextAllowsAutoParentheses(cursor)) + return 0; + + // verify that we indeed do have an extra opening brace in the document + int braceDepth = BaseTextDocumentLayout::braceDepth(doc->lastBlock()); + + if (braceDepth <= 0) + return 0; // braces are all balanced or worse, no need to do anything + + // we have an extra brace , let's see if we should close it + + /* verify that the next block is not further intended compared to the current block. + This covers the following case: + + if (condition) {| + statement; + */ + const TabSettings &ts = TextEditorSettings::instance()->tabSettings(); + QTextBlock block = cursor.block(); + int indentation = ts.indentationColumn(block.text()); + + if (block.next().isValid()) { // not the last block + block = block.next(); + //skip all empty blocks + while (block.isValid() && ts.onlySpace(block.text())) + block = block.next(); + if (block.isValid() + && ts.indentationColumn(block.text()) > indentation) + return 0; + } + + const QString &textToInsert = insertParagraphSeparator(cursor); + int pos = cursor.position(); + cursor.insertBlock(); + cursor.insertText(textToInsert); + cursor.setPosition(pos); + + m_allowSkippingOfBlockEnd = true; + + return 1; +} + bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert) const -{ - return doContextAllowsAutoParentheses(cursor, textToInsert); -} - -bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const -{ - return doContextAllowsElectricCharacters(cursor); -} - -bool AutoCompleter::isInComment(const QTextCursor &cursor) const -{ - return doIsInComment(cursor); -} - -QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const - QString &text, - QChar la, - int *skippedChars) const -{ - return doInsertMatchingBrace(cursor, text, la, skippedChars); -} - -QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const -{ - return doInsertParagraphSeparator(cursor); -} - -bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert) const { Q_UNUSED(cursor); Q_UNUSED(textToInsert); return false; } -bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const +bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const { - return doContextAllowsAutoParentheses(cursor); + return contextAllowsAutoParentheses(cursor); } -bool AutoCompleter::doIsInComment(const QTextCursor &cursor) const +bool AutoCompleter::isInComment(const QTextCursor &cursor) const { Q_UNUSED(cursor); return false; } -QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const +QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor, + const QString &text, + QChar la, + int *skippedChars) const { Q_UNUSED(cursor); Q_UNUSED(text); @@ -99,7 +340,7 @@ QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, return QString(); } -QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const +QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const { Q_UNUSED(cursor); return QString(); diff --git a/src/plugins/texteditor/autocompleter.h b/src/plugins/texteditor/autocompleter.h index 3b49d499a4e..f8ecc1ce49a 100644 --- a/src/plugins/texteditor/autocompleter.h +++ b/src/plugins/texteditor/autocompleter.h @@ -47,30 +47,45 @@ public: AutoCompleter(); virtual ~AutoCompleter(); - bool contextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; + void setAutoParenthesesEnabled(bool b); + bool isAutoParenthesesEnabled() const; + + void setSurroundWithEnabled(bool b); + bool isSurroundWithEnabled() const; + + // Returns the text to complete at the cursor position, or an empty string + virtual QString autoComplete(QTextCursor &cursor, const QString &text) const; + + // Handles backspace. When returning true, backspace processing is stopped + virtual bool autoBackspace(QTextCursor &cursor); + + // Hook to insert special characters on enter. Returns the number of extra blocks inserted. + virtual int paragraphSeparatorAboutToBeInserted(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. - bool isInComment(const QTextCursor &cursor) const; + virtual bool isInComment(const QTextCursor &cursor) const; + + virtual QString insertMatchingBrace(const QTextCursor &cursor, const + QString &text, + QChar la, + int *skippedChars) const; - QString insertMatchingBrace(const QTextCursor &cursor, const - QString &text, - QChar la, - int *skippedChars) const; // Returns the text that needs to be inserted - QString insertParagraphSeparator(const QTextCursor &cursor) const; + virtual QString insertParagraphSeparator(const QTextCursor &cursor) const; + +protected: + static void countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen); + static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close, + int *errors, int *stillopen); private: - virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, - const QString &textToInsert = QString()) const; - virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; - virtual bool doIsInComment(const QTextCursor &cursor) const; - virtual QString doInsertMatchingBrace(const QTextCursor &cursor, - const QString &text, - QChar la, - int *skippedChars) const; - virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; + mutable bool m_allowSkippingOfBlockEnd; + bool m_surroundWithEnabled; + bool m_autoParenthesesEnabled; }; } // TextEditor diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 1e58cf2265c..7fcea6ccdab 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1552,8 +1552,9 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) const TabSettings &ts = d->m_document->tabSettings(); cursor.beginEditBlock(); - int extraBlocks = paragraphSeparatorAboutToBeInserted(cursor); // virtual + int extraBlocks = d->m_autoCompleter->paragraphSeparatorAboutToBeInserted(cursor); + QString previousIndentationString; if (ts.m_autoIndent) { cursor.insertBlock(); indent(document(), cursor, QChar::Null); @@ -1561,8 +1562,10 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) cursor.insertBlock(); // After inserting the block, to avoid duplicating whitespace on the same line - const QString previousBlockText = cursor.block().previous().text(); - cursor.insertText(ts.indentationString(previousBlockText)); + const QString &previousBlockText = cursor.block().previous().text(); + previousIndentationString = ts.indentationString(previousBlockText); + if (!previousIndentationString.isEmpty()) + cursor.insertText(previousIndentationString); } cursor.endEditBlock(); e->accept(); @@ -1572,6 +1575,10 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) while (extraBlocks > 0) { --extraBlocks; ensureVisible.movePosition(QTextCursor::NextBlock); + if (ts.m_autoIndent) + indent(document(), ensureVisible, QChar::Null); + else if (!previousIndentationString.isEmpty()) + ensureVisible.insertText(previousIndentationString); } setTextCursor(ensureVisible); } @@ -1763,7 +1770,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) } else if ((e->modifiers() & (Qt::ControlModifier|Qt::AltModifier)) != Qt::ControlModifier){ QTextCursor cursor = textCursor(); QString text = e->text(); - QString autoText = autoComplete(cursor, text); + const QString &autoText = d->m_autoCompleter->autoComplete(cursor, text); QChar electricChar; if (d->m_document->tabSettings().m_autoIndent) { @@ -2178,26 +2185,6 @@ bool BaseTextEditor::isParenthesesMatchingEnabled() const return d->m_parenthesesMatchingEnabled; } -void BaseTextEditor::setAutoParenthesesEnabled(bool b) -{ - d->m_autoParenthesesEnabled = b; -} - -bool BaseTextEditor::isAutoParenthesesEnabled() const -{ - return d->m_autoParenthesesEnabled; -} - -void BaseTextEditor::setSurroundWithEnabled(bool b) -{ - d->m_surroundWithEnabled= b; -} - -bool BaseTextEditor::isSurroundWithEnabled() const -{ - return d->m_surroundWithEnabled; -} - void BaseTextEditor::setHighlightCurrentLine(bool b) { d->m_highlightCurrentLine = b; @@ -2359,11 +2346,8 @@ BaseTextEditorPrivate::BaseTextEditorPrivate() q(0), m_contentsChanged(false), m_lastCursorChangeWasInteresting(false), - m_allowSkippingOfBlockEnd(false), m_document(new BaseTextDocument), m_parenthesesMatchingEnabled(false), - m_autoParenthesesEnabled(true), - m_surroundWithEnabled(true), m_updateTimer(0), m_formatRange(false), m_parenthesesMatchingTimer(0), @@ -4413,7 +4397,7 @@ void BaseTextEditor::handleBackspaceKey() const TextEditor::TabSettings &tabSettings = d->m_document->tabSettings(); - if (tabSettings.m_autoIndent && autoBackspace(cursor)) + if (tabSettings.m_autoIndent && d->m_autoCompleter->autoBackspace(cursor)) return; if (!tabSettings.m_smartBackspace) { @@ -4487,250 +4471,6 @@ void BaseTextEditor::indentInsertedText(const QTextCursor &tc) indent(tc.document(), tc, QChar::Null); } -void BaseTextEditor::countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen) -{ - if (c == open) - ++*stillopen; - else if (c == close) - --*stillopen; - - if (*stillopen < 0) { - *errors += -1 * (*stillopen); - *stillopen = 0; - } -} - -void BaseTextEditor::countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close, int *errors, int *stillopen) -{ - cursor.setPosition(from); - QTextBlock block = cursor.block(); - while (block.isValid() && block.position() < end) { - TextEditor::Parentheses parenList = TextEditor::BaseTextDocumentLayout::parentheses(block); - if (!parenList.isEmpty() && !TextEditor::BaseTextDocumentLayout::ifdefedOut(block)) { - for (int i = 0; i < parenList.count(); ++i) { - TextEditor::Parenthesis paren = parenList.at(i); - int position = block.position() + paren.pos; - if (position < from || position >= end) - continue; - countBracket(open, close, paren.chr, errors, stillopen); - } - } - block = block.next(); - } -} - -QString BaseTextEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert) const -{ - const bool checkBlockEnd = d->m_allowSkippingOfBlockEnd; - d->m_allowSkippingOfBlockEnd = false; // consume blockEnd. - - if (d->m_surroundWithEnabled && cursor.hasSelection()) { - if (textToInsert == QLatin1String("(")) - return cursor.selectedText() + QLatin1String(")"); - if (textToInsert == QLatin1String("{")) { - //If the text span multiple lines, insert on different lines - QString str = cursor.selectedText(); - if (str.contains(QChar::ParagraphSeparator)) { - //Also, try to simulate auto-indent - str = (str.startsWith(QChar::ParagraphSeparator) ? QString() : QString(QChar::ParagraphSeparator)) + - str; - if (str.endsWith(QChar::ParagraphSeparator)) - str += QLatin1String("}") + QString(QChar::ParagraphSeparator); - else - str += QString(QChar::ParagraphSeparator) + QLatin1String("}"); - } - else { - str += QLatin1String("}"); - } - return str; - } - if (textToInsert == QLatin1String("[")) - return cursor.selectedText() + QLatin1String("]"); - if (textToInsert == QLatin1String("\"")) - return cursor.selectedText() + QLatin1String("\""); - if (textToInsert == QLatin1String("'")) - return cursor.selectedText() + QLatin1String("'"); - } - - if (!d->m_autoParenthesesEnabled) - return QString(); - - if (!d->m_autoCompleter->contextAllowsAutoParentheses(cursor, textToInsert)) - return QString(); - - const QString text = textToInsert; - const QChar lookAhead = characterAt(cursor.selectionEnd()); - - const QChar character = textToInsert.at(0); - const QString parentheses = QLatin1String("()"); - const QString brackets = QLatin1String("[]"); - if (parentheses.contains(character) || brackets.contains(character)) { - QTextCursor tmp= cursor; - bool foundBlockStart = TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); - int blockStart = foundBlockStart ? tmp.position() : 0; - tmp = cursor; - bool foundBlockEnd = TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); - int blockEnd = foundBlockEnd ? tmp.position() : (cursor.document()->characterCount() - 1); - const QChar openChar = parentheses.contains(character) ? QLatin1Char('(') : QLatin1Char('['); - const QChar closeChar = parentheses.contains(character) ? QLatin1Char(')') : QLatin1Char(']'); - - int errors = 0; - int stillopen = 0; - countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsBeforeInsertion = errors + stillopen; - errors = 0; - stillopen = 0; - countBrackets(cursor, blockStart, cursor.position(), openChar, closeChar, &errors, &stillopen); - countBracket(openChar, closeChar, character, &errors, &stillopen); - countBrackets(cursor, cursor.position(), blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsAfterInsertion = errors + stillopen; - if (errorsAfterInsertion < errorsBeforeInsertion) - return QString(); // insertion fixes parentheses or bracket errors, do not auto complete - } - - int skippedChars = 0; - const QString autoText = d->m_autoCompleter->insertMatchingBrace(cursor, text, lookAhead, &skippedChars); - - if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) { - if (textToInsert.length() > 1) - qWarning() << "*** handle event compression"; - - int startPos = cursor.selectionEnd(), pos = startPos; - while (characterAt(pos).isSpace()) - ++pos; - - if (characterAt(pos) == QLatin1Char('}')) - skippedChars += (pos - startPos) + 1; - } - - if (skippedChars) { - const int pos = cursor.position(); - cursor.setPosition(pos + skippedChars); - cursor.setPosition(pos, QTextCursor::KeepAnchor); - } - - return autoText; -} - -bool BaseTextEditor::autoBackspace(QTextCursor &cursor) -{ - d->m_allowSkippingOfBlockEnd = false; - - if (!d->m_autoParenthesesEnabled) - return false; - - int pos = cursor.position(); - if (pos == 0) - return false; - QTextCursor c = cursor; - c.setPosition(pos - 1); - - const QChar lookAhead = characterAt(pos); - const QChar lookBehind = characterAt(pos - 1); - const QChar lookFurtherBehind = characterAt(pos - 2); - - const QChar character = lookBehind; - if (character == QLatin1Char('(') || character == QLatin1Char('[')) { - QTextCursor tmp = cursor; - TextEditor::TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); - int blockStart = tmp.isNull() ? 0 : tmp.position(); - tmp = cursor; - TextEditor::TextBlockUserData::findNextBlockClosingParenthesis(&tmp); - int blockEnd = tmp.isNull() ? (cursor.document()->characterCount()-1) : tmp.position(); - QChar openChar = character; - QChar closeChar = (character == QLatin1Char('(')) ? QLatin1Char(')') : QLatin1Char(']'); - - int errors = 0; - int stillopen = 0; - countBrackets(cursor, blockStart, blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsBeforeDeletion = errors + stillopen; - errors = 0; - stillopen = 0; - countBrackets(cursor, blockStart, pos - 1, openChar, closeChar, &errors, &stillopen); - countBrackets(cursor, pos, blockEnd, openChar, closeChar, &errors, &stillopen); - int errorsAfterDeletion = errors + stillopen; - - if (errorsAfterDeletion < errorsBeforeDeletion) - return false; // insertion fixes parentheses or bracket errors, do not auto complete - } - - // ### this code needs to be generalized - if ((lookBehind == QLatin1Char('(') && lookAhead == QLatin1Char(')')) - || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']')) - || (lookBehind == QLatin1Char('"') && lookAhead == QLatin1Char('"') - && lookFurtherBehind != QLatin1Char('\\')) - || (lookBehind == QLatin1Char('\'') && lookAhead == QLatin1Char('\'') - && lookFurtherBehind != QLatin1Char('\\'))) { - if (! d->m_autoCompleter->isInComment(c)) { - cursor.beginEditBlock(); - cursor.deleteChar(); - cursor.deletePreviousChar(); - cursor.endEditBlock(); - return true; - } - } - return false; -} - -int BaseTextEditor::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor) -{ - if (!d->m_autoParenthesesEnabled) - return 0; - - if (characterAt(cursor.position() - 1) != QLatin1Char('{')) - return 0; - - if (!d->m_autoCompleter->contextAllowsAutoParentheses(cursor)) - return 0; - - // verify that we indeed do have an extra opening brace in the document - int braceDepth = BaseTextDocumentLayout::braceDepth(document()->lastBlock()); - - if (braceDepth <= 0) - return 0; // braces are all balanced or worse, no need to do anything - - // we have an extra brace , let's see if we should close it - - - /* verify that the next block is not further intended compared to the current block. - This covers the following case: - - if (condition) {| - statement; - */ - const TabSettings &ts = tabSettings(); - QTextBlock block = cursor.block(); - int indentation = ts.indentationColumn(block.text()); - - if (block.next().isValid()) { // not the last block - block = block.next(); - //skip all empty blocks - while (block.isValid() && ts.onlySpace(block.text())) - block = block.next(); - if (block.isValid() - && ts.indentationColumn(block.text()) > indentation) - return 0; - } - - int pos = cursor.position(); - - const QString textToInsert = d->m_autoCompleter->insertParagraphSeparator(cursor); - - cursor.insertText(textToInsert); - cursor.setPosition(pos); - if (ts.m_autoIndent) { - cursor.insertBlock(); - indent(document(), cursor, QChar::Null); - } else { - QString previousBlockText = cursor.block().text(); - cursor.insertBlock(); - cursor.insertText(ts.indentationString(previousBlockText)); - } - cursor.setPosition(pos); - d->m_allowSkippingOfBlockEnd = true; - return 1; -} - void BaseTextEditor::indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar) { maybeClearSomeExtraSelections(cursor); @@ -5624,7 +5364,8 @@ void BaseTextEditor::setStorageSettings(const StorageSettings &storageSettings) void BaseTextEditor::setCompletionSettings(const TextEditor::CompletionSettings &completionSettings) { - setAutoParenthesesEnabled(completionSettings.m_autoInsertBrackets); + d->m_autoCompleter->setAutoParenthesesEnabled(completionSettings.m_autoInsertBrackets); + d->m_autoCompleter->setSurroundWithEnabled(completionSettings.m_autoInsertBrackets); } void BaseTextEditor::fold() diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index c6e3fe6ef79..dcb590e6318 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -168,12 +168,6 @@ public: void setParenthesesMatchingEnabled(bool b); bool isParenthesesMatchingEnabled() const; - void setAutoParenthesesEnabled(bool b); - bool isAutoParenthesesEnabled() const; - - void setSurroundWithEnabled(bool b); - bool isSurroundWithEnabled() const; - void setHighlightCurrentLine(bool b); bool highlightCurrentLine() const; @@ -424,24 +418,10 @@ protected: void dragEnterEvent(QDragEnterEvent *e); public: - // Returns the text to complete at the cursor position, or an empty string - virtual QString autoComplete(QTextCursor &cursor, const QString &text) const; - // Handles backspace. When returning true, backspace processing is stopped - virtual bool autoBackspace(QTextCursor &cursor); - // Hook to insert special characters on enter. Returns the number of extra blocks inserted. - virtual int paragraphSeparatorAboutToBeInserted(QTextCursor &cursor); - void indentInsertedText(const QTextCursor &tc); void indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar); void reindent(QTextDocument *doc, const QTextCursor &cursor); -protected: - static void countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen); - - static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close, - int *errors, int *stillopen); - -public: struct Link { Link(const QString &fileName = QString(), diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 3fd10bc054b..d658899cd1a 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -180,7 +180,6 @@ public: BaseTextEditor *q; bool m_contentsChanged; bool m_lastCursorChangeWasInteresting; - bool m_allowSkippingOfBlockEnd; QList m_syntaxHighlighterSelections; QTextEdit::ExtraSelection m_lineSelection; @@ -191,8 +190,6 @@ public: QString m_displayName; bool m_parenthesesMatchingEnabled; - bool m_autoParenthesesEnabled; - bool m_surroundWithEnabled; QTimer *m_updateTimer; Utils::ChangeSet m_changeSet; diff --git a/src/plugins/texteditor/indenter.cpp b/src/plugins/texteditor/indenter.cpp index 97ae9ebf17c..3a833cd0976 100644 --- a/src/plugins/texteditor/indenter.cpp +++ b/src/plugins/texteditor/indenter.cpp @@ -39,38 +39,12 @@ Indenter::Indenter() Indenter::~Indenter() {} -bool Indenter::isElectricCharacter(const QChar &ch) const -{ - return doIsElectricalCharacter(ch); -} - -void Indenter::indentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor) -{ - doIndentBlock(doc, block, typedChar, editor); -} - -void Indenter::indent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - BaseTextEditor *editor) -{ - doIndent(doc, cursor, typedChar, editor); -} - -void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor) -{ - doReindent(doc, cursor, editor); -} - -bool Indenter::doIsElectricalCharacter(const QChar &) const +bool Indenter::isElectricCharacter(const QChar &) const { return false; } -void Indenter::doIndentBlock(QTextDocument *doc, +void Indenter::indentBlock(QTextDocument *doc, const QTextBlock &block, const QChar &typedChar, BaseTextEditor *editor) @@ -81,7 +55,10 @@ void Indenter::doIndentBlock(QTextDocument *doc, Q_UNUSED(editor); } -void Indenter::doIndent(QTextDocument *doc, const QTextCursor &cursor, const QChar &typedChar, BaseTextEditor *editor) +void Indenter::indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); @@ -95,7 +72,7 @@ void Indenter::doIndent(QTextDocument *doc, const QTextCursor &cursor, const QCh } } -void Indenter::doReindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor) +void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); diff --git a/src/plugins/texteditor/indenter.h b/src/plugins/texteditor/indenter.h index 22a95b888ed..49e8546e7ff 100644 --- a/src/plugins/texteditor/indenter.h +++ b/src/plugins/texteditor/indenter.h @@ -51,32 +51,23 @@ public: virtual ~Indenter(); // Returns true if key triggers an indent. - bool isElectricCharacter(const QChar &ch) const; + virtual bool isElectricCharacter(const QChar &ch) const; + // Indent a text block based on previous line. Default does nothing - void indentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor); + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + BaseTextEditor *editor); + // Indent at cursor. Calls indentBlock for selection or current line. - void indent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - BaseTextEditor *editor); + virtual void indent(QTextDocument *doc, + const QTextCursor &cursor, + const QChar &typedChar, + BaseTextEditor *editor); + // Reindent at cursor. Selection will be adjusted according to the indentation // change of the first block. - void reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor); - -private: - virtual bool doIsElectricalCharacter(const QChar &ch) const; - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor); - virtual void doIndent(QTextDocument *doc, - const QTextCursor &cursor, - const QChar &typedChar, - BaseTextEditor *editor); - virtual void doReindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor); + virtual void reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor); }; } // namespace TextEditor diff --git a/src/plugins/texteditor/normalindenter.cpp b/src/plugins/texteditor/normalindenter.cpp index d0c84b210f7..7acb9f78278 100644 --- a/src/plugins/texteditor/normalindenter.cpp +++ b/src/plugins/texteditor/normalindenter.cpp @@ -60,10 +60,10 @@ NormalIndenter::~NormalIndenter() // for additional block being inserted. It might be possible // to do in 2 steps (indenting/wrapping)} // -void NormalIndenter::doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor) +void NormalIndenter::indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + BaseTextEditor *editor) { Q_UNUSED(typedChar) diff --git a/src/plugins/texteditor/normalindenter.h b/src/plugins/texteditor/normalindenter.h index f66bbaef0a0..98be4ed1321 100644 --- a/src/plugins/texteditor/normalindenter.h +++ b/src/plugins/texteditor/normalindenter.h @@ -40,11 +40,10 @@ public: NormalIndenter(); virtual ~NormalIndenter(); -private: - virtual void doIndentBlock(QTextDocument *doc, - const QTextBlock &block, - const QChar &typedChar, - BaseTextEditor *editor); + virtual void indentBlock(QTextDocument *doc, + const QTextBlock &block, + const QChar &typedChar, + BaseTextEditor *editor); }; } // namespace TextEditor