File: codecompletion.cpp

package info (click to toggle)
kdevelop 4%3A22.12.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 70,096 kB
  • sloc: cpp: 284,635; javascript: 3,558; python: 3,422; sh: 1,319; ansic: 685; xml: 331; php: 95; lisp: 66; makefile: 39; sed: 12
file content (122 lines) | stat: -rw-r--r-- 3,589 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
    SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "codecompletion.h"

#include <interfaces/icore.h>
#include <interfaces/ilanguagecontroller.h>
#include <interfaces/ilanguagesupport.h>

#include "../duchain/duchain.h"
#include "../duchain/topducontext.h"
#include <debug.h>
#include "codecompletionmodel.h"
#include <interfaces/idocumentcontroller.h>

#include <KTextEditor/View>
#include <KTextEditor/Document>
#include <KTextEditor/CodeCompletionModel>
#include <KTextEditor/CodeCompletionInterface>

using namespace KTextEditor;
using namespace KDevelop;

CodeCompletion::CodeCompletion(QObject* parent, KTextEditor::CodeCompletionModel* aModel, const QString& language)
    : QObject(parent)
    , m_model(aModel)
    , m_language(language)
{
    auto* kdevModel = qobject_cast<KDevelop::CodeCompletionModel*>(aModel);
    if (kdevModel)
        kdevModel->initialize();
    connect(KDevelop::ICore::self()->documentController(), &IDocumentController::textDocumentCreated,
            this, &CodeCompletion::textDocumentCreated);
    connect(ICore::self()->documentController(), &IDocumentController::documentUrlChanged,
            this, &CodeCompletion::documentUrlChanged);
    aModel->setParent(this);

    // prevent deadlock
    QMetaObject::invokeMethod(this, "checkDocuments", Qt::QueuedConnection);
}

CodeCompletion::~CodeCompletion()
{
}

void CodeCompletion::checkDocuments()
{
    const auto documents = KDevelop::ICore::self()->documentController()->openDocuments();
    for (KDevelop::IDocument* doc : documents) {
        if (doc->textDocument()) {
            checkDocument(doc->textDocument());
        }
    }
}

void CodeCompletion::viewCreated(KTextEditor::Document* document, KTextEditor::View* view)
{
    Q_UNUSED(document);

    if (auto* cc = qobject_cast<CodeCompletionInterface*>(view)) {
        cc->registerCompletionModel(m_model);
        qCDebug(LANGUAGE) << "Registered completion model";
        emit registeredToView(view);
    }
}

void CodeCompletion::documentUrlChanged(KDevelop::IDocument* document)
{
    // The URL has changed (might have a different language now), so we re-register the document
    Document* textDocument = document->textDocument();

    if (textDocument) {
        checkDocument(textDocument);
    }
}

void CodeCompletion::textDocumentCreated(KDevelop::IDocument* document)
{
    Q_ASSERT(document->textDocument());
    checkDocument(document->textDocument());
}

void CodeCompletion::unregisterDocument(Document* textDocument)
{
    const auto views = textDocument->views();
    for (KTextEditor::View* view : views) {
        if (auto* cc = qobject_cast<CodeCompletionInterface*>(view)) {
            cc->unregisterCompletionModel(m_model);
            emit unregisteredFromView(view);
        }
    }

    disconnect(textDocument, &Document::viewCreated, this, &CodeCompletion::viewCreated);
}

void CodeCompletion::checkDocument(Document* textDocument)
{
    unregisterDocument(textDocument);

    const auto langs = ICore::self()->languageController()->languagesForUrl(textDocument->url());

    bool found = false;
    for (const auto lang : langs) {
        if (m_language == lang->name()) {
            found = true;
            break;
        }
    }

    if (!found && !m_language.isEmpty())
        return;

    const auto views = textDocument->views();
    for (KTextEditor::View* view : views) {
        viewCreated(textDocument, view);
    }

    connect(textDocument, &Document::viewCreated, this, &CodeCompletion::viewCreated);
}