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

0001 /*
0002     SPDX-FileCopyrightText: 2021 Waqar Ahmed <waqar.17a@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #pragma once
0007 
0008 #include "lspclientprotocol.h"
0009 #include <QObject>
0010 #include <QPointer>
0011 #include <QString>
0012 #include <QTimer>
0013 
0014 #include <KTextEditor/InlineNoteProvider>
0015 #include <KTextEditor/MovingRange>
0016 
0017 #include <memory>
0018 #include <unordered_map>
0019 #include <vector>
0020 
0021 namespace KTextEditor
0022 {
0023 class View;
0024 class Document;
0025 }
0026 
0027 class LSPClientServerManager;
0028 
0029 class InlayHintNoteProvider : public KTextEditor::InlineNoteProvider
0030 {
0031 public:
0032     InlayHintNoteProvider();
0033     void setView(KTextEditor::View *v);
0034     void setHints(const QList<LSPInlayHint> &hints);
0035 
0036     QList<int> inlineNotes(int line) const override;
0037     QSize inlineNoteSize(const KTextEditor::InlineNote &note) const override;
0038     void paintInlineNote(const KTextEditor::InlineNote &note, QPainter &painter, Qt::LayoutDirection) const override;
0039 
0040 private:
0041     QColor m_noteColor;
0042     QColor m_noteBgColor;
0043     QPointer<KTextEditor::View> m_view;
0044     QList<LSPInlayHint> m_hints;
0045 };
0046 
0047 class InlayHintsManager : public QObject
0048 {
0049     Q_OBJECT
0050 public:
0051     explicit InlayHintsManager(const std::shared_ptr<LSPClientServerManager> &manager, QObject *parent = nullptr);
0052     ~InlayHintsManager();
0053 
0054     void setActiveView(KTextEditor::View *v);
0055     void disable();
0056 
0057 private:
0058     void registerView(KTextEditor::View *);
0059     void unregisterView(KTextEditor::View *);
0060     void sendRequestDelayed(KTextEditor::Range, int delay = 300);
0061     void sendPendingRequests();
0062     void sendRequest(KTextEditor::Range r);
0063 
0064     // if doc is null, it will clear hints for all invalid docs
0065     void clearHintsForDoc(KTextEditor::Document *);
0066     struct InsertResult {
0067         const bool newDoc = false;
0068         const QVarLengthArray<int, 16> changedLines;
0069         const QList<LSPInlayHint> addedHints;
0070     };
0071     InsertResult insertHintsForDoc(KTextEditor::Document *doc, KTextEditor::Range requestedRange, const QList<LSPInlayHint> &newHints);
0072 
0073     void onTextInserted(KTextEditor::Document *doc, KTextEditor::Cursor pos, const QString &text);
0074     void onTextRemoved(KTextEditor::Document *doc, KTextEditor::Range range, const QString &t);
0075     void onWrapped(KTextEditor::Document *doc, KTextEditor::Cursor position);
0076     void onUnwrapped(KTextEditor::Document *doc, int line);
0077 
0078     struct HintData {
0079         QPointer<KTextEditor::Document> doc;
0080         QByteArray checksum;
0081         QList<LSPInlayHint> m_hints;
0082     };
0083     std::vector<HintData> m_hintDataByDoc;
0084 
0085     QTimer m_requestTimer;
0086     QPointer<KTextEditor::View> m_currentView;
0087     InlayHintNoteProvider m_noteProvider;
0088     std::shared_ptr<LSPClientServerManager> m_serverManager;
0089     QList<KTextEditor::Range> pendingRanges;
0090 };