TextEditor: request assist after trigger char inserted

... while proposal is shown

amends 23d63dcc8b

Fixes: QTCREATORBUG-24225
Change-Id: Ie935c7c1d4786a4fd3cf338d7f1df52ae28de63b
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2020-09-23 12:48:17 +02:00
parent fcaa6801cf
commit 2842b613ed
3 changed files with 28 additions and 12 deletions

View File

@@ -196,6 +196,8 @@ void ClangEditorDocumentProcessor::updateCodeWarnings(
uint documentRevision) uint documentRevision)
{ {
if (documentRevision == revision()) { if (documentRevision == revision()) {
if (m_invalidationState == InvalidationState::Scheduled)
m_invalidationState = InvalidationState::Canceled;
m_diagnosticManager.processNewDiagnostics(diagnostics, m_isProjectFile); m_diagnosticManager.processNewDiagnostics(diagnostics, m_isProjectFile);
const auto codeWarnings = m_diagnosticManager.takeExtraSelections(); const auto codeWarnings = m_diagnosticManager.takeExtraSelections();
const auto fixitAvailableMarkers = m_diagnosticManager.takeFixItAvailableMarkers(); const auto fixitAvailableMarkers = m_diagnosticManager.takeFixItAvailableMarkers();
@@ -298,11 +300,14 @@ TextEditor::QuickFixOperations ClangEditorDocumentProcessor::extraRefactoringOpe
void ClangEditorDocumentProcessor::editorDocumentTimerRestarted() void ClangEditorDocumentProcessor::editorDocumentTimerRestarted()
{ {
m_updateBackendDocumentTimer.stop(); // Wait for the next call to run(). m_updateBackendDocumentTimer.stop(); // Wait for the next call to run().
m_invalidationState = InvalidationState::Scheduled;
} }
void ClangEditorDocumentProcessor::invalidateDiagnostics() void ClangEditorDocumentProcessor::invalidateDiagnostics()
{ {
if (m_invalidationState != InvalidationState::Canceled)
m_diagnosticManager.invalidateDiagnostics(); m_diagnosticManager.invalidateDiagnostics();
m_invalidationState = InvalidationState::Off;
} }
TextEditor::TextMarks ClangEditorDocumentProcessor::diagnosticTextMarksAt(uint line, TextEditor::TextMarks ClangEditorDocumentProcessor::diagnosticTextMarksAt(uint line,

View File

@@ -140,6 +140,7 @@ private:
QFutureWatcher<void> m_parserWatcher; QFutureWatcher<void> m_parserWatcher;
QTimer m_updateBackendDocumentTimer; QTimer m_updateBackendDocumentTimer;
unsigned m_parserRevision; unsigned m_parserRevision;
enum class InvalidationState { Off, Scheduled, Canceled } m_invalidationState;
QVector<ClangBackEnd::TokenInfoContainer> m_tokenInfos; QVector<ClangBackEnd::TokenInfoContainer> m_tokenInfos;
CppTools::SemanticHighlighter m_semanticHighlighter; CppTools::SemanticHighlighter m_semanticHighlighter;

View File

@@ -88,6 +88,7 @@ public:
bool eventFilter(QObject *o, QEvent *e) override; bool eventFilter(QObject *o, QEvent *e) override;
private: private:
bool requestActivationCharProposal();
void processProposalItem(AssistProposalItemInterface *proposalItem); void processProposalItem(AssistProposalItemInterface *proposalItem);
void handlePrefixExpansion(const QString &newPrefix); void handlePrefixExpansion(const QString &newPrefix);
void finalizeProposal(); void finalizeProposal();
@@ -161,6 +162,19 @@ void CodeAssistantPrivate::invoke(AssistKind kind, IAssistProvider *provider)
} }
} }
bool CodeAssistantPrivate::requestActivationCharProposal()
{
if (m_assistKind == Completion && m_settings.m_completionTrigger != ManualCompletion) {
if (CompletionAssistProvider *provider = identifyActivationSequence()) {
if (isWaitingForProposal())
cancelCurrentRequest();
requestProposal(ActivationCharacter, Completion, provider);
return true;
}
}
return false;
}
void CodeAssistantPrivate::process() void CodeAssistantPrivate::process()
{ {
if (!isConfigured()) if (!isConfigured())
@@ -169,15 +183,7 @@ void CodeAssistantPrivate::process()
stopAutomaticProposalTimer(); stopAutomaticProposalTimer();
if (m_assistKind == TextEditor::Completion) { if (m_assistKind == TextEditor::Completion) {
if (m_settings.m_completionTrigger != ManualCompletion) { if (!requestActivationCharProposal())
if (CompletionAssistProvider *provider = identifyActivationSequence()) {
if (isWaitingForProposal())
cancelCurrentRequest();
requestProposal(ActivationCharacter, Completion, provider);
return;
}
}
startAutomaticProposalTimer(); startAutomaticProposalTimer();
} else if (m_assistKind != FunctionHint){ } else if (m_assistKind != FunctionHint){
m_assistKind = TextEditor::Completion; m_assistKind = TextEditor::Completion;
@@ -365,6 +371,8 @@ void CodeAssistantPrivate::processProposalItem(AssistProposalItemInterface *prop
proposalItem->apply(manipulator, m_proposal->basePosition()); proposalItem->apply(manipulator, m_proposal->basePosition());
destroyContext(); destroyContext();
m_editorWidget->encourageApply(); m_editorWidget->encourageApply();
if (!proposalItem->isSnippet())
requestActivationCharProposal();
} }
void CodeAssistantPrivate::handlePrefixExpansion(const QString &newPrefix) void CodeAssistantPrivate::handlePrefixExpansion(const QString &newPrefix)
@@ -404,7 +412,7 @@ void CodeAssistantPrivate::finalizeProposal()
bool CodeAssistantPrivate::isDisplayingProposal() const bool CodeAssistantPrivate::isDisplayingProposal() const
{ {
return m_proposalWidget != nullptr; return m_proposalWidget != nullptr && m_proposalWidget->isVisible();
} }
bool CodeAssistantPrivate::isWaitingForProposal() const bool CodeAssistantPrivate::isWaitingForProposal() const
@@ -457,6 +465,8 @@ void CodeAssistantPrivate::notifyChange()
m_proposalWidget->updateProposal( m_proposalWidget->updateProposal(
m_editorWidget->textAt(m_proposal->basePosition(), m_editorWidget->textAt(m_proposal->basePosition(),
m_editorWidget->position() - m_proposal->basePosition())); m_editorWidget->position() - m_proposal->basePosition()));
if (!isDisplayingProposal())
requestActivationCharProposal();
} else { } else {
destroyContext(); destroyContext();
requestProposal(ExplicitlyInvoked, m_assistKind, m_requestProvider); requestProposal(ExplicitlyInvoked, m_assistKind, m_requestProvider);