From 3b0a43802e45affc7cfbef065d99720a1415e791 Mon Sep 17 00:00:00 2001 From: Leandro Melo Date: Wed, 17 Aug 2011 12:31:15 +0200 Subject: [PATCH] Editors: Enhance smart backspace behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a new smart backspace behavior option. Now it's also possible to simply unindent (like a backtab). This is particularly useful when the cursor is not inside an "indentation area" but the user still wants to go backwards by indent levels when possible (for example before a comment that appears after the code line). The option also allows the user to reach a new indent level which has not been seen so far in previous lines. The original follows indentation user setting will be lost with this patch, but we consider this ok for not very "significant" settings. Change-Id: I49efb6b0309d9b7d7ff2a589413446bc16fb753c Reviewed-on: http://codereview.qt.nokia.com/3105 Reviewed-by: Qt Sanity Bot Reviewed-by: Robert Löhning Reviewed-by: hjk --- src/plugins/fakevim/fakevimplugin.cpp | 3 +- src/plugins/texteditor/basetexteditor.cpp | 26 ++++++-- src/plugins/texteditor/tabsettings.cpp | 15 ++--- src/plugins/texteditor/tabsettings.h | 9 ++- src/plugins/texteditor/tabsettingswidget.cpp | 12 ++-- src/plugins/texteditor/tabsettingswidget.ui | 63 +++++++++++++++----- 6 files changed, 93 insertions(+), 35 deletions(-) diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 4bb47b9c152..9924d09bc7e 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -288,7 +288,8 @@ void FakeVimOptionPage::copyTextEditorSettings() m_ui.checkBoxExpandTab->setChecked(ts.m_spacesForTabs); m_ui.spinBoxTabStop->setValue(ts.m_tabSize); m_ui.spinBoxShiftWidth->setValue(ts.m_indentSize); - m_ui.checkBoxSmartTab->setChecked(ts.m_smartBackspace); + m_ui.checkBoxSmartTab->setChecked( + ts.m_smartBackspaceBehavior == TabSettings::BackspaceFollowsPreviousIndents); m_ui.checkBoxAutoIndent->setChecked(true); m_ui.checkBoxSmartIndent->setChecked(ts.m_autoIndent); m_ui.checkBoxIncSearch->setChecked(true); diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index f08fa5ff1a0..b9a93ee844b 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -4529,12 +4529,12 @@ void BaseTextEditorWidget::handleBackspaceKey() return; bool handled = false; - if (!tabSettings.m_smartBackspace) { + if (tabSettings.m_smartBackspaceBehavior == TabSettings::BackspaceNeverIndents) { if (cursorWithinSnippet) cursor.beginEditBlock(); cursor.deletePreviousChar(); handled = true; - } else { + } else if (tabSettings.m_smartBackspaceBehavior == TabSettings::BackspaceFollowsPreviousIndents) { QTextBlock currentBlock = cursor.block(); int positionInBlock = pos - currentBlock.position(); const QString blockText = currentBlock.text(); @@ -4544,9 +4544,12 @@ void BaseTextEditorWidget::handleBackspaceKey() cursor.deletePreviousChar(); handled = true; } else { + if (cursorWithinSnippet) { + d->m_snippetOverlay->clear(); + cursorWithinSnippet = false; + } int previousIndent = 0; const int indent = tabSettings.columnAt(blockText, positionInBlock); - for (QTextBlock previousNonEmptyBlock = currentBlock.previous(); previousNonEmptyBlock.isValid(); previousNonEmptyBlock = previousNonEmptyBlock.previous()) { @@ -4554,8 +4557,8 @@ void BaseTextEditorWidget::handleBackspaceKey() if (previousNonEmptyBlockText.trimmed().isEmpty()) continue; previousIndent = - tabSettings.columnAt(previousNonEmptyBlockText, - tabSettings.firstNonSpace(previousNonEmptyBlockText)); + tabSettings.columnAt(previousNonEmptyBlockText, + tabSettings.firstNonSpace(previousNonEmptyBlockText)); if (previousIndent < indent) { cursor.beginEditBlock(); cursor.setPosition(currentBlock.position(), QTextCursor::KeepAnchor); @@ -4566,6 +4569,19 @@ void BaseTextEditorWidget::handleBackspaceKey() } } } + } else if (tabSettings.m_smartBackspaceBehavior == TabSettings::BackspaceUnindents) { + if (!pos || !characterAt(pos - 1).isSpace()) { + if (cursorWithinSnippet) + cursor.beginEditBlock(); + cursor.deletePreviousChar(); + } else { + if (cursorWithinSnippet) { + d->m_snippetOverlay->clear(); + cursorWithinSnippet = false; + } + indentOrUnindent(false); + } + handled = true; } if (!handled) { diff --git a/src/plugins/texteditor/tabsettings.cpp b/src/plugins/texteditor/tabsettings.cpp index 447eeea534b..09c7bf04743 100644 --- a/src/plugins/texteditor/tabsettings.cpp +++ b/src/plugins/texteditor/tabsettings.cpp @@ -42,7 +42,7 @@ static const char spacesForTabsKey[] = "SpacesForTabs"; static const char autoSpacesForTabsKey[] = "AutoSpacesForTabs"; -static const char smartBackspaceKey[] = "SmartBackspace"; +static const char smartBackspaceBehaviorKey[] = "SmartBackspaceBehavior"; static const char autoIndentKey[] = "AutoIndent"; static const char tabSizeKey[] = "TabSize"; static const char indentSizeKey[] = "IndentSize"; @@ -58,11 +58,11 @@ TabSettings::TabSettings() : m_spacesForTabs(true), m_autoSpacesForTabs(false), m_autoIndent(true), - m_smartBackspace(false), m_tabSize(8), m_indentSize(4), m_tabKeyBehavior(TabNeverIndents), - m_continuationAlignBehavior(ContinuationAlignWithSpaces) + m_continuationAlignBehavior(ContinuationAlignWithSpaces), + m_smartBackspaceBehavior(BackspaceNeverIndents) { } @@ -82,7 +82,7 @@ void TabSettings::toMap(const QString &prefix, QVariantMap *map) const map->insert(prefix + QLatin1String(spacesForTabsKey), m_spacesForTabs); map->insert(prefix + QLatin1String(autoSpacesForTabsKey), m_autoSpacesForTabs); map->insert(prefix + QLatin1String(autoIndentKey), m_autoIndent); - map->insert(prefix + QLatin1String(smartBackspaceKey), m_smartBackspace); + map->insert(prefix + QLatin1String(smartBackspaceBehaviorKey), m_smartBackspaceBehavior); map->insert(prefix + QLatin1String(tabSizeKey), m_tabSize); map->insert(prefix + QLatin1String(indentSizeKey), m_indentSize); map->insert(prefix + QLatin1String(tabKeyBehaviorKey), m_tabKeyBehavior); @@ -96,8 +96,9 @@ void TabSettings::fromMap(const QString &prefix, const QVariantMap &map) m_autoSpacesForTabs = map.value(prefix + QLatin1String(autoSpacesForTabsKey), m_autoSpacesForTabs).toBool(); m_autoIndent = map.value(prefix + QLatin1String(autoIndentKey), m_autoIndent).toBool(); - m_smartBackspace = - map.value(prefix + QLatin1String(smartBackspaceKey), m_smartBackspace).toBool(); + m_smartBackspaceBehavior = (SmartBackspaceBehavior) + map.value(prefix + QLatin1String(smartBackspaceBehaviorKey), + m_smartBackspaceBehavior).toInt(); m_tabSize = map.value(prefix + QLatin1String(tabSizeKey), m_tabSize).toInt(); m_indentSize = map.value(prefix + QLatin1String(indentSizeKey), m_indentSize).toInt(); m_tabKeyBehavior = (TabKeyBehavior) @@ -396,7 +397,7 @@ bool TabSettings::equals(const TabSettings &ts) const return m_spacesForTabs == ts.m_spacesForTabs && m_autoSpacesForTabs == ts.m_autoSpacesForTabs && m_autoIndent == ts.m_autoIndent - && m_smartBackspace == ts.m_smartBackspace + && m_smartBackspaceBehavior == ts.m_smartBackspaceBehavior && m_tabSize == ts.m_tabSize && m_indentSize == ts.m_indentSize && m_tabKeyBehavior == ts.m_tabKeyBehavior diff --git a/src/plugins/texteditor/tabsettings.h b/src/plugins/texteditor/tabsettings.h index 26a1c6f7ec6..885f4b23308 100644 --- a/src/plugins/texteditor/tabsettings.h +++ b/src/plugins/texteditor/tabsettings.h @@ -63,6 +63,13 @@ public: ContinuationAlignWithIndent = 2 }; + // This enum must match the indexes of smartBackspaceBehavior widget + enum SmartBackspaceBehavior { + BackspaceNeverIndents = 0, + BackspaceFollowsPreviousIndents = 1, + BackspaceUnindents = 2 + }; + TabSettings(); void toSettings(const QString &category, QSettings *s) const; @@ -96,11 +103,11 @@ public: bool m_spacesForTabs; bool m_autoSpacesForTabs; bool m_autoIndent; - bool m_smartBackspace; int m_tabSize; int m_indentSize; TabKeyBehavior m_tabKeyBehavior; ContinuationAlignBehavior m_continuationAlignBehavior; + SmartBackspaceBehavior m_smartBackspaceBehavior; bool equals(const TabSettings &ts) const; }; diff --git a/src/plugins/texteditor/tabsettingswidget.cpp b/src/plugins/texteditor/tabsettingswidget.cpp index 60cc37caf87..fea3255cba0 100644 --- a/src/plugins/texteditor/tabsettingswidget.cpp +++ b/src/plugins/texteditor/tabsettingswidget.cpp @@ -52,7 +52,7 @@ TabSettingsWidget::TabSettingsWidget(QWidget *parent) : this, SLOT(slotSettingsChanged())); connect(ui->autoIndent, SIGNAL(toggled(bool)), this, SLOT(slotSettingsChanged())); - connect(ui->smartBackspace, SIGNAL(toggled(bool)), + connect(ui->smartBackspaceBehavior, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSettingsChanged())); connect(ui->tabSize, SIGNAL(valueChanged(int)), this, SLOT(slotSettingsChanged())); @@ -77,7 +77,7 @@ void TabSettingsWidget::setSettings(const TextEditor::TabSettings& s) ui->insertSpaces->setChecked(s.m_spacesForTabs); ui->autoInsertSpaces->setChecked(s.m_autoSpacesForTabs); ui->autoIndent->setChecked(s.m_autoIndent); - ui->smartBackspace->setChecked(s.m_smartBackspace); + ui->smartBackspaceBehavior->setCurrentIndex(s.m_smartBackspaceBehavior); ui->tabSize->setValue(s.m_tabSize); ui->indentSize->setValue(s.m_indentSize); ui->tabKeyBehavior->setCurrentIndex(s.m_tabKeyBehavior); @@ -94,11 +94,13 @@ TabSettings TabSettingsWidget::settings() const set.m_spacesForTabs = ui->insertSpaces->isChecked(); set.m_autoSpacesForTabs = ui->autoInsertSpaces->isChecked(); set.m_autoIndent = ui->autoIndent->isChecked(); - set.m_smartBackspace = ui->smartBackspace->isChecked(); + set.m_smartBackspaceBehavior = + (TabSettings::SmartBackspaceBehavior)ui->smartBackspaceBehavior->currentIndex(); set.m_tabSize = ui->tabSize->value(); set.m_indentSize = ui->indentSize->value(); set.m_tabKeyBehavior = (TabSettings::TabKeyBehavior)(ui->tabKeyBehavior->currentIndex()); - set.m_continuationAlignBehavior = (TabSettings::ContinuationAlignBehavior)(ui->continuationAlignBehavior->currentIndex()); + set.m_continuationAlignBehavior = + (TabSettings::ContinuationAlignBehavior)(ui->continuationAlignBehavior->currentIndex()); return set; } @@ -124,7 +126,7 @@ QString TabSettingsWidget::searchKeywords() const << sep << ui->insertSpaces->text() << sep << ui->autoInsertSpaces->text() << sep << ui->autoIndent->text() - << sep << ui->smartBackspace->text() + << sep << ui->smartBackspaceLabel->text() << sep << ui->tabSizeLabel->text() << sep << ui->indentSizeLabel->text() << sep << ui->tabKeyBehaviorLabel->text() diff --git a/src/plugins/texteditor/tabsettingswidget.ui b/src/plugins/texteditor/tabsettingswidget.ui index 63494f7b8ab..3b0d91ce495 100644 --- a/src/plugins/texteditor/tabsettingswidget.ui +++ b/src/plugins/texteditor/tabsettingswidget.ui @@ -166,24 +166,14 @@ - - - - Backspace will go back one indentation level instead of one space. - - - &Backspace follows indentation - - - - + Align continuation lines: - + <html><head/><body> @@ -229,14 +219,14 @@ Influences the indentation of continuation lines. - + Tab key performs auto-indent: - + @@ -255,7 +245,7 @@ Influences the indentation of continuation lines. - + Qt::Vertical @@ -268,6 +258,48 @@ Influences the indentation of continuation lines. + + + + Backspace indentation: + + + + + + + <html><head/><body> +Specifies how backspace interacts with indentation. + +<ul> +<li>None: No interaction at all. Regular plain backspace behavior. +</li> + +<li>Follows Previous Indents: In leading white space it will take the cursor back to the nearest indentation level used in previous lines. +</li> + +<li>Unindents: If the character behind the cursor is a space it behaves as a backtab. +</li> +</ul></body></html> + + + + + None + + + + + Follows Previous Indents + + + + + Unindents + + + + @@ -279,7 +311,6 @@ Influences the indentation of continuation lines. tabSize indentSize autoIndent - smartBackspace continuationAlignBehavior tabKeyBehavior