forked from qt-creator/qt-creator
LSP: collect and execute quick fixes via shortcut
Fixes: QTCREATORBUG-21802 Change-Id: I611fac1c3fc5b094816441e36492ed57706c98b8 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -27,14 +27,15 @@
|
||||
#include "lsputils.h"
|
||||
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <utils/textutils.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QHash>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QMap>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocument>
|
||||
#include <QVector>
|
||||
#include <QFile>
|
||||
|
||||
namespace LanguageServerProtocol {
|
||||
|
||||
@@ -340,6 +341,24 @@ Range::Range(const Position &start, const Position &end)
|
||||
setEnd(end);
|
||||
}
|
||||
|
||||
Range::Range(const QTextCursor &cursor)
|
||||
{
|
||||
int line, character = 0;
|
||||
Utils::Text::convertPosition(cursor.document(), cursor.selectionStart(), &line, &character);
|
||||
if (line <= 0 || character <= 0)
|
||||
return;
|
||||
setStart(Position(line - 1, character - 1));
|
||||
Utils::Text::convertPosition(cursor.document(), cursor.selectionEnd(), &line, &character);
|
||||
if (line <= 0 || character <= 0)
|
||||
return;
|
||||
setEnd(Position(line - 1, character - 1));
|
||||
}
|
||||
|
||||
bool Range::overlaps(const Range &range) const
|
||||
{
|
||||
return contains(range.start()) || contains(range.end());
|
||||
}
|
||||
|
||||
bool DocumentFilter::applies(const Utils::FileName &fileName, const Utils::MimeType &mimeType) const
|
||||
{
|
||||
if (Utils::optional<QString> _scheme = scheme()) {
|
||||
|
@@ -100,6 +100,7 @@ class LANGUAGESERVERPROTOCOL_EXPORT Range : public JsonObject
|
||||
public:
|
||||
Range() = default;
|
||||
Range(const Position &start, const Position &end);
|
||||
explicit Range(const QTextCursor &cursor);
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
// The range's start position.
|
||||
@@ -111,6 +112,7 @@ public:
|
||||
void setEnd(const Position &end) { insert(endKey, end); }
|
||||
|
||||
bool contains(const Position &pos) const { return start() <= pos && pos <= end(); }
|
||||
bool overlaps(const Range &range) const;
|
||||
|
||||
bool isValid(QStringList *error) const override
|
||||
{ return check<Position>(error, startKey) && check<Position>(error, endKey); }
|
||||
|
@@ -69,6 +69,7 @@ class TextMark : public TextEditor::TextMark
|
||||
public:
|
||||
TextMark(const Utils::FileName &fileName, const Diagnostic &diag)
|
||||
: TextEditor::TextMark(fileName, diag.range().start().line() + 1, "lspmark")
|
||||
, m_diagnostic(diag)
|
||||
{
|
||||
using namespace Utils;
|
||||
setLineAnnotation(diag.message());
|
||||
@@ -81,11 +82,17 @@ public:
|
||||
setIcon(isError ? Icons::CODEMODEL_ERROR.icon()
|
||||
: Icons::CODEMODEL_WARNING.icon());
|
||||
}
|
||||
|
||||
const Diagnostic &diagnostic() const { return m_diagnostic; }
|
||||
|
||||
private:
|
||||
const Diagnostic m_diagnostic;
|
||||
};
|
||||
|
||||
Client::Client(BaseClientInterface *clientInterface)
|
||||
: m_id(Core::Id::fromString(QUuid::createUuid().toString()))
|
||||
, m_completionProvider(this)
|
||||
, m_quickFixProvider(this)
|
||||
, m_clientInterface(clientInterface)
|
||||
{
|
||||
m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(),
|
||||
@@ -101,8 +108,10 @@ Client::~Client()
|
||||
using namespace TextEditor;
|
||||
// FIXME: instead of replacing the completion provider in the text document store the
|
||||
// completion provider as a prioritised list in the text document
|
||||
for (TextDocument *document : m_resetCompletionProvider)
|
||||
for (TextDocument *document : m_resetAssistProvider) {
|
||||
document->setCompletionAssistProvider(nullptr);
|
||||
document->setQuickFixAssistProvider(nullptr);
|
||||
}
|
||||
for (Core::IEditor * editor : Core::DocumentModel::editorsForOpenedDocuments()) {
|
||||
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) {
|
||||
TextEditorWidget *widget = textEditor->editorWidget();
|
||||
@@ -192,10 +201,12 @@ void Client::openDocument(Core::IDocument *document)
|
||||
documentContentsChanged(document);
|
||||
});
|
||||
if (textDocument) {
|
||||
m_resetCompletionProvider << textDocument;
|
||||
textDocument->completionAssistProvider();
|
||||
m_resetAssistProvider << textDocument;
|
||||
textDocument->setCompletionAssistProvider(&m_completionProvider);
|
||||
textDocument->setQuickFixAssistProvider(&m_quickFixProvider);
|
||||
connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
|
||||
m_resetCompletionProvider.remove(textDocument);
|
||||
m_resetAssistProvider.remove(textDocument);
|
||||
});
|
||||
if (BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(textDocument)) {
|
||||
if (QPointer<TextEditorWidget> widget = editor->editorWidget()) {
|
||||
@@ -547,21 +558,6 @@ void Client::requestCodeActions(const DocumentUri &uri, const QList<Diagnostic>
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
const QString method(CodeActionRequest::methodName);
|
||||
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
||||
if (!registered.value())
|
||||
return;
|
||||
const TextDocumentRegistrationOptions option(
|
||||
m_dynamicCapabilities.option(method).toObject());
|
||||
if (option.isValid(nullptr) && !option.filterApplies(fileName))
|
||||
return;
|
||||
} else {
|
||||
Utils::variant<bool, CodeActionOptions> provider
|
||||
= m_serverCapabilities.codeActionProvider().value_or(false);
|
||||
if (!(Utils::holds_alternative<CodeActionOptions>(provider) || Utils::get<bool>(provider)))
|
||||
return;
|
||||
}
|
||||
|
||||
CodeActionParams codeActionParams;
|
||||
CodeActionParams::CodeActionContext context;
|
||||
context.setDiagnostics(diagnostics);
|
||||
@@ -577,6 +573,32 @@ void Client::requestCodeActions(const DocumentUri &uri, const QList<Diagnostic>
|
||||
if (self)
|
||||
self->handleCodeActionResponse(response, uri);
|
||||
});
|
||||
requestCodeActions(request);
|
||||
}
|
||||
|
||||
void Client::requestCodeActions(const CodeActionRequest &request)
|
||||
{
|
||||
if (!request.isValid(nullptr))
|
||||
return;
|
||||
|
||||
const Utils::FileName fileName
|
||||
= request.params().value_or(CodeActionParams()).textDocument().uri().toFileName();
|
||||
|
||||
const QString method(CodeActionRequest::methodName);
|
||||
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
||||
if (!registered.value())
|
||||
return;
|
||||
const TextDocumentRegistrationOptions option(
|
||||
m_dynamicCapabilities.option(method).toObject());
|
||||
if (option.isValid(nullptr) && !option.filterApplies(fileName))
|
||||
return;
|
||||
} else {
|
||||
Utils::variant<bool, CodeActionOptions> provider
|
||||
= m_serverCapabilities.codeActionProvider().value_or(false);
|
||||
if (!(Utils::holds_alternative<CodeActionOptions>(provider) || Utils::get<bool>(provider)))
|
||||
return;
|
||||
}
|
||||
|
||||
sendContent(request);
|
||||
}
|
||||
|
||||
@@ -682,6 +704,17 @@ bool Client::needsRestart(const BaseSettings *settings) const
|
||||
|| m_languagFilter.filePattern != settings->m_languageFilter.filePattern;
|
||||
}
|
||||
|
||||
QList<Diagnostic> Client::diagnosticsAt(const DocumentUri &uri, const Range &range) const
|
||||
{
|
||||
QList<Diagnostic> diagnostics;
|
||||
for (const TextMark *mark : m_diagnostics[uri]) {
|
||||
const Diagnostic diagnostic = mark->diagnostic();
|
||||
if (diagnostic.range().overlaps(range))
|
||||
diagnostics << diagnostic;
|
||||
}
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
bool Client::start()
|
||||
{
|
||||
return m_clientInterface->start();
|
||||
|
@@ -26,7 +26,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "dynamiccapabilities.h"
|
||||
#include "languageclientcodeassist.h"
|
||||
#include "languageclientcompletionassist.h"
|
||||
#include "languageclientquickfix.h"
|
||||
#include "languageclientsettings.h"
|
||||
|
||||
#include <coreplugin/id.h>
|
||||
@@ -104,6 +105,7 @@ public:
|
||||
|
||||
void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri,
|
||||
const QList<LanguageServerProtocol::Diagnostic> &diagnostics);
|
||||
void requestCodeActions(const LanguageServerProtocol::CodeActionRequest &request);
|
||||
void handleCodeActionResponse(const LanguageServerProtocol::CodeActionRequest::Response &response,
|
||||
const LanguageServerProtocol::DocumentUri &uri);
|
||||
void executeCommand(const LanguageServerProtocol::Command &command);
|
||||
@@ -129,6 +131,10 @@ public:
|
||||
|
||||
bool needsRestart(const BaseSettings *) const;
|
||||
|
||||
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(
|
||||
const LanguageServerProtocol::DocumentUri &uri,
|
||||
const LanguageServerProtocol::Range &range) const;
|
||||
|
||||
bool start();
|
||||
bool reset();
|
||||
|
||||
@@ -184,7 +190,8 @@ private:
|
||||
LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
|
||||
DynamicCapabilities m_dynamicCapabilities;
|
||||
LanguageClientCompletionAssistProvider m_completionProvider;
|
||||
QSet<TextEditor::TextDocument *> m_resetCompletionProvider;
|
||||
LanguageClientQuickFixProvider m_quickFixProvider;
|
||||
QSet<TextEditor::TextDocument *> m_resetAssistProvider;
|
||||
QHash<LanguageServerProtocol::DocumentUri, LanguageServerProtocol::MessageId> m_highlightRequests;
|
||||
int m_restartsLeft = 5;
|
||||
QScopedPointer<BaseClientInterface> m_clientInterface;
|
||||
|
@@ -6,11 +6,12 @@ HEADERS += \
|
||||
client.h \
|
||||
dynamiccapabilities.h \
|
||||
languageclient_global.h \
|
||||
languageclientcodeassist.h \
|
||||
languageclientcompletionassist.h \
|
||||
languageclientinterface.h \
|
||||
languageclientmanager.h \
|
||||
languageclientoutline.h \
|
||||
languageclientplugin.h \
|
||||
languageclientquickfix.h \
|
||||
languageclientsettings.h \
|
||||
languageclientutils.h
|
||||
|
||||
@@ -18,11 +19,12 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
client.cpp \
|
||||
dynamiccapabilities.cpp \
|
||||
languageclientcodeassist.cpp \
|
||||
languageclientcompletionassist.cpp \
|
||||
languageclientinterface.cpp \
|
||||
languageclientmanager.cpp \
|
||||
languageclientoutline.cpp \
|
||||
languageclientplugin.cpp \
|
||||
languageclientquickfix.cpp \
|
||||
languageclientsettings.cpp \
|
||||
languageclientutils.cpp
|
||||
|
||||
|
@@ -20,16 +20,18 @@ QtcPlugin {
|
||||
"dynamiccapabilities.h",
|
||||
"languageclient.qrc",
|
||||
"languageclient_global.h",
|
||||
"languageclientcodeassist.cpp",
|
||||
"languageclientcodeassist.h",
|
||||
"languageclientinterface.cpp",
|
||||
"languageclientinterface.h",
|
||||
"languageclientcompletionassist.cpp",
|
||||
"languageclientcompletionassist.h",
|
||||
"languageclientmanager.cpp",
|
||||
"languageclientmanager.h",
|
||||
"languageclientoutline.cpp",
|
||||
"languageclientoutline.h",
|
||||
"languageclientplugin.cpp",
|
||||
"languageclientplugin.h",
|
||||
"languageclientquickfix.cpp",
|
||||
"languageclientquickfix.h",
|
||||
"languageclientsettings.cpp",
|
||||
"languageclientsettings.h",
|
||||
"languageclientutils.cpp",
|
||||
|
@@ -23,7 +23,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "languageclientcodeassist.h"
|
||||
#include "languageclientcompletionassist.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "languageclientutils.h"
|
@@ -48,7 +48,7 @@ public:
|
||||
private:
|
||||
QList<QString> m_triggerChars;
|
||||
int m_activationCharSequenceLength = 0;
|
||||
Client *m_client;
|
||||
Client *m_client = nullptr; // not owned
|
||||
};
|
||||
|
||||
} // namespace LanguageClient
|
166
src/plugins/languageclient/languageclientquickfix.cpp
Normal file
166
src/plugins/languageclient/languageclientquickfix.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "languageclientquickfix.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "languageclientutils.h"
|
||||
|
||||
#include <texteditor/codeassist/assistinterface.h>
|
||||
#include <texteditor/codeassist/genericproposal.h>
|
||||
#include <texteditor/codeassist/iassistprocessor.h>
|
||||
#include <texteditor/quickfix.h>
|
||||
|
||||
|
||||
using namespace LanguageServerProtocol;
|
||||
using namespace TextEditor;
|
||||
|
||||
namespace LanguageClient {
|
||||
|
||||
class CodeActionQuickFixOperation : public QuickFixOperation
|
||||
{
|
||||
public:
|
||||
CodeActionQuickFixOperation(const CodeAction &action, Client *client)
|
||||
: m_action(action)
|
||||
, m_client(client)
|
||||
{ setDescription(action.title()); }
|
||||
|
||||
void perform() override
|
||||
{
|
||||
if (Utils::optional<WorkspaceEdit> edit = m_action.edit()) {
|
||||
applyWorkspaceEdit(*edit);
|
||||
} else if (Utils::optional<Command> command = m_action.command()) {
|
||||
if (m_client)
|
||||
m_client->executeCommand(*command);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CodeAction m_action;
|
||||
QPointer<Client> m_client;
|
||||
};
|
||||
|
||||
class CommandQuickFixOperation : public QuickFixOperation
|
||||
{
|
||||
public:
|
||||
CommandQuickFixOperation(const Command &command, Client *client)
|
||||
: m_command(command)
|
||||
, m_client(client)
|
||||
{ setDescription(command.title()); }
|
||||
void perform() override
|
||||
{
|
||||
if (m_client)
|
||||
m_client->executeCommand(m_command);
|
||||
}
|
||||
|
||||
private:
|
||||
Command m_command;
|
||||
QPointer<Client> m_client;
|
||||
};
|
||||
|
||||
class LanguageClientQuickFixAssistProcessor : public IAssistProcessor
|
||||
{
|
||||
public:
|
||||
explicit LanguageClientQuickFixAssistProcessor(Client *client) : m_client(client) {}
|
||||
bool running() override { return m_running; }
|
||||
IAssistProposal *perform(const AssistInterface *interface) override;
|
||||
|
||||
private:
|
||||
void handleCodeActionResponse(const CodeActionRequest::Response &response);
|
||||
|
||||
QSharedPointer<const AssistInterface> m_assistInterface;
|
||||
Client *m_client = nullptr; // not owned
|
||||
bool m_running = false;
|
||||
};
|
||||
|
||||
IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInterface *interface)
|
||||
{
|
||||
m_assistInterface = QSharedPointer<const AssistInterface>(interface);
|
||||
|
||||
CodeActionParams params;
|
||||
params.setContext({});
|
||||
QTextCursor cursor(interface->textDocument());
|
||||
cursor.setPosition(interface->position());
|
||||
if (cursor.atBlockEnd() || cursor.atBlockStart())
|
||||
cursor.select(QTextCursor::LineUnderCursor);
|
||||
else
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
if (!cursor.hasSelection())
|
||||
cursor.select(QTextCursor::LineUnderCursor);
|
||||
Range range(cursor);
|
||||
params.setRange(range);
|
||||
auto uri = DocumentUri::fromFileName(Utils::FileName::fromString(interface->fileName()));
|
||||
params.setTextDocument(uri);
|
||||
CodeActionParams::CodeActionContext context;
|
||||
context.setDiagnostics(m_client->diagnosticsAt(uri, range));
|
||||
params.setContext(context);
|
||||
|
||||
CodeActionRequest request(params);
|
||||
request.setResponseCallback([this](const CodeActionRequest::Response &response){
|
||||
handleCodeActionResponse(response);
|
||||
});
|
||||
|
||||
m_client->requestCodeActions(request);
|
||||
m_running = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse(
|
||||
const CodeActionRequest::Response &response)
|
||||
{
|
||||
m_running = false;
|
||||
if (const Utils::optional<CodeActionRequest::Response::Error> &error = response.error())
|
||||
m_client->log(*error);
|
||||
QuickFixOperations ops;
|
||||
if (const Utils::optional<CodeActionResult> &_result = response.result()) {
|
||||
const CodeActionResult &result = _result.value();
|
||||
if (auto list = Utils::get_if<QList<Utils::variant<Command, CodeAction>>>(&result)) {
|
||||
for (const Utils::variant<Command, CodeAction> &item : *list) {
|
||||
if (auto action = Utils::get_if<CodeAction>(&item))
|
||||
ops << new CodeActionQuickFixOperation(*action, m_client);
|
||||
else if (auto command = Utils::get_if<Command>(&item))
|
||||
ops << new CommandQuickFixOperation(*command, m_client);
|
||||
}
|
||||
}
|
||||
}
|
||||
setAsyncProposalAvailable(GenericProposal::createProposal(m_assistInterface.data(), ops));
|
||||
}
|
||||
|
||||
LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client) : m_client(client)
|
||||
{
|
||||
QTC_CHECK(client);
|
||||
}
|
||||
|
||||
IAssistProvider::RunType LanguageClientQuickFixProvider::runType() const
|
||||
{
|
||||
return Asynchronous;
|
||||
}
|
||||
|
||||
IAssistProcessor *LanguageClientQuickFixProvider::createProcessor() const
|
||||
{
|
||||
return new LanguageClientQuickFixAssistProcessor(m_client);
|
||||
}
|
||||
|
||||
} // namespace LanguageClient
|
45
src/plugins/languageclient/languageclientquickfix.h
Normal file
45
src/plugins/languageclient/languageclientquickfix.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <texteditor/codeassist/iassistprovider.h>
|
||||
|
||||
namespace LanguageClient {
|
||||
|
||||
class Client;
|
||||
|
||||
class LanguageClientQuickFixProvider : public TextEditor::IAssistProvider
|
||||
{
|
||||
public:
|
||||
explicit LanguageClientQuickFixProvider(Client *client);
|
||||
IAssistProvider::RunType runType() const override;
|
||||
TextEditor::IAssistProcessor *createProcessor() const override;
|
||||
|
||||
private:
|
||||
Client *m_client = nullptr; // not owned
|
||||
};
|
||||
|
||||
} // namespace LanguageClient
|
@@ -100,6 +100,7 @@ public:
|
||||
QTextDocument m_document;
|
||||
SyntaxHighlighter *m_highlighter = nullptr;
|
||||
CompletionAssistProvider *m_completionAssistProvider = nullptr;
|
||||
IAssistProvider *m_quickFixProvider = nullptr;
|
||||
QScopedPointer<Indenter> m_indenter;
|
||||
|
||||
bool m_fileIsReadOnly = false;
|
||||
@@ -388,9 +389,14 @@ CompletionAssistProvider *TextDocument::completionAssistProvider() const
|
||||
return d->m_completionAssistProvider;
|
||||
}
|
||||
|
||||
void TextDocument::setQuickFixAssistProvider(IAssistProvider *provider) const
|
||||
{
|
||||
d->m_quickFixProvider = provider;
|
||||
}
|
||||
|
||||
IAssistProvider *TextDocument::quickFixAssistProvider() const
|
||||
{
|
||||
return nullptr;
|
||||
return d->m_quickFixProvider;
|
||||
}
|
||||
|
||||
void TextDocument::applyFontSettings()
|
||||
|
@@ -140,6 +140,7 @@ public:
|
||||
|
||||
void setCompletionAssistProvider(CompletionAssistProvider *provider);
|
||||
virtual CompletionAssistProvider *completionAssistProvider() const;
|
||||
void setQuickFixAssistProvider(IAssistProvider *provider) const;
|
||||
virtual IAssistProvider *quickFixAssistProvider() const;
|
||||
|
||||
void setTabSettings(const TextEditor::TabSettings &tabSettings);
|
||||
|
Reference in New Issue
Block a user