integrate qmlformat and improve formatter settings UX

- Add reformat action to trigger full document formatting via qmlformat
- Integrate reformat action into context menu and qmljstools menu
- Remove custom formatter command from preferences, default to
  qmlformat when LSP formatting fails
- Group tabSettings and other options under 'Built-In Formatter Settings'
  for clarity
- Move formatter selection to Code Style page with a new radio button
  for selection
- Ensure preview updates according to the selected formatter
- Populate qmlformat configuration widget automatically for Qt's built-in
code style option by running qmlformat --write-defaults.
- TabSettings is a data structure being considered by the text editor
while rewriting the formatted data. Overwrite tabSettings with the
values in the .qmlformat.ini.
- fix the issue of builtin formatter being not respecting the
current codestyle's tab settings.

Task-number: QTCREATORBUG-26602
Change-Id: I2ec1b4a69712eedfafab358aaabb25c6b43ffa8e
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
This commit is contained in:
Semih Yavuz
2025-03-20 12:32:04 +01:00
parent 3805e2f191
commit a7e5b68bed
25 changed files with 875 additions and 252 deletions

View File

@@ -19,11 +19,12 @@
#include <projectexplorer/projectmanager.h> #include <projectexplorer/projectmanager.h>
#include <qmljs/parser/qmljsast_p.h>
#include <qmljstools/qmljsindenter.h> #include <qmljstools/qmljsindenter.h>
#include <qmljstools/qmljsmodelmanager.h> #include <qmljstools/qmljsmodelmanager.h>
#include <qmljstools/qmljsqtstylecodeformatter.h> #include <qmljstools/qmljsqtstylecodeformatter.h>
#include <qmljs/parser/qmljsast_p.h> #include <texteditor/tabsettings.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/infobar.h> #include <utils/infobar.h>
@@ -466,6 +467,7 @@ QmlJSEditorDocumentPrivate::QmlJSEditorDocumentPrivate(QmlJSEditorDocument *pare
: q(parent) : q(parent)
, m_semanticHighlighter(new SemanticHighlighter(parent)) , m_semanticHighlighter(new SemanticHighlighter(parent))
, m_outlineModel(new QmlOutlineModel(parent)) , m_outlineModel(new QmlOutlineModel(parent))
, m_tabSettings(parent->TextDocument::tabSettings())
{ {
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
@@ -838,5 +840,17 @@ void QmlJSEditorDocument::setSourcesWithCapabilities(
d->setSourcesWithCapabilities(cap); d->setSourcesWithCapabilities(cap);
} }
TextEditor::TabSettings QmlJSEditorDocument::tabSettings() const
{
return d->m_tabSettings;
}
void QmlJSEditorDocument::setTabSettings(const TextEditor::TabSettings &tabSettings)
{
if (tabSettings != d->m_tabSettings) {
d->m_tabSettings = tabSettings;
emit tabSettingsChanged();
}
}
} // QmlJSEditor } // QmlJSEditor

View File

@@ -40,6 +40,8 @@ public:
void setSourcesWithCapabilities(const LanguageServerProtocol::ServerCapabilities &cap); void setSourcesWithCapabilities(const LanguageServerProtocol::ServerCapabilities &cap);
virtual TextEditor::TabSettings tabSettings() const override;
void setTabSettings(const TextEditor::TabSettings &tabSettings);
signals: signals:
void updateCodeWarnings(QmlJS::Document::Ptr doc); void updateCodeWarnings(QmlJS::Document::Ptr doc);
void semanticInfoUpdated(const QmlJSTools::SemanticInfo &semanticInfo); void semanticInfoUpdated(const QmlJSTools::SemanticInfo &semanticInfo);

View File

@@ -6,6 +6,8 @@
#include <languageserverprotocol/servercapabilities.h> #include <languageserverprotocol/servercapabilities.h>
#include <qmljs/qmljsdocument.h> #include <qmljs/qmljsdocument.h>
#include <qmljstools/qmljssemanticinfo.h> #include <qmljstools/qmljssemanticinfo.h>
#include <texteditor/tabsettings.h>
#include <texteditor/textdocument.h>
#include <QObject> #include <QObject>
#include <QTextLayout> #include <QTextLayout>
@@ -83,6 +85,7 @@ public:
QmllsStatus::Source::EmbeddedCodeModel, QmllsStatus::Source::EmbeddedCodeModel,
QmllsStatus::Source::EmbeddedCodeModel, QmllsStatus::Source::EmbeddedCodeModel,
{}}; {}};
TextEditor::TabSettings m_tabSettings;
}; };
} // Internal } // Internal

View File

@@ -16,6 +16,8 @@
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljs/qmljsreformatter.h> #include <qmljs/qmljsreformatter.h>
#include <qmljstools/qmlformatsettings.h>
#include <qmljstools/qmljscodestylesettings.h>
#include <qmljstools/qmljstoolsconstants.h> #include <qmljstools/qmljstoolsconstants.h>
#include <qmljstools/qmljstoolssettings.h> #include <qmljstools/qmljstoolssettings.h>
@@ -25,6 +27,7 @@
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
@@ -42,6 +45,7 @@
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <texteditor/texteditorconstants.h> #include <texteditor/texteditorconstants.h>
#include <utils/filepath.h>
#include <utils/fsengine/fileiconprovider.h> #include <utils/fsengine/fileiconprovider.h>
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
#include <utils/mimeconstants.h> #include <utils/mimeconstants.h>
@@ -54,6 +58,7 @@
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Core; using namespace Core;
using namespace Utils; using namespace Utils;
using namespace QmlJSTools;
namespace QmlJSEditor::Internal { namespace QmlJSEditor::Internal {
@@ -70,7 +75,7 @@ public:
Command *addToolAction(QAction *a, Context &context, Id id, Command *addToolAction(QAction *a, Context &context, Id id,
ActionContainer *c1, const QString &keySequence); ActionContainer *c1, const QString &keySequence);
void reformatFile(); FormatResult reformatFile();
QmlJS::JsonSchemaManager *jsonManager() { return &m_jsonManager;} QmlJS::JsonSchemaManager *jsonManager() { return &m_jsonManager;}
QmlJSQuickFixAssistProvider *quickFixAssistProvider() { return &m_quickFixAssistProvider; } QmlJSQuickFixAssistProvider *quickFixAssistProvider() { return &m_quickFixAssistProvider; }
@@ -140,11 +145,15 @@ QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate()
connect(semanticScan, &QAction::triggered, this, &QmlJSEditorPluginPrivate::runSemanticScan); connect(semanticScan, &QAction::triggered, this, &QmlJSEditorPluginPrivate::runSemanticScan);
qmlToolsMenu->addAction(cmd); qmlToolsMenu->addAction(cmd);
m_reformatFileAction = new QAction(Tr::tr("Reformat File"), this);
cmd = ActionManager::registerAction(m_reformatFileAction, m_reformatFileAction = ActionBuilder(this, TextEditor::Constants::REFORMAT_FILE)
Id("QmlJSEditor.ReformatFile"), .setContext(context)
context); .addOnTriggered([this] { reformatFile(); })
connect(m_reformatFileAction, &QAction::triggered, this, &QmlJSEditorPluginPrivate::reformatFile); .setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Shift+;")))
.setText(Tr::tr("Reformat Document"))
.addToContainer(Core::Constants::M_EDIT_ADVANCED, Core::Constants::G_EDIT_FORMAT)
.contextAction();
cmd = ActionManager::command(TextEditor::Constants::REFORMAT_FILE);
qmlToolsMenu->addAction(cmd); qmlToolsMenu->addAction(cmd);
QAction *inspectElementAction = new QAction(Tr::tr("Inspect API for Element Under Cursor"), this); QAction *inspectElementAction = new QAction(Tr::tr("Inspect API for Element Under Cursor"), this);
@@ -171,6 +180,9 @@ QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate()
cmd = ActionManager::command(TextEditor::Constants::AUTO_INDENT_SELECTION); cmd = ActionManager::command(TextEditor::Constants::AUTO_INDENT_SELECTION);
contextMenu->addAction(cmd); contextMenu->addAction(cmd);
cmd = ActionManager::command(TextEditor::Constants::REFORMAT_FILE);
contextMenu->addAction(cmd);
cmd = ActionManager::command(TextEditor::Constants::UN_COMMENT_SELECTION); cmd = ActionManager::command(TextEditor::Constants::UN_COMMENT_SELECTION);
contextMenu->addAction(cmd); contextMenu->addAction(cmd);
@@ -188,35 +200,56 @@ QmlJS::JsonSchemaManager *jsonManager()
return dd->jsonManager(); return dd->jsonManager();
} }
static void reformatByQmlFormat(QPointer<QmlJSEditorDocument> document) static void overrideTabSettings(QPointer<QmlJSEditorDocument> document)
{ {
QString formatCommand = settings().formatCommand(); // Search .qmlformat.ini and read the tab settings from it
if (formatCommand.isEmpty()) if (!document)
formatCommand = settings().defaultFormatCommand(); return;
const auto exe = FilePath::fromUserInput(globalMacroExpander()->expand(formatCommand));
const QString args = globalMacroExpander()->expand( TextEditor::TabSettings tabSettings = document->tabSettings();
settings().formatCommandOptions()); QSettings settings(
const CommandLine commandLine(exe, args, CommandLine::Raw); QmlJSTools::QmlFormatSettings::currentQmlFormatIniFile(document->filePath()).toUrlishString(),
QSettings::IniFormat);
if (settings.contains("IndentWidth"))
tabSettings.m_indentSize = settings.value("IndentWidth").toInt();
if (settings.contains("UseTabs"))
tabSettings.m_tabPolicy = settings.value("UseTabs").toBool()
? TextEditor::TabSettings::TabPolicy::TabsOnlyTabPolicy
: TextEditor::TabSettings::TabPolicy::SpacesOnlyTabPolicy;
document->setTabSettings(tabSettings);
}
static FormatResult reformatByQmlFormat(QPointer<QmlJSEditorDocument> document)
{
const FilePath &qmlformatPath = QmlFormatSettings::instance().latestQmlFormatPath();
if (!qmlformatPath.isExecutableFile()) {
Core::MessageManager::writeSilently(
Tr::tr("QmlFormat not found."));
return FormatResult::Failed;
}
const CommandLine commandLine(qmlformatPath, {});
TextEditor::Command command; TextEditor::Command command;
command.setExecutable(commandLine.executable()); command.setExecutable(commandLine.executable());
command.setProcessing(TextEditor::Command::FileProcessing); command.setProcessing(TextEditor::Command::FileProcessing);
command.addOptions(commandLine.splitArguments()); command.addOptions(commandLine.splitArguments());
command.addOption("--inplace"); command.addOption("--inplace");
command.addOption("%file"); command.addOption("%file");
if (!command.isValid()) if (!command.isValid())
return; return FormatResult::Failed;
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocument(document); const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocument(document);
if (editors.isEmpty()) if (editors.isEmpty())
return; return FormatResult::Failed;
IEditor *currentEditor = EditorManager::currentEditor(); IEditor *currentEditor = EditorManager::currentEditor();
IEditor *editor = editors.contains(currentEditor) ? currentEditor : editors.first(); IEditor *editor = editors.contains(currentEditor) ? currentEditor : editors.first();
if (auto widget = TextEditor::TextEditorWidget::fromEditor(editor)) if (auto widget = TextEditor::TextEditorWidget::fromEditor(editor)) {
TextEditor::formatEditor(widget, command); TextEditor::formatEditor(widget, command);
return FormatResult::Success;
}
return FormatResult::Failed;
} }
static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document) static FormatResult reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
{ {
QmlJS::Document::Ptr documentPtr = document->semanticInfo().document; QmlJS::Document::Ptr documentPtr = document->semanticInfo().document;
QmlJS::Snapshot snapshot = QmlJS::ModelManagerInterface::instance()->snapshot(); QmlJS::Snapshot snapshot = QmlJS::ModelManagerInterface::instance()->snapshot();
@@ -224,7 +257,7 @@ static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
if (document->isSemanticInfoOutdated()) { if (document->isSemanticInfoOutdated()) {
QmlJS::Document::MutablePtr latestDocument; QmlJS::Document::MutablePtr latestDocument;
const Utils::FilePath fileName = document->filePath(); const FilePath fileName = document->filePath();
latestDocument = snapshot.documentFromSource( latestDocument = snapshot.documentFromSource(
QString::fromUtf8(document->contents()), QString::fromUtf8(document->contents()),
fileName, fileName,
@@ -235,14 +268,16 @@ static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
} }
if (!documentPtr->isParsedCorrectly()) if (!documentPtr->isParsedCorrectly())
return; return FormatResult::Failed;
TextEditor::TabSettings tabSettings = document->tabSettings(); QmlJSTools::QmlJSCodeStylePreferences *codeStyle
= QmlJSTools::QmlJSToolsSettings::globalCodeStyle();
TextEditor::TabSettings tabSettings = codeStyle->currentTabSettings();
const QString newText = QmlJS::reformat( const QString newText = QmlJS::reformat(
documentPtr, documentPtr,
tabSettings.m_indentSize, tabSettings.m_indentSize,
tabSettings.m_tabSize, tabSettings.m_tabSize,
QmlJSTools::QmlJSToolsSettings::globalCodeStyle()->currentCodeStyleSettings().lineLength); codeStyle->currentCodeStyleSettings().lineLength);
auto ed = qobject_cast<TextEditor::BaseTextEditor *>(EditorManager::currentEditor()); auto ed = qobject_cast<TextEditor::BaseTextEditor *>(EditorManager::currentEditor());
if (ed) { if (ed) {
TextEditor::updateEditorText(ed->editorWidget(), newText); TextEditor::updateEditorText(ed->editorWidget(), newText);
@@ -252,45 +287,98 @@ static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
tc.insertText(newText); tc.insertText(newText);
} }
return FormatResult::Success;
} }
static bool reformatUsingLanguageServer(QPointer<QmlJSEditorDocument> document) static FormatResult reformatUsingLanguageServer(QPointer<QmlJSEditorDocument> document)
{ {
if (!document) if (!document)
return false; return FormatResult::Failed;
if (!document->formatter()) if (!document->formatter())
return false; return FormatResult::Failed;
TextEditor::BaseTextEditor *editor = qobject_cast<TextEditor::BaseTextEditor *>( TextEditor::BaseTextEditor *editor = qobject_cast<TextEditor::BaseTextEditor *>(
EditorManager::currentEditor()); EditorManager::currentEditor());
if (!editor) if (!editor)
return false; return FormatResult::Failed;
TextEditor::TextEditorWidget *editorWidget = editor->editorWidget(); TextEditor::TextEditorWidget *editorWidget = editor->editorWidget();
if (!editorWidget) if (!editorWidget)
return false; return FormatResult::Failed;
overrideTabSettings(document);
document->setFormatterMode(TextEditor::Formatter::FormatMode::FullDocument); document->setFormatterMode(TextEditor::Formatter::FormatMode::FullDocument);
editorWidget->autoFormat(); editorWidget->autoFormat();
return FormatResult::Success;
return true;
} }
void QmlJSEditorPluginPrivate::reformatFile() static FormatResult reformatByCustomFormatter(
QPointer<QmlJSEditorDocument> document, const QmlJSTools::QmlJSCodeStyleSettings &settings)
{ {
if (!m_currentDocument) const FilePath &formatter = settings.customFormatterPath;
return; const QStringList &args = settings.customFormatterArguments.split(" ", Qt::SkipEmptyParts);
if (!formatter.isExecutableFile()) {
if (reformatUsingLanguageServer(m_currentDocument)) MessageManager::writeSilently(
return; Tr::tr("Custom Formatter path not found."));
return FormatResult::Failed;
if (settings().useCustomFormatCommand()) { }
reformatByQmlFormat(m_currentDocument); const CommandLine commandLine(formatter, args);
return; TextEditor::Command command;
command.setExecutable(commandLine.executable());
command.setProcessing(TextEditor::Command::FileProcessing);
command.addOptions(commandLine.splitArguments());
command.addOption("--inplace");
command.addOption("%file");
if (!command.isValid())
return FormatResult::Failed;
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocument(document);
if (editors.isEmpty())
return FormatResult::Failed;
IEditor *currentEditor = EditorManager::currentEditor();
IEditor *editor = editors.contains(currentEditor) ? currentEditor : editors.first();
if (auto widget = TextEditor::TextEditorWidget::fromEditor(editor)) {
TextEditor::formatEditor(widget, command);
return FormatResult::Success;
}
return FormatResult::Failed;
} }
reformatByBuiltInFormatter(m_currentDocument); FormatResult QmlJSEditorPluginPrivate::reformatFile()
{
if (!m_currentDocument) {
MessageManager::writeSilently(Tr::tr("Error: No current document to format."));
return FormatResult::Failed;
}
const QmlJSCodeStyleSettings settings
= QmlJSToolsSettings::globalCodeStyle()->currentCodeStyleSettings();
const auto tryReformat = [this](auto formatterFunction) {
const FormatResult result = formatterFunction(m_currentDocument);
if (result != FormatResult::Success) {
MessageManager::writeSilently(
Tr::tr("Error: Formatting failed with the selected formatter."));
}
return result;
};
switch (settings.formatter) {
case QmlJSCodeStyleSettings::Formatter::QmlFormat:
return tryReformat([](auto doc) {
return reformatUsingLanguageServer(doc) == FormatResult::Success
? FormatResult::Success
: reformatByQmlFormat(doc);
});
case QmlJSCodeStyleSettings::Formatter::Custom:
return tryReformat(
[&settings](auto doc) { return reformatByCustomFormatter(doc, settings); });
case QmlJSCodeStyleSettings::Formatter::Builtin:
default:
return tryReformat([](auto doc) { return reformatByBuiltInFormatter(doc); });
}
} }
Command *QmlJSEditorPluginPrivate::addToolAction(QAction *a, Command *QmlJSEditorPluginPrivate::addToolAction(QAction *a,

View File

@@ -16,4 +16,9 @@ void setupQmlJSEditor();
void inspectElement(); void inspectElement();
void showContextPane(); void showContextPane();
enum class FormatResult {
Success,
Failed
};
} // QmlJSEditor::Internal } // QmlJSEditor::Internal

View File

@@ -63,15 +63,10 @@ const char QML_CONTEXTPANE_KEY[] = "QmlJSEditor.ContextPaneEnabled";
const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned"; const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned";
const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData"; const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData";
const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode"; const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode";
const char FORMAT_COMMAND[] = "QmlJSEditor.formatCommand";
const char FORMAT_COMMAND_OPTIONS[] = "QmlJSEditor.formatCommandOptions";
const char CUSTOM_COMMAND[] = "QmlJSEditor.useCustomFormatCommand";
const char CUSTOM_ANALYZER[] = "QmlJSEditor.useCustomAnalyzer"; const char CUSTOM_ANALYZER[] = "QmlJSEditor.useCustomAnalyzer";
const char DISABLED_MESSAGES[] = "QmlJSEditor.disabledMessages"; const char DISABLED_MESSAGES[] = "QmlJSEditor.disabledMessages";
const char DISABLED_MESSAGES_NONQUICKUI[] = "QmlJSEditor.disabledMessagesNonQuickUI"; const char DISABLED_MESSAGES_NONQUICKUI[] = "QmlJSEditor.disabledMessagesNonQuickUI";
const char QDS_COMMAND[] = "QmlJSEditor.qdsCommand"; const char QDS_COMMAND[] = "QmlJSEditor.qdsCommand";
const char DEFAULT_CUSTOM_FORMAT_COMMAND[]
= "%{CurrentDocument:Project:QT_HOST_BINS}/qmlformat%{HostOs:ExecutableSuffix}";
const char SETTINGS_PAGE[] = "C.QmlJsEditing"; const char SETTINGS_PAGE[] = "C.QmlJsEditing";
QmlJsEditingSettings &settings() QmlJsEditingSettings &settings()
@@ -142,19 +137,6 @@ QmlJsEditingSettings::QmlJsEditingSettings()
uiQmlOpenMode.addOption({Tr::tr("Qt Design Studio"), {}, Core::Constants::MODE_DESIGN}); uiQmlOpenMode.addOption({Tr::tr("Qt Design Studio"), {}, Core::Constants::MODE_DESIGN});
uiQmlOpenMode.addOption({Tr::tr("Qt Creator"), {}, Core::Constants::MODE_EDIT}); uiQmlOpenMode.addOption({Tr::tr("Qt Creator"), {}, Core::Constants::MODE_EDIT});
useCustomFormatCommand.setSettingsKey(group, CUSTOM_COMMAND);
useCustomFormatCommand.setLabelText(
Tr::tr("Use custom command instead of built-in formatter"));
formatCommand.setSettingsKey(group, FORMAT_COMMAND);
formatCommand.setDisplayStyle(StringAspect::LineEditDisplay);
formatCommand.setPlaceHolderText(defaultFormatCommand());
formatCommand.setLabelText(Tr::tr("Command:"));
formatCommandOptions.setSettingsKey(group, FORMAT_COMMAND_OPTIONS);
formatCommandOptions.setDisplayStyle(StringAspect::LineEditDisplay);
formatCommandOptions.setLabelText(Tr::tr("Arguments:"));
useCustomAnalyzer.setSettingsKey(group, CUSTOM_ANALYZER); useCustomAnalyzer.setSettingsKey(group, CUSTOM_ANALYZER);
useCustomAnalyzer.setLabelText(Tr::tr("Use customized static analyzer")); useCustomAnalyzer.setLabelText(Tr::tr("Use customized static analyzer"));
@@ -174,15 +156,6 @@ QmlJsEditingSettings::QmlJsEditingSettings()
qdsCommand.setVisible(false); qdsCommand.setVisible(false);
readSettings(); readSettings();
autoFormatOnlyCurrentProject.setEnabler(&autoFormatOnSave);
formatCommand.setEnabler(&useCustomFormatCommand);
formatCommandOptions.setEnabler(&useCustomFormatCommand);
}
QString QmlJsEditingSettings::defaultFormatCommand() const
{
return DEFAULT_CUSTOM_FORMAT_COMMAND;
} }
FilePath QmlJsEditingSettings::defaultQdsCommand() const FilePath QmlJsEditingSettings::defaultQdsCommand() const
@@ -285,15 +258,10 @@ public:
Column { Column {
Group { Group {
bindTo(&formattingGroup), bindTo(&formattingGroup),
title(Tr::tr("Automatic Formatting on File Save")), title(Tr::tr("Formatting")),
Column { Column {
s.autoFormatOnSave, s.autoFormatOnSave,
s.autoFormatOnlyCurrentProject, s.autoFormatOnlyCurrentProject,
s.useCustomFormatCommand,
Form {
s.formatCommand, br,
s.formatCommandOptions
}
}, },
}, },
Group { Group {

View File

@@ -20,7 +20,6 @@ class QmlJsEditingSettings final : public Utils::AspectContainer
public: public:
QmlJsEditingSettings(); QmlJsEditingSettings();
QString defaultFormatCommand() const;
Utils::FilePath defaultQdsCommand() const; Utils::FilePath defaultQdsCommand() const;
Utils::BoolAspect enableContextPane{this}; Utils::BoolAspect enableContextPane{this};
@@ -28,11 +27,8 @@ public:
Utils::BoolAspect autoFormatOnSave{this}; Utils::BoolAspect autoFormatOnSave{this};
Utils::BoolAspect autoFormatOnlyCurrentProject{this}; Utils::BoolAspect autoFormatOnlyCurrentProject{this};
Utils::BoolAspect foldAuxData{this}; Utils::BoolAspect foldAuxData{this};
Utils::BoolAspect useCustomFormatCommand{this};
Utils::BoolAspect useCustomAnalyzer{this}; Utils::BoolAspect useCustomAnalyzer{this};
Utils::SelectionAspect uiQmlOpenMode{this}; Utils::SelectionAspect uiQmlOpenMode{this};
Utils::StringAspect formatCommand{this};
Utils::StringAspect formatCommandOptions{this};
Utils::IntegersAspect disabledMessages{this}; Utils::IntegersAspect disabledMessages{this};
Utils::IntegersAspect disabledMessagesForNonQuickUi{this}; Utils::IntegersAspect disabledMessagesForNonQuickUi{this};
Utils::FilePathAspect qdsCommand{this}; Utils::FilePathAspect qdsCommand{this};

View File

@@ -7,8 +7,10 @@ add_qtc_plugin(QmlJSTools
qmljsbundleprovider.cpp qmljsbundleprovider.h qmljsbundleprovider.cpp qmljsbundleprovider.h
qmljscodestylepreferenceswidget.cpp qmljscodestylepreferenceswidget.h qmljscodestylepreferenceswidget.cpp qmljscodestylepreferenceswidget.h
qmljscodestylesettings.cpp qmljscodestylesettings.h qmljscodestylesettings.cpp qmljscodestylesettings.h
qmljscodestylesettingswidget.cpp qmljscodestylesettingswidget.h
qmljscodestylesettingspage.cpp qmljscodestylesettingspage.h qmljscodestylesettingspage.cpp qmljscodestylesettingspage.h
qmljscustomformatterwidget.cpp qmljscustomformatterwidget.h
qmlformatsettingswidget.cpp qmlformatsettingswidget.h
qmljsformatterselectionwidget.cpp qmljsformatterselectionwidget.h
qmljsfunctionfilter.cpp qmljsfunctionfilter.h qmljsfunctionfilter.cpp qmljsfunctionfilter.h
qmljsindenter.cpp qmljsindenter.h qmljsindenter.cpp qmljsindenter.h
qmljsmodelmanager.cpp qmljsmodelmanager.h qmljsmodelmanager.cpp qmljsmodelmanager.h

View File

@@ -0,0 +1,98 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qmlformatsettingswidget.h"
#include "qmljsformatterselectionwidget.h"
#include "qmlformatsettings.h"
#include "qmljstoolstr.h"
#include <texteditor/snippets/snippeteditor.h>
#include <utils/layoutbuilder.h>
#include <QVBoxLayout>
namespace QmlJSTools {
QmlFormatSettingsWidget::QmlFormatSettingsWidget(
QWidget *parent, FormatterSelectionWidget *selection)
: QmlCodeStyleWidgetBase(parent)
, m_qmlformatConfigTextEdit(std::make_unique<TextEditor::SnippetEditorWidget>())
, m_formatterSelectionWidget(selection)
{
QSizePolicy sp(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sp.setHorizontalStretch(1);
m_qmlformatConfigTextEdit->setSizePolicy(sp);
using namespace Layouting;
// clang-format off
Column {
Group {
title(Tr::tr("Global qmlformat Configuration")),
Column {
m_qmlformatConfigTextEdit.get(),
},
},
noMargin
}.attachTo(this);
// clang-format on
connect(
m_qmlformatConfigTextEdit.get(),
&TextEditor::SnippetEditorWidget::textChanged,
this,
&QmlFormatSettingsWidget::slotSettingsChanged);
}
void QmlFormatSettingsWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &s)
{
QSignalBlocker blocker(this);
if (s.qmlformatIniContent != m_qmlformatConfigTextEdit->toPlainText())
m_qmlformatConfigTextEdit->setPlainText(s.qmlformatIniContent);
}
void QmlFormatSettingsWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
{
if (m_preferences == preferences)
return; // nothing changes
slotCurrentPreferencesChanged(preferences);
// cleanup old
if (m_preferences) {
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &QmlFormatSettingsWidget::slotCurrentPreferencesChanged);
}
m_preferences = preferences;
// fillup new
if (m_preferences) {
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
this->setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
});
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &QmlFormatSettingsWidget::slotCurrentPreferencesChanged);
}
}
void QmlFormatSettingsWidget::slotCurrentPreferencesChanged(
TextEditor::ICodeStylePreferences *preferences)
{
auto *current = dynamic_cast<QmlJSCodeStylePreferences *>(
preferences ? preferences->currentPreferences() : nullptr);
const bool enableWidgets = current && !current->isReadOnly() && m_formatterSelectionWidget
&& m_formatterSelectionWidget->selection().value()
== QmlCodeStyleWidgetBase::QmlFormat;
setEnabled(enableWidgets);
}
void QmlFormatSettingsWidget::slotSettingsChanged()
{
QmlJSCodeStyleSettings settings = m_preferences ? m_preferences->currentCodeStyleSettings()
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
settings.qmlformatIniContent = m_qmlformatConfigTextEdit->toPlainText();
QmlFormatSettings::instance().globalQmlFormatIniFile().writeFileContents(settings.qmlformatIniContent.toUtf8());
emit settingsChanged(settings);
}
} // namespace QmlJSTools

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "qmljsformatterselectionwidget.h"
#include "qmljscodestylesettings.h"
#include <texteditor/snippets/snippeteditor.h>
#include <memory>
#include <QWidget>
namespace QmlJSTools {
class FormatterSelectionWidget;
class QmlFormatSettingsWidget : public QmlCodeStyleWidgetBase
{
public:
explicit QmlFormatSettingsWidget(
QWidget *parent = nullptr,
FormatterSelectionWidget *selection = nullptr);
void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) override;
void setPreferences(QmlJSCodeStylePreferences *preferences) override;
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences) override;
private:
void slotSettingsChanged();
std::unique_ptr<TextEditor::SnippetEditorWidget> m_qmlformatConfigTextEdit;
FormatterSelectionWidget *m_formatterSelectionWidget = nullptr;
QmlJSCodeStylePreferences *m_preferences = nullptr;
};
} // namespace QmlJSTools

View File

@@ -4,23 +4,58 @@
#include "qmljscodestylepreferenceswidget.h" #include "qmljscodestylepreferenceswidget.h"
#include "qmljscodestylesettings.h" #include "qmljscodestylesettings.h"
#include "qmljscodestylesettingswidget.h" #include "qmljsformatterselectionwidget.h"
#include "qmljstoolstr.h"
#include <texteditor/simplecodestylepreferenceswidget.h>
#include <texteditor/texteditor.h>
#include <utils/layoutbuilder.h>
#include <utils/aspects.h>
#include <QLabel> #include <QLabel>
#include <QVBoxLayout> #include <QVBoxLayout>
using namespace TextEditor;
namespace QmlJSTools { namespace QmlJSTools {
QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget(QWidget *parent) : BuiltinFormatterSettingsWidget::BuiltinFormatterSettingsWidget(QWidget *parent, FormatterSelectionWidget *selection)
QWidget(parent) : QmlCodeStyleWidgetBase(parent)
, m_tabSettingsWidget(new TextEditor::TabSettingsWidget)
, m_formatterSelectionWidget(selection)
{ {
m_codeStyleSettingsWidget = new QmlJSCodeStyleSettingsWidget(this); m_lineLength.setRange(0, 999);
auto layout = new QVBoxLayout(this); m_tabSettingsWidget->setParent(this);
layout->addWidget(m_codeStyleSettingsWidget);
layout->setContentsMargins(QMargins()); using namespace Layouting;
Column {
Group {
title(Tr::tr("Builtin Formatter Settings")),
Column {
m_tabSettingsWidget,
Group {
title(Tr::tr("Other Settings")),
Form {
Tr::tr("Line Length:"), m_lineLength, br
}
}
}
}
}.attachTo(this);
connect(
&m_lineLength,
&Utils::IntegerAspect::changed,
this,
&BuiltinFormatterSettingsWidget::slotSettingsChanged);
} }
void QmlJSCodeStylePreferencesWidget::setPreferences(QmlJSCodeStylePreferences *preferences) void BuiltinFormatterSettingsWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &settings)
{
QSignalBlocker blocker(this);
m_lineLength.setValue(settings.lineLength);
}
void BuiltinFormatterSettingsWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
{ {
if (m_preferences == preferences) if (m_preferences == preferences)
return; // nothing changes return; // nothing changes
@@ -31,41 +66,58 @@ void QmlJSCodeStylePreferencesWidget::setPreferences(QmlJSCodeStylePreferences *
if (m_preferences) { if (m_preferences) {
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr); disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged, disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &QmlJSCodeStylePreferencesWidget::slotCurrentPreferencesChanged); this, &BuiltinFormatterSettingsWidget::slotCurrentPreferencesChanged);
disconnect(m_codeStyleSettingsWidget, &QmlJSCodeStyleSettingsWidget::settingsChanged, disconnect(m_preferences, &ICodeStylePreferences::currentTabSettingsChanged,
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged); m_tabSettingsWidget, &TabSettingsWidget::setTabSettings);
disconnect(m_tabSettingsWidget, &TabSettingsWidget::settingsChanged,
this, &BuiltinFormatterSettingsWidget::slotTabSettingsChanged);
} }
m_preferences = preferences; m_preferences = preferences;
// fillup new // fillup new
if (m_preferences) { if (m_preferences) {
m_codeStyleSettingsWidget->setCodeStyleSettings(m_preferences->currentCodeStyleSettings()); setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] { connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
m_codeStyleSettingsWidget->setCodeStyleSettings(m_preferences->currentCodeStyleSettings()); setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
}); });
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged, connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &QmlJSCodeStylePreferencesWidget::slotCurrentPreferencesChanged); this, &BuiltinFormatterSettingsWidget::slotCurrentPreferencesChanged);
connect(m_codeStyleSettingsWidget, &QmlJSCodeStyleSettingsWidget::settingsChanged, m_tabSettingsWidget->setTabSettings(m_preferences->currentTabSettings());
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged); connect(m_preferences, &ICodeStylePreferences::currentTabSettingsChanged,
m_tabSettingsWidget, &TabSettingsWidget::setTabSettings);
connect(m_tabSettingsWidget, &TabSettingsWidget::settingsChanged,
this, &BuiltinFormatterSettingsWidget::slotTabSettingsChanged);
} }
} }
void QmlJSCodeStylePreferencesWidget::slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences) void BuiltinFormatterSettingsWidget::slotCurrentPreferencesChanged(
TextEditor::ICodeStylePreferences *preferences)
{ {
m_codeStyleSettingsWidget->setEnabled(preferences && preferences->currentPreferences() && QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences *>(
!preferences->currentPreferences()->isReadOnly()); preferences ? preferences->currentPreferences() : nullptr);
const bool enableWidgets = current && !current->isReadOnly() && m_formatterSelectionWidget
&& m_formatterSelectionWidget->selection().value()
== QmlCodeStyleWidgetBase::Builtin;
setEnabled(enableWidgets);
} }
void QmlJSCodeStylePreferencesWidget::slotSettingsChanged(const QmlJSCodeStyleSettings &settings) void BuiltinFormatterSettingsWidget::slotSettingsChanged()
{
QmlJSCodeStyleSettings settings = m_preferences ? m_preferences->currentCodeStyleSettings()
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
settings.lineLength = m_lineLength.value();
emit settingsChanged(settings);
}
void BuiltinFormatterSettingsWidget::slotTabSettingsChanged(const TextEditor::TabSettings &settings)
{ {
if (!m_preferences) if (!m_preferences)
return; return;
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences*>(m_preferences->currentPreferences()); ICodeStylePreferences *current = m_preferences->currentPreferences();
if (!current) if (!current)
return; return;
current->setCodeStyleSettings(settings); current->setTabSettings(settings);
} }
} // namespace QmlJSTools } // namespace QmlJSTools

View File

@@ -3,30 +3,35 @@
#pragma once #pragma once
#include "qmljstools_global.h"
#include "qmljscodestylesettings.h" #include "qmljscodestylesettings.h"
#include "qmljsformatterselectionwidget.h"
#include <texteditor/tabsettingswidget.h>
#include <utils/aspects.h>
#include <QWidget> #include <QWidget>
QT_BEGIN_NAMESPACE
class QSpinBox;
QT_END_NAMESPACE
namespace QmlJSTools { namespace QmlJSTools {
class QmlJSCodeStyleSettingsWidget;
class QMLJSTOOLS_EXPORT QmlJSCodeStylePreferencesWidget : public QWidget class BuiltinFormatterSettingsWidget : public QmlCodeStyleWidgetBase
{ {
Q_OBJECT
public: public:
explicit QmlJSCodeStylePreferencesWidget(QWidget *parent = nullptr); explicit BuiltinFormatterSettingsWidget(QWidget *parent, FormatterSelectionWidget *selection);
void setCodeStyleSettings(const QmlJSCodeStyleSettings &settings) override;
void setPreferences(QmlJSCodeStylePreferences *tabPreferences); void setPreferences(QmlJSCodeStylePreferences *tabPreferences) override;
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences) override;
private: private:
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences); void slotSettingsChanged();
void slotSettingsChanged(const QmlJSCodeStyleSettings &settings); void slotTabSettingsChanged(const TextEditor::TabSettings &settings);
QmlJSCodeStyleSettingsWidget *m_codeStyleSettingsWidget; Utils::IntegerAspect m_lineLength;
TextEditor::TabSettingsWidget *m_tabSettingsWidget;
QmlJSCodeStylePreferences *m_preferences = nullptr; QmlJSCodeStylePreferences *m_preferences = nullptr;
FormatterSelectionWidget *m_formatterSelectionWidget;
}; };
} // namespace QmlJSTools } // namespace QmlJSTools

View File

@@ -18,9 +18,12 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
static const char lineLengthKey[] = "LineLength"; static const char lineLengthKey[] = "LineLength";
static const char qmlformatIniContentKey[] = "QmlFormatIniContent";
static const char formatterKey[] = "Formatter";
static const char customFormatterPathKey[] = "CustomFormatterPath";
static const char customFormatterArgumentsKey[] = "CustomFormatterArguments";
using namespace Utils; using namespace Utils;
namespace QmlJSTools { namespace QmlJSTools {
// QmlJSCodeStyleSettings // QmlJSCodeStyleSettings
@@ -30,18 +33,28 @@ QmlJSCodeStyleSettings::QmlJSCodeStyleSettings() = default;
Store QmlJSCodeStyleSettings::toMap() const Store QmlJSCodeStyleSettings::toMap() const
{ {
return { return {
{lineLengthKey, lineLength} {formatterKey, formatter},
{lineLengthKey, lineLength},
{qmlformatIniContentKey, qmlformatIniContent},
{customFormatterPathKey, customFormatterPath.toUrlishString()},
{customFormatterArgumentsKey, customFormatterArguments}
}; };
} }
void QmlJSCodeStyleSettings::fromMap(const Store &map) void QmlJSCodeStyleSettings::fromMap(const Store &map)
{ {
lineLength = map.value(lineLengthKey, lineLength).toInt(); lineLength = map.value(lineLengthKey, lineLength).toInt();
qmlformatIniContent = map.value(qmlformatIniContentKey, qmlformatIniContent).toString();
formatter = static_cast<Formatter>(map.value(formatterKey, formatter).toInt());
customFormatterPath = Utils::FilePath::fromString(map.value(customFormatterPathKey).toString());
customFormatterArguments = map.value(customFormatterArgumentsKey).toString();
} }
bool QmlJSCodeStyleSettings::equals(const QmlJSCodeStyleSettings &rhs) const bool QmlJSCodeStyleSettings::equals(const QmlJSCodeStyleSettings &rhs) const
{ {
return lineLength == rhs.lineLength; return lineLength == rhs.lineLength && qmlformatIniContent == rhs.qmlformatIniContent
&& formatter == rhs.formatter && customFormatterPath == rhs.customFormatterPath
&& customFormatterArguments == rhs.customFormatterArguments;
} }
QmlJSCodeStyleSettings QmlJSCodeStyleSettings::currentGlobalCodeStyle() QmlJSCodeStyleSettings QmlJSCodeStyleSettings::currentGlobalCodeStyle()

View File

@@ -7,6 +7,7 @@
#include <texteditor/icodestylepreferences.h> #include <texteditor/icodestylepreferences.h>
#include <utils/filepath.h>
#include <utils/store.h> #include <utils/store.h>
namespace TextEditor { class TabSettings; } namespace TextEditor { class TabSettings; }
@@ -19,7 +20,17 @@ class QMLJSTOOLS_EXPORT QmlJSCodeStyleSettings
public: public:
QmlJSCodeStyleSettings(); QmlJSCodeStyleSettings();
enum Formatter {
Builtin,
QmlFormat,
Custom
};
int lineLength = 80; int lineLength = 80;
QString qmlformatIniContent;
Formatter formatter = Builtin;
Utils::FilePath customFormatterPath;
QString customFormatterArguments;
Utils::Store toMap() const; Utils::Store toMap() const;
void fromMap(const Utils::Store &map); void fromMap(const Utils::Store &map);

View File

@@ -3,64 +3,112 @@
#include "qmljscodestylesettingspage.h" #include "qmljscodestylesettingspage.h"
#include "qmlformatsettings.h"
#include "qmlformatsettingswidget.h"
#include "qmljscodestylepreferenceswidget.h" #include "qmljscodestylepreferenceswidget.h"
#include "qmljscodestylesettings.h" #include "qmljscodestylesettings.h"
#include "qmljscustomformatterwidget.h"
#include "qmljsformatterselectionwidget.h"
#include "qmljsqtstylecodeformatter.h" #include "qmljsqtstylecodeformatter.h"
#include "qmljstoolsconstants.h" #include "qmljstoolsconstants.h"
#include "qmljstoolssettings.h" #include "qmljstoolssettings.h"
#include "qmljstoolstr.h" #include "qmljstoolstr.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <qmljseditor/qmljseditorconstants.h>
#include <texteditor/codestyleeditor.h> #include <texteditor/codestyleeditor.h>
#include <texteditor/command.h>
#include <texteditor/displaysettings.h> #include <texteditor/displaysettings.h>
#include <texteditor/fontsettings.h> #include <texteditor/fontsettings.h>
#include <texteditor/formattexteditor.h>
#include <texteditor/icodestylepreferencesfactory.h> #include <texteditor/icodestylepreferencesfactory.h>
#include <texteditor/simplecodestylepreferenceswidget.h> #include <texteditor/simplecodestylepreferenceswidget.h>
#include <texteditor/snippets/snippeteditor.h> #include <texteditor/snippets/snippeteditor.h>
#include <texteditor/snippets/snippetprovider.h> #include <texteditor/snippets/snippetprovider.h>
#include <texteditor/tabsettings.h> #include <texteditor/tabsettings.h>
#include <texteditor/texteditorsettings.h> #include <texteditor/texteditorsettings.h>
#include <utils/commandline.h>
#include <utils/filepath.h>
#include <utils/layoutbuilder.h> #include <utils/layoutbuilder.h>
#include <qmljseditor/qmljseditorconstants.h>
#include <QTextStream> #include <QTextStream>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QStandardPaths>
using namespace TextEditor; using namespace TextEditor;
using namespace QmlJSTools;
namespace QmlJSTools::Internal { namespace QmlJSTools::Internal {
constexpr int BuiltinFormatterIndex = QmlCodeStyleWidgetBase::Builtin;
constexpr int QmlFormatIndex = QmlCodeStyleWidgetBase::QmlFormat;
constexpr int CustomFormatterIndex = QmlCodeStyleWidgetBase::Custom;
// QmlJSCodeStylePreferencesWidget // QmlJSCodeStylePreferencesWidget
QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget( QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget(
const QString &previewText, QWidget *parent) const QString &previewText, QWidget *parent)
: TextEditor::CodeStyleEditorWidget(parent) : TextEditor::CodeStyleEditorWidget(parent)
, m_formatterSelectionWidget(new FormatterSelectionWidget(this))
, m_formatterSettingsStack(new QStackedWidget(this))
{ {
m_tabPreferencesWidget = new SimpleCodeStylePreferencesWidget; m_formatterSettingsStack->insertWidget(BuiltinFormatterIndex, new BuiltinFormatterSettingsWidget(this, m_formatterSelectionWidget));
m_codeStylePreferencesWidget = new QmlJSTools::QmlJSCodeStylePreferencesWidget; m_formatterSettingsStack->insertWidget(QmlFormatIndex, new QmlFormatSettingsWidget(this, m_formatterSelectionWidget));
m_previewTextEdit = new SnippetEditorWidget; m_formatterSettingsStack->insertWidget(CustomFormatterIndex, new CustomFormatterWidget(this, m_formatterSelectionWidget));
for (const auto &formatterWidget :
m_formatterSettingsStack->findChildren<QmlCodeStyleWidgetBase *>()) {
connect(
formatterWidget,
&QmlCodeStyleWidgetBase::settingsChanged,
this,
&QmlJSCodeStylePreferencesWidget::slotSettingsChanged);
}
const int index = m_formatterSelectionWidget->selection().value();
m_formatterSettingsStack->setCurrentIndex(index);
m_previewTextEdit = new SnippetEditorWidget(this);
m_previewTextEdit->setPlainText(previewText); m_previewTextEdit->setPlainText(previewText);
QSizePolicy sp(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); QSizePolicy sp(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sp.setHorizontalStretch(1); sp.setHorizontalStretch(1);
m_previewTextEdit->setSizePolicy(sp); m_previewTextEdit->setSizePolicy(sp);
decorateEditor(TextEditorSettings::fontSettings()); decorateEditor(TextEditorSettings::fontSettings());
connect(
TextEditorSettings::instance(),
&TextEditorSettings::fontSettingsChanged,
this,
&QmlJSCodeStylePreferencesWidget::decorateEditor);
connect(
m_formatterSelectionWidget,
&FormatterSelectionWidget::settingsChanged,
[this](const QmlJSCodeStyleSettings &settings) {
int index = m_formatterSelectionWidget->selection().volatileValue();
if (index < 0 || index >= static_cast<int>(m_formatterSettingsStack->count()))
return;
m_formatterSettingsStack->setCurrentIndex(index);
if (auto *current = dynamic_cast<QmlCodeStyleWidgetBase *>(
m_formatterSettingsStack->widget(index))) {
current->slotCurrentPreferencesChanged(m_preferences);
}
slotSettingsChanged(settings);
});
using namespace Layouting; using namespace Layouting;
Row { Row {
Column { Column {
m_tabPreferencesWidget, m_formatterSelectionWidget, br,
m_codeStylePreferencesWidget, m_formatterSettingsStack,
st, st
}, },
m_previewTextEdit, m_previewTextEdit,
noMargin noMargin
}.attachTo(this); }.attachTo(this);
connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged,
this, &QmlJSCodeStylePreferencesWidget::decorateEditor);
setVisualizeWhitespace(true); setVisualizeWhitespace(true);
updatePreview(); updatePreview();
@@ -69,14 +117,20 @@ QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget(
void QmlJSCodeStylePreferencesWidget::setPreferences(QmlJSCodeStylePreferences *preferences) void QmlJSCodeStylePreferencesWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
{ {
m_preferences = preferences; m_preferences = preferences;
m_tabPreferencesWidget->setPreferences(preferences); m_formatterSelectionWidget->setPreferences(preferences);
m_codeStylePreferencesWidget->setPreferences(preferences); for (const auto &formatterWidget :
m_formatterSettingsStack->findChildren<QmlCodeStyleWidgetBase *>()) {
formatterWidget->setPreferences(preferences);
}
if (m_preferences) if (m_preferences)
{ {
connect(m_preferences, &ICodeStylePreferences::currentTabSettingsChanged, connect(m_preferences, &ICodeStylePreferences::currentTabSettingsChanged,
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged); this, &QmlJSCodeStylePreferencesWidget::updatePreview);
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged,
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged); [this]{
m_formatterSettingsStack->setCurrentIndex(m_formatterSelectionWidget->selection().value());
updatePreview();
});
} }
updatePreview(); updatePreview();
} }
@@ -95,12 +149,36 @@ void QmlJSCodeStylePreferencesWidget::setVisualizeWhitespace(bool on)
m_previewTextEdit->setDisplaySettings(displaySettings); m_previewTextEdit->setDisplaySettings(displaySettings);
} }
void QmlJSCodeStylePreferencesWidget::slotSettingsChanged() void QmlJSCodeStylePreferencesWidget::slotSettingsChanged(const QmlJSCodeStyleSettings &settings)
{ {
if (!m_preferences)
return;
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences*>(m_preferences->currentPreferences());
if (!current)
return;
current->setCodeStyleSettings(settings);
updatePreview(); updatePreview();
} }
void QmlJSCodeStylePreferencesWidget::updatePreview() void QmlJSCodeStylePreferencesWidget::updatePreview()
{
switch (m_formatterSelectionWidget->selection().value()) {
case QmlCodeStyleWidgetBase::Builtin:
builtInFormatterPreview();
break;
case QmlCodeStyleWidgetBase::QmlFormat:
qmlformatPreview();
break;
case QmlCodeStyleWidgetBase::Custom:
customFormatterPreview();
break;
}
}
void QmlJSCodeStylePreferencesWidget::builtInFormatterPreview()
{ {
QTextDocument *doc = m_previewTextEdit->document(); QTextDocument *doc = m_previewTextEdit->document();
@@ -121,6 +199,63 @@ void QmlJSCodeStylePreferencesWidget::updatePreview()
tc.endEditBlock(); tc.endEditBlock();
} }
void QmlJSCodeStylePreferencesWidget::qmlformatPreview()
{
using namespace Core;
const Utils::FilePath &qmlFormatPath = QmlFormatSettings::instance().latestQmlFormatPath();
if (qmlFormatPath.isEmpty()) {
MessageManager::writeSilently("QmlFormat not found.");
return;
}
const Utils::CommandLine commandLine(qmlFormatPath);
TextEditor::Command command;
command.setExecutable(commandLine.executable());
command.setProcessing(TextEditor::Command::FileProcessing);
command.addOptions(commandLine.splitArguments());
command.addOption("--inplace");
command.addOption("%file");
if (!command.isValid())
return;
TextEditor::TabSettings tabSettings;
QSettings settings(
QmlJSTools::QmlFormatSettings::globalQmlFormatIniFile().toUrlishString(),
QSettings::IniFormat);
if (settings.contains("IndentWidth"))
tabSettings.m_indentSize = settings.value("IndentWidth").toInt();
if (settings.contains("UseTabs"))
tabSettings.m_tabPolicy = settings.value("UseTabs").toBool()
? TextEditor::TabSettings::TabPolicy::TabsOnlyTabPolicy
: TextEditor::TabSettings::TabPolicy::SpacesOnlyTabPolicy;
QString dummyFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/dummy.qml";
m_previewTextEdit->textDocument()->setFilePath(Utils::FilePath::fromString(dummyFilePath));
m_previewTextEdit->textDocument()->setTabSettings(tabSettings);
TextEditor::formatEditor(m_previewTextEdit, command);
}
void QmlJSCodeStylePreferencesWidget::customFormatterPreview()
{
Utils::FilePath path = m_preferences->currentCodeStyleSettings().customFormatterPath;
QStringList args = m_preferences->currentCodeStyleSettings()
.customFormatterArguments.split(" ", Qt::SkipEmptyParts);
if (path.isEmpty()) {
Core::MessageManager::writeSilently("Custom formatter not found.");
return;
}
const Utils::CommandLine commandLine(path, args);
TextEditor::Command command;
command.setExecutable(commandLine.executable());
command.setProcessing(TextEditor::Command::FileProcessing);
command.addOptions(commandLine.splitArguments());
command.addOption("--inplace");
command.addOption("%file");
if (!command.isValid())
return;
QString dummyFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/dummy.qml";
m_previewTextEdit->textDocument()->setFilePath(Utils::FilePath::fromString(dummyFilePath));
TextEditor::formatEditor(m_previewTextEdit, command);
}
// QmlJSCodeStyleSettingsPageWidget // QmlJSCodeStyleSettingsPageWidget
class QmlJSCodeStyleSettingsPageWidget : public Core::IOptionsPageWidget class QmlJSCodeStyleSettingsPageWidget : public Core::IOptionsPageWidget

View File

@@ -4,10 +4,13 @@
#pragma once #pragma once
#include "qmljscodestylesettings.h" #include "qmljscodestylesettings.h"
#include "qmljsformatterselectionwidget.h"
#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/dialogs/ioptionspage.h>
#include <texteditor/codestyleeditor.h> #include <texteditor/codestyleeditor.h>
#include <QStackedWidget>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QString; class QString;
class QWidget; class QWidget;
@@ -15,14 +18,10 @@ QT_END_NAMESPACE
namespace TextEditor { namespace TextEditor {
class FontSettings; class FontSettings;
class SimpleCodeStylePreferencesWidget;
class SnippetEditorWidget;
} }
namespace QmlJSTools { namespace QmlJSTools {
class QmlJSCodeStylePreferencesWidget;
class QmlJSCodeStyleSettings; class QmlJSCodeStyleSettings;
namespace Internal { namespace Internal {
class QmlJSCodeStylePreferencesWidget : public TextEditor::CodeStyleEditorWidget class QmlJSCodeStylePreferencesWidget : public TextEditor::CodeStyleEditorWidget
@@ -37,16 +36,19 @@ public:
private: private:
void decorateEditor(const TextEditor::FontSettings &fontSettings); void decorateEditor(const TextEditor::FontSettings &fontSettings);
void setVisualizeWhitespace(bool on); void setVisualizeWhitespace(bool on);
void slotSettingsChanged(); void slotSettingsChanged(const QmlJSCodeStyleSettings &);
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences);
void updatePreview(); void updatePreview();
void builtInFormatterPreview();
void qmlformatPreview();
void customFormatterPreview();
QmlJSCodeStylePreferences *m_preferences = nullptr; FormatterSelectionWidget *m_formatterSelectionWidget;
TextEditor::SimpleCodeStylePreferencesWidget *m_tabPreferencesWidget; QStackedWidget *m_formatterSettingsStack;
QmlJSTools::QmlJSCodeStylePreferencesWidget *m_codeStylePreferencesWidget;
TextEditor::SnippetEditorWidget *m_previewTextEdit; TextEditor::SnippetEditorWidget *m_previewTextEdit;
QmlJSCodeStylePreferences *m_preferences = nullptr;
}; };
class QmlJSCodeStyleSettingsPage : public Core::IOptionsPage class QmlJSCodeStyleSettingsPage : public Core::IOptionsPage
{ {
public: public:

View File

@@ -1,59 +0,0 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qmljscodestylesettingswidget.h"
#include "qmljscodestylesettings.h"
#include "qmljstoolstr.h"
#include <utils/layoutbuilder.h>
#include <QSpinBox>
#include <QTextStream>
namespace QmlJSTools {
QmlJSCodeStyleSettingsWidget::QmlJSCodeStyleSettingsWidget(QWidget *parent)
: QWidget(parent)
{
m_lineLengthSpinBox = new QSpinBox;
m_lineLengthSpinBox->setMinimum(0);
m_lineLengthSpinBox->setMaximum(999);
using namespace Layouting;
// clang-format off
Column {
Group {
title(Tr::tr("Other")),
Form {
Tr::tr("&Line length:"), m_lineLengthSpinBox, br,
}
},
noMargin
}.attachTo(this);
// clang-format on
connect(m_lineLengthSpinBox, &QSpinBox::valueChanged,
this, &QmlJSCodeStyleSettingsWidget::slotSettingsChanged);
}
void QmlJSCodeStyleSettingsWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &settings)
{
QSignalBlocker blocker(this);
m_lineLengthSpinBox->setValue(settings.lineLength);
}
QmlJSCodeStyleSettings QmlJSCodeStyleSettingsWidget::codeStyleSettings() const
{
QmlJSCodeStyleSettings set;
set.lineLength = m_lineLengthSpinBox->value();
return set;
}
void QmlJSCodeStyleSettingsWidget::slotSettingsChanged()
{
emit settingsChanged(codeStyleSettings());
}
} // namespace TextEditor

View File

@@ -1,44 +0,0 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "qmljstools_global.h"
#include <QGroupBox>
QT_BEGIN_NAMESPACE
class QSpinBox;
QT_END_NAMESPACE
namespace QmlJSTools {
class QmlJSCodeStyleSettings;
class QMLJSTOOLS_EXPORT QmlJSCodeStyleSettingsWidget : public QWidget
{
Q_OBJECT
public:
enum CodingStyleLink {
CppLink,
QtQuickLink
};
explicit QmlJSCodeStyleSettingsWidget(QWidget *parent = nullptr);
QmlJSCodeStyleSettings codeStyleSettings() const;
void setCodingStyleWarningVisible(bool visible);
void setCodeStyleSettings(const QmlJSCodeStyleSettings &settings);
signals:
void settingsChanged(const QmlJSCodeStyleSettings &);
private:
void slotSettingsChanged();
void codingStyleLinkActivated(const QString &linkString);
QSpinBox *m_lineLengthSpinBox;
};
} // namespace QmlJSTools

View File

@@ -0,0 +1,117 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qmljscustomformatterwidget.h"
#include "qmlformatsettings.h"
#include "qmljsformatterselectionwidget.h"
#include "qmljstoolstr.h"
#include <utils/layoutbuilder.h>
#include <QWidget>
namespace QmlJSTools {
CustomFormatterWidget::CustomFormatterWidget(QWidget *parent, FormatterSelectionWidget *selection)
: QmlCodeStyleWidgetBase(parent)
, m_formatterSelectionWidget(selection)
{
m_customFormatterPath.setParent(this);
m_customFormatterArguments.setParent(this);
m_customFormatterPath.setPlaceHolderText(
QmlFormatSettings::instance().latestQmlFormatPath().toUrlishString());
m_customFormatterPath.setLabelText(Tr::tr("Command:"));
m_customFormatterArguments.setLabelText(Tr::tr("Arguments:"));
m_customFormatterArguments.setDisplayStyle(Utils::StringAspect::LineEditDisplay);
using namespace Layouting;
// clang-format off
Column {
Group {
title(Tr::tr("Custom Formatter Configuration")),
Column {
m_customFormatterPath, br,
m_customFormatterArguments, br,
st
},
},
noMargin,
}.attachTo(this);
// clang-format on
connect(
&m_customFormatterPath,
&Utils::BaseAspect::changed,
this,
&CustomFormatterWidget::slotSettingsChanged);
connect(
&m_customFormatterArguments,
&Utils::BaseAspect::changed,
this,
&CustomFormatterWidget::slotSettingsChanged);
}
void CustomFormatterWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings& s)
{
QSignalBlocker blocker(this);
if (s.customFormatterPath != m_customFormatterPath.expandedValue()) {
m_customFormatterPath.setValue(s.customFormatterPath);
}
if (s.customFormatterArguments != m_customFormatterArguments.value()) {
m_customFormatterArguments.setValue(s.customFormatterArguments);
}
}
void CustomFormatterWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
{
if (m_preferences == preferences)
return; // nothing changes
slotCurrentPreferencesChanged(preferences);
// cleanup old
if (m_preferences) {
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &CustomFormatterWidget::slotCurrentPreferencesChanged);
}
m_preferences = preferences;
// fillup new
if (m_preferences) {
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
this->setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
});
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &CustomFormatterWidget::slotCurrentPreferencesChanged);
}
}
void CustomFormatterWidget::slotCurrentPreferencesChanged(
TextEditor::ICodeStylePreferences *preferences)
{
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences *>(
preferences ? preferences->currentPreferences() : nullptr);
const bool enableWidgets = current && !current->isReadOnly() && m_formatterSelectionWidget
&& m_formatterSelectionWidget->selection().value()
== QmlCodeStyleWidgetBase::Custom;
setEnabled(enableWidgets);
}
void CustomFormatterWidget::slotSettingsChanged()
{
QmlJSCodeStyleSettings settings = m_preferences ? m_preferences->currentCodeStyleSettings()
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
if (m_customFormatterPath.value().isEmpty()) {
m_customFormatterPath.setValue(
QmlFormatSettings::instance().latestQmlFormatPath().toUrlishString());
}
settings.customFormatterPath = m_customFormatterPath.expandedValue();
settings.customFormatterArguments = m_customFormatterArguments.value();
emit settingsChanged(settings);
}
} // namespace QmlJSTools

View File

@@ -0,0 +1,27 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "qmljscodestylesettings.h"
#include "qmljsformatterselectionwidget.h"
#include <utils/aspects.h>
namespace QmlJSTools {
class CustomFormatterWidget : public QmlCodeStyleWidgetBase
{
public:
explicit CustomFormatterWidget(QWidget *parent, FormatterSelectionWidget *selection = nullptr);
void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) override;
void setPreferences(QmlJSCodeStylePreferences *preferences) override;
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences) override;
private:
void slotSettingsChanged();
Utils::FilePathAspect m_customFormatterPath;
Utils::StringAspect m_customFormatterArguments;
FormatterSelectionWidget *m_formatterSelectionWidget = nullptr;
QmlJSCodeStylePreferences *m_preferences = nullptr;
};
} // namespace QmlJSTools

View File

@@ -0,0 +1,89 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qmljsformatterselectionwidget.h"
#include "qmljstoolstr.h"
#include <utils/layoutbuilder.h>
namespace QmlJSTools {
QmlCodeStyleWidgetBase::QmlCodeStyleWidgetBase(QWidget *parent)
: QWidget(parent)
{
}
FormatterSelectionWidget::FormatterSelectionWidget(QWidget *parent)
: QmlCodeStyleWidgetBase(parent)
{
using namespace Utils;
m_formatterSelection.setDefaultValue(Builtin);
m_formatterSelection.setDisplayStyle(SelectionAspect::DisplayStyle::RadioButtons);
m_formatterSelection.addOption(Tr::tr("Built-In Formatter [Deprecated]") );
m_formatterSelection.addOption(Tr::tr("QmlFormat [LSP]"));
m_formatterSelection.addOption(Tr::tr("Custom Formatter [Must be qmlformat compatible]"));
m_formatterSelection.setLabelText(Tr::tr("Formatter"));
connect(&m_formatterSelection, &SelectionAspect::changed,
this, &FormatterSelectionWidget::slotSettingsChanged);
using namespace Layouting;
Column {
Group {
title(Tr::tr("Formatter Selection")),
Column {
m_formatterSelection, br
}
}
}.attachTo(this);
}
void FormatterSelectionWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &s)
{
if (s.formatter != m_formatterSelection.value())
m_formatterSelection.setValue(s.formatter);
}
void FormatterSelectionWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
{
if (m_preferences == preferences)
return; // nothing changes
slotCurrentPreferencesChanged(preferences);
// cleanup old
if (m_preferences) {
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &FormatterSelectionWidget::slotCurrentPreferencesChanged);
}
m_preferences = preferences;
// fillup new
if (m_preferences) {
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
});
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
this, &FormatterSelectionWidget::slotCurrentPreferencesChanged);
}
}
void FormatterSelectionWidget::slotCurrentPreferencesChanged(
TextEditor::ICodeStylePreferences *preferences)
{
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences *>(
preferences ? preferences->currentPreferences() : nullptr);
const bool enableWidgets = current && !current->isReadOnly();
setEnabled(enableWidgets);
}
void FormatterSelectionWidget::slotSettingsChanged()
{
QmlJSCodeStyleSettings settings = m_preferences
? m_preferences->currentCodeStyleSettings()
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
settings.formatter = static_cast<QmlJSCodeStyleSettings::Formatter>(m_formatterSelection.value());
emit settingsChanged(settings);
}
} // namespace QmlJSTools

View File

@@ -0,0 +1,51 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "qmljscodestylesettings.h"
#include <utils/aspects.h>
namespace QmlJSTools {
class QmlJSCodeStyleSettings;
class QmlCodeStyleWidgetBase : public QWidget
{
Q_OBJECT
public:
QmlCodeStyleWidgetBase(QWidget *parent = nullptr);
virtual ~QmlCodeStyleWidgetBase() = default;
enum Formatter {
Builtin,
QmlFormat,
Custom,
Count
};
virtual void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) = 0;
virtual void setPreferences(QmlJSCodeStylePreferences *preferences) = 0;
virtual void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences) = 0;
signals:
void settingsChanged(const QmlJSCodeStyleSettings &);
};
class FormatterSelectionWidget : public QmlCodeStyleWidgetBase
{
Q_OBJECT
public:
explicit FormatterSelectionWidget(QWidget *parent);
const Utils::SelectionAspect &selection() const { return m_formatterSelection; }
Utils::SelectionAspect &selection() { return m_formatterSelection; }
void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) override;
void setPreferences(QmlJSCodeStylePreferences *preferences) override;
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences) override;
private:
void slotSettingsChanged();
Utils::SelectionAspect m_formatterSelection;
QmlJSCodeStylePreferences *m_preferences = nullptr;
};
} // namespace QmlJSTools

View File

@@ -25,8 +25,6 @@ QtcPlugin {
"qmljscodestylesettings.h", "qmljscodestylesettings.h",
"qmljscodestylesettingspage.cpp", "qmljscodestylesettingspage.cpp",
"qmljscodestylesettingspage.h", "qmljscodestylesettingspage.h",
"qmljscodestylesettingswidget.cpp",
"qmljscodestylesettingswidget.h",
"qmljsfunctionfilter.cpp", "qmljsfunctionfilter.cpp",
"qmljsfunctionfilter.h", "qmljsfunctionfilter.h",
"qmljsindenter.cpp", "qmljsindenter.cpp",

View File

@@ -8,6 +8,7 @@
#include "qmljsindenter.h" #include "qmljsindenter.h"
#include "qmljstoolsconstants.h" #include "qmljstoolsconstants.h"
#include "qmljstoolssettings.h" #include "qmljstoolssettings.h"
#include "qmlformatsettings.h"
#include "qmljstoolstr.h" #include "qmljstoolstr.h"
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
@@ -20,6 +21,7 @@
#include <texteditor/texteditorsettings.h> #include <texteditor/texteditorsettings.h>
#include <utils/id.h> #include <utils/id.h>
#include <utils/filepath.h>
#include <utils/mimeconstants.h> #include <utils/mimeconstants.h>
#include <utils/mimeutils.h> #include <utils/mimeutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -166,9 +168,22 @@ QmlJSToolsSettings::QmlJSToolsSettings()
qtTabSettings.m_indentSize = 4; qtTabSettings.m_indentSize = 4;
qtTabSettings.m_continuationAlignBehavior = TabSettings::ContinuationAlignWithIndent; qtTabSettings.m_continuationAlignBehavior = TabSettings::ContinuationAlignWithIndent;
qtCodeStyle->setTabSettings(qtTabSettings); qtCodeStyle->setTabSettings(qtTabSettings);
QmlJSCodeStyleSettings qtQmlJSSetings;
qtQmlJSSetings.lineLength = 80; connect(&QmlFormatSettings::instance(), &QmlFormatSettings::qmlformatIniCreated, [](Utils::FilePath qmlformatIniPath) {
qtCodeStyle->setCodeStyleSettings(qtQmlJSSetings); QmlJSCodeStyleSettings s;
s.lineLength = 80;
Utils::expected_str<QByteArray> fileContents = qmlformatIniPath.fileContents();
if (fileContents)
s.qmlformatIniContent = QString::fromUtf8(*qmlformatIniPath.fileContents());
auto builtInCodeStyles = TextEditorSettings::codeStylePool(
QmlJSTools::Constants::QML_JS_SETTINGS_ID)
->builtInCodeStyles();
for (auto codeStyle : builtInCodeStyles) {
if (auto qtCodeStyle = dynamic_cast<QmlJSCodeStylePreferences *>(codeStyle))
qtCodeStyle->setCodeStyleSettings(s);
}
});
pool->addCodeStyle(qtCodeStyle); pool->addCodeStyle(qtCodeStyle);
// default delegate for global preferences // default delegate for global preferences

View File

@@ -138,6 +138,7 @@ const char UNFOLD_RECURSIVELY[] = "TextEditor.UnfoldRecursively";
const char UNFOLD_ALL[] = "TextEditor.UnFoldAll"; const char UNFOLD_ALL[] = "TextEditor.UnFoldAll";
const char AUTO_INDENT_SELECTION[] = "TextEditor.AutoIndentSelection"; const char AUTO_INDENT_SELECTION[] = "TextEditor.AutoIndentSelection";
const char AUTO_FORMAT_SELECTION[] = "TextEditor.AutoFormatSelection"; const char AUTO_FORMAT_SELECTION[] = "TextEditor.AutoFormatSelection";
const char REFORMAT_FILE[] = "TextEditor.ReformatFile";
const char INCREASE_FONT_SIZE[] = "TextEditor.IncreaseFontSize"; const char INCREASE_FONT_SIZE[] = "TextEditor.IncreaseFontSize";
const char DECREASE_FONT_SIZE[] = "TextEditor.DecreaseFontSize"; const char DECREASE_FONT_SIZE[] = "TextEditor.DecreaseFontSize";
const char RESET_FONT_SIZE[] = "TextEditor.ResetFontSize"; const char RESET_FONT_SIZE[] = "TextEditor.ResetFontSize";