Beautifier: Fix clang-format's custom style handling

Instead of dealing with clang-format's YAML format use proper command
line parameters.

Task-number: QTCREATORBUG-15604
Change-Id: Ie0b22aff105c8d208d30e2e945b0036b0b8606c1
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
Lorenz Haas
2016-03-16 21:17:10 +01:00
committed by Lorenz Haas
parent e63f503592
commit 3310fbc8f2
6 changed files with 70 additions and 49 deletions

View File

@@ -41,11 +41,11 @@ namespace Internal {
AbstractSettings::AbstractSettings(const QString &name, const QString &ending) AbstractSettings::AbstractSettings(const QString &name, const QString &ending)
: m_version(0) : m_version(0)
, m_name(name)
, m_ending(ending) , m_ending(ending)
, m_styleDir(Core::ICore::userResourcePath() + QLatin1Char('/') , m_styleDir(Core::ICore::userResourcePath() + QLatin1Char('/')
+ QLatin1String(Beautifier::Constants::SETTINGS_DIRNAME) + QLatin1Char('/') + QLatin1String(Beautifier::Constants::SETTINGS_DIRNAME) + QLatin1Char('/')
+ m_name) + name)
, m_name(name)
{ {
} }
@@ -97,7 +97,7 @@ void AbstractSettings::setStyle(const QString &key, const QString &value)
void AbstractSettings::removeStyle(const QString &key) void AbstractSettings::removeStyle(const QString &key)
{ {
m_styles.remove(key); m_styles.remove(key);
m_stylesToRemove << key + m_ending; m_stylesToRemove << key;
} }
void AbstractSettings::replaceStyle(const QString &oldKey, const QString &newKey, void AbstractSettings::replaceStyle(const QString &oldKey, const QString &newKey,
@@ -178,18 +178,13 @@ void AbstractSettings::save()
if (m_stylesToRemove.isEmpty() && m_styles.isEmpty()) if (m_stylesToRemove.isEmpty() && m_styles.isEmpty())
return; return;
if (!m_styleDir.exists()) { // remove old files and possible subfolder
const QString path = m_styleDir.absolutePath(); foreach (const QString &key, m_stylesToRemove) {
if (!(m_styleDir.mkpath(path) const QFileInfo fi(styleFileName(key));
&& m_styleDir.cd(path))) { QFile::remove(fi.absoluteFilePath());
BeautifierPlugin::showError(tr("Cannot save styles. %1 does not exist.").arg(path)); if (fi.absoluteDir() != m_styleDir)
return; m_styleDir.rmdir(fi.absolutePath());
}
} }
// remove old files
foreach (const QString &file, m_stylesToRemove)
m_styleDir.remove(file);
m_stylesToRemove.clear(); m_stylesToRemove.clear();
QMap<QString, QString>::const_iterator iStyles = m_styles.constBegin(); QMap<QString, QString>::const_iterator iStyles = m_styles.constBegin();
@@ -200,7 +195,14 @@ void AbstractSettings::save()
continue; continue;
} }
Utils::FileSaver saver(styleFileName(iStyles.key())); const QFileInfo fi(styleFileName(iStyles.key()));
if (!(m_styleDir.mkpath(fi.absolutePath()))) {
BeautifierPlugin::showError(tr("Cannot save styles. %1 does not exist.")
.arg(fi.absolutePath()));
continue;
}
Utils::FileSaver saver(fi.absoluteFilePath());
if (saver.hasError()) { if (saver.hasError()) {
BeautifierPlugin::showError(tr("Cannot open file \"%1\": %2.") BeautifierPlugin::showError(tr("Cannot open file \"%1\": %2.")
.arg(saver.fileName()) .arg(saver.fileName())
@@ -242,29 +244,10 @@ void AbstractSettings::read()
s->endGroup(); s->endGroup();
s->endGroup(); s->endGroup();
// Read styles
if (!m_styleDir.exists())
return;
m_stylesToRemove.clear();
m_styles.clear(); m_styles.clear();
const QStringList files
= m_styleDir.entryList(QStringList() << QLatin1Char('*') + m_ending,
QDir::Files | QDir::Readable | QDir::NoDotAndDotDot);
foreach (const QString &filename, files) {
// do not allow empty file names
if (filename == m_ending)
continue;
QFile file(m_styleDir.absoluteFilePath(filename));
if (file.open(QIODevice::ReadOnly)) {
m_styles.insert(filename.left(filename.length() - m_ending.length()),
QString::fromLocal8Bit(file.readAll()));
}
}
m_changedStyles.clear(); m_changedStyles.clear();
m_stylesToRemove.clear(); m_stylesToRemove.clear();
readStyles();
} }
void AbstractSettings::readDocumentation() void AbstractSettings::readDocumentation()
@@ -324,5 +307,26 @@ void AbstractSettings::readDocumentation()
} }
} }
void AbstractSettings::readStyles()
{
if (!m_styleDir.exists())
return;
const QStringList files
= m_styleDir.entryList(QStringList() << QLatin1Char('*') + m_ending,
QDir::Files | QDir::Readable | QDir::NoDotAndDotDot);
foreach (const QString &filename, files) {
// do not allow empty file names
if (filename == m_ending)
continue;
QFile file(m_styleDir.absoluteFilePath(filename));
if (file.open(QIODevice::ReadOnly)) {
m_styles.insert(filename.left(filename.length() - m_ending.length()),
QString::fromLocal8Bit(file.readAll()));
}
}
}
} // namespace Internal } // namespace Internal
} // namespace Beautifier } // namespace Beautifier

View File

@@ -59,7 +59,7 @@ public:
void setStyle(const QString &key, const QString &value); void setStyle(const QString &key, const QString &value);
void removeStyle(const QString &key); void removeStyle(const QString &key);
void replaceStyle(const QString &oldKey, const QString &newKey, const QString &value); void replaceStyle(const QString &oldKey, const QString &newKey, const QString &value);
QString styleFileName(const QString &key) const; virtual QString styleFileName(const QString &key) const;
QString command() const; QString command() const;
void setCommand(const QString &command); void setCommand(const QString &command);
@@ -73,13 +73,14 @@ protected:
QMap<QString, QString> m_styles; QMap<QString, QString> m_styles;
QMap<QString, QVariant> m_settings; QMap<QString, QVariant> m_settings;
int m_version; int m_version;
QString m_ending;
QDir m_styleDir;
void readDocumentation(); void readDocumentation();
virtual void readStyles();
private: private:
QString m_name; QString m_name;
QString m_ending;
QDir m_styleDir;
QStringList m_stylesToRemove; QStringList m_stylesToRemove;
QSet<QString> m_changedStyles; QSet<QString> m_changedStyles;
QString m_command; QString m_command;

View File

@@ -119,6 +119,7 @@ FormatTask format(FormatTask task)
case Command::PipeProcessing: { case Command::PipeProcessing: {
QProcess process; QProcess process;
QStringList options = task.command.options(); QStringList options = task.command.options();
options.replaceInStrings(QLatin1String("%filename"), QFileInfo(task.filePath).fileName());
options.replaceInStrings(QLatin1String("%file"), task.filePath); options.replaceInStrings(QLatin1String("%file"), task.filePath);
process.start(executable, options); process.start(executable, options);
if (!process.waitForStarted(3000)) { if (!process.waitForStarted(3000)) {

View File

@@ -132,23 +132,19 @@ Command ClangFormat::command(int offset, int length) const
if (m_settings->usePredefinedStyle()) { if (m_settings->usePredefinedStyle()) {
command.addOption(QLatin1String("-style=") + m_settings->predefinedStyle()); command.addOption(QLatin1String("-style=") + m_settings->predefinedStyle());
command.addOption(QLatin1String("-assume-filename=%filename"));
} else { } else {
// The clang-format option file is YAML command.addOption(QLatin1String("-style=file"));
const QStringList lines = m_settings->style(m_settings->customStyle()) const QString path =
.split(QLatin1Char('\n'), QString::SkipEmptyParts); QFileInfo(m_settings->styleFileName(m_settings->customStyle())).absolutePath();
const QStringList options = Utils::filtered(lines, [](const QString &s) -> bool { command.addOption(QLatin1String("-assume-filename=") + path + QDir::separator()
const QString option = s.trimmed(); + QLatin1String("%filename"));
return !(option.startsWith(QLatin1Char('#')) || option == QLatin1String("---"));
});
command.addOption(QLatin1String("-style={") + options.join(QLatin1String(", "))
+ QLatin1Char('}'));
} }
if (offset != -1) { if (offset != -1) {
command.addOption(QLatin1String("-offset=") + QString::number(offset)); command.addOption(QLatin1String("-offset=") + QString::number(offset));
command.addOption(QLatin1String("-length=") + QString::number(length)); command.addOption(QLatin1String("-length=") + QString::number(length));
} }
command.addOption(QLatin1String("-assume-filename=%file"));
return command; return command;
} }

View File

@@ -48,7 +48,6 @@ const char kFormatEntireFileFallback[] = "formatEntireFileFallback";
ClangFormatSettings::ClangFormatSettings() : ClangFormatSettings::ClangFormatSettings() :
AbstractSettings(QLatin1String(Constants::ClangFormat::SETTINGS_NAME), AbstractSettings(QLatin1String(Constants::ClangFormat::SETTINGS_NAME),
QLatin1String(".clang-format")) QLatin1String(".clang-format"))
{ {
setCommand(QLatin1String("clang-format")); setCommand(QLatin1String("clang-format"));
m_settings.insert(QLatin1String(kUsePredefinedStyle), QVariant(true)); m_settings.insert(QLatin1String(kUsePredefinedStyle), QVariant(true));
@@ -225,6 +224,21 @@ QStringList ClangFormatSettings::predefinedStyles() const
<< QLatin1String("File"); << QLatin1String("File");
} }
QString ClangFormatSettings::styleFileName(const QString &key) const
{
return m_styleDir.absolutePath() + QLatin1Char('/') + key + QLatin1Char('/') + m_ending;
}
void ClangFormatSettings::readStyles()
{
const QStringList dirs = m_styleDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
for (const QString &dir : dirs) {
QFile file(m_styleDir.absoluteFilePath(dir + QLatin1Char('/') + m_ending));
if (file.open(QIODevice::ReadOnly))
m_styles.insert(dir, QString::fromLocal8Bit(file.readAll()));
}
}
} // namespace ClangFormat } // namespace ClangFormat
} // namespace Internal } // namespace Internal
} // namespace Beautifier } // namespace Beautifier

View File

@@ -57,6 +57,11 @@ public:
void setFormatEntireFileFallback(bool formatEntireFileFallback); void setFormatEntireFileFallback(bool formatEntireFileFallback);
QStringList predefinedStyles() const; QStringList predefinedStyles() const;
QString styleFileName(const QString &key) const override;
private:
void readStyles() override;
}; };
} // namespace ClangFormat } // namespace ClangFormat