forked from qt-creator/qt-creator
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:
@@ -43,6 +43,10 @@
|
|||||||
|
|
||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
|
|
||||||
|
static const char kDefinitionForMimeType[] = "definitionForMimeType";
|
||||||
|
static const char kDefinitionForExtension[] = "definitionForExtension";
|
||||||
|
static const char kDefinitionForFilePath[] = "definitionForFilePath";
|
||||||
|
|
||||||
KSyntaxHighlighting::Repository *highlightRepository()
|
KSyntaxHighlighting::Repository *highlightRepository()
|
||||||
{
|
{
|
||||||
static KSyntaxHighlighting::Repository *repository = nullptr;
|
static KSyntaxHighlighting::Repository *repository = nullptr;
|
||||||
@@ -107,18 +111,24 @@ Highlighter::Definition Highlighter::definitionForDocument(const TextDocument *d
|
|||||||
if (mimeType.isValid())
|
if (mimeType.isValid())
|
||||||
definition = Highlighter::definitionForMimeType(mimeType.name());
|
definition = Highlighter::definitionForMimeType(mimeType.name());
|
||||||
if (!definition.isValid())
|
if (!definition.isValid())
|
||||||
definition = Highlighter::definitionForFileName(document->filePath().fileName());
|
definition = Highlighter::definitionForFilePath(document->filePath());
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType)
|
Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType)
|
||||||
{
|
{
|
||||||
|
const Definitions definitions = definitionsForMimeType(mimeType);
|
||||||
|
if (definitions.size() == 1)
|
||||||
|
return definitions.first();
|
||||||
return highlightRepository()->definitionForMimeType(mimeType);
|
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)
|
Highlighter::Definition Highlighter::definitionForName(const QString &name)
|
||||||
@@ -133,18 +143,88 @@ Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument
|
|||||||
if (mimeType.isValid())
|
if (mimeType.isValid())
|
||||||
definitions = Highlighter::definitionsForMimeType(mimeType.name());
|
definitions = Highlighter::definitionsForMimeType(mimeType.name());
|
||||||
if (definitions.isEmpty())
|
if (definitions.isEmpty())
|
||||||
definitions = Highlighter::definitionsForFileName(document->filePath().fileName());
|
definitions = Highlighter::definitionsForFileName(document->filePath());
|
||||||
return definitions;
|
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)
|
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)
|
void Highlighter::addCustomHighlighterPath(const Utils::FileName &path)
|
||||||
|
@@ -38,6 +38,8 @@ class TextDocument;
|
|||||||
|
|
||||||
class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter
|
class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(KSyntaxHighlighting::AbstractHighlighter)
|
||||||
public:
|
public:
|
||||||
using Definition = KSyntaxHighlighting::Definition;
|
using Definition = KSyntaxHighlighting::Definition;
|
||||||
using Definitions = QList<Definition>;
|
using Definitions = QList<Definition>;
|
||||||
@@ -45,12 +47,16 @@ public:
|
|||||||
|
|
||||||
static Definition definitionForDocument(const TextDocument *document);
|
static Definition definitionForDocument(const TextDocument *document);
|
||||||
static Definition definitionForMimeType(const QString &mimeType);
|
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 Definition definitionForName(const QString &name);
|
||||||
|
|
||||||
static Definitions definitionsForDocument(const TextDocument *document);
|
static Definitions definitionsForDocument(const TextDocument *document);
|
||||||
static Definitions definitionsForMimeType(const QString &mimeType);
|
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 addCustomHighlighterPath(const Utils::FileName &path);
|
||||||
static void updateDefinitions(std::function<void()> callback = nullptr);
|
static void updateDefinitions(std::function<void()> callback = nullptr);
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "highlightersettings.h"
|
#include "highlightersettings.h"
|
||||||
|
|
||||||
|
#include "texteditorconstants.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/synchronousprocess.h>
|
#include <utils/synchronousprocess.h>
|
||||||
@@ -97,7 +99,6 @@ namespace {
|
|||||||
|
|
||||||
static const QLatin1String kDefinitionFilesPath("UserDefinitionFilesPath");
|
static const QLatin1String kDefinitionFilesPath("UserDefinitionFilesPath");
|
||||||
static const QLatin1String kIgnoredFilesPatterns("IgnoredFilesPatterns");
|
static const QLatin1String kIgnoredFilesPatterns("IgnoredFilesPatterns");
|
||||||
static const QLatin1String kGroupPostfix("HighlighterSettings");
|
|
||||||
|
|
||||||
QString groupSpecifier(const QString &postFix, const QString &category)
|
QString groupSpecifier(const QString &postFix, const QString &category)
|
||||||
{
|
{
|
||||||
@@ -113,7 +114,7 @@ using namespace Internal;
|
|||||||
|
|
||||||
void HighlighterSettings::toSettings(const QString &category, QSettings *s) const
|
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->beginGroup(group);
|
||||||
s->setValue(kDefinitionFilesPath, m_definitionFilesPath);
|
s->setValue(kDefinitionFilesPath, m_definitionFilesPath);
|
||||||
s->setValue(kIgnoredFilesPatterns, ignoredFilesPatterns());
|
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)
|
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);
|
s->beginGroup(group);
|
||||||
m_definitionFilesPath = s->value(kDefinitionFilesPath, QString()).toString();
|
m_definitionFilesPath = s->value(kDefinitionFilesPath, QString()).toString();
|
||||||
if (!s->contains(kDefinitionFilesPath))
|
if (!s->contains(kDefinitionFilesPath))
|
||||||
|
@@ -112,6 +112,9 @@ QWidget *HighlighterSettingsPage::widget()
|
|||||||
label->setText(tr("Update finished"));
|
label->setText(tr("Update finished"));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
connect(m_d->m_page->resetCache, &QPushButton::clicked, []() {
|
||||||
|
Highlighter::clearDefintionForDocumentCache();
|
||||||
|
});
|
||||||
|
|
||||||
settingsToUI();
|
settingsToUI();
|
||||||
}
|
}
|
||||||
|
@@ -110,6 +110,30 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@@ -613,6 +613,7 @@ public:
|
|||||||
void reconfigure();
|
void reconfigure();
|
||||||
void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName);
|
void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName);
|
||||||
void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition);
|
void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition);
|
||||||
|
void rememberCurrentSyntaxDefinition();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextEditorWidget *q;
|
TextEditorWidget *q;
|
||||||
@@ -3306,6 +3307,11 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions
|
|||||||
this->configureGenericHighlighter(Highlighter::definitionForName(definition));
|
this->configureGenericHighlighter(Highlighter::definitionForName(definition));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
info.setCustomButtonInfo(BaseTextEditor::tr("Remember My Choice"), [multiple, this]() {
|
||||||
|
m_document->infoBar()->removeInfo(multiple);
|
||||||
|
rememberCurrentSyntaxDefinition();
|
||||||
|
});
|
||||||
|
|
||||||
infoBar->removeInfo(missing);
|
infoBar->removeInfo(missing);
|
||||||
infoBar->addInfo(info);
|
infoBar->addInfo(info);
|
||||||
} else {
|
} else {
|
||||||
@@ -3333,6 +3339,16 @@ void TextEditorWidgetPrivate::configureGenericHighlighter(
|
|||||||
m_document->setFontSettings(TextEditorSettings::fontSettings());
|
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
|
bool TextEditorWidget::codeFoldingVisible() const
|
||||||
{
|
{
|
||||||
return d->m_codeFoldingVisible;
|
return d->m_codeFoldingVisible;
|
||||||
@@ -8543,7 +8559,7 @@ QString TextEditorWidget::textAt(int from, int to) const
|
|||||||
|
|
||||||
void TextEditorWidget::configureGenericHighlighter()
|
void TextEditorWidget::configureGenericHighlighter()
|
||||||
{
|
{
|
||||||
const Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument());
|
Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument());
|
||||||
d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition()
|
d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition()
|
||||||
: definitions.first());
|
: definitions.first());
|
||||||
d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName());
|
d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName());
|
||||||
|
@@ -214,6 +214,8 @@ const char TEXT_EDITOR_DISPLAY_SETTINGS[] = "D.DisplaySettings";
|
|||||||
const char TEXT_EDITOR_HIGHLIGHTER_SETTINGS[] = "E.HighlighterSettings";
|
const char TEXT_EDITOR_HIGHLIGHTER_SETTINGS[] = "E.HighlighterSettings";
|
||||||
const char TEXT_EDITOR_SNIPPETS_SETTINGS[] = "F.SnippetsSettings";
|
const char TEXT_EDITOR_SNIPPETS_SETTINGS[] = "F.SnippetsSettings";
|
||||||
|
|
||||||
|
const char HIGHLIGHTER_SETTINGS_CATEGORY[] = "HighlighterSettings";
|
||||||
|
|
||||||
const char SNIPPET_EDITOR_ID[] = "TextEditor.SnippetEditor";
|
const char SNIPPET_EDITOR_ID[] = "TextEditor.SnippetEditor";
|
||||||
const char TEXT_SNIPPET_GROUP_ID[] = "Text";
|
const char TEXT_SNIPPET_GROUP_ID[] = "Text";
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user