aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/languageclient/currentdocumentsymbolsrequest.cpp
blob: 2d272a721617c230af709fdfcfbdf0e603881804 (plain)
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
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#include "currentdocumentsymbolsrequest.h"

#include "documentsymbolcache.h"
#include "languageclientmanager.h"

#include <coreplugin/editormanager/editormanager.h>

using namespace Core;
using namespace LanguageServerProtocol;
using namespace TextEditor;
using namespace Utils;

namespace LanguageClient {

void CurrentDocumentSymbolsRequest::start()
{
    QTC_ASSERT(!isRunning(), return);

    m_currentDocumentSymbolsData = {};

    TextDocument *document = TextDocument::currentTextDocument();
    Client *client = LanguageClientManager::clientForDocument(document);
    if (!client) {
        emit done(false);
        return;
    }

    DocumentSymbolCache *symbolCache = client->documentSymbolCache();
    DocumentUri currentUri = client->hostPathToServerUri(document->filePath());
    DocumentUri::PathMapper pathMapper = client->hostPathMapper();

    const auto reportFailure = [this] {
        clearConnections();
        emit done(false);
    };

    const auto updateSymbols = [this, currentUri, pathMapper](const DocumentUri &uri,
                                                              const DocumentSymbolsResult &symbols)
    {
        if (uri != currentUri) // We might get updates for not current editor
            return;

        const FilePath filePath = pathMapper ? currentUri.toFilePath(pathMapper) : FilePath();
        m_currentDocumentSymbolsData = {filePath, pathMapper, symbols};
        clearConnections();
        emit done(true);
    };

    m_connections.append(connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
                                 this, reportFailure));
    m_connections.append(connect(client, &Client::finished, this, reportFailure));
    m_connections.append(connect(document, &IDocument::contentsChanged, this, reportFailure));
    m_connections.append(connect(symbolCache, &DocumentSymbolCache::gotSymbols,
                                 this, updateSymbols));
    symbolCache->requestSymbols(currentUri, Schedule::Now);
}

bool CurrentDocumentSymbolsRequest::isRunning() const
{
    return !m_connections.isEmpty();
}

void CurrentDocumentSymbolsRequest::clearConnections()
{
    for (const QMetaObject::Connection &connection : std::as_const(m_connections))
        disconnect(connection);
    m_connections.clear();
}

CurrentDocumentSymbolsRequestTaskAdapter::CurrentDocumentSymbolsRequestTaskAdapter()
{
    connect(task(), &CurrentDocumentSymbolsRequest::done, this, &TaskInterface::done);
}

void CurrentDocumentSymbolsRequestTaskAdapter::start()
{
    task()->start();
}

} // namespace LanguageClient