File indexing completed on 2024-04-28 05:48:56

0001 /*
0002     SPDX-FileCopyrightText: 2019 Mark Nauwelaerts <mark.nauwelaerts@gmail.com>
0003     SPDX-FileCopyrightText: 2019 Christoph Cullmann <cullmann@kde.org>
0004 
0005     SPDX-License-Identifier: MIT
0006 */
0007 
0008 #include "lspclienthover.h"
0009 
0010 #include <KTextEditor/Cursor>
0011 #include <KTextEditor/Document>
0012 #include <KTextEditor/View>
0013 
0014 #include "lspclientserver.h"
0015 #include "lspclientservermanager.h"
0016 #include "texthint/KateTextHintManager.h"
0017 
0018 static TextHintMarkupKind toKateMarkupKind(LSPMarkupKind kind)
0019 {
0020     switch (kind) {
0021     case LSPMarkupKind::None:
0022     case LSPMarkupKind::PlainText:
0023         return TextHintMarkupKind::PlainText;
0024     case LSPMarkupKind::MarkDown:
0025         return TextHintMarkupKind::MarkDown;
0026     }
0027     qWarning() << Q_FUNC_INFO << "Unknown markup kind" << (int)kind;
0028     return TextHintMarkupKind::PlainText;
0029 }
0030 
0031 class LSPClientHoverImpl : public LSPClientHover
0032 {
0033     Q_OBJECT
0034 
0035     typedef LSPClientHoverImpl self_type;
0036 
0037     std::shared_ptr<LSPClientServerManager> m_manager;
0038     std::shared_ptr<LSPClientServer> m_server;
0039 
0040     LSPClientServer::RequestHandle m_handle;
0041     KateTextHintProvider *m_textHintProvider;
0042 
0043 public:
0044     explicit LSPClientHoverImpl(std::shared_ptr<LSPClientServerManager> manager, KateTextHintProvider *provider)
0045         : m_manager(std::move(manager))
0046         , m_server(nullptr)
0047         , m_textHintProvider(provider)
0048     {
0049     }
0050 
0051     void setServer(std::shared_ptr<LSPClientServer> server) override
0052     {
0053         m_server = server;
0054     }
0055 
0056     QString showTextHint(KTextEditor::View *view, const KTextEditor::Cursor &position, bool manual) override
0057     {
0058         if (!position.isValid()) {
0059             return {};
0060         }
0061 
0062         // hack: delayed handling of tooltip on our own, the API is too dumb for a-sync feedback ;=)
0063         if (m_server) {
0064             QPointer<KTextEditor::View> v(view);
0065             auto h = [v, position, manual, this](const LSPHover &info) {
0066                 if (!v || info.contents.isEmpty()) {
0067                     return;
0068                 }
0069 
0070                 // combine contents elements to one string
0071                 LSPMarkupKind kind = LSPMarkupKind::PlainText;
0072                 QString finalTooltip;
0073                 for (auto &element : info.contents) {
0074                     kind = element.kind;
0075                     if (!finalTooltip.isEmpty()) {
0076                         finalTooltip.append(QLatin1Char('\n'));
0077                     }
0078                     finalTooltip.append(element.value);
0079                 }
0080 
0081                 // make sure there is no selection, otherwise we interrupt
0082                 if (!v->selection()) {
0083                     if (manual) {
0084                         Q_EMIT m_textHintProvider->showTextHint(finalTooltip, toKateMarkupKind(kind), position);
0085                     } else {
0086                         Q_EMIT m_textHintProvider->textHintAvailable(finalTooltip, toKateMarkupKind(kind), position);
0087                     }
0088                 }
0089             };
0090 
0091             if (view && view->document()) {
0092                 auto doc = view->document();
0093                 if (doc->wordAt(position).isEmpty() || view->selection()) {
0094                     return {};
0095                 }
0096                 m_handle.cancel() = m_server->documentHover(view->document()->url(), position, this, h);
0097             }
0098         }
0099 
0100         return QString();
0101     }
0102 };
0103 
0104 LSPClientHover *LSPClientHover::new_(std::shared_ptr<LSPClientServerManager> manager, class KateTextHintProvider *provider)
0105 {
0106     return new LSPClientHoverImpl(std::move(manager), provider);
0107 }
0108 
0109 #include "lspclienthover.moc"
0110 #include "moc_lspclienthover.cpp"