forked from qt-creator/qt-creator
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:
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 ¤tBlock = 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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user