From fcd93256c0696c7d58308d3306784bca1394c73e Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 21 May 2021 13:17:14 +0200 Subject: [PATCH] Snippets: Allow defining a final snippet tabstop Change-Id: I8b9704f66c9f0ac33dfb9d8f5e970a85bbcf143e Reviewed-by: Christian Stenger --- .../texteditor/snippets/snippetoverlay.cpp | 22 +++++++++++- .../texteditor/snippets/snippetoverlay.h | 5 +++ .../texteditor/snippets/snippetparser.h | 1 + src/plugins/texteditor/texteditor.cpp | 36 +++++++++++++------ 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/plugins/texteditor/snippets/snippetoverlay.cpp b/src/plugins/texteditor/snippets/snippetoverlay.cpp index 182813c556e..b773acfee11 100644 --- a/src/plugins/texteditor/snippets/snippetoverlay.cpp +++ b/src/plugins/texteditor/snippets/snippetoverlay.cpp @@ -51,6 +51,12 @@ void SnippetOverlay::addSnippetSelection(const QTextCursor &cursor, 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) { const int ¤tIndex = indexForCursor(cursor); @@ -92,6 +98,12 @@ bool SnippetOverlay::hasCursorInSelection(const QTextCursor &cursor) const return indexForCursor(cursor) >= 0; } +QTextCursor SnippetOverlay::firstSelectionCursor() const +{ + const QList selections = TextEditorOverlay::selections(); + return selections.isEmpty() ? QTextCursor() : cursorForSelection(selections.first()); +} + QTextCursor SnippetOverlay::nextSelectionCursor(const QTextCursor &cursor) const { const QList selections = TextEditorOverlay::selections(); @@ -100,8 +112,11 @@ QTextCursor SnippetOverlay::nextSelectionCursor(const QTextCursor &cursor) const const SnippetSelection ¤tSelection = selectionForCursor(cursor); if (currentSelection.variableIndex >= 0) { 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; + } for (int selectionIndex : m_variables[nextVariableIndex]) { if (selections[selectionIndex].m_cursor_begin.position() > cursor.position()) @@ -143,6 +158,11 @@ QTextCursor SnippetOverlay::previousSelectionCursor(const QTextCursor &cursor) c 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 { return Utils::indexOf(selections(), diff --git a/src/plugins/texteditor/snippets/snippetoverlay.h b/src/plugins/texteditor/snippets/snippetoverlay.h index a6ca9f64069..9bf80524d62 100644 --- a/src/plugins/texteditor/snippets/snippetoverlay.h +++ b/src/plugins/texteditor/snippets/snippetoverlay.h @@ -46,13 +46,17 @@ public: const QColor &color, NameMangler *mangler, int variableGoup); + void setFinalSelection(const QTextCursor &cursor, const QColor &color); + void updateEquivalentSelections(const QTextCursor &cursor); void mangle(); bool hasCursorInSelection(const QTextCursor &cursor) const; + QTextCursor firstSelectionCursor() const; QTextCursor nextSelectionCursor(const QTextCursor &cursor) const; QTextCursor previousSelectionCursor(const QTextCursor &cursor) const; + bool isFinalSelection(const QTextCursor &cursor) const; private: struct SnippetSelection @@ -65,6 +69,7 @@ private: SnippetSelection selectionForCursor(const QTextCursor &cursor) const; QList m_selections; + int m_finalSelectionIndex = -1; QMap> m_variables; }; diff --git a/src/plugins/texteditor/snippets/snippetparser.h b/src/plugins/texteditor/snippets/snippetparser.h index b5afac29ee3..67d0560d02b 100644 --- a/src/plugins/texteditor/snippets/snippetparser.h +++ b/src/plugins/texteditor/snippets/snippetparser.h @@ -51,6 +51,7 @@ public: QString text; int variableIndex = -1; // if variable index is >= 0 the text is interpreted as a variable NameMangler *mangler = nullptr; + bool finalPart = false; }; QList parts; QList> variables; diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 8ccfa0591d4..033dd2a58aa 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -2770,15 +2770,26 @@ void TextEditorWidget::insertCodeSnippet(const QTextCursor &cursor_arg, for (const CursorPart &part : cursorParts) { const QColor &color = part.cursor.hasSelection() ? occurrencesColor : renameColor; - d->m_snippetOverlay->addSnippetSelection(part.cursor, - color, - part.mangler, - part.variableIndex); + if (part.finalPart) { + d->m_snippetOverlay->setFinalSelection(part.cursor, color); + } else { + d->m_snippetOverlay->addSnippetSelection(part.cursor, + color, + part.mangler, + part.variableIndex); + } } - if (!cursorParts.isEmpty()) { - setTextCursor(cursorParts.first().cursor); - d->m_snippetOverlay->setVisible(true); + cursor = d->m_snippetOverlay->firstSelectionCursor(); + if (!cursor.isNull()) { + 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()) return; - QTextCursor cursor = q->textCursor(); - q->setTextCursor(forward ? m_snippetOverlay->nextSelectionCursor(cursor) - : m_snippetOverlay->previousSelectionCursor(cursor)); + QTextCursor cursor = forward ? m_snippetOverlay->nextSelectionCursor(q->textCursor()) + : m_snippetOverlay->previousSelectionCursor(q->textCursor()); + 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.