forked from qt-creator/qt-creator
TextEditor: Introduce shortcut for forcing a function hint proposal
... and support it in the ClangCodeModel. This allows users to get function signature(s) displayed regardless of where exactly the cursor is on the function call. Fixes: QTCREATORBUG-19394 Change-Id: I033e8774db93680bfc3ee52610b817e0ef8ccc76 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -30,8 +30,7 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
ClangCompletionAssistInterface::ClangCompletionAssistInterface(
|
||||
BackendCommunicator &communicator,
|
||||
ClangCompletionAssistInterface::ClangCompletionAssistInterface(BackendCommunicator &communicator, CompletionType type,
|
||||
const TextEditor::TextEditorWidget *textEditorWidget,
|
||||
int position,
|
||||
const QString &fileName,
|
||||
@@ -40,6 +39,7 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(
|
||||
const CPlusPlus::LanguageFeatures &features)
|
||||
: AssistInterface(textEditorWidget->document(), position, fileName, reason)
|
||||
, m_communicator(communicator)
|
||||
, m_type(type)
|
||||
, m_headerPaths(headerPaths)
|
||||
, m_languageFeatures(features)
|
||||
, m_textEditorWidget(textEditorWidget)
|
||||
|
@@ -33,10 +33,13 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
enum class CompletionType { FunctionHint, Other };
|
||||
|
||||
class ClangCompletionAssistInterface: public TextEditor::AssistInterface
|
||||
{
|
||||
public:
|
||||
ClangCompletionAssistInterface(BackendCommunicator &communicator,
|
||||
CompletionType type,
|
||||
const TextEditor::TextEditorWidget *textEditorWidget,
|
||||
int position,
|
||||
const QString &fileName,
|
||||
@@ -45,6 +48,7 @@ public:
|
||||
const CPlusPlus::LanguageFeatures &features);
|
||||
|
||||
BackendCommunicator &communicator() const;
|
||||
CompletionType type() const { return m_type; }
|
||||
bool objcEnabled() const;
|
||||
const ProjectExplorer::HeaderPaths &headerPaths() const;
|
||||
CPlusPlus::LanguageFeatures languageFeatures() const;
|
||||
@@ -54,6 +58,7 @@ public:
|
||||
|
||||
private:
|
||||
BackendCommunicator &m_communicator;
|
||||
const CompletionType m_type;
|
||||
QStringList m_options;
|
||||
ProjectExplorer::HeaderPaths m_headerPaths;
|
||||
CPlusPlus::LanguageFeatures m_languageFeatures;
|
||||
|
@@ -347,6 +347,7 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
|
||||
analyzer.functionNameStart());
|
||||
break;
|
||||
}
|
||||
case ClangCompletionContextAnalyzer::CompleteNone:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -43,8 +43,9 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
ClangCompletionAssistProvider::ClangCompletionAssistProvider(BackendCommunicator &communicator)
|
||||
: m_communicator(communicator)
|
||||
ClangCompletionAssistProvider::ClangCompletionAssistProvider(BackendCommunicator &communicator,
|
||||
CompletionType type)
|
||||
: m_communicator(communicator), m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -68,6 +69,7 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac
|
||||
const CppTools::ProjectPart::Ptr projectPart = projectPartForFileBasedOnProcessor(filePath);
|
||||
if (projectPart) {
|
||||
return new ClangCompletionAssistInterface(m_communicator,
|
||||
m_type,
|
||||
textEditorWidget,
|
||||
position,
|
||||
filePath,
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "clangbackendcommunicator.h"
|
||||
#include "clangcompletionassistinterface.h"
|
||||
|
||||
#include <cpptools/cppcompletionassistprovider.h>
|
||||
|
||||
@@ -39,7 +40,7 @@ class ClangCompletionAssistProvider : public CppTools::CppCompletionAssistProvid
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClangCompletionAssistProvider(BackendCommunicator &communicator);
|
||||
ClangCompletionAssistProvider(BackendCommunicator &communicator, CompletionType type);
|
||||
|
||||
IAssistProvider::RunType runType() const override;
|
||||
|
||||
@@ -53,6 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
BackendCommunicator &m_communicator;
|
||||
CompletionType m_type;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -84,7 +84,8 @@ void ClangCompletionContextAnalyzer::analyze()
|
||||
m_positionEndOfExpression = activationSequenceContextProcessor.operatorStartPosition();
|
||||
m_positionForProposal = activationSequenceContextProcessor.startOfNamePosition();
|
||||
|
||||
const bool actionIsSet = handleNonFunctionCall(afterOperatorPosition);
|
||||
const bool actionIsSet = m_interface->type() != CompletionType::FunctionHint
|
||||
&& handleNonFunctionCall(afterOperatorPosition);
|
||||
if (!actionIsSet) {
|
||||
handleCommaInFunctionCall();
|
||||
handleFunctionCall(afterOperatorPosition);
|
||||
@@ -150,6 +151,19 @@ void ClangCompletionContextAnalyzer::handleCommaInFunctionCall()
|
||||
|
||||
void ClangCompletionContextAnalyzer::handleFunctionCall(int afterOperatorPosition)
|
||||
{
|
||||
if (m_interface->type() == CompletionType::FunctionHint) {
|
||||
const int functionNameStart = startOfFunctionCall(afterOperatorPosition);
|
||||
if (functionNameStart >= 0) {
|
||||
m_addSnippets = functionNameStart == afterOperatorPosition;
|
||||
setActionAndClangPosition(PassThroughToLibClangAfterLeftParen,
|
||||
m_positionForProposal,
|
||||
functionNameStart);
|
||||
} else {
|
||||
m_completionAction = CompleteNone;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_completionOperator == T_LPAREN || m_completionOperator == T_LBRACE) {
|
||||
ExpressionUnderCursor expressionUnderCursor(m_languageFeatures);
|
||||
QTextCursor textCursor(m_interface->textDocument());
|
||||
|
@@ -51,7 +51,8 @@ public:
|
||||
CompleteIncludePath,
|
||||
CompletePreprocessorDirective,
|
||||
CompleteSignal,
|
||||
CompleteSlot
|
||||
CompleteSlot,
|
||||
CompleteNone
|
||||
};
|
||||
CompletionAction completionAction() const { return m_completionAction; }
|
||||
unsigned completionOperator() const { return m_completionOperator; }
|
||||
|
@@ -69,7 +69,8 @@ static CppTools::CppModelManager *cppModelManager()
|
||||
}
|
||||
|
||||
ClangModelManagerSupport::ClangModelManagerSupport()
|
||||
: m_completionAssistProvider(m_communicator)
|
||||
: m_completionAssistProvider(m_communicator, CompletionType::Other)
|
||||
, m_functionHintAssistProvider(m_communicator, CompletionType::FunctionHint)
|
||||
, m_followSymbol(new ClangFollowSymbol)
|
||||
, m_refactoringEngine(new RefactoringEngine)
|
||||
{
|
||||
@@ -119,6 +120,11 @@ CppTools::CppCompletionAssistProvider *ClangModelManagerSupport::completionAssis
|
||||
return &m_completionAssistProvider;
|
||||
}
|
||||
|
||||
CppTools::CppCompletionAssistProvider *ClangModelManagerSupport::functionHintAssistProvider()
|
||||
{
|
||||
return &m_functionHintAssistProvider;
|
||||
}
|
||||
|
||||
TextEditor::BaseHoverHandler *ClangModelManagerSupport::createHoverHandler()
|
||||
{
|
||||
return new Internal::ClangHoverHandler;
|
||||
|
@@ -63,6 +63,7 @@ public:
|
||||
~ClangModelManagerSupport() override;
|
||||
|
||||
CppTools::CppCompletionAssistProvider *completionAssistProvider() override;
|
||||
CppTools::CppCompletionAssistProvider *functionHintAssistProvider() override;
|
||||
TextEditor::BaseHoverHandler *createHoverHandler() override;
|
||||
CppTools::BaseEditorDocumentProcessor *createEditorDocumentProcessor(
|
||||
TextEditor::TextDocument *baseTextDocument) override;
|
||||
@@ -121,6 +122,7 @@ private:
|
||||
UiHeaderOnDiskManager m_uiHeaderOnDiskManager;
|
||||
BackendCommunicator m_communicator;
|
||||
ClangCompletionAssistProvider m_completionAssistProvider;
|
||||
ClangCompletionAssistProvider m_functionHintAssistProvider;
|
||||
std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
|
||||
std::unique_ptr<CppTools::RefactoringEngineInterface> m_refactoringEngine;
|
||||
|
||||
|
@@ -142,6 +142,11 @@ CppTools::CppCompletionAssistProvider *CppEditorDocument::completionAssistProvid
|
||||
return m_completionAssistProvider;
|
||||
}
|
||||
|
||||
CppTools::CppCompletionAssistProvider *CppEditorDocument::functionHintAssistProvider() const
|
||||
{
|
||||
return m_functionHintAssistProvider;
|
||||
}
|
||||
|
||||
TextEditor::IAssistProvider *CppEditorDocument::quickFixAssistProvider() const
|
||||
{
|
||||
return CppEditorPlugin::instance()->quickFixProvider();
|
||||
@@ -195,6 +200,7 @@ void CppEditorDocument::onMimeTypeChanged()
|
||||
m_isObjCEnabled = (mt == QLatin1String(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE)
|
||||
|| mt == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE));
|
||||
m_completionAssistProvider = mm()->completionAssistProvider();
|
||||
m_functionHintAssistProvider = mm()->functionHintAssistProvider();
|
||||
|
||||
initializeTimer();
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ public:
|
||||
|
||||
bool isObjCEnabled() const;
|
||||
CppTools::CppCompletionAssistProvider *completionAssistProvider() const override;
|
||||
CppTools::CppCompletionAssistProvider *functionHintAssistProvider() const override;
|
||||
TextEditor::IAssistProvider *quickFixAssistProvider() const override;
|
||||
|
||||
void recalculateSemanticInfoDetached();
|
||||
@@ -128,6 +129,7 @@ private:
|
||||
QScopedPointer<CppTools::BaseEditorDocumentProcessor> m_processor;
|
||||
|
||||
CppTools::CppCompletionAssistProvider *m_completionAssistProvider = nullptr;
|
||||
CppTools::CppCompletionAssistProvider *m_functionHintAssistProvider = nullptr;
|
||||
|
||||
// (Un)Registration in CppModelManager
|
||||
QScopedPointer<CppTools::CppEditorDocumentHandle> m_editorDocumentHandle;
|
||||
|
@@ -1017,8 +1017,11 @@ void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo,
|
||||
|
||||
AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistReason reason) const
|
||||
{
|
||||
if (kind == Completion) {
|
||||
if (CppCompletionAssistProvider *cap = cppEditorDocument()->completionAssistProvider()) {
|
||||
if (kind == Completion || kind == FunctionHint) {
|
||||
CppCompletionAssistProvider * const cap = kind == Completion
|
||||
? cppEditorDocument()->completionAssistProvider()
|
||||
: cppEditorDocument()->functionHintAssistProvider();
|
||||
if (cap) {
|
||||
LanguageFeatures features = LanguageFeatures::defaultFeatures();
|
||||
if (Document::Ptr doc = d->m_lastSemanticInfo.doc)
|
||||
features = doc->languageFeatures();
|
||||
|
@@ -74,6 +74,12 @@ CppCompletionAssistProvider *BuiltinModelManagerSupport::completionAssistProvide
|
||||
return m_completionAssistProvider.data();
|
||||
}
|
||||
|
||||
|
||||
CppCompletionAssistProvider *BuiltinModelManagerSupport::functionHintAssistProvider()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TextEditor::BaseHoverHandler *BuiltinModelManagerSupport::createHoverHandler()
|
||||
{
|
||||
return new CppHoverHandler;
|
||||
|
@@ -41,6 +41,7 @@ public:
|
||||
~BuiltinModelManagerSupport() override;
|
||||
|
||||
CppCompletionAssistProvider *completionAssistProvider() final;
|
||||
CppCompletionAssistProvider *functionHintAssistProvider() override;
|
||||
TextEditor::BaseHoverHandler *createHoverHandler() final;
|
||||
BaseEditorDocumentProcessor *createEditorDocumentProcessor(
|
||||
TextEditor::TextDocument *baseTextDocument) final;
|
||||
|
@@ -1442,6 +1442,11 @@ CppCompletionAssistProvider *CppModelManager::completionAssistProvider() const
|
||||
return d->m_activeModelManagerSupport->completionAssistProvider();
|
||||
}
|
||||
|
||||
CppCompletionAssistProvider *CppModelManager::functionHintAssistProvider() const
|
||||
{
|
||||
return d->m_activeModelManagerSupport->functionHintAssistProvider();
|
||||
}
|
||||
|
||||
TextEditor::BaseHoverHandler *CppModelManager::createHoverHandler() const
|
||||
{
|
||||
return d->m_activeModelManagerSupport->createHoverHandler();
|
||||
|
@@ -180,6 +180,7 @@ public:
|
||||
|
||||
void activateClangCodeModel(ModelManagerSupportProvider *modelManagerSupportProvider);
|
||||
CppCompletionAssistProvider *completionAssistProvider() const;
|
||||
CppCompletionAssistProvider *functionHintAssistProvider() const;
|
||||
BaseEditorDocumentProcessor *createEditorDocumentProcessor(
|
||||
TextEditor::TextDocument *baseTextDocument) const;
|
||||
TextEditor::BaseHoverHandler *createHoverHandler() const;
|
||||
|
@@ -54,6 +54,7 @@ public:
|
||||
virtual ~ModelManagerSupport() = 0;
|
||||
|
||||
virtual CppCompletionAssistProvider *completionAssistProvider() = 0;
|
||||
virtual CppCompletionAssistProvider *functionHintAssistProvider() = 0;
|
||||
virtual TextEditor::BaseHoverHandler *createHoverHandler() = 0;
|
||||
virtual BaseEditorDocumentProcessor *createEditorDocumentProcessor(
|
||||
TextEditor::TextDocument *baseTextDocument) = 0;
|
||||
|
@@ -31,7 +31,8 @@ enum AssistKind
|
||||
{
|
||||
Completion,
|
||||
QuickFix,
|
||||
FollowSymbol
|
||||
FollowSymbol,
|
||||
FunctionHint
|
||||
};
|
||||
|
||||
enum AssistReason
|
||||
|
@@ -180,7 +180,7 @@ void CodeAssistantPrivate::process()
|
||||
}
|
||||
|
||||
startAutomaticProposalTimer();
|
||||
} else {
|
||||
} else if (m_assistKind != FunctionHint){
|
||||
m_assistKind = TextEditor::Completion;
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,8 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
|
||||
if (!provider) {
|
||||
if (kind == Completion)
|
||||
provider = m_editorWidget->textDocument()->completionAssistProvider();
|
||||
else if (kind == FunctionHint)
|
||||
provider = m_editorWidget->textDocument()->functionHintAssistProvider();
|
||||
else
|
||||
provider = m_editorWidget->textDocument()->quickFixAssistProvider();
|
||||
|
||||
|
@@ -124,6 +124,7 @@ const char G_COPYPASTE[] = "TextEditor.CopyPasteGroup";
|
||||
const char G_SELECT[] = "TextEditor.SelectGroup";
|
||||
const char G_BOM[] = "TextEditor.BomGroup";
|
||||
const char COMPLETE_THIS[] = "TextEditor.CompleteThis";
|
||||
const char FUNCTION_HINT[] = "TextEditor.FunctionHint";
|
||||
const char QUICKFIX_THIS[] = "TextEditor.QuickFix";
|
||||
const char SHOWCONTEXTMENU[] = "TextEditor.ShowContextMenu";
|
||||
const char CREATE_SCRATCH_BUFFER[] = "TextEditor.CreateScratchBuffer";
|
||||
|
@@ -131,6 +131,16 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe
|
||||
});
|
||||
Utils::FancyLineEdit::setCompletionShortcut(command->keySequence());
|
||||
|
||||
// Add shortcut for invoking function hint completion
|
||||
QAction *functionHintAction = new QAction(tr("Display Function Hint"), this);
|
||||
command = ActionManager::registerAction(functionHintAction, Constants::FUNCTION_HINT, context);
|
||||
command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+Shift+D")
|
||||
: tr("Ctrl+Shift+D")));
|
||||
connect(functionHintAction, &QAction::triggered, []() {
|
||||
if (BaseTextEditor *editor = BaseTextEditor::currentTextEditor())
|
||||
editor->editorWidget()->invokeAssist(FunctionHint);
|
||||
});
|
||||
|
||||
// Add shortcut for invoking quick fix options
|
||||
QAction *quickFixAction = new QAction(tr("Trigger Refactoring Action"), this);
|
||||
Command *quickFixCommand = ActionManager::registerAction(quickFixAction, Constants::QUICKFIX_THIS, context);
|
||||
|
@@ -32,6 +32,8 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
enum class CompletionType { FunctionHint, Other };
|
||||
|
||||
class ClangCompletionAssistInterface: public TextEditor::AssistInterface
|
||||
{
|
||||
public:
|
||||
@@ -41,6 +43,7 @@ public:
|
||||
languageFeatures_(CPlusPlus::LanguageFeatures::defaultFeatures())
|
||||
{}
|
||||
|
||||
CompletionType type() const { return CompletionType::Other; }
|
||||
CPlusPlus::LanguageFeatures languageFeatures() const { return languageFeatures_; }
|
||||
|
||||
private:
|
||||
|
@@ -48,6 +48,7 @@ void PrintTo(const ClangCompletionContextAnalyzer::CompletionAction &completionA
|
||||
case CCA::CompletePreprocessorDirective: *os << "CompletePreprocessorDirective"; break;
|
||||
case CCA::CompleteSignal: *os << "CompleteSignal"; break;
|
||||
case CCA::CompleteSlot: *os << "CompleteSlot"; break;
|
||||
case CCA::CompleteNone: *os << "CompleteNone"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user