File indexing completed on 2024-05-12 04:37:44
0001 /* 0002 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "codecompletion.h" 0008 0009 #include <interfaces/icore.h> 0010 #include <interfaces/ilanguagecontroller.h> 0011 #include <interfaces/ilanguagesupport.h> 0012 0013 #include "../duchain/duchain.h" 0014 #include "../duchain/topducontext.h" 0015 #include <debug.h> 0016 #include "codecompletionmodel.h" 0017 #include <interfaces/idocumentcontroller.h> 0018 0019 #include <KTextEditor/View> 0020 #include <KTextEditor/Document> 0021 #include <KTextEditor/CodeCompletionModel> 0022 #include <KTextEditor/CodeCompletionInterface> 0023 0024 using namespace KTextEditor; 0025 using namespace KDevelop; 0026 0027 CodeCompletion::CodeCompletion(QObject* parent, KTextEditor::CodeCompletionModel* aModel, const QString& language) 0028 : QObject(parent) 0029 , m_model(aModel) 0030 , m_language(language) 0031 { 0032 auto* kdevModel = qobject_cast<KDevelop::CodeCompletionModel*>(aModel); 0033 if (kdevModel) 0034 kdevModel->initialize(); 0035 connect(KDevelop::ICore::self()->documentController(), &IDocumentController::textDocumentCreated, 0036 this, &CodeCompletion::textDocumentCreated); 0037 connect(ICore::self()->documentController(), &IDocumentController::documentUrlChanged, 0038 this, &CodeCompletion::documentUrlChanged); 0039 aModel->setParent(this); 0040 0041 // prevent deadlock 0042 QMetaObject::invokeMethod(this, "checkDocuments", Qt::QueuedConnection); 0043 } 0044 0045 CodeCompletion::~CodeCompletion() 0046 { 0047 } 0048 0049 void CodeCompletion::checkDocuments() 0050 { 0051 const auto documents = KDevelop::ICore::self()->documentController()->openDocuments(); 0052 for (KDevelop::IDocument* doc : documents) { 0053 if (doc->textDocument()) { 0054 checkDocument(doc->textDocument()); 0055 } 0056 } 0057 } 0058 0059 void CodeCompletion::viewCreated(KTextEditor::Document* document, KTextEditor::View* view) 0060 { 0061 Q_UNUSED(document); 0062 0063 if (auto* cc = qobject_cast<CodeCompletionInterface*>(view)) { 0064 cc->registerCompletionModel(m_model); 0065 qCDebug(LANGUAGE) << "Registered completion model"; 0066 emit registeredToView(view); 0067 } 0068 } 0069 0070 void CodeCompletion::documentUrlChanged(KDevelop::IDocument* document) 0071 { 0072 // The URL has changed (might have a different language now), so we re-register the document 0073 Document* textDocument = document->textDocument(); 0074 0075 if (textDocument) { 0076 checkDocument(textDocument); 0077 } 0078 } 0079 0080 void CodeCompletion::textDocumentCreated(KDevelop::IDocument* document) 0081 { 0082 Q_ASSERT(document->textDocument()); 0083 checkDocument(document->textDocument()); 0084 } 0085 0086 void CodeCompletion::unregisterDocument(Document* textDocument) 0087 { 0088 const auto views = textDocument->views(); 0089 for (KTextEditor::View* view : views) { 0090 if (auto* cc = qobject_cast<CodeCompletionInterface*>(view)) { 0091 cc->unregisterCompletionModel(m_model); 0092 emit unregisteredFromView(view); 0093 } 0094 } 0095 0096 disconnect(textDocument, &Document::viewCreated, this, &CodeCompletion::viewCreated); 0097 } 0098 0099 void CodeCompletion::checkDocument(Document* textDocument) 0100 { 0101 unregisterDocument(textDocument); 0102 0103 const auto langs = ICore::self()->languageController()->languagesForUrl(textDocument->url()); 0104 0105 bool found = false; 0106 for (const auto lang : langs) { 0107 if (m_language == lang->name()) { 0108 found = true; 0109 break; 0110 } 0111 } 0112 0113 if (!found && !m_language.isEmpty()) 0114 return; 0115 0116 const auto views = textDocument->views(); 0117 for (KTextEditor::View* view : views) { 0118 viewCreated(textDocument, view); 0119 } 0120 0121 connect(textDocument, &Document::viewCreated, this, &CodeCompletion::viewCreated); 0122 } 0123 0124 #include "moc_codecompletion.cpp"