forked from qt-creator/qt-creator
ClangCodeModel: Do not trigger snippets
... in strings or comments with clangd. Change-Id: Ic16e94051018e91f273fafe2ec90d5395e4cc07a Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -35,9 +35,11 @@
|
|||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/find/searchresultitem.h>
|
#include <coreplugin/find/searchresultitem.h>
|
||||||
#include <coreplugin/find/searchresultwindow.h>
|
#include <coreplugin/find/searchresultwindow.h>
|
||||||
|
#include <cplusplus/BackwardsScanner.h>
|
||||||
#include <cplusplus/FindUsages.h>
|
#include <cplusplus/FindUsages.h>
|
||||||
#include <cplusplus/Icons.h>
|
#include <cplusplus/Icons.h>
|
||||||
#include <cplusplus/MatchingText.h>
|
#include <cplusplus/MatchingText.h>
|
||||||
|
#include <cplusplus/SimpleLexer.h>
|
||||||
#include <cppeditor/cppeditorconstants.h>
|
#include <cppeditor/cppeditorconstants.h>
|
||||||
#include <cppeditor/cppcodemodelsettings.h>
|
#include <cppeditor/cppcodemodelsettings.h>
|
||||||
#include <cppeditor/cppcompletionassistprocessor.h>
|
#include <cppeditor/cppcompletionassistprocessor.h>
|
||||||
@@ -712,20 +714,12 @@ private:
|
|||||||
case CustomAssistMode::Preprocessor:
|
case CustomAssistMode::Preprocessor:
|
||||||
static QIcon macroIcon = Utils::CodeModelIcon::iconForType(Utils::CodeModelIcon::Macro);
|
static QIcon macroIcon = Utils::CodeModelIcon::iconForType(Utils::CodeModelIcon::Macro);
|
||||||
for (const QString &completion
|
for (const QString &completion
|
||||||
: CppEditor::CppCompletionAssistProcessor::preprocessorCompletions())
|
: CppEditor::CppCompletionAssistProcessor::preprocessorCompletions()) {
|
||||||
completions << createItem(completion, macroIcon);
|
completions << createItem(completion, macroIcon);
|
||||||
const CppEditor::ProjectFile::Kind fileType
|
|
||||||
= CppEditor::ProjectFile::classify(interface->filePath().toString());
|
|
||||||
switch (fileType) {
|
|
||||||
case CppEditor::ProjectFile::ObjCHeader:
|
|
||||||
case CppEditor::ProjectFile::ObjCXXHeader:
|
|
||||||
case CppEditor::ProjectFile::ObjCSource:
|
|
||||||
case CppEditor::ProjectFile::ObjCXXSource:
|
|
||||||
completions << createItem("import", macroIcon);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (CppEditor::ProjectFile::isObjC(interface->filePath().toString()))
|
||||||
|
completions << createItem("import", macroIcon);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
GenericProposalModelPtr model(new GenericProposalModel);
|
GenericProposalModelPtr model(new GenericProposalModel);
|
||||||
model->loadContent(completions);
|
model->loadContent(completions);
|
||||||
@@ -1057,12 +1051,14 @@ public:
|
|||||||
ClangdCompletionAssistProvider(ClangdClient *client);
|
ClangdCompletionAssistProvider(ClangdClient *client);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IAssistProcessor *createProcessor(const AssistInterface *assistInterface) const override;
|
IAssistProcessor *createProcessor(const AssistInterface *interface) const override;
|
||||||
|
|
||||||
int activationCharSequenceLength() const override { return 3; }
|
int activationCharSequenceLength() const override { return 3; }
|
||||||
bool isActivationCharSequence(const QString &sequence) const override;
|
bool isActivationCharSequence(const QString &sequence) const override;
|
||||||
bool isContinuationChar(const QChar &c) const override;
|
bool isContinuationChar(const QChar &c) const override;
|
||||||
|
|
||||||
|
bool isInCommentOrString(const AssistInterface *interface) const;
|
||||||
|
|
||||||
ClangdClient * const m_client;
|
ClangdClient * const m_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2573,10 +2569,10 @@ ClangdClient::ClangdCompletionAssistProvider::ClangdCompletionAssistProvider(Cla
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::createProcessor(
|
IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::createProcessor(
|
||||||
const AssistInterface *assistInterface) const
|
const AssistInterface *interface) const
|
||||||
{
|
{
|
||||||
ClangCompletionContextAnalyzer contextAnalyzer(assistInterface->textDocument(),
|
ClangCompletionContextAnalyzer contextAnalyzer(interface->textDocument(),
|
||||||
assistInterface->position(), false, {});
|
interface->position(), false, {});
|
||||||
contextAnalyzer.analyze();
|
contextAnalyzer.analyze();
|
||||||
switch (contextAnalyzer.completionAction()) {
|
switch (contextAnalyzer.completionAction()) {
|
||||||
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen:
|
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen:
|
||||||
@@ -2595,7 +2591,7 @@ IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::createProcessor(
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const QString snippetsGroup = contextAnalyzer.addSnippets()
|
const QString snippetsGroup = contextAnalyzer.addSnippets() && !isInCommentOrString(interface)
|
||||||
? CppEditor::Constants::CPP_SNIPPETS_GROUP_ID
|
? CppEditor::Constants::CPP_SNIPPETS_GROUP_ID
|
||||||
: QString();
|
: QString();
|
||||||
return new ClangdCompletionAssistProcessor(m_client, snippetsGroup);
|
return new ClangdCompletionAssistProcessor(m_client, snippetsGroup);
|
||||||
@@ -2628,6 +2624,43 @@ bool ClangdClient::ClangdCompletionAssistProvider::isContinuationChar(const QCha
|
|||||||
return CppEditor::isValidIdentifierChar(c);
|
return CppEditor::isValidIdentifierChar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClangdClient::ClangdCompletionAssistProvider::isInCommentOrString(
|
||||||
|
const AssistInterface *interface) const
|
||||||
|
{
|
||||||
|
QTextCursor tc(interface->textDocument());
|
||||||
|
tc.setPosition(interface->position());
|
||||||
|
|
||||||
|
SimpleLexer tokenize;
|
||||||
|
tokenize.setSkipComments(false);
|
||||||
|
const Tokens &tokens = tokenize(tc.block().text(),
|
||||||
|
BackwardsScanner::previousBlockState(tc.block()));
|
||||||
|
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
|
||||||
|
const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
|
||||||
|
|
||||||
|
if (tk.isComment())
|
||||||
|
return true;
|
||||||
|
if (!tk.isLiteral())
|
||||||
|
return false;
|
||||||
|
if (tokens.size() == 3 && tokens.at(0).kind() == T_POUND
|
||||||
|
&& tokens.at(1).kind() == T_IDENTIFIER) {
|
||||||
|
const QString &line = tc.block().text();
|
||||||
|
const Token &idToken = tokens.at(1);
|
||||||
|
QStringView identifier = idToken.utf16charsEnd() > line.size()
|
||||||
|
? QStringView(line).mid(
|
||||||
|
idToken.utf16charsBegin())
|
||||||
|
: QStringView(line)
|
||||||
|
.mid(idToken.utf16charsBegin(),
|
||||||
|
idToken.utf16chars());
|
||||||
|
if (identifier == QLatin1String("include")
|
||||||
|
|| identifier == QLatin1String("include_next")
|
||||||
|
|| (CppEditor::ProjectFile::isObjC(interface->filePath().toString())
|
||||||
|
&& identifier == QLatin1String("import"))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
|
void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
|
||||||
int /*basePosition*/) const
|
int /*basePosition*/) const
|
||||||
{
|
{
|
||||||
|
@@ -87,6 +87,20 @@ bool ProjectFile::isAmbiguousHeader(const QString &filePath)
|
|||||||
return filePath.endsWith(".h");
|
return filePath.endsWith(".h");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProjectFile::isObjC(const QString &filePath)
|
||||||
|
{
|
||||||
|
const Kind kind = classify(filePath);
|
||||||
|
switch (kind) {
|
||||||
|
case CppEditor::ProjectFile::ObjCHeader:
|
||||||
|
case CppEditor::ProjectFile::ObjCXXHeader:
|
||||||
|
case CppEditor::ProjectFile::ObjCSource:
|
||||||
|
case CppEditor::ProjectFile::ObjCXXSource:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ProjectFile::Kind ProjectFile::sourceForHeaderKind(ProjectFile::Kind kind)
|
ProjectFile::Kind ProjectFile::sourceForHeaderKind(ProjectFile::Kind kind)
|
||||||
{
|
{
|
||||||
ProjectFile::Kind sourceKind;
|
ProjectFile::Kind sourceKind;
|
||||||
|
@@ -61,6 +61,7 @@ public:
|
|||||||
static bool isC(Kind kind);
|
static bool isC(Kind kind);
|
||||||
static bool isCxx(Kind kind);
|
static bool isCxx(Kind kind);
|
||||||
static bool isAmbiguousHeader(const QString &filePath);
|
static bool isAmbiguousHeader(const QString &filePath);
|
||||||
|
static bool isObjC(const QString &filePath);
|
||||||
|
|
||||||
bool isHeader() const;
|
bool isHeader() const;
|
||||||
bool isSource() const;
|
bool isSource() const;
|
||||||
|
Reference in New Issue
Block a user