forked from qt-creator/qt-creator
Snippets: Allow lowercase/titlecase/uppercase modifiers for variables
Use the same syntax already used in the custom wizard to denote variables that are modified to be lower-/title-/uppercase: $tESt:u$ will become TEST $tESt:c$ will become TESt $tESt:l$ will become test The snippet will be inserted without any name mangling happening. Once the editing is done the name mangling is applied to all fields. Change-Id: I7c1f5a1ad2bb5acf1b88b54de51bb39391c64763 Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
@@ -71,5 +71,5 @@ case $value$:
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}</snippet>
|
}</snippet>
|
||||||
<snippet group="C++" trigger="Q_PROPERTY" id="cpp_q_property">Q_PROPERTY($type$ $name$ READ $name$ WRITE set$name$ NOTIFY $name$Changed)</snippet>
|
<snippet group="C++" trigger="Q_PROPERTY" id="cpp_q_property">Q_PROPERTY($type$ $name$ READ $name$ WRITE set$name:c$ NOTIFY $name$Changed)</snippet>
|
||||||
</snippets>
|
</snippets>
|
||||||
|
|||||||
@@ -1559,6 +1559,7 @@ void BaseTextEditorWidget::keyPressEvent(QKeyEvent *e)
|
|||||||
&& d->m_snippetOverlay->isVisible()) {
|
&& d->m_snippetOverlay->isVisible()) {
|
||||||
e->accept();
|
e->accept();
|
||||||
d->m_snippetOverlay->hide();
|
d->m_snippetOverlay->hide();
|
||||||
|
d->m_snippetOverlay->mangle();
|
||||||
d->m_snippetOverlay->clear();
|
d->m_snippetOverlay->clear();
|
||||||
QTextCursor cursor = textCursor();
|
QTextCursor cursor = textCursor();
|
||||||
cursor.clearSelection();
|
cursor.clearSelection();
|
||||||
@@ -1598,6 +1599,7 @@ void BaseTextEditorWidget::keyPressEvent(QKeyEvent *e)
|
|||||||
if (d->m_snippetOverlay->isVisible()) {
|
if (d->m_snippetOverlay->isVisible()) {
|
||||||
e->accept();
|
e->accept();
|
||||||
d->m_snippetOverlay->hide();
|
d->m_snippetOverlay->hide();
|
||||||
|
d->m_snippetOverlay->mangle();
|
||||||
d->m_snippetOverlay->clear();
|
d->m_snippetOverlay->clear();
|
||||||
QTextCursor cursor = textCursor();
|
QTextCursor cursor = textCursor();
|
||||||
cursor.movePosition(QTextCursor::EndOfBlock);
|
cursor.movePosition(QTextCursor::EndOfBlock);
|
||||||
@@ -1942,6 +1944,7 @@ void BaseTextEditorWidget::insertCodeSnippet(const QTextCursor &cursor_arg, cons
|
|||||||
cursor.insertText(data.text);
|
cursor.insertText(data.text);
|
||||||
QList<QTextEdit::ExtraSelection> selections;
|
QList<QTextEdit::ExtraSelection> selections;
|
||||||
|
|
||||||
|
QList<NameMangler *> manglers;
|
||||||
for (int i = 0; i < data.ranges.count(); ++i) {
|
for (int i = 0; i < data.ranges.count(); ++i) {
|
||||||
int position = data.ranges.at(i).start + startCursorPosition;
|
int position = data.ranges.at(i).start + startCursorPosition;
|
||||||
int length = data.ranges.at(i).length;
|
int length = data.ranges.at(i).length;
|
||||||
@@ -1953,6 +1956,7 @@ void BaseTextEditorWidget::insertCodeSnippet(const QTextCursor &cursor_arg, cons
|
|||||||
selection.cursor = tc;
|
selection.cursor = tc;
|
||||||
selection.format = (length ? d->m_occurrencesFormat : d->m_occurrenceRenameFormat);
|
selection.format = (length ? d->m_occurrencesFormat : d->m_occurrenceRenameFormat);
|
||||||
selections.append(selection);
|
selections.append(selection);
|
||||||
|
manglers << data.ranges.at(i).mangler;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.setPosition(startCursorPosition, QTextCursor::KeepAnchor);
|
cursor.setPosition(startCursorPosition, QTextCursor::KeepAnchor);
|
||||||
@@ -1960,6 +1964,7 @@ void BaseTextEditorWidget::insertCodeSnippet(const QTextCursor &cursor_arg, cons
|
|||||||
cursor.endEditBlock();
|
cursor.endEditBlock();
|
||||||
|
|
||||||
setExtraSelections(BaseTextEditorWidget::SnippetPlaceholderSelection, selections);
|
setExtraSelections(BaseTextEditorWidget::SnippetPlaceholderSelection, selections);
|
||||||
|
d->m_snippetOverlay->setNameMangler(manglers);
|
||||||
|
|
||||||
if (!selections.isEmpty()) {
|
if (!selections.isEmpty()) {
|
||||||
const QTextEdit::ExtraSelection &selection = selections.first();
|
const QTextEdit::ExtraSelection &selection = selections.first();
|
||||||
@@ -2516,6 +2521,7 @@ bool BaseTextEditorWidgetPrivate::snippetCheckCursor(const QTextCursor &cursor)
|
|||||||
|| !m_snippetOverlay->hasCursorInSelection(end)
|
|| !m_snippetOverlay->hasCursorInSelection(end)
|
||||||
|| m_snippetOverlay->hasFirstSelectionBeginMoved()) {
|
|| m_snippetOverlay->hasFirstSelectionBeginMoved()) {
|
||||||
m_snippetOverlay->setVisible(false);
|
m_snippetOverlay->setVisible(false);
|
||||||
|
m_snippetOverlay->mangle();
|
||||||
m_snippetOverlay->clear();
|
m_snippetOverlay->clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -4696,6 +4702,7 @@ void BaseTextEditorWidget::handleBackspaceKey()
|
|||||||
handled = true;
|
handled = true;
|
||||||
} else {
|
} else {
|
||||||
if (cursorWithinSnippet) {
|
if (cursorWithinSnippet) {
|
||||||
|
d->m_snippetOverlay->mangle();
|
||||||
d->m_snippetOverlay->clear();
|
d->m_snippetOverlay->clear();
|
||||||
cursorWithinSnippet = false;
|
cursorWithinSnippet = false;
|
||||||
}
|
}
|
||||||
@@ -4728,6 +4735,7 @@ void BaseTextEditorWidget::handleBackspaceKey()
|
|||||||
cursor.deletePreviousChar();
|
cursor.deletePreviousChar();
|
||||||
} else {
|
} else {
|
||||||
if (cursorWithinSnippet) {
|
if (cursorWithinSnippet) {
|
||||||
|
d->m_snippetOverlay->mangle();
|
||||||
d->m_snippetOverlay->clear();
|
d->m_snippetOverlay->clear();
|
||||||
cursorWithinSnippet = false;
|
cursorWithinSnippet = false;
|
||||||
}
|
}
|
||||||
@@ -5317,6 +5325,7 @@ void BaseTextEditorWidget::setExtraSelections(ExtraSelectionKind kind, const QLi
|
|||||||
}
|
}
|
||||||
d->m_overlay->setVisible(!d->m_overlay->isEmpty());
|
d->m_overlay->setVisible(!d->m_overlay->isEmpty());
|
||||||
} else if (kind == SnippetPlaceholderSelection) {
|
} else if (kind == SnippetPlaceholderSelection) {
|
||||||
|
d->m_snippetOverlay->mangle();
|
||||||
d->m_snippetOverlay->clear();
|
d->m_snippetOverlay->clear();
|
||||||
foreach (const QTextEdit::ExtraSelection &selection, d->m_extraSelections[kind]) {
|
foreach (const QTextEdit::ExtraSelection &selection, d->m_extraSelections[kind]) {
|
||||||
d->m_snippetOverlay->addOverlaySelection(selection.cursor,
|
d->m_snippetOverlay->addOverlaySelection(selection.cursor,
|
||||||
@@ -5990,6 +5999,7 @@ void BaseTextEditorWidget::insertFromMimeData(const QMimeData *source)
|
|||||||
|
|
||||||
if (d->m_snippetOverlay->isVisible() && lines.count() > 1) {
|
if (d->m_snippetOverlay->isVisible() && lines.count() > 1) {
|
||||||
d->m_snippetOverlay->hide();
|
d->m_snippetOverlay->hide();
|
||||||
|
d->m_snippetOverlay->mangle();
|
||||||
d->m_snippetOverlay->clear();
|
d->m_snippetOverlay->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6006,6 +6016,7 @@ void BaseTextEditorWidget::insertFromMimeData(const QMimeData *source)
|
|||||||
if (d->m_snippetOverlay->isVisible() && (text.contains(QLatin1Char('\n'))
|
if (d->m_snippetOverlay->isVisible() && (text.contains(QLatin1Char('\n'))
|
||||||
|| text.contains(QLatin1Char('\t')))) {
|
|| text.contains(QLatin1Char('\t')))) {
|
||||||
d->m_snippetOverlay->hide();
|
d->m_snippetOverlay->hide();
|
||||||
|
d->m_snippetOverlay->mangle();
|
||||||
d->m_snippetOverlay->clear();
|
d->m_snippetOverlay->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,12 +29,54 @@
|
|||||||
|
|
||||||
#include "snippet.h"
|
#include "snippet.h"
|
||||||
|
|
||||||
|
#include <coreplugin/id.h>
|
||||||
|
|
||||||
#include <QLatin1Char>
|
#include <QLatin1Char>
|
||||||
#include <QLatin1String>
|
#include <QLatin1String>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
|
|
||||||
|
const char NOMANGLER_ID[] = "TextEditor::NoMangler";
|
||||||
|
const char UCMANGLER_ID[] = "TextEditor::UppercaseMangler";
|
||||||
|
const char LCMANGLER_ID[] = "TextEditor::LowercaseMangler";
|
||||||
|
const char TCMANGLER_ID[] = "TextEditor::TitlecaseMangler";
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Manglers:
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
class UppercaseMangler : public NameMangler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Core::Id id() const { return UCMANGLER_ID; }
|
||||||
|
QString mangle(const QString &unmangled) const { return unmangled.toUpper(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class LowercaseMangler : public NameMangler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Core::Id id() const { return LCMANGLER_ID; }
|
||||||
|
QString mangle(const QString &unmangled) const { return unmangled.toLower(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TitlecaseMangler : public NameMangler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Core::Id id() const { return TCMANGLER_ID; }
|
||||||
|
QString mangle(const QString &unmangled) const
|
||||||
|
{
|
||||||
|
QString result = unmangled;
|
||||||
|
if (!result.isEmpty())
|
||||||
|
result[0] = unmangled.at(0).toTitleCase();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Snippet:
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
const QChar Snippet::kVariableDelimiter(QLatin1Char('$'));
|
const QChar Snippet::kVariableDelimiter(QLatin1Char('$'));
|
||||||
|
|
||||||
Snippet::Snippet(const QString &groupId, const QString &id) :
|
Snippet::Snippet(const QString &groupId, const QString &id) :
|
||||||
@@ -145,12 +187,17 @@ QString Snippet::generateTip() const
|
|||||||
|
|
||||||
Snippet::ParsedSnippet Snippet::parse(const QString &snippet)
|
Snippet::ParsedSnippet Snippet::parse(const QString &snippet)
|
||||||
{
|
{
|
||||||
|
static UppercaseMangler ucMangler;
|
||||||
|
static LowercaseMangler lcMangler;
|
||||||
|
static TitlecaseMangler tcMangler;
|
||||||
|
|
||||||
Snippet::ParsedSnippet result;
|
Snippet::ParsedSnippet result;
|
||||||
result.success = true;
|
result.success = true;
|
||||||
|
|
||||||
const int count = snippet.count();
|
const int count = snippet.count();
|
||||||
bool success = true;
|
bool success = true;
|
||||||
int start = -1;
|
int start = -1;
|
||||||
|
NameMangler *mangler = 0;
|
||||||
|
|
||||||
result.text.reserve(count);
|
result.text.reserve(count);
|
||||||
|
|
||||||
@@ -158,6 +205,45 @@ Snippet::ParsedSnippet Snippet::parse(const QString &snippet)
|
|||||||
QChar current = snippet.at(i);
|
QChar current = snippet.at(i);
|
||||||
QChar next = (i + 1) < count ? snippet.at(i + 1) : QChar();
|
QChar next = (i + 1) < count ? snippet.at(i + 1) : QChar();
|
||||||
|
|
||||||
|
if (current == Snippet::kVariableDelimiter) {
|
||||||
|
if (start < 0) {
|
||||||
|
// start delimiter:
|
||||||
|
start = result.text.count();
|
||||||
|
} else {
|
||||||
|
int length = result.text.count() - start;
|
||||||
|
result.ranges << ParsedSnippet::Range(start, length, mangler);
|
||||||
|
mangler = 0;
|
||||||
|
start = -1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mangler) {
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current == QLatin1Char(':')) {
|
||||||
|
if (start >= 0) {
|
||||||
|
if (mangler != 0) {
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (next == QLatin1Char('l')) {
|
||||||
|
mangler = &lcMangler;
|
||||||
|
} else if (next == QLatin1Char('u')) {
|
||||||
|
mangler = &ucMangler;
|
||||||
|
} else if (next == QLatin1Char('c')) {
|
||||||
|
mangler = &tcMangler;
|
||||||
|
} else {
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (current == QLatin1Char('\\')) {
|
if (current == QLatin1Char('\\')) {
|
||||||
if (next.isNull()) {
|
if (next.isNull()) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -168,16 +254,6 @@ Snippet::ParsedSnippet Snippet::parse(const QString &snippet)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current == Snippet::kVariableDelimiter) {
|
|
||||||
if (start < 0) {
|
|
||||||
// start delimiter:
|
|
||||||
start = result.text.count();
|
|
||||||
} else {
|
|
||||||
result.ranges << ParsedSnippet::Range(start, result.text.count() - start);
|
|
||||||
start = -1;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
result.text.append(current);
|
result.text.append(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,34 +282,60 @@ void Internal::TextEditorPlugin::testSnippetParsing_data()
|
|||||||
QTest::addColumn<bool>("success");
|
QTest::addColumn<bool>("success");
|
||||||
QTest::addColumn<QList<int> >("ranges_start");
|
QTest::addColumn<QList<int> >("ranges_start");
|
||||||
QTest::addColumn<QList<int> >("ranges_length");
|
QTest::addColumn<QList<int> >("ranges_length");
|
||||||
|
QTest::addColumn<QList<Core::Id> >("ranges_mangler");
|
||||||
|
|
||||||
QTest::newRow("no input")
|
QTest::newRow("no input")
|
||||||
<< QString() << QString() << true << (QList<int>()) << (QList<int>());
|
<< QString() << QString() << true
|
||||||
|
<< (QList<int>()) << (QList<int>()) << (QList<Core::Id>());
|
||||||
QTest::newRow("empty input")
|
QTest::newRow("empty input")
|
||||||
<< QString::fromLatin1("") << QString::fromLatin1("") << true << (QList<int>()) << (QList<int>());
|
<< QString::fromLatin1("") << QString::fromLatin1("") << true
|
||||||
|
<< (QList<int>()) << (QList<int>()) << (QList<Core::Id>());
|
||||||
|
|
||||||
QTest::newRow("simple identifier")
|
QTest::newRow("simple identifier")
|
||||||
<< QString::fromLatin1("$test$") << QString::fromLatin1("test") << true
|
<< QString::fromLatin1("$tESt$") << QString::fromLatin1("tESt") << true
|
||||||
<< (QList<int>() << 0) << (QList<int>() << 4);
|
<< (QList<int>() << 0) << (QList<int>() << 4)
|
||||||
|
<< (QList<Core::Id>() << NOMANGLER_ID);
|
||||||
|
QTest::newRow("simple identifier with lc")
|
||||||
|
<< QString::fromLatin1("$tESt:l$") << QString::fromLatin1("tESt") << true
|
||||||
|
<< (QList<int>() << 0) << (QList<int>() << 4)
|
||||||
|
<< (QList<Core::Id>() << LCMANGLER_ID);
|
||||||
|
QTest::newRow("simple identifier with uc")
|
||||||
|
<< QString::fromLatin1("$tESt:u$") << QString::fromLatin1("tESt") << true
|
||||||
|
<< (QList<int>() << 0) << (QList<int>() << 4)
|
||||||
|
<< (QList<Core::Id>() << UCMANGLER_ID);
|
||||||
|
QTest::newRow("simple identifier with tc")
|
||||||
|
<< QString::fromLatin1("$tESt:c$") << QString::fromLatin1("tESt") << true
|
||||||
|
<< (QList<int>() << 0) << (QList<int>() << 4)
|
||||||
|
<< (QList<Core::Id>() << TCMANGLER_ID);
|
||||||
|
|
||||||
QTest::newRow("escaped string")
|
QTest::newRow("escaped string")
|
||||||
<< QString::fromLatin1("\\$test\\$") << QString::fromLatin1("$test$") << true
|
<< QString::fromLatin1("\\$test\\$") << QString::fromLatin1("$test$") << true
|
||||||
<< (QList<int>()) << (QList<int>());
|
<< (QList<int>()) << (QList<int>())
|
||||||
|
<< (QList<Core::Id>());
|
||||||
QTest::newRow("escaped escape")
|
QTest::newRow("escaped escape")
|
||||||
<< QString::fromLatin1("\\\\$test\\\\$") << QString::fromLatin1("\\test\\") << true
|
<< QString::fromLatin1("\\\\$test\\\\$") << QString::fromLatin1("\\test\\") << true
|
||||||
<< (QList<int>() << 1) << (QList<int>() << 5);
|
<< (QList<int>() << 1) << (QList<int>() << 5)
|
||||||
|
<< (QList<Core::Id>() << NOMANGLER_ID);
|
||||||
|
|
||||||
QTest::newRow("Q_PROPERTY")
|
QTest::newRow("Q_PROPERTY")
|
||||||
<< QString::fromLatin1("Q_PROPERTY($type$ $name$ READ $name$ WRITE set$name$ NOTIFY $name$Changed)")
|
<< QString::fromLatin1("Q_PROPERTY($type$ $name$ READ $name$ WRITE set$name:c$ NOTIFY $name$Changed)")
|
||||||
<< QString::fromLatin1("Q_PROPERTY(type name READ name WRITE setname NOTIFY nameChanged)") << true
|
<< QString::fromLatin1("Q_PROPERTY(type name READ name WRITE setname NOTIFY nameChanged)") << true
|
||||||
<< (QList<int>() << 11 << 16 << 26 << 40 << 52)
|
<< (QList<int>() << 11 << 16 << 26 << 40 << 52)
|
||||||
<< (QList<int>() << 4 << 4 << 4 << 4 << 4);
|
<< (QList<int>() << 4 << 4 << 4 << 4 << 4)
|
||||||
|
<< (QList<Core::Id>() << NOMANGLER_ID << NOMANGLER_ID << NOMANGLER_ID << TCMANGLER_ID << NOMANGLER_ID);
|
||||||
|
|
||||||
QTest::newRow("broken escape")
|
QTest::newRow("broken escape")
|
||||||
<< QString::fromLatin1("\\\\$test\\\\$\\") << QString::fromLatin1("\\\\$test\\\\$\\") << false
|
<< QString::fromLatin1("\\\\$test\\\\$\\") << QString::fromLatin1("\\\\$test\\\\$\\") << false
|
||||||
<< (QList<int>()) << (QList<int>());
|
<< (QList<int>()) << (QList<int>())
|
||||||
|
<< (QList<Core::Id>());
|
||||||
QTest::newRow("open identifier")
|
QTest::newRow("open identifier")
|
||||||
<< QString::fromLatin1("$test") << QString::fromLatin1("$test") << false
|
<< QString::fromLatin1("$test") << QString::fromLatin1("$test") << false
|
||||||
<< (QList<int>()) << (QList<int>());
|
<< (QList<int>()) << (QList<int>())
|
||||||
|
<< (QList<Core::Id>());
|
||||||
|
QTest::newRow("wrong mangler")
|
||||||
|
<< QString::fromLatin1("$test:X$") << QString::fromLatin1("$test:X$") << false
|
||||||
|
<< (QList<int>()) << (QList<int>())
|
||||||
|
<< (QList<Core::Id>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Internal::TextEditorPlugin::testSnippetParsing()
|
void Internal::TextEditorPlugin::testSnippetParsing()
|
||||||
@@ -243,7 +345,9 @@ void Internal::TextEditorPlugin::testSnippetParsing()
|
|||||||
QFETCH(bool, success);
|
QFETCH(bool, success);
|
||||||
QFETCH(QList<int>, ranges_start);
|
QFETCH(QList<int>, ranges_start);
|
||||||
QFETCH(QList<int>, ranges_length);
|
QFETCH(QList<int>, ranges_length);
|
||||||
|
QFETCH(QList<Core::Id>, ranges_mangler);
|
||||||
Q_ASSERT(ranges_start.count() == ranges_length.count()); // sanity check for the test data
|
Q_ASSERT(ranges_start.count() == ranges_length.count()); // sanity check for the test data
|
||||||
|
Q_ASSERT(ranges_start.count() == ranges_mangler.count()); // sanity check for the test data
|
||||||
|
|
||||||
Snippet::ParsedSnippet result = Snippet::parse(input);
|
Snippet::ParsedSnippet result = Snippet::parse(input);
|
||||||
|
|
||||||
@@ -253,6 +357,10 @@ void Internal::TextEditorPlugin::testSnippetParsing()
|
|||||||
for (int i = 0; i < ranges_start.count(); ++i) {
|
for (int i = 0; i < ranges_start.count(); ++i) {
|
||||||
QCOMPARE(result.ranges.at(i).start, ranges_start.at(i));
|
QCOMPARE(result.ranges.at(i).start, ranges_start.at(i));
|
||||||
QCOMPARE(result.ranges.at(i).length, ranges_length.at(i));
|
QCOMPARE(result.ranges.at(i).length, ranges_length.at(i));
|
||||||
|
Core::Id id = NOMANGLER_ID;
|
||||||
|
if (result.ranges.at(i).mangler)
|
||||||
|
id = result.ranges.at(i).mangler->id();
|
||||||
|
QCOMPARE(id, ranges_mangler.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,8 +36,19 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Core { class Id; }
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
|
|
||||||
|
class TEXTEDITOR_EXPORT NameMangler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~NameMangler() { }
|
||||||
|
|
||||||
|
virtual Core::Id id() const = 0;
|
||||||
|
virtual QString mangle(const QString &unmangled) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT Snippet
|
class TEXTEDITOR_EXPORT Snippet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -73,9 +84,10 @@ public:
|
|||||||
QString text;
|
QString text;
|
||||||
bool success;
|
bool success;
|
||||||
struct Range {
|
struct Range {
|
||||||
Range(int s, int l) : start(s), length(l) { }
|
Range(int s, int l, NameMangler *m) : start(s), length(l), mangler(m) { }
|
||||||
int start;
|
int start;
|
||||||
int length;
|
int length;
|
||||||
|
NameMangler *mangler;
|
||||||
};
|
};
|
||||||
QList<Range> ranges;
|
QList<Range> ranges;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "texteditoroverlay.h"
|
#include "texteditoroverlay.h"
|
||||||
#include "basetexteditor.h"
|
#include "basetexteditor.h"
|
||||||
|
#include "snippets/snippet.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
@@ -72,6 +73,8 @@ void TextEditorOverlay::clear()
|
|||||||
return;
|
return;
|
||||||
m_selections.clear();
|
m_selections.clear();
|
||||||
m_firstSelectionOriginalBegin = -1;
|
m_firstSelectionOriginalBegin = -1;
|
||||||
|
m_equivalentSelections.clear();
|
||||||
|
m_manglers.clear();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,7 +493,7 @@ void TextEditorOverlay::mapEquivalentSelections()
|
|||||||
|
|
||||||
QMap<QString, int> all;
|
QMap<QString, int> all;
|
||||||
for (int i = 0; i < m_selections.size(); ++i)
|
for (int i = 0; i < m_selections.size(); ++i)
|
||||||
all.insertMulti(selectionText(i), i);
|
all.insertMulti(selectionText(i).toLower(), i);
|
||||||
|
|
||||||
const QList<QString> &uniqueKeys = all.uniqueKeys();
|
const QList<QString> &uniqueKeys = all.uniqueKeys();
|
||||||
foreach (const QString &key, uniqueKeys) {
|
foreach (const QString &key, uniqueKeys) {
|
||||||
@@ -529,6 +532,29 @@ void TextEditorOverlay::updateEquivalentSelections(const QTextCursor &cursor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEditorOverlay::setNameMangler(const QList<NameMangler *> &manglers)
|
||||||
|
{
|
||||||
|
m_manglers = manglers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorOverlay::mangle()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_manglers.count(); ++i) {
|
||||||
|
if (!m_manglers.at(i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const QString current = selectionText(i);
|
||||||
|
const QString result = m_manglers.at(i)->mangle(current);
|
||||||
|
if (result != current) {
|
||||||
|
QTextCursor selectionCursor = assembleCursorForSelection(i);
|
||||||
|
selectionCursor.joinPreviousEditBlock();
|
||||||
|
selectionCursor.removeSelectedText();
|
||||||
|
selectionCursor.insertText(result);
|
||||||
|
selectionCursor.endEditBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TextEditorOverlay::hasFirstSelectionBeginMoved() const
|
bool TextEditorOverlay::hasFirstSelectionBeginMoved() const
|
||||||
{
|
{
|
||||||
if (m_firstSelectionOriginalBegin == -1 || m_selections.isEmpty())
|
if (m_firstSelectionOriginalBegin == -1 || m_selections.isEmpty())
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
QT_FORWARD_DECLARE_CLASS(QWidget)
|
QT_FORWARD_DECLARE_CLASS(QWidget)
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
|
class NameMangler;
|
||||||
class BaseTextEditorWidget;
|
class BaseTextEditorWidget;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -100,6 +101,8 @@ public:
|
|||||||
|
|
||||||
void mapEquivalentSelections();
|
void mapEquivalentSelections();
|
||||||
void updateEquivalentSelections(const QTextCursor &cursor);
|
void updateEquivalentSelections(const QTextCursor &cursor);
|
||||||
|
void setNameMangler(const QList<NameMangler *> &manglers);
|
||||||
|
void mangle();
|
||||||
|
|
||||||
bool hasFirstSelectionBeginMoved() const;
|
bool hasFirstSelectionBeginMoved() const;
|
||||||
|
|
||||||
@@ -120,6 +123,7 @@ private:
|
|||||||
QWidget *m_viewport;
|
QWidget *m_viewport;
|
||||||
QList<OverlaySelection> m_selections;
|
QList<OverlaySelection> m_selections;
|
||||||
QVector<QList<int> > m_equivalentSelections;
|
QVector<QList<int> > m_equivalentSelections;
|
||||||
|
QList<NameMangler *> m_manglers;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Reference in New Issue
Block a user