diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp index 857c0f88cc7..b21af3644c8 100644 --- a/src/plugins/texteditor/highlighter.cpp +++ b/src/plugins/texteditor/highlighter.cpp @@ -43,6 +43,10 @@ using namespace TextEditor; +static const char kDefinitionForMimeType[] = "definitionForMimeType"; +static const char kDefinitionForExtension[] = "definitionForExtension"; +static const char kDefinitionForFilePath[] = "definitionForFilePath"; + KSyntaxHighlighting::Repository *highlightRepository() { static KSyntaxHighlighting::Repository *repository = nullptr; @@ -107,18 +111,24 @@ Highlighter::Definition Highlighter::definitionForDocument(const TextDocument *d if (mimeType.isValid()) definition = Highlighter::definitionForMimeType(mimeType.name()); if (!definition.isValid()) - definition = Highlighter::definitionForFileName(document->filePath().fileName()); + definition = Highlighter::definitionForFilePath(document->filePath()); return definition; } Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType) { + const Definitions definitions = definitionsForMimeType(mimeType); + if (definitions.size() == 1) + return definitions.first(); return highlightRepository()->definitionForMimeType(mimeType); } -Highlighter::Definition Highlighter::definitionForFileName(const QString &fileName) +Highlighter::Definition Highlighter::definitionForFilePath(const Utils::FileName &fileName) { - return highlightRepository()->definitionForFileName(fileName); + const Definitions definitions = definitionsForFileName(fileName); + if (definitions.size() == 1) + return definitions.first(); + return highlightRepository()->definitionForFileName(fileName.fileName()); } Highlighter::Definition Highlighter::definitionForName(const QString &name) @@ -133,18 +143,88 @@ Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument if (mimeType.isValid()) definitions = Highlighter::definitionsForMimeType(mimeType.name()); if (definitions.isEmpty()) - definitions = Highlighter::definitionsForFileName(document->filePath().fileName()); + definitions = Highlighter::definitionsForFileName(document->filePath()); return definitions; } +static Highlighter::Definition definitionForSetting(const QString &settingsKey, + const QString &mapKey) +{ + QSettings *settings = Core::ICore::settings(); + settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); + const QString &definitionName = settings->value(settingsKey).toMap().value(mapKey).toString(); + settings->endGroup(); + return Highlighter::definitionForName(definitionName); +} + Highlighter::Definitions Highlighter::definitionsForMimeType(const QString &mimeType) { - return highlightRepository()->definitionsForMimeType(mimeType).toList(); + Definitions definitions = highlightRepository()->definitionsForMimeType(mimeType).toList(); + if (definitions.size() > 1) { + const Definition &rememberedDefinition = definitionForSetting(kDefinitionForMimeType, + mimeType); + if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition)) + definitions = {rememberedDefinition}; + } + return definitions; } -Highlighter::Definitions Highlighter::definitionsForFileName(const QString &fileName) +Highlighter::Definitions Highlighter::definitionsForFileName(const Utils::FileName &fileName) { - return highlightRepository()->definitionsForFileName(fileName).toList(); + Definitions definitions + = highlightRepository()->definitionsForFileName(fileName.fileName()).toList(); + + if (definitions.size() > 1) { + const QString &fileExtension = fileName.toFileInfo().completeSuffix(); + const Definition &rememberedDefinition + = fileExtension.isEmpty() + ? definitionForSetting(kDefinitionForFilePath, + fileName.toFileInfo().canonicalFilePath()) + : definitionForSetting(kDefinitionForExtension, fileExtension); + if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition)) + definitions = {rememberedDefinition}; + } + + return definitions; +} + +void Highlighter::rememberDefintionForDocument(const Highlighter::Definition &definition, + const TextDocument *document) +{ + if (!definition.isValid()) + return; + const QString &mimeType = document->mimeType(); + const QString &fileExtension = document->filePath().toFileInfo().completeSuffix(); + const QString &path = document->filePath().toFileInfo().canonicalFilePath(); + QSettings *settings = Core::ICore::settings(); + settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); + if (!mimeType.isEmpty()) { + const QString id(kDefinitionForMimeType); + QMap map = settings->value(id).toMap(); + map.insert(mimeType, definition.name()); + settings->setValue(id, map); + } else if (!fileExtension.isEmpty()) { + const QString id(kDefinitionForExtension); + QMap map = settings->value(id).toMap(); + map.insert(fileExtension, definition.name()); + settings->setValue(id, map); + } else if (!path.isEmpty()) { + const QString id(kDefinitionForFilePath); + QMap map = settings->value(id).toMap(); + map.insert(document->filePath().toFileInfo().absoluteFilePath(), definition.name()); + settings->setValue(id, map); + } + settings->endGroup(); +} + +void Highlighter::clearDefintionForDocumentCache() +{ + QSettings *settings = Core::ICore::settings(); + settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); + settings->remove(kDefinitionForMimeType); + settings->remove(kDefinitionForExtension); + settings->remove(kDefinitionForFilePath); + settings->endGroup(); } void Highlighter::addCustomHighlighterPath(const Utils::FileName &path) diff --git a/src/plugins/texteditor/highlighter.h b/src/plugins/texteditor/highlighter.h index 776f92faf35..92e7e136c18 100644 --- a/src/plugins/texteditor/highlighter.h +++ b/src/plugins/texteditor/highlighter.h @@ -38,6 +38,8 @@ class TextDocument; class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter { + Q_OBJECT + Q_INTERFACES(KSyntaxHighlighting::AbstractHighlighter) public: using Definition = KSyntaxHighlighting::Definition; using Definitions = QList; @@ -45,12 +47,16 @@ public: static Definition definitionForDocument(const TextDocument *document); static Definition definitionForMimeType(const QString &mimeType); - static Definition definitionForFileName(const QString &fileName); + static Definition definitionForFilePath(const Utils::FileName &fileName); static Definition definitionForName(const QString &name); static Definitions definitionsForDocument(const TextDocument *document); static Definitions definitionsForMimeType(const QString &mimeType); - static Definitions definitionsForFileName(const QString &fileName); + static Definitions definitionsForFileName(const Utils::FileName &fileName); + + static void rememberDefintionForDocument(const Definition &definition, + const TextDocument *document); + static void clearDefintionForDocumentCache(); static void addCustomHighlighterPath(const Utils::FileName &path); static void updateDefinitions(std::function callback = nullptr); diff --git a/src/plugins/texteditor/highlightersettings.cpp b/src/plugins/texteditor/highlightersettings.cpp index 76b88b063ab..84afbd79ded 100644 --- a/src/plugins/texteditor/highlightersettings.cpp +++ b/src/plugins/texteditor/highlightersettings.cpp @@ -25,6 +25,8 @@ #include "highlightersettings.h" +#include "texteditorconstants.h" + #include #include #include @@ -97,7 +99,6 @@ namespace { static const QLatin1String kDefinitionFilesPath("UserDefinitionFilesPath"); static const QLatin1String kIgnoredFilesPatterns("IgnoredFilesPatterns"); -static const QLatin1String kGroupPostfix("HighlighterSettings"); QString groupSpecifier(const QString &postFix, const QString &category) { @@ -113,7 +114,7 @@ using namespace Internal; void HighlighterSettings::toSettings(const QString &category, QSettings *s) const { - const QString &group = groupSpecifier(kGroupPostfix, category); + const QString &group = groupSpecifier(Constants::HIGHLIGHTER_SETTINGS_CATEGORY, category); s->beginGroup(group); s->setValue(kDefinitionFilesPath, m_definitionFilesPath); s->setValue(kIgnoredFilesPatterns, ignoredFilesPatterns()); @@ -122,7 +123,7 @@ void HighlighterSettings::toSettings(const QString &category, QSettings *s) cons void HighlighterSettings::fromSettings(const QString &category, QSettings *s) { - const QString &group = groupSpecifier(kGroupPostfix, category); + const QString &group = groupSpecifier(Constants::HIGHLIGHTER_SETTINGS_CATEGORY, category); s->beginGroup(group); m_definitionFilesPath = s->value(kDefinitionFilesPath, QString()).toString(); if (!s->contains(kDefinitionFilesPath)) diff --git a/src/plugins/texteditor/highlightersettingspage.cpp b/src/plugins/texteditor/highlightersettingspage.cpp index ec9d34ee65c..86a1a7fdbf3 100644 --- a/src/plugins/texteditor/highlightersettingspage.cpp +++ b/src/plugins/texteditor/highlightersettingspage.cpp @@ -112,6 +112,9 @@ QWidget *HighlighterSettingsPage::widget() label->setText(tr("Update finished")); }); }); + connect(m_d->m_page->resetCache, &QPushButton::clicked, []() { + Highlighter::clearDefintionForDocumentCache(); + }); settingsToUI(); } diff --git a/src/plugins/texteditor/highlightersettingspage.ui b/src/plugins/texteditor/highlightersettingspage.ui index bcc5d5fe11b..fcd4919b128 100644 --- a/src/plugins/texteditor/highlightersettingspage.ui +++ b/src/plugins/texteditor/highlightersettingspage.ui @@ -110,6 +110,30 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Reset Remembered Definitions + + + + + diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 235ac7f673e..0d92b2d16f1 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -613,6 +613,7 @@ public: void reconfigure(); void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName); void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition); + void rememberCurrentSyntaxDefinition(); public: TextEditorWidget *q; @@ -3306,6 +3307,11 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions this->configureGenericHighlighter(Highlighter::definitionForName(definition)); }); + info.setCustomButtonInfo(BaseTextEditor::tr("Remember My Choice"), [multiple, this]() { + m_document->infoBar()->removeInfo(multiple); + rememberCurrentSyntaxDefinition(); + }); + infoBar->removeInfo(missing); infoBar->addInfo(info); } else { @@ -3333,6 +3339,16 @@ void TextEditorWidgetPrivate::configureGenericHighlighter( m_document->setFontSettings(TextEditorSettings::fontSettings()); } +void TextEditorWidgetPrivate::rememberCurrentSyntaxDefinition() +{ + auto highlighter = qobject_cast(m_document->syntaxHighlighter()); + if (!highlighter) + return; + const Highlighter::Definition &definition = highlighter->definition(); + if (definition.isValid()) + Highlighter::rememberDefintionForDocument(definition, m_document.data()); +} + bool TextEditorWidget::codeFoldingVisible() const { return d->m_codeFoldingVisible; @@ -8543,7 +8559,7 @@ QString TextEditorWidget::textAt(int from, int to) const void TextEditorWidget::configureGenericHighlighter() { - const Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument()); + Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument()); d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition() : definitions.first()); d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName()); diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index 949b4934570..78c9c1cb714 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -214,6 +214,8 @@ const char TEXT_EDITOR_DISPLAY_SETTINGS[] = "D.DisplaySettings"; const char TEXT_EDITOR_HIGHLIGHTER_SETTINGS[] = "E.HighlighterSettings"; const char TEXT_EDITOR_SNIPPETS_SETTINGS[] = "F.SnippetsSettings"; +const char HIGHLIGHTER_SETTINGS_CATEGORY[] = "HighlighterSettings"; + const char SNIPPET_EDITOR_ID[] = "TextEditor.SnippetEditor"; const char TEXT_SNIPPET_GROUP_ID[] = "Text";