lspclientserver.h 5.52 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/***************************************************************************
 *   Copyright (C) 2019 by Mark Nauwelaerts <mark.nauwelaerts@gmail.com>   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
 ***************************************************************************/

#ifndef LSPCLIENTSERVER_H
#define LSPCLIENTSERVER_H

23 24
#include "lspclientprotocol.h"

25 26 27 28
#include <QObject>
#include <QString>
#include <QUrl>
#include <QList>
29
#include <QVector>
30
#include <QPointer>
31
#include <QJsonValue>
32 33 34

#include <functional>

35 36 37
namespace utils
{

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
// template helper
// function bind helpers
template<typename R, typename T, typename Tp, typename... Args>
inline std::function<R(Args ...)>
mem_fun(R (T::*pm)(Args ...), Tp object)
{
  return [object, pm](Args... args) {
    return (object->*pm)(std::forward<Args>(args)...);
  };
}

template<typename R, typename T, typename Tp, typename... Args>
inline std::function<R(Args...)>
mem_fun(R (T::*pm)(Args ...) const, Tp object)
{
  return [object, pm](Args... args) {
    return (object->*pm)(std::forward<Args>(args)...);
  };
}

58 59 60 61 62 63
// prevent argument deduction
template<typename T> struct identity { typedef T type; };

} // namespace utils


64 65
static const int TIMEOUT_SHUTDOWN = 200;

66 67 68 69
template<typename T>
using ReplyHandler = std::function<void(const T &)>;

using DocumentSymbolsReplyHandler = ReplyHandler<QList<LSPSymbolInformation>>;
70
using DocumentDefinitionReplyHandler = ReplyHandler<QList<LSPLocation>>;
71
using DocumentHighlightReplyHandler = ReplyHandler<QList<LSPDocumentHighlight>>;
Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
72
using DocumentHoverReplyHandler = ReplyHandler<LSPHover>;
73
using DocumentCompletionReplyHandler = ReplyHandler<QList<LSPCompletionItem>>;
74
using SignatureHelpReplyHandler = ReplyHandler<LSPSignatureHelp>;
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

class LSPClientServer : public QObject
{
    Q_OBJECT

public:
    enum class State
    {
        None,
        Started,
        Running,
        Shutdown
    };

    class LSPClientServerPrivate;
    class RequestHandle
    {
        friend class LSPClientServerPrivate;
        QPointer<LSPClientServer> m_server;
        int m_id = -1;
    public:
        RequestHandle& cancel()
        {
            if (m_server)
                m_server->cancel(m_id);
            return *this;
        }
    };

104 105
    LSPClientServer(const QStringList & server, const QUrl & root,
                    const QJsonValue & init = QJsonValue());
106 107 108 109 110 111 112 113 114 115
    ~LSPClientServer();

    // server management
    // request start
    bool start();
    // request shutdown/stop
    // if to_xxx >= 0 -> send signal if not exit'ed after timeout
    void stop(int to_term_ms, int to_kill_ms);
    int cancel(int id);

116
    // properties
117
    const QStringList& cmdline() const;
118
    State state() const;
119
    Q_SIGNAL void stateChanged(LSPClientServer * server);
120

121 122
    const LSPServerCapabilities& capabilities() const;

123
    // language
124 125
    RequestHandle documentSymbols(const QUrl & document, const QObject *context,
        const DocumentSymbolsReplyHandler & h);
126
    RequestHandle documentDefinition(const QUrl & document, const LSPPosition & pos,
127
        const QObject *context, const DocumentDefinitionReplyHandler & h);
128 129
    RequestHandle documentDeclaration(const QUrl & document, const LSPPosition & pos,
        const QObject *context, const DocumentDefinitionReplyHandler & h);
130 131
    RequestHandle documentHighlight(const QUrl & document, const LSPPosition & pos,
        const QObject *context, const DocumentHighlightReplyHandler & h);
Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
132 133
    RequestHandle documentHover(const QUrl & document, const LSPPosition & pos,
        const QObject *context, const DocumentHoverReplyHandler & h);
134 135
    RequestHandle documentReferences(const QUrl & document, const LSPPosition & pos, bool decl,
        const QObject *context, const DocumentDefinitionReplyHandler & h);
136
    RequestHandle documentCompletion(const QUrl & document, const LSPPosition & pos,
137
        const QObject *context, const DocumentCompletionReplyHandler & h);
138 139
    RequestHandle signatureHelp(const QUrl & document, const LSPPosition & pos,
        const QObject *context, const SignatureHelpReplyHandler & h);
140 141 142 143 144 145 146

    // sync
    void didOpen(const QUrl & document, int version, const QString & text);
    void didChange(const QUrl & document, int version, const QString & text);
    void didSave(const QUrl & document, const QString & text);
    void didClose(const QUrl & document);

147 148 149 150
    // notifcation = signal
Q_SIGNALS:
    void publishDiagnostics(const LSPPublishDiagnosticsParams & );

151 152 153 154 155 156
private:
    // pimpl data holder
    LSPClientServerPrivate * const d;
};

#endif