Editor: use detected indentation by default

This removes the undescribed Mixed tab settings option. It was unclear
and undocumented what this option actually means.

In theory this option tries to detect whether tabs or spaces are used
for indentation around a specific position in the document. This now
conflicts with the automatic auto detection which scans the complete
document. That auto detection not just detects whether tabs are used but
also the indent depth. Having a source document with a different indent
depth is arguably a more common use case than a source file with mixed
tabs and spaces for indentation. So in order to not confuse the user
with to many unclear magic options that might interfere with each other
the mixed tab settings option was removed in this change.

Fixes: QTCREATORBUG-11575
Fixes: QTCREATORBUG-11675
Fixes: QTCREATORBUG-19576
Fixes: QTCREATORBUG-25628
Change-Id: Ib95662ade38d0384d503e9a7b99f54ea4b416f68
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2024-11-27 15:13:04 +01:00
parent 6cdacdacef
commit 08a66b7780
11 changed files with 58 additions and 89 deletions

View File

@@ -78,14 +78,11 @@ std::optional<TabSettings> ClangFormatIndenter::tabSettings() const
TabSettings tabSettings; TabSettings tabSettings;
switch (style.UseTab) { switch (style.UseTab) {
case FormatStyle::UT_Never:
tabSettings.m_tabPolicy = TabSettings::SpacesOnlyTabPolicy;
break;
case FormatStyle::UT_Always: case FormatStyle::UT_Always:
tabSettings.m_tabPolicy = TabSettings::TabsOnlyTabPolicy; tabSettings.m_tabPolicy = TabSettings::TabsOnlyTabPolicy;
break; break;
default: default:
tabSettings.m_tabPolicy = TabSettings::MixedTabPolicy; tabSettings.m_tabPolicy = TabSettings::SpacesOnlyTabPolicy;
} }
tabSettings.m_tabSize = static_cast<int>(style.TabWidth); tabSettings.m_tabSize = static_cast<int>(style.TabWidth);

View File

@@ -246,13 +246,10 @@ void fromTabSettings(clang::format::FormatStyle &style, const TextEditor::TabSet
style.TabWidth = settings.m_tabSize; style.TabWidth = settings.m_tabSize;
switch (settings.m_tabPolicy) { switch (settings.m_tabPolicy) {
case TextEditor::TabSettings::TabPolicy::MixedTabPolicy: case TextEditor::TabSettings::SpacesOnlyTabPolicy:
style.UseTab = FormatStyle::UT_ForContinuationAndIndentation;
break;
case TextEditor::TabSettings::TabPolicy::SpacesOnlyTabPolicy:
style.UseTab = FormatStyle::UT_Never; style.UseTab = FormatStyle::UT_Never;
break; break;
case TextEditor::TabSettings::TabPolicy::TabsOnlyTabPolicy: case TextEditor::TabSettings::TabsOnlyTabPolicy:
style.UseTab = FormatStyle::UT_Always; style.UseTab = FormatStyle::UT_Always;
break; break;
} }

View File

@@ -106,8 +106,8 @@ CppToolsSettings::CppToolsSettings()
gnuCodeStyle->setDisplayName(Tr::tr("GNU")); gnuCodeStyle->setDisplayName(Tr::tr("GNU"));
gnuCodeStyle->setReadOnly(true); gnuCodeStyle->setReadOnly(true);
TabSettings gnuTabSettings; TabSettings gnuTabSettings;
gnuTabSettings.m_tabPolicy = TabSettings::MixedTabPolicy; gnuTabSettings.m_tabPolicy = TabSettings::TabsOnlyTabPolicy;
gnuTabSettings.m_tabSize = 8; gnuTabSettings.m_tabSize = 2;
gnuTabSettings.m_indentSize = 2; gnuTabSettings.m_indentSize = 2;
gnuTabSettings.m_continuationAlignBehavior = TabSettings::ContinuationAlignWithIndent; gnuTabSettings.m_continuationAlignBehavior = TabSettings::ContinuationAlignWithIndent;
gnuCodeStyle->setTabSettings(gnuTabSettings); gnuCodeStyle->setTabSettings(gnuTabSettings);

View File

@@ -324,7 +324,7 @@ private:
int lineIndentColumn = sts.indentationColumn(text) + columnOffset; int lineIndentColumn = sts.indentationColumn(text) + columnOffset;
text.replace(0, text.replace(0,
TabSettings::firstNonSpace(text), TabSettings::firstNonSpace(text),
tts.indentationString(0, lineIndentColumn, 0, insertionBlock)); tts.indentationString(0, lineIndentColumn, 0));
} }
functionDoc += text; functionDoc += text;
} }

View File

@@ -9,7 +9,7 @@
#include <QTextDocument> #include <QTextDocument>
static const char spacesForTabsKey[] = "SpacesForTabs"; static const char spacesForTabsKey[] = "SpacesForTabs";
static const char autoSpacesForTabsKey[] = "AutoSpacesForTabs"; static const char autoDetectKey[] = "AutoDetect";
static const char tabSizeKey[] = "TabSize"; static const char tabSizeKey[] = "TabSize";
static const char indentSizeKey[] = "IndentSize"; static const char indentSizeKey[] = "IndentSize";
static const char paddingModeKey[] = "PaddingMode"; static const char paddingModeKey[] = "PaddingMode";
@@ -33,7 +33,7 @@ Store TabSettings::toMap() const
{ {
return { return {
{spacesForTabsKey, m_tabPolicy != TabsOnlyTabPolicy}, {spacesForTabsKey, m_tabPolicy != TabsOnlyTabPolicy},
{autoSpacesForTabsKey, m_tabPolicy == MixedTabPolicy}, {autoDetectKey, m_autoDetect},
{tabSizeKey, m_tabSize}, {tabSizeKey, m_tabSize},
{indentSizeKey, m_indentSize}, {indentSizeKey, m_indentSize},
{paddingModeKey, m_continuationAlignBehavior} {paddingModeKey, m_continuationAlignBehavior}
@@ -43,8 +43,8 @@ Store TabSettings::toMap() const
void TabSettings::fromMap(const Store &map) void TabSettings::fromMap(const Store &map)
{ {
const bool spacesForTabs = map.value(spacesForTabsKey, true).toBool(); const bool spacesForTabs = map.value(spacesForTabsKey, true).toBool();
const bool autoSpacesForTabs = map.value(autoSpacesForTabsKey, false).toBool(); m_autoDetect = map.value(autoDetectKey, true).toBool();
m_tabPolicy = spacesForTabs ? (autoSpacesForTabs ? MixedTabPolicy : SpacesOnlyTabPolicy) : TabsOnlyTabPolicy; m_tabPolicy = spacesForTabs ? SpacesOnlyTabPolicy : TabsOnlyTabPolicy;
m_tabSize = map.value(tabSizeKey, m_tabSize).toInt(); m_tabSize = map.value(tabSizeKey, m_tabSize).toInt();
m_indentSize = map.value(indentSizeKey, m_indentSize).toInt(); m_indentSize = map.value(indentSizeKey, m_indentSize).toInt();
m_continuationAlignBehavior = (ContinuationAlignBehavior) m_continuationAlignBehavior = (ContinuationAlignBehavior)
@@ -55,8 +55,7 @@ TabSettings TabSettings::autoDetect(const QTextDocument *document) const
{ {
QTC_ASSERT(document, return *this); QTC_ASSERT(document, return *this);
const int blockCount = document->blockCount(); if (!m_autoDetect)
if (blockCount < 10)
return *this; return *this;
int totalIndentations = 0; int totalIndentations = 0;
@@ -64,16 +63,15 @@ TabSettings TabSettings::autoDetect(const QTextDocument *document) const
QMap<int, int> indentCount; QMap<int, int> indentCount;
auto checkText = auto checkText =
[this, &totalIndentations, &indentCount, &indentationWithTabs](const QTextBlock &block) { [this, document, &totalIndentations, &indentCount, &indentationWithTabs](const QTextBlock &block) {
if (block.length() == 0) if (block.length() == 0)
return; return;
const QTextDocument *doc = block.document();
int pos = block.position(); int pos = block.position();
bool hasTabs = false; bool hasTabs = false;
int indentation = 0; int indentation = 0;
// iterate ove the characters in the document is faster since we do not have to allocate // iterate ove the characters in the document is faster since we do not have to allocate
// a string for each block text when we are only interested in the first few characters // a string for each block text when we are only interested in the first few characters
QChar c = doc->characterAt(pos); QChar c = document->characterAt(pos);
while (c.isSpace() && c != QChar::ParagraphSeparator) { while (c.isSpace() && c != QChar::ParagraphSeparator) {
if (c == QChar::Tabulation) { if (c == QChar::Tabulation) {
hasTabs = true; hasTabs = true;
@@ -81,7 +79,7 @@ TabSettings TabSettings::autoDetect(const QTextDocument *document) const
} else { } else {
++indentation; ++indentation;
} }
c = doc->characterAt(++pos); c = document->characterAt(++pos);
} }
// only track indentations that are at least 2 columns wide // only track indentations that are at least 2 columns wide
if (indentation > 1) { if (indentation > 1) {
@@ -92,6 +90,7 @@ TabSettings TabSettings::autoDetect(const QTextDocument *document) const
} }
}; };
const int blockCount = document->blockCount();
if (blockCount < 200) { if (blockCount < 200) {
// check the indentation of all blocks if the document is shorter than 200 lines // check the indentation of all blocks if the document is shorter than 200 lines
for (QTextBlock block = document->firstBlock(); block.isValid(); block = block.next()) for (QTextBlock block = document->firstBlock(); block.isValid(); block = block.next())
@@ -118,6 +117,9 @@ TabSettings TabSettings::autoDetect(const QTextDocument *document) const
} }
} }
if (indentCount.size() < 3)
return *this;
// find the most common indent // find the most common indent
int mostCommonIndent = 0; int mostCommonIndent = 0;
int mostCommonIndentCount = 0; int mostCommonIndentCount = 0;
@@ -222,7 +224,6 @@ bool TabSettings::isIndentationClean(const QTextBlock &block, const int indent)
int i = 0; int i = 0;
int spaceCount = 0; int spaceCount = 0;
QString text = block.text(); QString text = block.text();
bool spacesForTabs = guessSpacesForTabs(block);
while (i < text.size()) { while (i < text.size()) {
QChar c = text.at(i); QChar c = text.at(i);
if (!c.isSpace()) if (!c.isSpace())
@@ -231,13 +232,13 @@ bool TabSettings::isIndentationClean(const QTextBlock &block, const int indent)
if (c == QLatin1Char(' ')) { if (c == QLatin1Char(' ')) {
++spaceCount; ++spaceCount;
if (spaceCount == m_tabSize) if (spaceCount == m_tabSize)
if (!spacesForTabs) if (m_tabPolicy == TabsOnlyTabPolicy)
if ((m_continuationAlignBehavior != ContinuationAlignWithSpaces) || (i < indent)) if ((m_continuationAlignBehavior != ContinuationAlignWithSpaces) || (i < indent))
return false; return false;
if (spaceCount > indent && m_continuationAlignBehavior == NoContinuationAlign) if (spaceCount > indent && m_continuationAlignBehavior == NoContinuationAlign)
return false; return false;
} else if (c == QLatin1Char('\t')) { } else if (c == QLatin1Char('\t')) {
if (spacesForTabs || (spaceCount != 0)) if (m_tabPolicy == SpacesOnlyTabPolicy || (spaceCount != 0))
return false; return false;
if ((m_continuationAlignBehavior != ContinuationAlignWithIndent) && ((i + 1) * m_tabSize > indent)) if ((m_continuationAlignBehavior != ContinuationAlignWithIndent) && ((i + 1) * m_tabSize > indent))
return false; return false;
@@ -316,41 +317,10 @@ int TabSettings::indentedColumn(int column, bool doIndent) const
return qMax(0, aligned - m_indentSize); return qMax(0, aligned - m_indentSize);
} }
bool TabSettings::guessSpacesForTabs(const QTextBlock &block) const QString TabSettings::indentationString(int startColumn, int targetColumn, int padding) const
{
if (m_tabPolicy == MixedTabPolicy && block.isValid()) {
QTextBlock prev = block.previous();
QTextBlock next = block.next();
auto checkFirstChar =
[doc = block.document()](const QTextBlock &block) -> std::optional<bool> {
if (block.length() > 0) {
const QChar firstChar = doc->characterAt(block.position());
if (firstChar == QLatin1Char(' '))
return true;
if (firstChar == QLatin1Char('\t'))
return false;
}
return {};
};
for (int delta = 1; delta <= 100 && (prev.isValid() || next.isValid()); ++delta) {
if (auto result = checkFirstChar(prev))
return *result;
if (auto result = checkFirstChar(next))
return *result;
prev = prev.previous();
next = next.next();
}
}
return m_tabPolicy != TabsOnlyTabPolicy;
}
QString TabSettings::indentationString(int startColumn, int targetColumn, int padding,
const QTextBlock &block) const
{ {
targetColumn = qMax(startColumn, targetColumn); targetColumn = qMax(startColumn, targetColumn);
if (guessSpacesForTabs(block)) if (m_tabPolicy == SpacesOnlyTabPolicy)
return QString(targetColumn - startColumn, QLatin1Char(' ')); return QString(targetColumn - startColumn, QLatin1Char(' '));
QString s; QString s;
@@ -390,7 +360,7 @@ void TabSettings::indentLine(const QTextBlock &block, int newIndent, int padding
// if (indentationColumn(text) == newIndent) // if (indentationColumn(text) == newIndent)
// return; // return;
const QString indentString = indentationString(0, newIndent, padding, block); const QString indentString = indentationString(0, newIndent, padding);
if (oldBlockLength == indentString.length() && text == indentString) if (oldBlockLength == indentString.length() && text == indentString)
return; return;
@@ -419,7 +389,7 @@ void TabSettings::reindentLine(QTextBlock block, int delta) const
// user likes tabs for spaces and uses tabs for indentation, preserve padding // user likes tabs for spaces and uses tabs for indentation, preserve padding
if (m_tabPolicy == TabsOnlyTabPolicy && m_tabSize == m_indentSize) if (m_tabPolicy == TabsOnlyTabPolicy && m_tabSize == m_indentSize)
padding = qMin(maximumPadding(text), newIndent); padding = qMin(maximumPadding(text), newIndent);
const QString indentString = indentationString(0, newIndent, padding, block); const QString indentString = indentationString(0, newIndent, padding);
if (oldBlockLength == indentString.length() && text == indentString) if (oldBlockLength == indentString.length() && text == indentString)
return; return;
@@ -434,7 +404,8 @@ void TabSettings::reindentLine(QTextBlock block, int delta) const
bool TabSettings::equals(const TabSettings &ts) const bool TabSettings::equals(const TabSettings &ts) const
{ {
return m_tabPolicy == ts.m_tabPolicy return m_autoDetect == ts.m_autoDetect
&& m_tabPolicy == ts.m_tabPolicy
&& m_tabSize == ts.m_tabSize && m_tabSize == ts.m_tabSize
&& m_indentSize == ts.m_indentSize && m_indentSize == ts.m_indentSize
&& m_continuationAlignBehavior == ts.m_continuationAlignBehavior; && m_continuationAlignBehavior == ts.m_continuationAlignBehavior;

View File

@@ -20,11 +20,9 @@ namespace TextEditor {
class TEXTEDITORSUPPORT_EXPORT TabSettings class TEXTEDITORSUPPORT_EXPORT TabSettings
{ {
public: public:
enum TabPolicy { enum TabPolicy {
SpacesOnlyTabPolicy = 0, SpacesOnlyTabPolicy = 0,
TabsOnlyTabPolicy = 1, TabsOnlyTabPolicy
MixedTabPolicy = 2
}; };
// This enum must match the indexes of continuationAlignBehavior widget // This enum must match the indexes of continuationAlignBehavior widget
@@ -49,7 +47,7 @@ public:
int positionAtColumn(const QString &text, int column, int *offset = nullptr, bool allowOverstep = false) const; int positionAtColumn(const QString &text, int column, int *offset = nullptr, bool allowOverstep = false) const;
int columnCountForText(const QString &text, int startColumn = 0) const; int columnCountForText(const QString &text, int startColumn = 0) const;
int indentedColumn(int column, bool doIndent = true) const; int indentedColumn(int column, bool doIndent = true) const;
QString indentationString(int startColumn, int targetColumn, int padding, const QTextBlock &currentBlock = QTextBlock()) const; QString indentationString(int startColumn, int targetColumn, int padding) const;
int indentationColumn(const QString &text) const; int indentationColumn(const QString &text) const;
static int maximumPadding(const QString &text); static int maximumPadding(const QString &text);
@@ -57,7 +55,6 @@ public:
void reindentLine(QTextBlock block, int delta) const; void reindentLine(QTextBlock block, int delta) const;
bool isIndentationClean(const QTextBlock &block, const int indent) const; bool isIndentationClean(const QTextBlock &block, const int indent) const;
bool guessSpacesForTabs(const QTextBlock &block) const;
friend bool operator==(const TabSettings &t1, const TabSettings &t2) { return t1.equals(t2); } friend bool operator==(const TabSettings &t1, const TabSettings &t2) { return t1.equals(t2); }
friend bool operator!=(const TabSettings &t1, const TabSettings &t2) { return !t1.equals(t2); } friend bool operator!=(const TabSettings &t1, const TabSettings &t2) { return !t1.equals(t2); }
@@ -70,6 +67,7 @@ public:
static int trailingWhitespaces(const QString &text); static int trailingWhitespaces(const QString &text);
static void removeTrailingWhitespace(QTextCursor cursor, QTextBlock &block); static void removeTrailingWhitespace(QTextCursor cursor, QTextBlock &block);
bool m_autoDetect = true;
TabPolicy m_tabPolicy = SpacesOnlyTabPolicy; TabPolicy m_tabPolicy = SpacesOnlyTabPolicy;
int m_tabSize = 8; int m_tabSize = 8;
int m_indentSize = 4; int m_indentSize = 4;

View File

@@ -7,6 +7,7 @@
#include "texteditortr.h" #include "texteditortr.h"
#include <QApplication> #include <QApplication>
#include <QCheckBox>
#include <QComboBox> #include <QComboBox>
#include <QLabel> #include <QLabel>
#include <QSpinBox> #include <QSpinBox>
@@ -60,17 +61,22 @@ TabSettingsWidget::TabSettingsWidget(QWidget *parent) :
Tr::tr("The text editor indentation setting is used for non-code files only. See the C++ " Tr::tr("The text editor indentation setting is used for non-code files only. See the C++ "
"and Qt Quick coding style settings to configure indentation for code files.")); "and Qt Quick coding style settings to configure indentation for code files."));
m_autoDetect = new QCheckBox(Tr::tr("Auto detect"), this);
m_autoDetect->setToolTip(
Tr::tr("%1 tries to detect the indentation settings based on the file contents. It "
"will fallback to the settings below if the detection fails.")
.arg(QGuiApplication::applicationDisplayName()));
m_tabPolicy = new QComboBox(this); m_tabPolicy = new QComboBox(this);
m_tabPolicy->addItem(Tr::tr("Spaces Only")); m_tabPolicy->addItem(Tr::tr("Spaces Only"));
m_tabPolicy->addItem(Tr::tr("Tabs Only")); m_tabPolicy->addItem(Tr::tr("Tabs Only"));
m_tabPolicy->addItem(Tr::tr("Mixed"));
auto tabSizeLabel = new QLabel(Tr::tr("Ta&b size:")); auto tabSizeLabel = new QLabel(Tr::tr("Ta&b size:"));
m_tabSize = new QSpinBox(this); m_tabSize = new QSpinBox(this);
m_tabSize->setRange(1, 20); m_tabSize->setRange(1, 20);
auto indentSizeLabel = new QLabel(Tr::tr("&Indent size:")); auto indentSizeLabel = new QLabel(Tr::tr("Default &indent size:"));
m_indentSize = new QSpinBox(this); m_indentSize = new QSpinBox(this);
m_indentSize->setRange(1, 20); m_indentSize->setRange(1, 20);
@@ -89,15 +95,18 @@ TabSettingsWidget::TabSettingsWidget(QWidget *parent) :
Row { Row {
Form { Form {
m_codingStyleWarning, br, m_codingStyleWarning, br,
Tr::tr("Tab policy:"), m_tabPolicy, br, m_autoDetect, br,
tabSizeLabel, m_tabSize, br, Tr::tr("Default tab policy:"), m_tabPolicy, br,
indentSizeLabel, m_indentSize, br, indentSizeLabel, m_indentSize, br,
tabSizeLabel, m_tabSize, br,
Tr::tr("Align continuation lines:"), m_continuationAlignBehavior, br Tr::tr("Align continuation lines:"), m_continuationAlignBehavior, br
}, st }, st
}.attachTo(this); }.attachTo(this);
connect(m_codingStyleWarning, &QLabel::linkActivated, connect(m_codingStyleWarning, &QLabel::linkActivated,
this, &TabSettingsWidget::codingStyleLinkActivated); this, &TabSettingsWidget::codingStyleLinkActivated);
connect(m_autoDetect, &QCheckBox::stateChanged,
this, &TabSettingsWidget::slotSettingsChanged);
connect(m_tabPolicy, &QComboBox::currentIndexChanged, connect(m_tabPolicy, &QComboBox::currentIndexChanged,
this, &TabSettingsWidget::slotSettingsChanged); this, &TabSettingsWidget::slotSettingsChanged);
connect(m_tabSize, &QSpinBox::valueChanged, connect(m_tabSize, &QSpinBox::valueChanged,
@@ -113,7 +122,7 @@ TabSettingsWidget::~TabSettingsWidget() = default;
void TabSettingsWidget::setTabSettings(const TabSettings &s) void TabSettingsWidget::setTabSettings(const TabSettings &s)
{ {
QSignalBlocker blocker(this); QSignalBlocker blocker(this);
m_tabPolicy->setCurrentIndex(s.m_tabPolicy); m_tabPolicy->setCurrentIndex(int(s.m_tabPolicy));
m_tabSize->setValue(s.m_tabSize); m_tabSize->setValue(s.m_tabSize);
m_indentSize->setValue(s.m_indentSize); m_indentSize->setValue(s.m_indentSize);
m_continuationAlignBehavior->setCurrentIndex(s.m_continuationAlignBehavior); m_continuationAlignBehavior->setCurrentIndex(s.m_continuationAlignBehavior);

View File

@@ -8,6 +8,7 @@
#include <QGroupBox> #include <QGroupBox>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QCheckBox;
class QComboBox; class QComboBox;
class QLabel; class QLabel;
class QSpinBox; class QSpinBox;
@@ -44,6 +45,7 @@ private:
void codingStyleLinkActivated(const QString &linkString); void codingStyleLinkActivated(const QString &linkString);
QLabel *m_codingStyleWarning; QLabel *m_codingStyleWarning;
QCheckBox *m_autoDetect;
QComboBox *m_tabPolicy; QComboBox *m_tabPolicy;
QSpinBox *m_tabSize; QSpinBox *m_tabSize;
QSpinBox *m_indentSize; QSpinBox *m_indentSize;

View File

@@ -153,7 +153,7 @@ MultiTextCursor TextDocumentPrivate::indentOrUnindent(const MultiTextCursor &cur
= tabSettings.indentedColumn(tabSettings.columnAt(text, indentPosition), = tabSettings.indentedColumn(tabSettings.columnAt(text, indentPosition),
doIndent); doIndent);
cursor.setPosition(block.position() + indentPosition); cursor.setPosition(block.position() + indentPosition);
cursor.insertText(tabSettings.indentationString(0, targetColumn, 0, block)); cursor.insertText(tabSettings.indentationString(0, targetColumn, 0));
cursor.setPosition(block.position()); cursor.setPosition(block.position());
cursor.setPosition(block.position() + indentPosition, QTextCursor::KeepAnchor); cursor.setPosition(block.position() + indentPosition, QTextCursor::KeepAnchor);
cursor.removeSelectedText(); cursor.removeSelectedText();
@@ -184,7 +184,7 @@ MultiTextCursor TextDocumentPrivate::indentOrUnindent(const MultiTextCursor &cur
QTextCursor::KeepAnchor); QTextCursor::KeepAnchor);
cursor.removeSelectedText(); cursor.removeSelectedText();
cursor.insertText( cursor.insertText(
tabSettings.indentationString(startColumn, targetColumn, 0, startBlock)); tabSettings.indentationString(startColumn, targetColumn, 0));
} }
cursor.endEditBlock(); cursor.endEditBlock();
@@ -367,13 +367,13 @@ const StorageSettings &TextDocument::storageSettings() const
return d->m_storageSettings; return d->m_storageSettings;
} }
void TextDocument::setTabSettings(const TabSettings &newTabSettings) void TextDocument::setTabSettings(const TabSettings &tabSettings)
{ {
if (newTabSettings == d->m_tabSettings) if (const TabSettings candidate = tabSettings.autoDetect(document());
return; candidate != d->m_tabSettings) {
d->m_tabSettings = newTabSettings; d->m_tabSettings = candidate;
emit tabSettingsChanged(); emit tabSettingsChanged();
}
} }
TabSettings TextDocument::tabSettings() const TabSettings TextDocument::tabSettings() const
@@ -752,6 +752,7 @@ Core::IDocument::OpenResult TextDocument::open(QString *errorString,
OpenResult success = openImpl(errorString, filePath, realFilePath, /*reload =*/ false); OpenResult success = openImpl(errorString, filePath, realFilePath, /*reload =*/ false);
if (success == OpenResult::Success) { if (success == OpenResult::Success) {
setMimeType(Utils::mimeTypeForFile(filePath, MimeMatchMode::MatchDefaultAndRemote).name()); setMimeType(Utils::mimeTypeForFile(filePath, MimeMatchMode::MatchDefaultAndRemote).name());
setTabSettings(d->m_tabSettings);
emit openFinishedSuccessfully(); emit openFinishedSuccessfully();
} }
return success; return success;
@@ -960,8 +961,7 @@ void TextDocument::cleanWhitespace(QTextCursor &cursor, bool inEntireDocument,
} else { } else {
int column = currentTabSettings.columnAt(blockText, firstNonSpace); int column = currentTabSettings.columnAt(blockText, firstNonSpace);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, firstNonSpace); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, firstNonSpace);
QString indentationString = currentTabSettings.indentationString(0, column, column - indent, block); cursor.insertText(currentTabSettings.indentationString(0, column, column - indent));
cursor.insertText(indentationString);
} }
} }
} }

View File

@@ -302,9 +302,6 @@ private:
case TabSettings::TabsOnlyTabPolicy: case TabSettings::TabsOnlyTabPolicy:
policy = Tr::tr("Tabs"); policy = Tr::tr("Tabs");
break; break;
case TabSettings::MixedTabPolicy:
policy = Tr::tr("Mixed");
break;
} }
setText(QString("%1: %2").arg(policy).arg(ts.m_indentSize)); setText(QString("%1: %2").arg(policy).arg(ts.m_indentSize));
} }
@@ -321,6 +318,7 @@ private:
[this](std::function<void(TabSettings & tabSettings)> modifier) { [this](std::function<void(TabSettings & tabSettings)> modifier) {
return [this, modifier]() { return [this, modifier]() {
auto ts = m_doc->tabSettings(); auto ts = m_doc->tabSettings();
ts.m_autoDetect = false;
modifier(ts); modifier(ts);
m_doc->setTabSettings(ts); m_doc->setTabSettings(ts);
}; };
@@ -328,7 +326,7 @@ private:
documentSettings->addAction( documentSettings->addAction(
Tr::tr("Auto detect"), Tr::tr("Auto detect"),
modifyTabSettings([doc = m_doc->document()](TabSettings &tabSettings) { modifyTabSettings([doc = m_doc->document()](TabSettings &tabSettings) {
tabSettings = tabSettings.autoDetect(doc); tabSettings.m_autoDetect = true;
})); }));
auto tabSettings = documentSettings->addMenu(Tr::tr("Tab Settings")); auto tabSettings = documentSettings->addMenu(Tr::tr("Tab Settings"));
tabSettings->addAction(Tr::tr("Spaces"), modifyTabSettings([](TabSettings &tabSettings) { tabSettings->addAction(Tr::tr("Spaces"), modifyTabSettings([](TabSettings &tabSettings) {
@@ -8999,7 +8997,7 @@ void TextEditorWidget::rewrapParagraph()
QString spacing; QString spacing;
if (commonPrefix.isEmpty()) { if (commonPrefix.isEmpty()) {
spacing = ts.indentationString(0, indentLevel, 0, textCursor().block()); spacing = ts.indentationString(0, indentLevel, 0);
} else { } else {
spacing = commonPrefix; spacing = commonPrefix;
indentLevel = ts.columnCountForText(spacing); indentLevel = ts.columnCountForText(spacing);

View File

@@ -17,8 +17,6 @@ static QString tabPolicyToString(TabSettings::TabPolicy policy)
return QLatin1String("spacesOnlyPolicy"); return QLatin1String("spacesOnlyPolicy");
case TabSettings::TabsOnlyTabPolicy: case TabSettings::TabsOnlyTabPolicy:
return QLatin1String("tabsOnlyPolicy"); return QLatin1String("tabsOnlyPolicy");
case TabSettings::MixedTabPolicy:
return QLatin1String("mixedIndentPolicy");
} }
return QString(); return QString();
} }
@@ -49,7 +47,6 @@ static void generateTestRows(const QLatin1String &name, const QString &text, IsC
const QVector<TabSettings::TabPolicy> allPolicies = { const QVector<TabSettings::TabPolicy> allPolicies = {
TabSettings::SpacesOnlyTabPolicy, TabSettings::SpacesOnlyTabPolicy,
TabSettings::TabsOnlyTabPolicy, TabSettings::TabsOnlyTabPolicy,
TabSettings::MixedTabPolicy
}; };
const QVector<TabSettings::ContinuationAlignBehavior> allbehaviors = { const QVector<TabSettings::ContinuationAlignBehavior> allbehaviors = {
TabSettings::NoContinuationAlign, TabSettings::NoContinuationAlign,