1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qtextsynchronization_p.h" |
5 | #include "qqmllsutils_p.h" |
6 | #include "qtextdocument_p.h" |
7 | |
8 | using namespace QLspSpecification; |
9 | using namespace Qt::StringLiterals; |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | TextSynchronization::TextSynchronization(QmlLsp::QQmlCodeModel *codeModel, QObject *parent) |
14 | : QLanguageServerModule(parent), m_codeModel(codeModel) |
15 | { |
16 | } |
17 | |
18 | void TextSynchronization::didCloseTextDocument(const DidCloseTextDocumentParams ¶ms) |
19 | { |
20 | m_codeModel->closeOpenFile(url: QQmlLSUtils::lspUriToQmlUrl(uri: params.textDocument.uri)); |
21 | } |
22 | |
23 | void TextSynchronization::didOpenTextDocument(const DidOpenTextDocumentParams ¶ms) |
24 | { |
25 | const TextDocumentItem &item = params.textDocument; |
26 | const QString fileName = m_codeModel->url2Path(url: QQmlLSUtils::lspUriToQmlUrl(uri: item.uri)); |
27 | m_codeModel->newOpenFile(url: QQmlLSUtils::lspUriToQmlUrl(uri: item.uri), version: item.version, |
28 | docText: QString::fromUtf8(ba: item.text)); |
29 | } |
30 | |
31 | void TextSynchronization::didDidChangeTextDocument(const DidChangeTextDocumentParams ¶ms) |
32 | { |
33 | QByteArray url = QQmlLSUtils::lspUriToQmlUrl(uri: params.textDocument.uri); |
34 | const QString fileName = m_codeModel->url2Path(url); |
35 | auto openDoc = m_codeModel->openDocumentByUrl(url); |
36 | std::shared_ptr<Utils::TextDocument> document = openDoc.textDocument; |
37 | if (!document) { |
38 | qCWarning(lspServerLog) << "Ingnoring changes to non open or closed document" |
39 | << QString::fromUtf8(ba: url); |
40 | return; |
41 | } |
42 | const auto &changes = params.contentChanges; |
43 | { |
44 | QMutexLocker l(document->mutex()); |
45 | for (const auto &change : changes) { |
46 | if (!change.range) { |
47 | document->setPlainText(QString::fromUtf8(ba: change.text)); |
48 | continue; |
49 | } |
50 | |
51 | const auto &range = *change.range; |
52 | const auto &rangeStart = range.start; |
53 | const int start = |
54 | document->findBlockByNumber(blockNumber: rangeStart.line).position() + rangeStart.character; |
55 | const auto &rangeEnd = range.end; |
56 | const int end = |
57 | document->findBlockByNumber(blockNumber: rangeEnd.line).position() + rangeEnd.character; |
58 | |
59 | document->setPlainText(document->toPlainText().replace(i: start, len: end - start, |
60 | after: QString::fromUtf8(ba: change.text))); |
61 | } |
62 | document->setVersion(params.textDocument.version); |
63 | qCDebug(lspServerLog).noquote() |
64 | << "text is\n:----------" << document->toPlainText() << "\n_________" ; |
65 | } |
66 | m_codeModel->addOpenToUpdate(url); |
67 | m_codeModel->openNeedUpdate(); |
68 | } |
69 | |
70 | void TextSynchronization::registerHandlers(QLanguageServer *server, QLanguageServerProtocol *) |
71 | { |
72 | QObject::connect(sender: server->notifySignals(), |
73 | signal: &QLspNotifySignals::receivedDidOpenTextDocumentNotification, context: this, |
74 | slot: &TextSynchronization::didOpenTextDocument); |
75 | |
76 | QObject::connect(sender: server->notifySignals(), |
77 | signal: &QLspNotifySignals::receivedDidChangeTextDocumentNotification, context: this, |
78 | slot: &TextSynchronization::didDidChangeTextDocument); |
79 | |
80 | QObject::connect(sender: server->notifySignals(), |
81 | signal: &QLspNotifySignals::receivedDidCloseTextDocumentNotification, context: this, |
82 | slot: &TextSynchronization::didCloseTextDocument); |
83 | } |
84 | |
85 | QString TextSynchronization::name() const |
86 | { |
87 | return u"TextSynchonization"_s ; |
88 | } |
89 | |
90 | void TextSynchronization::setupCapabilities(const QLspSpecification::InitializeParams &, |
91 | QLspSpecification::InitializeResult &serverInfo) |
92 | { |
93 | TextDocumentSyncOptions syncOptions; |
94 | syncOptions.openClose = true; |
95 | syncOptions.change = TextDocumentSyncKind::Incremental; |
96 | serverInfo.capabilities.textDocumentSync = syncOptions; |
97 | } |
98 | |
99 | QT_END_NAMESPACE |
100 | |