aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@theqtcompany.com>2016-04-14 09:00:05 +0200
committerDavid Schulz <david.schulz@theqtcompany.com>2016-05-25 13:55:50 +0000
commit7595aaa227305950c5ce03c7a636a340671400ce (patch)
treebda4fa5a864b5c6914e0ca59fbd37ab82ef5d6f4
parent94fc57c00521e9b56d7b88759831a82cf9bff67e (diff)
Editor: Separate auto insert brace and quote magic.
To allow enabling/disabling both features separately. Change-Id: Ica154e3b400823de7cf22daf006958802d751c64 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
-rw-r--r--src/libs/cplusplus/MatchingText.cpp72
-rw-r--r--src/libs/cplusplus/MatchingText.h6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp44
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeautocompleter.h8
-rw-r--r--src/plugins/cppeditor/cppautocompleter.cpp22
-rw-r--r--src/plugins/cppeditor/cppautocompleter.h26
-rw-r--r--src/plugins/cpptools/completionsettingspage.cpp12
-rw-r--r--src/plugins/cpptools/completionsettingspage.ui280
-rw-r--r--src/plugins/glsleditor/glslautocompleter.cpp24
-rw-r--r--src/plugins/glsleditor/glslautocompleter.h20
-rw-r--r--src/plugins/qmljseditor/qmljsautocompleter.cpp78
-rw-r--r--src/plugins/qmljseditor/qmljsautocompleter.h26
-rw-r--r--src/plugins/texteditor/autocompleter.cpp133
-rw-r--r--src/plugins/texteditor/autocompleter.h34
-rw-r--r--src/plugins/texteditor/completionsettings.cpp10
-rw-r--r--src/plugins/texteditor/completionsettings.h2
-rw-r--r--src/plugins/texteditor/texteditor.cpp19
17 files changed, 483 insertions, 333 deletions
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index 2fdcbab9f69..1d88f8e8bff 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -151,6 +151,11 @@ bool MatchingText::contextAllowsAutoParentheses(const QTextCursor &cursor,
return true;
}
+bool MatchingText::contextAllowsAutoQuotes(const QTextCursor &cursor, const QString &textToInsert)
+{
+ return !textToInsert.isEmpty() && !isInCommentHelper(cursor);
+}
+
bool MatchingText::contextAllowsElectricCharacters(const QTextCursor &cursor)
{
Token token;
@@ -250,36 +255,21 @@ bool MatchingText::isInStringHelper(const QTextCursor &cursor)
}
QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QString &textToProcess,
- QChar la, int *skippedChars)
+ QChar /*lookAhead*/, int *skippedChars)
{
+ if (textToProcess.isEmpty())
+ return QString();
+
QTextCursor tc = cursor;
QString text = textToProcess;
const QString blockText = tc.block().text().mid(tc.positionInBlock());
const QString trimmedBlockText = blockText.trimmed();
- if (!textToProcess.isEmpty()) {
- if (!isQuote(textToProcess.at(0)) || !isEscaped(tc)) {
- *skippedChars = countSkippedChars(blockText, textToProcess);
- if (*skippedChars != 0) {
- tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars);
- text = textToProcess.mid(*skippedChars);
- }
- }
- }
-
- if (text.isEmpty() || !shouldInsertMatchingText(la))
- return QString();
-
- BackwardsScanner tk(tc, LanguageFeatures::defaultFeatures(), MAX_NUM_LINES,
- textToProcess.left(*skippedChars));
- const QChar ch0 = text.at(0);
- if (isQuote(ch0)) {
- if (text.length() != 1)
- qWarning() << Q_FUNC_INFO << "handle event compression";
- if (insertQuote(ch0, tk))
- return ch0;
- return QString();
+ *skippedChars = countSkippedChars(blockText, textToProcess);
+ if (*skippedChars != 0) {
+ tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars);
+ text = textToProcess.mid(*skippedChars);
}
QString result;
@@ -294,6 +284,42 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri
return result;
}
+QString MatchingText::insertMatchingQuote(const QTextCursor &cursor, const QString &textToProcess,
+ QChar lookAhead, int *skippedChars)
+{
+ if (textToProcess.isEmpty())
+ return QString();
+
+ QTextCursor tc = cursor;
+ QString text = textToProcess;
+
+ if (!isEscaped(tc)) {
+ const QString blockText = tc.block().text().mid(tc.positionInBlock());
+ *skippedChars = countSkippedChars(blockText, textToProcess);
+ if (*skippedChars != 0) {
+ tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars);
+ text = textToProcess.mid(*skippedChars);
+ }
+ }
+
+ if (!shouldInsertMatchingText(lookAhead))
+ return QString();
+
+ if (!text.isEmpty()) {
+ const QChar ch = text.at(0);
+ if (!isQuote(ch))
+ return QString();
+ if (text.length() != 1)
+ qWarning() << Q_FUNC_INFO << "handle event compression";
+
+ BackwardsScanner tk(tc, LanguageFeatures::defaultFeatures(), MAX_NUM_LINES,
+ textToProcess.left(*skippedChars));
+ if (insertQuote(ch, tk))
+ return ch;
+ }
+ return QString();
+}
+
static bool shouldInsertNewline(const QTextCursor &tc)
{
QTextDocument *doc = tc.document();
diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h
index b13ede23fc9..c93488c8ec8 100644
--- a/src/libs/cplusplus/MatchingText.h
+++ b/src/libs/cplusplus/MatchingText.h
@@ -38,6 +38,8 @@ class CPLUSPLUS_EXPORT MatchingText
public:
static bool contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert);
+ static bool contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert);
static bool contextAllowsElectricCharacters(const QTextCursor &cursor);
static bool shouldInsertMatchingText(const QTextCursor &tc);
@@ -47,7 +49,9 @@ public:
static bool isInStringHelper(const QTextCursor &cursor);
static QString insertMatchingBrace(const QTextCursor &tc, const QString &text,
- QChar la, int *skippedChars);
+ QChar lookAhead, int *skippedChars);
+ static QString insertMatchingQuote(const QTextCursor &tc, const QString &text,
+ QChar lookAhead, int *skippedChars);
static QString insertParagraphSeparator(const QTextCursor &tc);
};
diff --git a/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp b/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
index bcfee0ce13c..60cbfcddb79 100644
--- a/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
@@ -36,7 +36,7 @@ namespace Internal {
CMakeAutoCompleter::CMakeAutoCompleter()
{
- setAutoParenthesesEnabled(true);
+ setAutoInsertBracketsEnabled(true);
}
bool CMakeAutoCompleter::isInComment(const QTextCursor &cursor) const
@@ -73,25 +73,20 @@ bool CMakeAutoCompleter::isInString(const QTextCursor &cursor) const
return inString;
}
-QString CMakeAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text, QChar la, int *skippedChars) const
+QString CMakeAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const
{
Q_UNUSED(cursor)
- Q_UNUSED(skippedChars);
+ Q_UNUSED(skippedChars)
if (text.isEmpty())
return QString();
const QChar current = text.at(0);
switch (current.unicode()) {
- case '"':
- if (la != current)
- return QStringLiteral("\"");
- ++*skippedChars;
- break;
-
case '(':
return QStringLiteral(")");
case ')':
- if (current == la)
+ if (current == lookAhead)
++*skippedChars;
break;
@@ -102,6 +97,19 @@ QString CMakeAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const
return QString();
}
+QString CMakeAutoCompleter::insertMatchingQuote(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const
+{
+ Q_UNUSED(cursor)
+ static const QChar quote(QLatin1Char('"'));
+ if (text.isEmpty() || text != quote)
+ return QString();
+ if (lookAhead != quote)
+ return quote;
+ ++*skippedChars;
+ return QString();
+}
+
int CMakeAutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor, const TextEditor::TabSettings &tabSettings)
{
const QString line = cursor.block().text().trimmed();
@@ -110,13 +118,25 @@ int CMakeAutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor,
return 0;
}
-bool CMakeAutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert) const
+bool CMakeAutoCompleter::contextAllowsAutoBrackets(const QTextCursor &cursor,
+ const QString &textToInsert) const
+{
+ if (textToInsert.isEmpty())
+ return false;
+
+ const QChar c = textToInsert.at(0);
+ if (c == QLatin1Char('(') || c == QLatin1Char(')'))
+ return !isInComment(cursor);
+ return false;
+}
+
+bool CMakeAutoCompleter::contextAllowsAutoQuotes(const QTextCursor &cursor, const QString &textToInsert) const
{
if (textToInsert.isEmpty())
return false;
const QChar c = textToInsert.at(0);
- if (c == QLatin1Char('"') || c == QLatin1Char('(') || c == QLatin1Char(')'))
+ if (c == QLatin1Char('"'))
return !isInComment(cursor);
return false;
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeautocompleter.h b/src/plugins/cmakeprojectmanager/cmakeautocompleter.h
index 890fe4d3021..dee6655d94b 100644
--- a/src/plugins/cmakeprojectmanager/cmakeautocompleter.h
+++ b/src/plugins/cmakeprojectmanager/cmakeautocompleter.h
@@ -39,9 +39,13 @@ public:
bool isInComment(const QTextCursor &cursor) const override;
bool isInString(const QTextCursor &cursor) const override;
- QString insertMatchingBrace(const QTextCursor &cursor, const QString &text, QChar la, int *skippedChars) const override;
+ QString insertMatchingBrace(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const override;
+ QString insertMatchingQuote(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const override;
int paragraphSeparatorAboutToBeInserted(QTextCursor &cursor, const TextEditor::TabSettings &tabSettings) override;
- bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert) const override;
+ bool contextAllowsAutoBrackets(const QTextCursor &cursor, const QString &textToInsert) const override;
+ bool contextAllowsAutoQuotes(const QTextCursor &cursor, const QString &textToInsert) const override;
bool contextAllowsElectricCharacters(const QTextCursor &cursor) const override;
};
diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp
index e838660836d..2114a86e679 100644
--- a/src/plugins/cppeditor/cppautocompleter.cpp
+++ b/src/plugins/cppeditor/cppautocompleter.cpp
@@ -32,12 +32,18 @@
using namespace CppEditor;
using namespace Internal;
-bool CppAutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
+bool CppAutoCompleter::contextAllowsAutoBrackets(const QTextCursor &cursor,
const QString &textToInsert) const
{
return CPlusPlus::MatchingText::contextAllowsAutoParentheses(cursor, textToInsert);
}
+bool CppAutoCompleter::contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert) const
+{
+ return CPlusPlus::MatchingText::contextAllowsAutoQuotes(cursor, textToInsert);
+}
+
bool CppAutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{
return CPlusPlus::MatchingText::contextAllowsElectricCharacters(cursor);
@@ -53,12 +59,16 @@ bool CppAutoCompleter::isInString(const QTextCursor &cursor) const
return CPlusPlus::MatchingText::isInStringHelper(cursor);
}
-QString CppAutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
- const QString &text,
- QChar la,
- int *skippedChars) const
+QString CppAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const
+{
+ return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, lookAhead, skippedChars);
+}
+
+QString CppAutoCompleter::insertMatchingQuote(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const
{
- return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, la, skippedChars);
+ return CPlusPlus::MatchingText::insertMatchingQuote(cursor, text, lookAhead, skippedChars);
}
QString CppAutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
diff --git a/src/plugins/cppeditor/cppautocompleter.h b/src/plugins/cppeditor/cppautocompleter.h
index d58acda6087..3508c38a2b0 100644
--- a/src/plugins/cppeditor/cppautocompleter.h
+++ b/src/plugins/cppeditor/cppautocompleter.h
@@ -35,16 +35,22 @@ class CppAutoCompleter : public TextEditor::AutoCompleter
public:
CppAutoCompleter() {}
- 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 bool isInString(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;
+ bool contextAllowsAutoBrackets(const QTextCursor &cursor,
+ const QString &textToInsert = QString()) const override;
+ bool contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert = QString()) const override;
+ bool contextAllowsElectricCharacters(const QTextCursor &cursor) const override;
+ bool isInComment(const QTextCursor &cursor) const override;
+ bool isInString(const QTextCursor &cursor) const override;
+ QString insertMatchingBrace(const QTextCursor &cursor,
+ const QString &text,
+ QChar lookAhead,
+ int *skippedChars) const override;
+ QString insertMatchingQuote(const QTextCursor &cursor,
+ const QString &text,
+ QChar lookAhead,
+ int *skippedChars) const override;
+ QString insertParagraphSeparator(const QTextCursor &cursor) const override;
};
} // Internal
diff --git a/src/plugins/cpptools/completionsettingspage.cpp b/src/plugins/cpptools/completionsettingspage.cpp
index c0748cafd25..07a6f950c99 100644
--- a/src/plugins/cpptools/completionsettingspage.cpp
+++ b/src/plugins/cpptools/completionsettingspage.cpp
@@ -93,8 +93,10 @@ QWidget *CompletionSettingsPage::widget()
m_page->completionTrigger->setCurrentIndex(completionTriggerIndex);
m_page->automaticProposalTimeoutSpinBox
->setValue(completionSettings.m_automaticProposalTimeoutInMs);
- m_page->autoInsertBrackets->setChecked(completionSettings.m_autoInsertBrackets);
- m_page->surroundSelectedText->setChecked(completionSettings.m_surroundingAutoBrackets);
+ m_page->insertBrackets->setChecked(completionSettings.m_autoInsertBrackets);
+ m_page->surroundBrackets->setChecked(completionSettings.m_surroundingAutoBrackets);
+ m_page->insertQuotes->setChecked(completionSettings.m_autoInsertQuotes);
+ m_page->surroundQuotes->setChecked(completionSettings.m_surroundingAutoQuotes);
m_page->partiallyComplete->setChecked(completionSettings.m_partiallyComplete);
m_page->spaceAfterFunctionName->setChecked(completionSettings.m_spaceAfterFunctionName);
m_page->autoSplitStrings->setChecked(completionSettings.m_autoSplitStrings);
@@ -119,8 +121,10 @@ void CompletionSettingsPage::apply()
completionSettings.m_completionTrigger = completionTrigger();
completionSettings.m_automaticProposalTimeoutInMs
= m_page->automaticProposalTimeoutSpinBox->value();
- completionSettings.m_autoInsertBrackets = m_page->autoInsertBrackets->isChecked();
- completionSettings.m_surroundingAutoBrackets = m_page->surroundSelectedText->isChecked();
+ completionSettings.m_autoInsertBrackets = m_page->insertBrackets->isChecked();
+ completionSettings.m_surroundingAutoBrackets = m_page->surroundBrackets->isChecked();
+ completionSettings.m_autoInsertQuotes = m_page->insertQuotes->isChecked();
+ completionSettings.m_surroundingAutoQuotes = m_page->surroundQuotes->isChecked();
completionSettings.m_partiallyComplete = m_page->partiallyComplete->isChecked();
completionSettings.m_spaceAfterFunctionName = m_page->spaceAfterFunctionName->isChecked();
completionSettings.m_autoSplitStrings = m_page->autoSplitStrings->isChecked();
diff --git a/src/plugins/cpptools/completionsettingspage.ui b/src/plugins/cpptools/completionsettingspage.ui
index a03db2255c7..f8786d4ca79 100644
--- a/src/plugins/cpptools/completionsettingspage.ui
+++ b/src/plugins/cpptools/completionsettingspage.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>484</width>
- <height>376</height>
+ <width>511</width>
+ <height>420</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -17,35 +17,25 @@
<string>Behavior</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="5" column="0">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>30</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QCheckBox" name="spaceAfterFunctionName">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>Insert &amp;space after function name</string>
- </property>
- </widget>
- </item>
- </layout>
+ <item row="1" column="0">
+ <widget class="QLabel" name="completionTriggerLabel">
+ <property name="text">
+ <string>Activate completion:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" colspan="4">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>70</width>
+ <height>24</height>
+ </size>
+ </property>
+ </spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="caseSensitivityLabel">
@@ -82,77 +72,6 @@
</item>
</widget>
</item>
- <item row="4" column="0">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>30</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QCheckBox" name="surroundSelectedText">
- <property name="toolTip">
- <string>When typing a matching character and there is a text selection, instead of removing the selection, surrounds it with the corresponding characters.</string>
- </property>
- <property name="text">
- <string>Surround &amp;text selections</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="6" column="0">
- <widget class="QCheckBox" name="autoSplitStrings">
- <property name="toolTip">
- <string>Splits a string into two lines by adding an end quote at the cursor position when you press Enter and a start quote to the next line, before the rest of the string.
-
-In addition, Shift+Enter inserts an escape character at the cursor position and moves the rest of the string to the next line.</string>
- </property>
- <property name="text">
- <string>Automatically split strings</string>
- </property>
- </widget>
- </item>
- <item row="1" column="5">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>24</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="2" colspan="4">
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>70</width>
- <height>24</height>
- </size>
- </property>
- </spacer>
- </item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="completionTrigger">
<item>
@@ -179,6 +98,32 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
</property>
</widget>
</item>
+ <item row="1" column="4">
+ <widget class="QSpinBox" name="automaticProposalTimeoutSpinBox">
+ <property name="maximum">
+ <number>500</number>
+ </property>
+ <property name="singleStep">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>400</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>24</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item row="2" column="0">
<widget class="QCheckBox" name="partiallyComplete">
<property name="toolTip">
@@ -192,36 +137,80 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="completionTriggerLabel">
+ <item row="3" column="0">
+ <widget class="QCheckBox" name="autoSplitStrings">
+ <property name="toolTip">
+ <string>Splits a string into two lines by adding an end quote at the cursor position when you press Enter and a start quote to the next line, before the rest of the string.
+
+In addition, Shift+Enter inserts an escape character at the cursor position and moves the rest of the string to the next line.</string>
+ </property>
<property name="text">
- <string>Activate completion:</string>
+ <string>Automatically split strings</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="autoInsertGroupBox">
+ <property name="title">
+ <string>&amp;Automatically insert matching characters</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="insertBrackets">
+ <property name="text">
+ <string>Insert opening or closing brackets</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
</property>
</widget>
</item>
- <item row="3" column="0" colspan="2">
- <widget class="QCheckBox" name="autoInsertBrackets">
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="insertQuotes">
+ <property name="text">
+ <string>Insert closing quote</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="surroundBrackets">
<property name="toolTip">
- <string>Automatically inserts semicolons and closing brackets, parentheses, curly braces, and quotes when appropriate.</string>
+ <string>When typing a matching bracket and there is a text selection, instead of removing the selection, surrounds it with the corresponding characters.</string>
</property>
<property name="text">
- <string>&amp;Automatically insert matching characters</string>
+ <string>Surround text selection with brackets</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
- <item row="1" column="4">
- <widget class="QSpinBox" name="automaticProposalTimeoutSpinBox">
- <property name="maximum">
- <number>500</number>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="spaceAfterFunctionName">
+ <property name="enabled">
+ <bool>true</bool>
</property>
- <property name="singleStep">
- <number>50</number>
+ <property name="text">
+ <string>Insert &amp;space after function name</string>
</property>
- <property name="value">
- <number>400</number>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="surroundQuotes">
+ <property name="toolTip">
+ <string>When typing a matching quote and there is a text selection, instead of removing the selection, surrounds it with the corresponding characters.</string>
+ </property>
+ <property name="text">
+ <string>Surround text selection with quotes</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
</property>
</widget>
</item>
@@ -288,7 +277,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
</widget>
</item>
<item>
- <spacer name="verticalSpacer">
+ <spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@@ -302,53 +291,36 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
</item>
</layout>
</widget>
+ <tabstops>
+ <tabstop>caseSensitivity</tabstop>
+ <tabstop>completionTrigger</tabstop>
+ <tabstop>automaticProposalTimeoutSpinBox</tabstop>
+ <tabstop>partiallyComplete</tabstop>
+ <tabstop>autoSplitStrings</tabstop>
+ <tabstop>insertBrackets</tabstop>
+ <tabstop>insertQuotes</tabstop>
+ <tabstop>surroundBrackets</tabstop>
+ <tabstop>surroundQuotes</tabstop>
+ <tabstop>spaceAfterFunctionName</tabstop>
+ <tabstop>enableDoxygenCheckBox</tabstop>
+ <tabstop>generateBriefCheckBox</tabstop>
+ <tabstop>leadingAsterisksCheckBox</tabstop>
+ </tabstops>
<resources/>
<connections>
<connection>
- <sender>autoInsertBrackets</sender>
- <signal>toggled(bool)</signal>
- <receiver>spaceAfterFunctionName</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>267</x>
- <y>131</y>
- </hint>
- <hint type="destinationlabel">
- <x>333</x>
- <y>206</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>autoInsertBrackets</sender>
- <signal>toggled(bool)</signal>
- <receiver>surroundSelectedText</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>109</x>
- <y>123</y>
- </hint>
- <hint type="destinationlabel">
- <x>119</x>
- <y>156</y>
- </hint>
- </hints>
- </connection>
- <connection>
<sender>enableDoxygenCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>generateBriefCheckBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
- <x>153</x>
- <y>272</y>
+ <x>174</x>
+ <y>294</y>
</hint>
<hint type="destinationlabel">
- <x>204</x>
- <y>293</y>
+ <x>262</x>
+ <y>321</y>
</hint>
</hints>
</connection>
diff --git a/src/plugins/glsleditor/glslautocompleter.cpp b/src/plugins/glsleditor/glslautocompleter.cpp
index b2e7d6313b7..e0ff3df2e84 100644
--- a/src/plugins/glsleditor/glslautocompleter.cpp
+++ b/src/plugins/glsleditor/glslautocompleter.cpp
@@ -32,12 +32,18 @@
namespace GlslEditor {
namespace Internal {
-bool GlslCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
- const QString &textToInsert) const
+bool GlslCompleter::contextAllowsAutoBrackets(const QTextCursor &cursor,
+ const QString &textToInsert) const
{
return CPlusPlus::MatchingText::contextAllowsAutoParentheses(cursor, textToInsert);
}
+bool GlslCompleter::contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert) const
+{
+ return CPlusPlus::MatchingText::contextAllowsAutoQuotes(cursor, textToInsert);
+}
+
bool GlslCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{
return CPlusPlus::MatchingText::contextAllowsElectricCharacters(cursor);
@@ -48,12 +54,16 @@ bool GlslCompleter::isInComment(const QTextCursor &cursor) const
return CPlusPlus::MatchingText::isInCommentHelper(cursor);
}
-QString GlslCompleter::insertMatchingBrace(const QTextCursor &cursor,
- const QString &text,
- QChar la,
- int *skippedChars) const
+QString GlslCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const
+{
+ return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, lookAhead, skippedChars);
+}
+
+QString GlslCompleter::insertMatchingQuote(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const
{
- return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, la, skippedChars);
+ return CPlusPlus::MatchingText::insertMatchingQuote(cursor, text, lookAhead, skippedChars);
}
QString GlslCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
diff --git a/src/plugins/glsleditor/glslautocompleter.h b/src/plugins/glsleditor/glslautocompleter.h
index 1e1d1a0f842..59cfd3daed5 100644
--- a/src/plugins/glsleditor/glslautocompleter.h
+++ b/src/plugins/glsleditor/glslautocompleter.h
@@ -33,15 +33,17 @@ namespace Internal {
class GlslCompleter : public TextEditor::AutoCompleter
{
public:
- 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;
+ bool contextAllowsAutoBrackets(const QTextCursor &cursor,
+ const QString &textToInsert = QString()) const override;
+ bool contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert = QString()) const override;
+ bool contextAllowsElectricCharacters(const QTextCursor &cursor) const override;
+ bool isInComment(const QTextCursor &cursor) const override;
+ QString insertMatchingBrace(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const override;
+ QString insertMatchingQuote(const QTextCursor &cursor, const QString &text,
+ QChar lookAhead, int *skippedChars) const override;
+ QString insertParagraphSeparator(const QTextCursor &cursor) const override;
};
} // namespace Internal
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp
index 532760d15ef..b379ed62ddf 100644
--- a/src/plugins/qmljseditor/qmljsautocompleter.cpp
+++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp
@@ -139,8 +139,8 @@ AutoCompleter::AutoCompleter()
AutoCompleter::~AutoCompleter()
{}
-bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
- const QString &textToInsert) const
+bool AutoCompleter::contextAllowsAutoBrackets(const QTextCursor &cursor,
+ const QString &textToInsert) const
{
QChar ch;
@@ -148,9 +148,6 @@ bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
ch = textToInsert.at(0);
switch (ch.unicode()) {
- case '\'':
- case '"':
-
case '(':
case '[':
case '{':
@@ -207,6 +204,50 @@ bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
return true;
}
+bool AutoCompleter::contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert) const
+{
+ if (!isQuote(textToInsert))
+ return false;
+
+ const Token token = tokenUnderCursor(cursor);
+ switch (token.kind) {
+ case Token::Comment:
+ return false;
+
+ case Token::RightBrace:
+ return false;
+
+ case Token::String: {
+ const QString blockText = cursor.block().text();
+ const QStringRef tokenText = blockText.midRef(token.offset, token.length);
+ QChar quote = tokenText.at(0);
+ // if a string literal doesn't start with a quote, it must be multiline
+ if (quote != QLatin1Char('"') && quote != QLatin1Char('\'')) {
+ const int startState = blockStartState(cursor.block());
+ if ((startState & Scanner::MultiLineMask) == Scanner::MultiLineStringDQuote)
+ quote = QLatin1Char('"');
+ else if ((startState & Scanner::MultiLineMask) == Scanner::MultiLineStringSQuote)
+ quote = QLatin1Char('\'');
+ }
+
+ // never insert ' into string literals, it adds spurious ' when writing contractions
+ if (textToInsert.at(0) == QLatin1Char('\''))
+ return false;
+
+ if (textToInsert.at(0) != quote || isCompleteStringLiteral(tokenText))
+ break;
+
+ return false;
+ }
+
+ default:
+ break;
+ } // end of switch
+
+ return true;
+}
+
bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{
Token token = tokenUnderCursor(cursor);
@@ -226,7 +267,7 @@ bool AutoCompleter::isInComment(const QTextCursor &cursor) const
QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text,
- QChar la,
+ QChar lookAhead,
int *skippedChars) const
{
if (text.length() != 1)
@@ -237,18 +278,6 @@ QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QChar ch = text.at(0);
switch (ch.unicode()) {
- case '\'':
- if (la != ch)
- return QString(ch);
- ++*skippedChars;
- break;
-
- case '"':
- if (la != ch)
- return QString(ch);
- ++*skippedChars;
- break;
-
case '(':
return QString(QLatin1Char(')'));
@@ -262,7 +291,7 @@ QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
case ']':
case '}':
case ';':
- if (la == ch)
+ if (lookAhead == ch)
++*skippedChars;
break;
@@ -273,6 +302,17 @@ QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
return QString();
}
+QString AutoCompleter::insertMatchingQuote(const QTextCursor &/*tc*/, const QString &text,
+ QChar lookAhead, int *skippedChars) const
+{
+ if (isQuote(text)) {
+ if (lookAhead != text)
+ return text;
+ ++*skippedChars;
+ }
+ return QString();
+}
+
QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
{
if (shouldInsertNewline(cursor)) {
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.h b/src/plugins/qmljseditor/qmljsautocompleter.h
index 701134dbd6d..dda7173d390 100644
--- a/src/plugins/qmljseditor/qmljsautocompleter.h
+++ b/src/plugins/qmljseditor/qmljsautocompleter.h
@@ -34,17 +34,23 @@ class AutoCompleter : public TextEditor::AutoCompleter
{
public:
AutoCompleter();
- virtual ~AutoCompleter();
+ ~AutoCompleter() override;
- virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
- const QString &textToInsert = QString()) const;
- virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
- virtual bool isInComment(const QTextCursor &cursor) const;
- virtual QString insertMatchingBrace(const QTextCursor &tc,
- const QString &text,
- QChar la,
- int *skippedChars) const;
- virtual QString insertParagraphSeparator(const QTextCursor &tc) const;
+ bool contextAllowsAutoBrackets(const QTextCursor &cursor,
+ const QString &textToInsert = QString()) const override;
+ bool contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert = QString()) const override;
+ bool contextAllowsElectricCharacters(const QTextCursor &cursor) const override;
+ bool isInComment(const QTextCursor &cursor) const override;
+ QString insertMatchingBrace(const QTextCursor &tc,
+ const QString &text,
+ QChar lookAhead,
+ int *skippedChars) const override;
+ QString insertMatchingQuote(const QTextCursor &tc,
+ const QString &text,
+ QChar lookAhead,
+ int *skippedChars) const override;
+ QString insertParagraphSeparator(const QTextCursor &tc) const override;
};
} // Internal
diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp
index bf49bb562b7..d457382a4cc 100644
--- a/src/plugins/texteditor/autocompleter.cpp
+++ b/src/plugins/texteditor/autocompleter.cpp
@@ -34,33 +34,15 @@ using namespace TextEditor;
AutoCompleter::AutoCompleter() :
m_allowSkippingOfBlockEnd(false),
- m_surroundWithEnabled(true),
- m_autoParenthesesEnabled(true)
+ m_autoInsertBrackets(true),
+ m_surroundWithBrackets(true),
+ m_autoInsertQuotes(true),
+ m_surroundWithQuotes(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;
-}
-
static void countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen)
{
if (c == open)
@@ -75,7 +57,7 @@ static void countBracket(QChar open, QChar close, QChar c, int *errors, int *sti
}
static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close,
- int *errors, int *stillopen)
+ int *errors, int *stillopen)
{
cursor.setPosition(from);
QTextBlock block = cursor.block();
@@ -124,11 +106,13 @@ static bool fixesBracketsError(const QString &textToInsert, const QTextCursor &c
return errorsAfterInsertion < errorsBeforeInsertion;
}
-static QString replaceSelection(const QString &textToInsert, const QString &selection)
+static QString surroundSelectionWithBrackets(const QString &textToInsert, const QString &selection)
{
QString replacement;
if (textToInsert == QLatin1String("(")) {
replacement = selection + QLatin1Char(')');
+ } else if (textToInsert == QLatin1String("[")) {
+ replacement = selection + QLatin1Char(']');
} else if (textToInsert == QLatin1String("{")) {
//If the text spans multiple lines, insert on different lines
replacement = selection;
@@ -144,50 +128,62 @@ static QString replaceSelection(const QString &textToInsert, const QString &sele
} else {
replacement += QLatin1Char('}');
}
- } else if (textToInsert == QLatin1String("[")) {
- replacement = selection + QLatin1Char(']');
- } else if (textToInsert == QLatin1String("\"")) {
- replacement = selection + QLatin1Char('"');
- } else if (textToInsert == QLatin1String("'")) {
- replacement = selection + QLatin1Char('\'');
}
return replacement;
}
+bool AutoCompleter::isQuote(const QString &text)
+{
+ return text == QLatin1String("\"") || text == QLatin1String("'");
+}
+
+QString AutoCompleter::replaceSelection(QTextCursor &cursor, const QString &textToInsert) const
+{
+ if (!cursor.hasSelection())
+ return QString();
+ if (isQuote(textToInsert) && m_surroundWithQuotes)
+ return cursor.selectedText() + textToInsert;
+ if (m_surroundWithBrackets)
+ return surroundSelectionWithBrackets(textToInsert, cursor.selectedText());
+ return QString();
+}
+
QString AutoCompleter::autoComplete(QTextCursor &cursor, const QString &textToInsert) const
{
const bool checkBlockEnd = m_allowSkippingOfBlockEnd;
m_allowSkippingOfBlockEnd = false; // consume blockEnd.
- if (m_surroundWithEnabled && cursor.hasSelection()) {
- const QString replacement = replaceSelection(textToInsert, cursor.selectedText());
- if (!replacement.isEmpty())
- return replacement;
- }
-
- if (!m_autoParenthesesEnabled)
- return QString();
- if (!contextAllowsAutoParentheses(cursor, textToInsert))
- return QString();
- if (fixesBracketsError(textToInsert, cursor))
- return QString();
+ QString autoText = replaceSelection(cursor, textToInsert);
+ if (!autoText.isEmpty())
+ return autoText;
QTextDocument *doc = cursor.document();
const QChar lookAhead = doc->characterAt(cursor.selectionEnd());
int skippedChars = 0;
- const QString autoText = insertMatchingBrace(cursor, textToInsert, lookAhead, &skippedChars);
- if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) {
- if (textToInsert.length() > 1)
- qWarning() << "*** handle event compression";
+ if (isQuote(textToInsert) && m_autoInsertQuotes
+ && contextAllowsAutoQuotes(cursor, textToInsert)) {
+ autoText = insertMatchingQuote(cursor, textToInsert, lookAhead, &skippedChars);
+ } else if (m_autoInsertBrackets && contextAllowsAutoBrackets(cursor, textToInsert)) {
+ if (fixesBracketsError(textToInsert, cursor))
+ return QString();
+
+ autoText = insertMatchingBrace(cursor, textToInsert, lookAhead, &skippedChars);
- int startPos = cursor.selectionEnd(), pos = startPos;
- while (doc->characterAt(pos).isSpace())
- ++pos;
+ if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) {
+ if (textToInsert.length() > 1)
+ qWarning() << "*** handle event compression";
- if (doc->characterAt(pos) == QLatin1Char('}'))
- skippedChars += (pos - startPos) + 1;
+ int startPos = cursor.selectionEnd(), pos = startPos;
+ while (doc->characterAt(pos).isSpace())
+ ++pos;
+
+ if (doc->characterAt(pos) == QLatin1Char('}'))
+ skippedChars += (pos - startPos) + 1;
+ }
+ } else {
+ return QString();
}
if (skippedChars) {
@@ -203,7 +199,7 @@ bool AutoCompleter::autoBackspace(QTextCursor &cursor)
{
m_allowSkippingOfBlockEnd = false;
- if (!m_autoParenthesesEnabled)
+ if (!m_autoInsertBrackets)
return false;
int pos = cursor.position();
@@ -258,14 +254,14 @@ bool AutoCompleter::autoBackspace(QTextCursor &cursor)
int AutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor,
const TabSettings &tabSettings)
{
- if (!m_autoParenthesesEnabled)
+ if (!m_autoInsertBrackets)
return 0;
QTextDocument *doc = cursor.document();
if (doc->characterAt(cursor.position() - 1) != QLatin1Char('{'))
return 0;
- if (!contextAllowsAutoParentheses(cursor))
+ if (!contextAllowsAutoBrackets(cursor))
return 0;
// verify that we indeed do have an extra opening brace in the document
@@ -310,8 +306,15 @@ int AutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor,
return 1;
}
-bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
- const QString &textToInsert) const
+bool AutoCompleter::contextAllowsAutoBrackets(const QTextCursor &cursor,
+ const QString &textToInsert) const
+{
+ Q_UNUSED(cursor);
+ Q_UNUSED(textToInsert);
+ return false;
+}
+
+bool AutoCompleter::contextAllowsAutoQuotes(const QTextCursor &cursor, const QString &textToInsert) const
{
Q_UNUSED(cursor);
Q_UNUSED(textToInsert);
@@ -320,7 +323,7 @@ bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const
{
- return contextAllowsAutoParentheses(cursor);
+ return contextAllowsAutoBrackets(cursor);
}
bool AutoCompleter::isInComment(const QTextCursor &cursor) const
@@ -337,12 +340,24 @@ bool AutoCompleter::isInString(const QTextCursor &cursor) const
QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text,
- QChar la,
+ QChar lookAhead,
+ int *skippedChars) const
+{
+ Q_UNUSED(cursor);
+ Q_UNUSED(text);
+ Q_UNUSED(lookAhead);
+ Q_UNUSED(skippedChars);
+ return QString();
+}
+
+QString AutoCompleter::insertMatchingQuote(const QTextCursor &cursor,
+ const QString &text,
+ QChar lookAhead,
int *skippedChars) const
{
Q_UNUSED(cursor);
Q_UNUSED(text);
- Q_UNUSED(la);
+ Q_UNUSED(lookAhead);
Q_UNUSED(skippedChars);
return QString();
}
diff --git a/src/plugins/texteditor/autocompleter.h b/src/plugins/texteditor/autocompleter.h
index 6835030bc55..1470fa1065d 100644
--- a/src/plugins/texteditor/autocompleter.h
+++ b/src/plugins/texteditor/autocompleter.h
@@ -43,11 +43,15 @@ public:
AutoCompleter();
virtual ~AutoCompleter();
- void setAutoParenthesesEnabled(bool b);
- bool isAutoParenthesesEnabled() const;
+ void setAutoInsertBracketsEnabled(bool b) { m_autoInsertBrackets = b; }
+ bool isAutoInsertBracketsEnabled() const { return m_autoInsertBrackets; }
+ void setSurroundWithBracketsEnabled(bool b) { m_surroundWithBrackets = b; }
+ bool isSurroundWithBracketsEnabled() const { return m_surroundWithBrackets; }
- void setSurroundWithEnabled(bool b);
- bool isSurroundWithEnabled() const;
+ void setAutoInsertQuotesEnabled(bool b) { m_autoInsertQuotes = b; }
+ bool isAutoInsertQuotesEnabled() const { return m_autoInsertQuotes; }
+ void setSurroundWithQuotesEnabled(bool b) { m_surroundWithQuotes = b; }
+ bool isSurroundWithQuotesEnabled() const { return m_surroundWithQuotes; }
// Returns the text to complete at the cursor position, or an empty string
virtual QString autoComplete(QTextCursor &cursor, const QString &text) const;
@@ -59,8 +63,10 @@ public:
virtual int paragraphSeparatorAboutToBeInserted(QTextCursor &cursor,
const TabSettings &tabSettings);
- virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
+ virtual bool contextAllowsAutoBrackets(const QTextCursor &cursor,
const QString &textToInsert = QString()) const;
+ virtual bool contextAllowsAutoQuotes(const QTextCursor &cursor,
+ const QString &textToInsert = QString()) const;
virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
// Returns true if the cursor is inside a comment.
@@ -71,16 +77,28 @@ public:
virtual QString insertMatchingBrace(const QTextCursor &cursor, const
QString &text,
- QChar la,
+ QChar lookAhead,
+ int *skippedChars) const;
+
+ virtual QString insertMatchingQuote(const QTextCursor &cursor, const
+ QString &text,
+ QChar lookAhead,
int *skippedChars) const;
// Returns the text that needs to be inserted
virtual QString insertParagraphSeparator(const QTextCursor &cursor) const;
+ static bool isQuote(const QString &text);
+
+private:
+ QString replaceSelection(QTextCursor &cursor, const QString &textToInsert) const;
+
private:
mutable bool m_allowSkippingOfBlockEnd;
- bool m_surroundWithEnabled;
- bool m_autoParenthesesEnabled;
+ bool m_autoInsertBrackets;
+ bool m_surroundWithBrackets;
+ bool m_autoInsertQuotes;
+ bool m_surroundWithQuotes;
};
} // TextEditor
diff --git a/src/plugins/texteditor/completionsettings.cpp b/src/plugins/texteditor/completionsettings.cpp
index 64d985435f1..83290cc5e14 100644
--- a/src/plugins/texteditor/completionsettings.cpp
+++ b/src/plugins/texteditor/completionsettings.cpp
@@ -33,6 +33,8 @@ static const char completionTriggerKey[] = "CompletionTrigger";
static const char automaticProposalTimeoutKey[] = "AutomaticProposalTimeout";
static const char autoInsertBracesKey[] = "AutoInsertBraces";
static const char surroundingAutoBracketsKey[] = "SurroundingAutoBrackets";
+static const char autoInsertQuotesKey[] = "AutoInsertQuotes";
+static const char surroundingAutoQuotesKey[] = "SurroundingAutoQuotes";
static const char partiallyCompleteKey[] = "PartiallyComplete";
static const char spaceAfterFunctionNameKey[] = "SpaceAfterFunctionName";
static const char autoSplitStringsKey[] = "AutoSplitStrings";
@@ -45,6 +47,8 @@ CompletionSettings::CompletionSettings()
, m_automaticProposalTimeoutInMs(400)
, m_autoInsertBrackets(true)
, m_surroundingAutoBrackets(true)
+ , m_autoInsertQuotes(true)
+ , m_surroundingAutoQuotes(true)
, m_partiallyComplete(true)
, m_spaceAfterFunctionName(false)
, m_autoSplitStrings(true)
@@ -63,6 +67,8 @@ void CompletionSettings::toSettings(const QString &category, QSettings *s) const
s->setValue(QLatin1String(automaticProposalTimeoutKey), m_automaticProposalTimeoutInMs);
s->setValue(QLatin1String(autoInsertBracesKey), m_autoInsertBrackets);
s->setValue(QLatin1String(surroundingAutoBracketsKey), m_surroundingAutoBrackets);
+ s->setValue(QLatin1String(autoInsertQuotesKey), m_autoInsertQuotes);
+ s->setValue(QLatin1String(surroundingAutoQuotesKey), m_surroundingAutoQuotes);
s->setValue(QLatin1String(partiallyCompleteKey), m_partiallyComplete);
s->setValue(QLatin1String(spaceAfterFunctionNameKey), m_spaceAfterFunctionName);
s->setValue(QLatin1String(autoSplitStringsKey), m_autoSplitStrings);
@@ -83,6 +89,8 @@ void CompletionSettings::fromSettings(const QString &category, const QSettings *
m_automaticProposalTimeoutInMs = s->value(group + QLatin1String(automaticProposalTimeoutKey), m_automaticProposalTimeoutInMs).toInt();
m_autoInsertBrackets = s->value(group + QLatin1String(autoInsertBracesKey), m_autoInsertBrackets).toBool();
m_surroundingAutoBrackets = s->value(group + QLatin1String(surroundingAutoBracketsKey), m_surroundingAutoBrackets).toBool();
+ m_autoInsertQuotes = s->value(group + QLatin1String(autoInsertQuotesKey), m_autoInsertQuotes).toBool();
+ m_surroundingAutoQuotes = s->value(group + QLatin1String(surroundingAutoQuotesKey), m_surroundingAutoQuotes).toBool();
m_partiallyComplete = s->value(group + QLatin1String(partiallyCompleteKey), m_partiallyComplete).toBool();
m_spaceAfterFunctionName = s->value(group + QLatin1String(spaceAfterFunctionNameKey), m_spaceAfterFunctionName).toBool();
m_autoSplitStrings = s->value(group + QLatin1String(autoSplitStringsKey), m_autoSplitStrings).toBool();
@@ -95,6 +103,8 @@ bool CompletionSettings::equals(const CompletionSettings &cs) const
&& m_automaticProposalTimeoutInMs == cs.m_automaticProposalTimeoutInMs
&& m_autoInsertBrackets == cs.m_autoInsertBrackets
&& m_surroundingAutoBrackets == cs.m_surroundingAutoBrackets
+ && m_autoInsertQuotes == cs.m_autoInsertQuotes
+ && m_surroundingAutoQuotes == cs.m_surroundingAutoQuotes
&& m_partiallyComplete == cs.m_partiallyComplete
&& m_spaceAfterFunctionName == cs.m_spaceAfterFunctionName
&& m_autoSplitStrings == cs.m_autoSplitStrings
diff --git a/src/plugins/texteditor/completionsettings.h b/src/plugins/texteditor/completionsettings.h
index 0b948baf56f..3f37d638c85 100644
--- a/src/plugins/texteditor/completionsettings.h
+++ b/src/plugins/texteditor/completionsettings.h
@@ -63,6 +63,8 @@ public:
int m_automaticProposalTimeoutInMs;
bool m_autoInsertBrackets;
bool m_surroundingAutoBrackets;
+ bool m_autoInsertQuotes;
+ bool m_surroundingAutoQuotes;
bool m_partiallyComplete;
bool m_spaceAfterFunctionName;
bool m_autoSplitStrings;
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index dc0b3eaa28b..c360891b8b7 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -2331,15 +2331,15 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
if (e->modifiers() == Qt::NoModifier) {
AutoCompleter *ac = d->m_autoCompleter.data();
if (inOverwriteMode) {
- ac->setAutoParenthesesEnabled(d->autoParenthesisOverwriteBackup);
- ac->setSurroundWithEnabled(d->surroundWithEnabledOverwriteBackup);
+ ac->setAutoInsertBracketsEnabled(d->autoParenthesisOverwriteBackup);
+ ac->setSurroundWithBracketsEnabled(d->surroundWithEnabledOverwriteBackup);
setOverwriteMode(false);
viewport()->update();
} else {
- d->autoParenthesisOverwriteBackup = ac->isAutoParenthesesEnabled();
- d->surroundWithEnabledOverwriteBackup = ac->isSurroundWithEnabled();
- ac->setAutoParenthesesEnabled(false);
- ac->setSurroundWithEnabled(false);
+ d->autoParenthesisOverwriteBackup = ac->isAutoInsertBracketsEnabled();
+ d->surroundWithEnabledOverwriteBackup = ac->isSurroundWithBracketsEnabled();
+ ac->setAutoInsertBracketsEnabled(false);
+ ac->setSurroundWithBracketsEnabled(false);
setOverwriteMode(true);
}
e->accept();
@@ -6545,9 +6545,10 @@ void TextEditorWidget::setStorageSettings(const StorageSettings &storageSettings
void TextEditorWidget::setCompletionSettings(const CompletionSettings &completionSettings)
{
- d->m_autoCompleter->setAutoParenthesesEnabled(completionSettings.m_autoInsertBrackets);
- d->m_autoCompleter->setSurroundWithEnabled(completionSettings.m_autoInsertBrackets
- && completionSettings.m_surroundingAutoBrackets);
+ d->m_autoCompleter->setAutoInsertBracketsEnabled(completionSettings.m_autoInsertBrackets);
+ d->m_autoCompleter->setSurroundWithBracketsEnabled(completionSettings.m_surroundingAutoBrackets);
+ d->m_autoCompleter->setAutoInsertQuotesEnabled(completionSettings.m_autoInsertQuotes);
+ d->m_autoCompleter->setSurroundWithQuotesEnabled(completionSettings.m_surroundingAutoQuotes);
d->m_codeAssistant.updateFromCompletionSettings(completionSettings);
}