Git commit e4328a41f90d5c619e329fa15a5923791d537a8f by Christoph Cullmann, on behalf of Waqar Ahmed. Committed on 12/11/2022 at 18:56. Pushed by cullmann into branch 'master'.
lsp: Add format on save M +6 -18 addons/lspclient/lspclientconfigpage.cpp M +3 -0 addons/lspclient/lspclientplugin.cpp M +1 -0 addons/lspclient/lspclientplugin.h M +23 -2 addons/lspclient/lspclientpluginview.cpp M +29 -23 addons/lspclient/lspconfigwidget.ui M +9 -0 doc/kate/plugins.docbook https://invent.kde.org/utilities/kate/commit/e4328a41f90d5c619e329fa15a5923791d537a8f diff --git a/addons/lspclient/lspclientconfigpage.cpp b/addons/lspclient/lspclientconfigpage.cpp index 08005cde8..0ecbbe01f 100644 --- a/addons/lspclient/lspclientconfigpage.cpp +++ b/addons/lspclient/lspclientconfigpage.cpp @@ -48,24 +48,10 @@ LSPClientConfigPage::LSPClientConfigPage(QWidget *parent, LSPClientPlugin *plugi reset(); for (const auto &cb : { - ui->chkSymbolDetails, - ui->chkSymbolExpand, - ui->chkSymbolSort, - ui->chkSymbolTree, - ui->chkComplDoc, - ui->chkRefDeclaration, - ui->chkComplParens, - ui->chkDiagnostics, - ui->chkDiagnosticsMark, - ui->chkDiagnosticsHover, - ui->chkMessages, - ui->chkOnTypeFormatting, - ui->chkIncrementalSync, - ui->chkHighlightGoto, - ui->chkSemanticHighlighting, - ui->chkAutoHover, - ui->chkSignatureHelp, - ui->chkAutoImport, + ui->chkSymbolDetails, ui->chkSymbolExpand, ui->chkSymbolSort, ui->chkSymbolTree, ui->chkComplDoc, + ui->chkRefDeclaration, ui->chkComplParens, ui->chkDiagnostics, ui->chkDiagnosticsMark, ui->chkDiagnosticsHover, + ui->chkMessages, ui->chkOnTypeFormatting, ui->chkIncrementalSync, ui->chkHighlightGoto, ui->chkSemanticHighlighting, + ui->chkAutoHover, ui->chkSignatureHelp, ui->chkAutoImport, ui->chkFmtOnSave, }) { connect(cb, &QCheckBox::toggled, this, &LSPClientConfigPage::changed); } @@ -149,6 +135,7 @@ void LSPClientConfigPage::apply() m_plugin->m_semanticHighlighting = ui->chkSemanticHighlighting->isChecked(); m_plugin->m_signatureHelp = ui->chkSignatureHelp->isChecked(); m_plugin->m_autoImport = ui->chkAutoImport->isChecked(); + m_plugin->m_fmtOnSave = ui->chkFmtOnSave->isChecked(); m_plugin->m_messages = ui->chkMessages->isChecked(); @@ -196,6 +183,7 @@ void LSPClientConfigPage::reset() ui->chkSemanticHighlighting->setChecked(m_plugin->m_semanticHighlighting); ui->chkSignatureHelp->setChecked(m_plugin->m_signatureHelp); ui->chkAutoImport->setChecked(m_plugin->m_autoImport); + ui->chkFmtOnSave->setChecked(m_plugin->m_fmtOnSave); ui->chkMessages->setChecked(m_plugin->m_messages); diff --git a/addons/lspclient/lspclientplugin.cpp b/addons/lspclient/lspclientplugin.cpp index 85e073a16..f00723e88 100644 --- a/addons/lspclient/lspclientplugin.cpp +++ b/addons/lspclient/lspclientplugin.cpp @@ -45,6 +45,7 @@ static const QString CONFIG_SIGNATURE_HELP{QStringLiteral("SignatureHelp")}; static const QString CONFIG_AUTO_IMPORT{QStringLiteral("AutoImport")}; static const QString CONFIG_ALLOWED_COMMANDS{QStringLiteral("AllowedServerCommandLines")}; static const QString CONFIG_BLOCKED_COMMANDS{QStringLiteral("BlockedServerCommandLines")}; +static const QString CONFIG_FORMAT_ON_SAVE{QStringLiteral("FormatOnSave")}; K_PLUGIN_FACTORY_WITH_JSON(LSPClientPluginFactory, "lspclientplugin.json", registerPlugin<LSPClientPlugin>();) @@ -132,6 +133,7 @@ void LSPClientPlugin::readConfig() m_semanticHighlighting = config.readEntry(CONFIG_SEMANTIC_HIGHLIGHTING, true); m_signatureHelp = config.readEntry(CONFIG_SIGNATURE_HELP, true); m_autoImport = config.readEntry(CONFIG_AUTO_IMPORT, true); + m_fmtOnSave = config.readEntry(CONFIG_FORMAT_ON_SAVE, false); // read allow + block lists as two separate keys, let block always win const auto allowed = config.readEntry(CONFIG_ALLOWED_COMMANDS, QStringList()); @@ -171,6 +173,7 @@ void LSPClientPlugin::writeConfig() const config.writeEntry(CONFIG_SEMANTIC_HIGHLIGHTING, m_semanticHighlighting); config.writeEntry(CONFIG_SIGNATURE_HELP, m_signatureHelp); config.writeEntry(CONFIG_AUTO_IMPORT, m_autoImport); + config.writeEntry(CONFIG_FORMAT_ON_SAVE, m_fmtOnSave); // write allow + block lists as two separate keys QStringList allowed, blocked; diff --git a/addons/lspclient/lspclientplugin.h b/addons/lspclient/lspclientplugin.h index 3df99a83f..d54a3a5cc 100644 --- a/addons/lspclient/lspclientplugin.h +++ b/addons/lspclient/lspclientplugin.h @@ -62,6 +62,7 @@ public: bool m_semanticHighlighting = false; bool m_signatureHelp = true; bool m_autoImport = true; + bool m_fmtOnSave = false; // debug mode? const bool m_debugMode; diff --git a/addons/lspclient/lspclientpluginview.cpp b/addons/lspclient/lspclientpluginview.cpp index 23cad2a71..5543800e5 100644 --- a/addons/lspclient/lspclientpluginview.cpp +++ b/addons/lspclient/lspclientpluginview.cpp @@ -2167,7 +2167,7 @@ public: }); } - void format(QChar lastChar = QChar()) + void format(QChar lastChar = QChar(), bool save = false) { KTextEditor::View *activeView = m_mainWindow->activeView(); QPointer<KTextEditor::Document> document = activeView->document(); @@ -2186,7 +2186,7 @@ public: // sigh, no move initialization capture ... // (again) assuming reply ranges wrt revisions submitted at this time QSharedPointer<LSPClientRevisionSnapshot> snapshot(m_serverManager->snapshot(server.data())); - auto h = [this, document, snapshot, lastChar](const QList<LSPTextEdit> &edits) { + auto h = [this, document, snapshot, lastChar, save](const QList<LSPTextEdit> &edits) { if (lastChar.isNull()) { checkEditResult(edits); } @@ -2197,6 +2197,11 @@ public: m_onTypeFormattingTriggers.clear(); applyEdits(document, snapshot.data(), edits); m_onTypeFormattingTriggers = savedTriggers; + if (save) { + disconnect(document, &KTextEditor::Document::documentSavedOrUploaded, this, &self_type::formatOnSave); + document->documentSave(); + connect(document, &KTextEditor::Document::documentSavedOrUploaded, this, &self_type::formatOnSave); + } } }; @@ -2965,6 +2970,15 @@ public: } } + void formatOnSave(KTextEditor::Document *doc, bool) + { + // only trigger for active doc + auto activeView = m_mainWindow->activeView(); + if (activeView && activeView->document() == doc) { + format({}, true); + } + } + void updateState() { KTextEditor::View *activeView = m_mainWindow->activeView(); @@ -2978,6 +2992,7 @@ public: bool selectionRangeEnabled = false; bool isClangd = false; bool isRustAnalyzer = false; + bool formatOnSave = false; if (server) { const auto &caps = server->capabilities(); @@ -2992,6 +3007,7 @@ public: renameEnabled = caps.renameProvider; codeActionEnabled = caps.codeActionProvider; selectionRangeEnabled = caps.selectionRangeProvider; + formatOnSave = formatEnabled && m_plugin->m_fmtOnSave; connect(server.data(), &LSPClientServer::publishDiagnostics, this, &self_type::onDiagnostics, Qt::UniqueConnection); connect(server.data(), &LSPClientServer::applyEdit, this, &self_type::onApplyEdit, Qt::UniqueConnection); @@ -3092,6 +3108,11 @@ public: updateMarks(doc); + if (formatOnSave) { + auto t = Qt::ConnectionType(Qt::UniqueConnection | Qt::QueuedConnection); + connect(activeView->document(), &KTextEditor::Document::documentSavedOrUploaded, this, &self_type::formatOnSave, t); + } + // connect for cleanup stuff if (activeView) { connect(activeView, &KTextEditor::View::destroyed, this, &self_type::viewDestroyed, Qt::UniqueConnection); diff --git a/addons/lspclient/lspconfigwidget.ui b/addons/lspclient/lspconfigwidget.ui index c6cf6581c..4bdf8be52 100644 --- a/addons/lspclient/lspconfigwidget.ui +++ b/addons/lspclient/lspconfigwidget.ui @@ -41,49 +41,49 @@ <property name="bottomMargin"> <number>0</number> </property> - <item row="2" column="0"> + <item row="3" column="0"> <widget class="QLabel" name="label_2"> <property name="text"> <string>Completions:</string> </property> </widget> </item> - <item row="2" column="1"> + <item row="3" column="1"> <widget class="QCheckBox" name="chkComplDoc"> <property name="text"> <string>Show inline docs for selected completion</string> </property> </widget> </item> - <item row="3" column="1"> + <item row="4" column="1"> <widget class="QCheckBox" name="chkSignatureHelp"> <property name="text"> <string>Show function signature when typing a function call</string> </property> </widget> </item> - <item row="4" column="1"> + <item row="5" column="1"> <widget class="QCheckBox" name="chkComplParens"> <property name="text"> <string>Add parentheses upon function completion</string> </property> </widget> </item> - <item row="6" column="0"> + <item row="7" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> <string>Diagnostics:</string> </property> </widget> </item> - <item row="6" column="1"> + <item row="7" column="1"> <widget class="QCheckBox" name="chkDiagnostics"> <property name="text"> <string>Show program diagnostics</string> </property> </widget> </item> - <item row="7" column="1"> + <item row="8" column="1"> <layout class="QVBoxLayout" name="verticalLayout_7"> <property name="leftMargin"> <number>20</number> @@ -127,70 +127,70 @@ </item> </layout> </item> - <item row="8" column="0"> + <item row="9" column="0"> <widget class="QLabel" name="label_5"> <property name="text"> <string>Navigation:</string> </property> </widget> </item> - <item row="8" column="1"> + <item row="9" column="1"> <widget class="QCheckBox" name="chkRefDeclaration"> <property name="text"> <string>Count declarations when searching for references to a symbol</string> </property> </widget> </item> - <item row="9" column="1"> + <item row="10" column="1"> <widget class="QCheckBox" name="chkAutoHover"> <property name="text"> <string>Show information about currently hovered symbol</string> </property> </widget> </item> - <item row="10" column="1"> + <item row="11" column="1"> <widget class="QCheckBox" name="chkHighlightGoto"> <property name="text"> <string>Highlight target line when hopping to it</string> </property> </widget> </item> - <item row="11" column="0"> + <item row="12" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> <string>Server:</string> </property> </widget> </item> - <item row="11" column="1"> + <item row="12" column="1"> <widget class="QCheckBox" name="chkMessages"> <property name="text"> <string>Show notifications from the LSP server</string> </property> </widget> </item> - <item row="12" column="1"> + <item row="13" column="1"> <widget class="QCheckBox" name="chkIncrementalSync"> <property name="text"> <string>Incrementally synchronize documents with the LSP server</string> </property> </widget> </item> - <item row="14" column="1"> + <item row="15" column="1"> <widget class="QCheckBox" name="chkSymbolDetails"> <property name="text"> <string>Display additional details for symbols</string> </property> </widget> </item> - <item row="15" column="1"> + <item row="16" column="1"> <widget class="QCheckBox" name="chkSymbolTree"> <property name="text"> <string>Present symbols in a hierarchy instead of a flat list</string> </property> </widget> </item> - <item row="16" column="1"> + <item row="17" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_4"> <property name="leftMargin"> <number>20</number> @@ -207,21 +207,21 @@ </item> </layout> </item> - <item row="13" column="1"> + <item row="14" column="1"> <widget class="QCheckBox" name="chkSymbolSort"> <property name="text"> <string>Sort symbols alphabetically</string> </property> </widget> </item> - <item row="13" column="0"> + <item row="14" column="0"> <widget class="QLabel" name="label_6"> <property name="text"> <string>Document outline:</string> </property> </widget> </item> - <item row="1" column="1"> + <item row="2" column="1"> <widget class="QCheckBox" name="chkSemanticHighlighting"> <property name="text"> <string>Enable semantic highlighting</string> @@ -235,13 +235,20 @@ </property> </widget> </item> - <item row="5" column="1"> + <item row="6" column="1"> <widget class="QCheckBox" name="chkAutoImport"> <property name="text"> <string>Add imports automatically if needed upon completion</string> </property> </widget> </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="chkFmtOnSave"> + <property name="text"> + <string>Format on save</string> + </property> + </widget> + </item> </layout> </item> <item> @@ -293,8 +300,7 @@ </layout> </item> <item> - <widget class="QPlainTextEdit" name="userConfig"> - </widget> + <widget class="QPlainTextEdit" name="userConfig"/> </item> <item> <widget class="QLabel" name="userConfigError"> diff --git a/doc/kate/plugins.docbook b/doc/kate/plugins.docbook index ab950b333..590c5335a 100644 --- a/doc/kate/plugins.docbook +++ b/doc/kate/plugins.docbook @@ -2797,6 +2797,15 @@ transformed to the &JSON; configuration that is used here and outlined above. </sect3> +<sect3 id="lspclient-format-on-save"> +<title>LSP Server Format On Save</title> + +<para> +You can enable "format on save" from LSP settings in configure dialog. +</para> + +</sect3> + <sect3 id="lspclient-diagnostics-suppression"> <title>LSP Server Diagnostic Suppression</title>