TextEditor: add option to remember highlighter definition

Add a button to the multiple definition found info that saves the
definition of the current highlighter for the open document.

Change-Id: I04b1b7571a864d781747547a1d315ec25bb6b5a1
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
David Schulz
2019-02-07 13:40:39 +01:00
parent f6c276daf0
commit 8a0f7bcfd5
7 changed files with 145 additions and 13 deletions

View File

@@ -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<QString, QVariant> map = settings->value(id).toMap();
map.insert(mimeType, definition.name());
settings->setValue(id, map);
} else if (!fileExtension.isEmpty()) {
const QString id(kDefinitionForExtension);
QMap<QString, QVariant> map = settings->value(id).toMap();
map.insert(fileExtension, definition.name());
settings->setValue(id, map);
} else if (!path.isEmpty()) {
const QString id(kDefinitionForFilePath);
QMap<QString, QVariant> 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)

View File

@@ -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<Definition>;
@@ -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<void()> callback = nullptr);

View File

@@ -25,6 +25,8 @@
#include "highlightersettings.h"
#include "texteditorconstants.h"
#include <coreplugin/icore.h>
#include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h>
@@ -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))

View File

@@ -112,6 +112,9 @@ QWidget *HighlighterSettingsPage::widget()
label->setText(tr("Update finished"));
});
});
connect(m_d->m_page->resetCache, &QPushButton::clicked, []() {
Highlighter::clearDefintionForDocumentCache();
});
settingsToUI();
}

View File

@@ -110,6 +110,30 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="resetCache">
<property name="text">
<string>Reset Remembered Definitions</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>

View File

@@ -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<Highlighter *>(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());

View File

@@ -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";