Snippets: Allow defining a final snippet tabstop

Change-Id: I8b9704f66c9f0ac33dfb9d8f5e970a85bbcf143e
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-05-21 13:17:14 +02:00
parent 2ccf5e2795
commit fcd93256c0
4 changed files with 53 additions and 11 deletions

View File

@@ -51,6 +51,12 @@ void SnippetOverlay::addSnippetSelection(const QTextCursor &cursor,
addOverlaySelection(cursor, color, color, TextEditorOverlay::ExpandBegin); addOverlaySelection(cursor, color, color, TextEditorOverlay::ExpandBegin);
} }
void SnippetOverlay::setFinalSelection(const QTextCursor &cursor, const QColor &color)
{
m_finalSelectionIndex = selections().size();
addOverlaySelection(cursor, color, color, TextEditorOverlay::ExpandBegin);
}
void SnippetOverlay::updateEquivalentSelections(const QTextCursor &cursor) void SnippetOverlay::updateEquivalentSelections(const QTextCursor &cursor)
{ {
const int &currentIndex = indexForCursor(cursor); const int &currentIndex = indexForCursor(cursor);
@@ -92,6 +98,12 @@ bool SnippetOverlay::hasCursorInSelection(const QTextCursor &cursor) const
return indexForCursor(cursor) >= 0; return indexForCursor(cursor) >= 0;
} }
QTextCursor SnippetOverlay::firstSelectionCursor() const
{
const QList<OverlaySelection> selections = TextEditorOverlay::selections();
return selections.isEmpty() ? QTextCursor() : cursorForSelection(selections.first());
}
QTextCursor SnippetOverlay::nextSelectionCursor(const QTextCursor &cursor) const QTextCursor SnippetOverlay::nextSelectionCursor(const QTextCursor &cursor) const
{ {
const QList<OverlaySelection> selections = TextEditorOverlay::selections(); const QList<OverlaySelection> selections = TextEditorOverlay::selections();
@@ -100,8 +112,11 @@ QTextCursor SnippetOverlay::nextSelectionCursor(const QTextCursor &cursor) const
const SnippetSelection &currentSelection = selectionForCursor(cursor); const SnippetSelection &currentSelection = selectionForCursor(cursor);
if (currentSelection.variableIndex >= 0) { if (currentSelection.variableIndex >= 0) {
int nextVariableIndex = currentSelection.variableIndex + 1; int nextVariableIndex = currentSelection.variableIndex + 1;
if (nextVariableIndex >= m_variables.size()) if (nextVariableIndex >= m_variables.size()) {
if (m_finalSelectionIndex >= 0)
return cursorForIndex(m_finalSelectionIndex);
nextVariableIndex = 0; nextVariableIndex = 0;
}
for (int selectionIndex : m_variables[nextVariableIndex]) { for (int selectionIndex : m_variables[nextVariableIndex]) {
if (selections[selectionIndex].m_cursor_begin.position() > cursor.position()) if (selections[selectionIndex].m_cursor_begin.position() > cursor.position())
@@ -143,6 +158,11 @@ QTextCursor SnippetOverlay::previousSelectionCursor(const QTextCursor &cursor) c
return cursorForSelection(selections.last()); return cursorForSelection(selections.last());
} }
bool SnippetOverlay::isFinalSelection(const QTextCursor &cursor) const
{
return m_finalSelectionIndex >= 0 ? cursor == cursorForIndex(m_finalSelectionIndex) : false;
}
int SnippetOverlay::indexForCursor(const QTextCursor &cursor) const int SnippetOverlay::indexForCursor(const QTextCursor &cursor) const
{ {
return Utils::indexOf(selections(), return Utils::indexOf(selections(),

View File

@@ -46,13 +46,17 @@ public:
const QColor &color, const QColor &color,
NameMangler *mangler, NameMangler *mangler,
int variableGoup); int variableGoup);
void setFinalSelection(const QTextCursor &cursor, const QColor &color);
void updateEquivalentSelections(const QTextCursor &cursor); void updateEquivalentSelections(const QTextCursor &cursor);
void mangle(); void mangle();
bool hasCursorInSelection(const QTextCursor &cursor) const; bool hasCursorInSelection(const QTextCursor &cursor) const;
QTextCursor firstSelectionCursor() const;
QTextCursor nextSelectionCursor(const QTextCursor &cursor) const; QTextCursor nextSelectionCursor(const QTextCursor &cursor) const;
QTextCursor previousSelectionCursor(const QTextCursor &cursor) const; QTextCursor previousSelectionCursor(const QTextCursor &cursor) const;
bool isFinalSelection(const QTextCursor &cursor) const;
private: private:
struct SnippetSelection struct SnippetSelection
@@ -65,6 +69,7 @@ private:
SnippetSelection selectionForCursor(const QTextCursor &cursor) const; SnippetSelection selectionForCursor(const QTextCursor &cursor) const;
QList<SnippetSelection> m_selections; QList<SnippetSelection> m_selections;
int m_finalSelectionIndex = -1;
QMap<int, QList<int>> m_variables; QMap<int, QList<int>> m_variables;
}; };

View File

@@ -51,6 +51,7 @@ public:
QString text; QString text;
int variableIndex = -1; // if variable index is >= 0 the text is interpreted as a variable int variableIndex = -1; // if variable index is >= 0 the text is interpreted as a variable
NameMangler *mangler = nullptr; NameMangler *mangler = nullptr;
bool finalPart = false;
}; };
QList<Part> parts; QList<Part> parts;
QList<QList<int>> variables; QList<QList<int>> variables;

View File

@@ -2770,15 +2770,26 @@ void TextEditorWidget::insertCodeSnippet(const QTextCursor &cursor_arg,
for (const CursorPart &part : cursorParts) { for (const CursorPart &part : cursorParts) {
const QColor &color = part.cursor.hasSelection() ? occurrencesColor : renameColor; const QColor &color = part.cursor.hasSelection() ? occurrencesColor : renameColor;
d->m_snippetOverlay->addSnippetSelection(part.cursor, if (part.finalPart) {
color, d->m_snippetOverlay->setFinalSelection(part.cursor, color);
part.mangler, } else {
part.variableIndex); d->m_snippetOverlay->addSnippetSelection(part.cursor,
color,
part.mangler,
part.variableIndex);
}
} }
if (!cursorParts.isEmpty()) { cursor = d->m_snippetOverlay->firstSelectionCursor();
setTextCursor(cursorParts.first().cursor); if (!cursor.isNull()) {
d->m_snippetOverlay->setVisible(true); setTextCursor(cursor);
if (d->m_snippetOverlay->isFinalSelection(cursor)) {
d->m_snippetOverlay->mangle();
d->m_snippetOverlay->clear();
d->m_snippetOverlay->setVisible(false);
} else {
d->m_snippetOverlay->setVisible(true);
}
} }
} }
@@ -3486,9 +3497,14 @@ void TextEditorWidgetPrivate::snippetTabOrBacktab(bool forward)
{ {
if (!m_snippetOverlay->isVisible() || m_snippetOverlay->isEmpty()) if (!m_snippetOverlay->isVisible() || m_snippetOverlay->isEmpty())
return; return;
QTextCursor cursor = q->textCursor(); QTextCursor cursor = forward ? m_snippetOverlay->nextSelectionCursor(q->textCursor())
q->setTextCursor(forward ? m_snippetOverlay->nextSelectionCursor(cursor) : m_snippetOverlay->previousSelectionCursor(q->textCursor());
: m_snippetOverlay->previousSelectionCursor(cursor)); q->setTextCursor(cursor);
if (m_snippetOverlay->isFinalSelection(cursor)) {
m_snippetOverlay->setVisible(false);
m_snippetOverlay->mangle();
m_snippetOverlay->clear();
}
} }
// Calculate global position for a tooltip considering the left extra area. // Calculate global position for a tooltip considering the left extra area.