Editors: Move auto-completion code out of the editor

This is basically a continuation of the commits which
refactor code out of the base text editor. For instance,
36fa1de4c6 and
3a684586fa.

Also removed the doXXXX() forwarding methods.
This commit is contained in:
Leandro Melo
2010-11-30 14:14:33 +01:00
parent e117f04fab
commit ea8cb4764b
21 changed files with 448 additions and 513 deletions

View File

@@ -48,7 +48,7 @@ CppAutoCompleter::CppAutoCompleter()
CppAutoCompleter::~CppAutoCompleter() CppAutoCompleter::~CppAutoCompleter()
{} {}
bool CppAutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, bool CppAutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert) const const QString &textToInsert) const
{ {
QChar ch; QChar ch;
@@ -66,7 +66,7 @@ bool CppAutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor,
return true; 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(), const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(),
BackwardsScanner::previousBlockState(cursor.block())); BackwardsScanner::previousBlockState(cursor.block()));
@@ -98,7 +98,7 @@ bool CppAutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &curs
return true; 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(), const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(),
BackwardsScanner::previousBlockState(cursor.block())); BackwardsScanner::previousBlockState(cursor.block()));
@@ -122,7 +122,7 @@ bool CppAutoCompleter::doIsInComment(const QTextCursor &cursor) const
return false; return false;
} }
QString CppAutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, QString CppAutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text, const QString &text,
QChar la, QChar la,
int *skippedChars) const int *skippedChars) const
@@ -131,7 +131,7 @@ QString CppAutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor,
return m.insertMatchingBrace(cursor, text, la, skippedChars); return m.insertMatchingBrace(cursor, text, la, skippedChars);
} }
QString CppAutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const QString CppAutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
{ {
MatchingText m; MatchingText m;
return m.insertParagraphSeparator(cursor); return m.insertParagraphSeparator(cursor);

View File

@@ -41,16 +41,15 @@ public:
CppAutoCompleter(); CppAutoCompleter();
virtual ~CppAutoCompleter(); virtual ~CppAutoCompleter();
private: virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert = QString()) const; const QString &textToInsert = QString()) const;
virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
virtual bool doIsInComment(const QTextCursor &cursor) const; virtual bool isInComment(const QTextCursor &cursor) const;
virtual QString doInsertMatchingBrace(const QTextCursor &cursor, virtual QString insertMatchingBrace(const QTextCursor &cursor,
const QString &text, const QString &text,
QChar la, QChar la,
int *skippedChars) const; int *skippedChars) const;
virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; virtual QString insertParagraphSeparator(const QTextCursor &cursor) const;
}; };
} // Internal } // Internal

View File

@@ -47,7 +47,7 @@ CppQtStyleIndenter::CppQtStyleIndenter()
CppQtStyleIndenter::~CppQtStyleIndenter() CppQtStyleIndenter::~CppQtStyleIndenter()
{} {}
bool CppQtStyleIndenter::doIsElectricalCharacter(const QChar &ch) const bool CppQtStyleIndenter::isElectricCharacter(const QChar &ch) const
{ {
if (ch == QLatin1Char('{') || if (ch == QLatin1Char('{') ||
ch == QLatin1Char('}') || ch == QLatin1Char('}') ||
@@ -58,7 +58,7 @@ bool CppQtStyleIndenter::doIsElectricalCharacter(const QChar &ch) const
return false; return false;
} }
void CppQtStyleIndenter::doIndentBlock(QTextDocument *doc, void CppQtStyleIndenter::indentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor) TextEditor::BaseTextEditor *editor)
@@ -86,7 +86,7 @@ void CppQtStyleIndenter::doIndentBlock(QTextDocument *doc,
ts.indentLine(block, indent + padding, padding); ts.indentLine(block, indent + padding, padding);
} }
void CppQtStyleIndenter::doIndent(QTextDocument *doc, void CppQtStyleIndenter::indent(QTextDocument *doc,
const QTextCursor &cursor, const QTextCursor &cursor,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor) TextEditor::BaseTextEditor *editor)

View File

@@ -41,14 +41,13 @@ public:
CppQtStyleIndenter(); CppQtStyleIndenter();
virtual ~CppQtStyleIndenter(); virtual ~CppQtStyleIndenter();
private: virtual bool isElectricCharacter(const QChar &ch) const;
virtual bool doIsElectricalCharacter(const QChar &ch) const; virtual void indentBlock(QTextDocument *doc,
virtual void doIndentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor); TextEditor::BaseTextEditor *editor);
virtual void doIndent(QTextDocument *doc, virtual void indent(QTextDocument *doc,
const QTextCursor &cursor, const QTextCursor &cursor,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor); TextEditor::BaseTextEditor *editor);

View File

@@ -47,7 +47,7 @@ GLSLCompleter::GLSLCompleter()
GLSLCompleter::~GLSLCompleter() GLSLCompleter::~GLSLCompleter()
{} {}
bool GLSLCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, bool GLSLCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert) const const QString &textToInsert) const
{ {
QChar ch; QChar ch;
@@ -65,7 +65,7 @@ bool GLSLCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor,
return true; 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(), const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(),
BackwardsScanner::previousBlockState(cursor.block())); BackwardsScanner::previousBlockState(cursor.block()));
@@ -97,7 +97,7 @@ bool GLSLCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor)
return true; 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(), const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(),
BackwardsScanner::previousBlockState(cursor.block())); BackwardsScanner::previousBlockState(cursor.block()));
@@ -121,7 +121,7 @@ bool GLSLCompleter::doIsInComment(const QTextCursor &cursor) const
return false; return false;
} }
QString GLSLCompleter::doInsertMatchingBrace(const QTextCursor &cursor, QString GLSLCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text, const QString &text,
QChar la, QChar la,
int *skippedChars) const int *skippedChars) const
@@ -130,7 +130,7 @@ QString GLSLCompleter::doInsertMatchingBrace(const QTextCursor &cursor,
return m.insertMatchingBrace(cursor, text, la, skippedChars); return m.insertMatchingBrace(cursor, text, la, skippedChars);
} }
QString GLSLCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const QString GLSLCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
{ {
MatchingText m; MatchingText m;
return m.insertParagraphSeparator(cursor); return m.insertParagraphSeparator(cursor);

View File

@@ -41,16 +41,15 @@ public:
GLSLCompleter(); GLSLCompleter();
virtual ~GLSLCompleter(); virtual ~GLSLCompleter();
private: virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert = QString()) const; const QString &textToInsert = QString()) const;
virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
virtual bool doIsInComment(const QTextCursor &cursor) const; virtual bool isInComment(const QTextCursor &cursor) const;
virtual QString doInsertMatchingBrace(const QTextCursor &cursor, virtual QString insertMatchingBrace(const QTextCursor &cursor,
const QString &text, const QString &text,
QChar la, QChar la,
int *skippedChars) const; int *skippedChars) const;
virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const; virtual QString insertParagraphSeparator(const QTextCursor &cursor) const;
}; };
} // Internal } // Internal

View File

@@ -47,7 +47,7 @@ GLSLIndenter::GLSLIndenter()
GLSLIndenter::~GLSLIndenter() GLSLIndenter::~GLSLIndenter()
{} {}
bool GLSLIndenter::doIsElectricalCharacter(const QChar &ch) const bool GLSLIndenter::isElectricCharacter(const QChar &ch) const
{ {
if (ch == QLatin1Char('{') || if (ch == QLatin1Char('{') ||
ch == QLatin1Char('}') || ch == QLatin1Char('}') ||
@@ -58,7 +58,7 @@ bool GLSLIndenter::doIsElectricalCharacter(const QChar &ch) const
return false; return false;
} }
void GLSLIndenter::doIndentBlock(QTextDocument *doc, void GLSLIndenter::indentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor) TextEditor::BaseTextEditor *editor)
@@ -86,7 +86,7 @@ void GLSLIndenter::doIndentBlock(QTextDocument *doc,
ts.indentLine(block, indent + padding, padding); ts.indentLine(block, indent + padding, padding);
} }
void GLSLIndenter::doIndent(QTextDocument *doc, void GLSLIndenter::indent(QTextDocument *doc,
const QTextCursor &cursor, const QTextCursor &cursor,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor) TextEditor::BaseTextEditor *editor)

View File

@@ -41,14 +41,13 @@ public:
GLSLIndenter(); GLSLIndenter();
virtual ~GLSLIndenter(); virtual ~GLSLIndenter();
private: virtual bool isElectricCharacter(const QChar &ch) const;
virtual bool doIsElectricalCharacter(const QChar &ch) const; virtual void indentBlock(QTextDocument *doc,
virtual void doIndentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor); TextEditor::BaseTextEditor *editor);
virtual void doIndent(QTextDocument *doc, virtual void indent(QTextDocument *doc,
const QTextCursor &cursor, const QTextCursor &cursor,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor); TextEditor::BaseTextEditor *editor);

View File

@@ -143,7 +143,7 @@ AutoCompleter::AutoCompleter()
AutoCompleter::~AutoCompleter() AutoCompleter::~AutoCompleter()
{} {}
bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor, bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert) const const QString &textToInsert) const
{ {
QChar ch; QChar ch;
@@ -200,7 +200,7 @@ bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor,
return true; return true;
} }
bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{ {
Token token = tokenUnderCursor(cursor); Token token = tokenUnderCursor(cursor);
switch (token.kind) { switch (token.kind) {
@@ -212,12 +212,12 @@ 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); return tokenUnderCursor(cursor).is(Token::Comment);
} }
QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text, const QString &text,
QChar, QChar,
int *skippedChars) const int *skippedChars) const
@@ -268,7 +268,7 @@ QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor,
return QString(); return QString();
} }
QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
{ {
if (shouldInsertNewline(cursor)) { if (shouldInsertNewline(cursor)) {
QTextCursor cursor = cursor; QTextCursor cursor = cursor;

View File

@@ -41,16 +41,15 @@ public:
AutoCompleter(); AutoCompleter();
virtual ~AutoCompleter(); virtual ~AutoCompleter();
private: virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert = QString()) const; const QString &textToInsert = QString()) const;
virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
virtual bool doIsInComment(const QTextCursor &cursor) const; virtual bool isInComment(const QTextCursor &cursor) const;
virtual QString doInsertMatchingBrace(const QTextCursor &tc, virtual QString insertMatchingBrace(const QTextCursor &tc,
const QString &text, const QString &text,
QChar la, QChar la,
int *skippedChars) const; int *skippedChars) const;
virtual QString doInsertParagraphSeparator(const QTextCursor &tc) const; virtual QString insertParagraphSeparator(const QTextCursor &tc) const;
}; };
} // Internal } // Internal

View File

@@ -47,7 +47,7 @@ Indenter::Indenter()
Indenter::~Indenter() Indenter::~Indenter()
{} {}
bool Indenter::doIsElectricalCharacter(const QChar &ch) const bool Indenter::isElectricCharacter(const QChar &ch) const
{ {
if (ch == QLatin1Char('}') if (ch == QLatin1Char('}')
|| ch == QLatin1Char(']') || ch == QLatin1Char(']')
@@ -56,7 +56,7 @@ bool Indenter::doIsElectricalCharacter(const QChar &ch) const
return false; return false;
} }
void Indenter::doIndentBlock(QTextDocument *doc, void Indenter::indentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor) TextEditor::BaseTextEditor *editor)

View File

@@ -41,9 +41,8 @@ public:
Indenter(); Indenter();
virtual ~Indenter(); virtual ~Indenter();
private: virtual bool isElectricCharacter(const QChar &ch) const;
virtual bool doIsElectricalCharacter(const QChar &ch) const; virtual void indentBlock(QTextDocument *doc,
virtual void doIndentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
TextEditor::BaseTextEditor *editor); TextEditor::BaseTextEditor *editor);

View File

@@ -28,66 +28,307 @@
**************************************************************************/ **************************************************************************/
#include "autocompleter.h" #include "autocompleter.h"
#include "basetextdocumentlayout.h"
#include "texteditorsettings.h"
#include "tabsettings.h"
#include <QtGui/QTextCursor> #include <QtGui/QTextCursor>
using namespace TextEditor; using namespace TextEditor;
AutoCompleter::AutoCompleter() AutoCompleter::AutoCompleter() :
m_allowSkippingOfBlockEnd(false),
m_surroundWithEnabled(true),
m_autoParenthesesEnabled(true)
{} {}
AutoCompleter::~AutoCompleter() 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, bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert) const 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(cursor);
Q_UNUSED(textToInsert); Q_UNUSED(textToInsert);
return false; 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); Q_UNUSED(cursor);
return false; return false;
} }
QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor, QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text, const QString &text,
QChar la, QChar la,
int *skippedChars) const int *skippedChars) const
@@ -99,7 +340,7 @@ QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor,
return QString(); return QString();
} }
QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
{ {
Q_UNUSED(cursor); Q_UNUSED(cursor);
return QString(); return QString();

View File

@@ -47,30 +47,45 @@ public:
AutoCompleter(); AutoCompleter();
virtual ~AutoCompleter(); virtual ~AutoCompleter();
bool contextAllowsAutoParentheses(const QTextCursor &cursor, 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; const QString &textToInsert = QString()) const;
bool contextAllowsElectricCharacters(const QTextCursor &cursor) const; virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
// Returns true if the cursor is inside a comment. // Returns true if the cursor is inside a comment.
bool isInComment(const QTextCursor &cursor) const; virtual bool isInComment(const QTextCursor &cursor) const;
QString insertMatchingBrace(const QTextCursor &cursor, const virtual QString insertMatchingBrace(const QTextCursor &cursor, const
QString &text, QString &text,
QChar la, QChar la,
int *skippedChars) const; int *skippedChars) const;
// Returns the text that needs to be inserted // 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: private:
virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor, mutable bool m_allowSkippingOfBlockEnd;
const QString &textToInsert = QString()) const; bool m_surroundWithEnabled;
virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const; bool m_autoParenthesesEnabled;
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;
}; };
} // TextEditor } // TextEditor

View File

@@ -1552,8 +1552,9 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
const TabSettings &ts = d->m_document->tabSettings(); const TabSettings &ts = d->m_document->tabSettings();
cursor.beginEditBlock(); cursor.beginEditBlock();
int extraBlocks = paragraphSeparatorAboutToBeInserted(cursor); // virtual int extraBlocks = d->m_autoCompleter->paragraphSeparatorAboutToBeInserted(cursor);
QString previousIndentationString;
if (ts.m_autoIndent) { if (ts.m_autoIndent) {
cursor.insertBlock(); cursor.insertBlock();
indent(document(), cursor, QChar::Null); indent(document(), cursor, QChar::Null);
@@ -1561,8 +1562,10 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
cursor.insertBlock(); cursor.insertBlock();
// After inserting the block, to avoid duplicating whitespace on the same line // After inserting the block, to avoid duplicating whitespace on the same line
const QString previousBlockText = cursor.block().previous().text(); const QString &previousBlockText = cursor.block().previous().text();
cursor.insertText(ts.indentationString(previousBlockText)); previousIndentationString = ts.indentationString(previousBlockText);
if (!previousIndentationString.isEmpty())
cursor.insertText(previousIndentationString);
} }
cursor.endEditBlock(); cursor.endEditBlock();
e->accept(); e->accept();
@@ -1572,6 +1575,10 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
while (extraBlocks > 0) { while (extraBlocks > 0) {
--extraBlocks; --extraBlocks;
ensureVisible.movePosition(QTextCursor::NextBlock); ensureVisible.movePosition(QTextCursor::NextBlock);
if (ts.m_autoIndent)
indent(document(), ensureVisible, QChar::Null);
else if (!previousIndentationString.isEmpty())
ensureVisible.insertText(previousIndentationString);
} }
setTextCursor(ensureVisible); setTextCursor(ensureVisible);
} }
@@ -1763,7 +1770,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
} else if ((e->modifiers() & (Qt::ControlModifier|Qt::AltModifier)) != Qt::ControlModifier){ } else if ((e->modifiers() & (Qt::ControlModifier|Qt::AltModifier)) != Qt::ControlModifier){
QTextCursor cursor = textCursor(); QTextCursor cursor = textCursor();
QString text = e->text(); QString text = e->text();
QString autoText = autoComplete(cursor, text); const QString &autoText = d->m_autoCompleter->autoComplete(cursor, text);
QChar electricChar; QChar electricChar;
if (d->m_document->tabSettings().m_autoIndent) { if (d->m_document->tabSettings().m_autoIndent) {
@@ -2178,26 +2185,6 @@ bool BaseTextEditor::isParenthesesMatchingEnabled() const
return d->m_parenthesesMatchingEnabled; 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) void BaseTextEditor::setHighlightCurrentLine(bool b)
{ {
d->m_highlightCurrentLine = b; d->m_highlightCurrentLine = b;
@@ -2359,11 +2346,8 @@ BaseTextEditorPrivate::BaseTextEditorPrivate()
q(0), q(0),
m_contentsChanged(false), m_contentsChanged(false),
m_lastCursorChangeWasInteresting(false), m_lastCursorChangeWasInteresting(false),
m_allowSkippingOfBlockEnd(false),
m_document(new BaseTextDocument), m_document(new BaseTextDocument),
m_parenthesesMatchingEnabled(false), m_parenthesesMatchingEnabled(false),
m_autoParenthesesEnabled(true),
m_surroundWithEnabled(true),
m_updateTimer(0), m_updateTimer(0),
m_formatRange(false), m_formatRange(false),
m_parenthesesMatchingTimer(0), m_parenthesesMatchingTimer(0),
@@ -4413,7 +4397,7 @@ void BaseTextEditor::handleBackspaceKey()
const TextEditor::TabSettings &tabSettings = d->m_document->tabSettings(); const TextEditor::TabSettings &tabSettings = d->m_document->tabSettings();
if (tabSettings.m_autoIndent && autoBackspace(cursor)) if (tabSettings.m_autoIndent && d->m_autoCompleter->autoBackspace(cursor))
return; return;
if (!tabSettings.m_smartBackspace) { if (!tabSettings.m_smartBackspace) {
@@ -4487,250 +4471,6 @@ void BaseTextEditor::indentInsertedText(const QTextCursor &tc)
indent(tc.document(), tc, QChar::Null); 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) void BaseTextEditor::indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar)
{ {
maybeClearSomeExtraSelections(cursor); maybeClearSomeExtraSelections(cursor);
@@ -5624,7 +5364,8 @@ void BaseTextEditor::setStorageSettings(const StorageSettings &storageSettings)
void BaseTextEditor::setCompletionSettings(const TextEditor::CompletionSettings &completionSettings) 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() void BaseTextEditor::fold()

View File

@@ -168,12 +168,6 @@ public:
void setParenthesesMatchingEnabled(bool b); void setParenthesesMatchingEnabled(bool b);
bool isParenthesesMatchingEnabled() const; bool isParenthesesMatchingEnabled() const;
void setAutoParenthesesEnabled(bool b);
bool isAutoParenthesesEnabled() const;
void setSurroundWithEnabled(bool b);
bool isSurroundWithEnabled() const;
void setHighlightCurrentLine(bool b); void setHighlightCurrentLine(bool b);
bool highlightCurrentLine() const; bool highlightCurrentLine() const;
@@ -424,24 +418,10 @@ protected:
void dragEnterEvent(QDragEnterEvent *e); void dragEnterEvent(QDragEnterEvent *e);
public: 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 indentInsertedText(const QTextCursor &tc);
void indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar); void indent(QTextDocument *doc, const QTextCursor &cursor, QChar typedChar);
void reindent(QTextDocument *doc, const QTextCursor &cursor); 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 struct Link
{ {
Link(const QString &fileName = QString(), Link(const QString &fileName = QString(),

View File

@@ -180,7 +180,6 @@ public:
BaseTextEditor *q; BaseTextEditor *q;
bool m_contentsChanged; bool m_contentsChanged;
bool m_lastCursorChangeWasInteresting; bool m_lastCursorChangeWasInteresting;
bool m_allowSkippingOfBlockEnd;
QList<QTextEdit::ExtraSelection> m_syntaxHighlighterSelections; QList<QTextEdit::ExtraSelection> m_syntaxHighlighterSelections;
QTextEdit::ExtraSelection m_lineSelection; QTextEdit::ExtraSelection m_lineSelection;
@@ -191,8 +190,6 @@ public:
QString m_displayName; QString m_displayName;
bool m_parenthesesMatchingEnabled; bool m_parenthesesMatchingEnabled;
bool m_autoParenthesesEnabled;
bool m_surroundWithEnabled;
QTimer *m_updateTimer; QTimer *m_updateTimer;
Utils::ChangeSet m_changeSet; Utils::ChangeSet m_changeSet;

View File

@@ -39,38 +39,12 @@ Indenter::Indenter()
Indenter::~Indenter() Indenter::~Indenter()
{} {}
bool Indenter::isElectricCharacter(const QChar &ch) const bool Indenter::isElectricCharacter(const QChar &) 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
{ {
return false; return false;
} }
void Indenter::doIndentBlock(QTextDocument *doc, void Indenter::indentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
BaseTextEditor *editor) BaseTextEditor *editor)
@@ -81,7 +55,10 @@ void Indenter::doIndentBlock(QTextDocument *doc,
Q_UNUSED(editor); 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()) { if (cursor.hasSelection()) {
QTextBlock block = doc->findBlock(cursor.selectionStart()); 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()) { if (cursor.hasSelection()) {
QTextBlock block = doc->findBlock(cursor.selectionStart()); QTextBlock block = doc->findBlock(cursor.selectionStart());

View File

@@ -51,32 +51,23 @@ public:
virtual ~Indenter(); virtual ~Indenter();
// Returns true if key triggers an indent. // 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 // Indent a text block based on previous line. Default does nothing
void indentBlock(QTextDocument *doc, virtual void indentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
BaseTextEditor *editor); BaseTextEditor *editor);
// Indent at cursor. Calls indentBlock for selection or current line. // Indent at cursor. Calls indentBlock for selection or current line.
void indent(QTextDocument *doc, virtual void indent(QTextDocument *doc,
const QTextCursor &cursor, const QTextCursor &cursor,
const QChar &typedChar, const QChar &typedChar,
BaseTextEditor *editor); BaseTextEditor *editor);
// Reindent at cursor. Selection will be adjusted according to the indentation // Reindent at cursor. Selection will be adjusted according to the indentation
// change of the first block. // change of the first block.
void reindent(QTextDocument *doc, const QTextCursor &cursor, BaseTextEditor *editor); virtual 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);
}; };
} // namespace TextEditor } // namespace TextEditor

View File

@@ -60,7 +60,7 @@ NormalIndenter::~NormalIndenter()
// for additional block being inserted. It might be possible // for additional block being inserted. It might be possible
// to do in 2 steps (indenting/wrapping)} // to do in 2 steps (indenting/wrapping)}
// //
void NormalIndenter::doIndentBlock(QTextDocument *doc, void NormalIndenter::indentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
BaseTextEditor *editor) BaseTextEditor *editor)

View File

@@ -40,8 +40,7 @@ public:
NormalIndenter(); NormalIndenter();
virtual ~NormalIndenter(); virtual ~NormalIndenter();
private: virtual void indentBlock(QTextDocument *doc,
virtual void doIndentBlock(QTextDocument *doc,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar, const QChar &typedChar,
BaseTextEditor *editor); BaseTextEditor *editor);