lspclientserver.h 6.96 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
23
/*  SPDX-License-Identifier: MIT

    Copyright (C) 2019 Mark Nauwelaerts <mark.nauwelaerts@gmail.com>

    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
24
25
26
27

#ifndef LSPCLIENTSERVER_H
#define LSPCLIENTSERVER_H

28
29
#include "lspclientprotocol.h"

30
31
#include <QJsonValue>
#include <QList>
32
#include <QObject>
33
#include <QPointer>
34
35
#include <QString>
#include <QUrl>
36
#include <QVector>
37
38
39

#include <functional>

40
41
namespace utils
{
42
43
// template helper
// function bind helpers
44
template<typename R, typename T, typename Tp, typename... Args> inline std::function<R(Args...)> mem_fun(R (T::*pm)(Args...), Tp object)
45
{
46
    return [object, pm](Args... args) { return (object->*pm)(std::forward<Args>(args)...); };
47
48
}

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

54
// prevent argument deduction
55
template<typename T> struct identity {
56
57
    typedef T type;
};
58
59
60

} // namespace utils

61
62
static const int TIMEOUT_SHUTDOWN = 200;

63
template<typename T> using ReplyHandler = std::function<void(const T &)>;
64
65

using DocumentSymbolsReplyHandler = ReplyHandler<QList<LSPSymbolInformation>>;
66
using DocumentDefinitionReplyHandler = ReplyHandler<QList<LSPLocation>>;
67
using DocumentHighlightReplyHandler = ReplyHandler<QList<LSPDocumentHighlight>>;
Mark Nauwelaerts's avatar
Mark Nauwelaerts committed
68
using DocumentHoverReplyHandler = ReplyHandler<LSPHover>;
69
using DocumentCompletionReplyHandler = ReplyHandler<QList<LSPCompletionItem>>;
70
using SignatureHelpReplyHandler = ReplyHandler<LSPSignatureHelp>;
71
using FormattingReplyHandler = ReplyHandler<QList<LSPTextEdit>>;
72
using CodeActionReplyHandler = ReplyHandler<QList<LSPCodeAction>>;
73
using WorkspaceEditReplyHandler = ReplyHandler<LSPWorkspaceEdit>;
74
using ApplyEditReplyHandler = ReplyHandler<LSPApplyWorkspaceEditResponse>;
75

76
77
class LSPClientPlugin;

78
79
80
81
82
class LSPClientServer : public QObject
{
    Q_OBJECT

public:
83
    enum class State { None, Started, Running, Shutdown };
84
85
86
87
88
89
90

    class LSPClientServerPrivate;
    class RequestHandle
    {
        friend class LSPClientServerPrivate;
        QPointer<LSPClientServer> m_server;
        int m_id = -1;
91

92
    public:
93
        RequestHandle &cancel()
94
95
96
97
98
99
100
        {
            if (m_server)
                m_server->cancel(m_id);
            return *this;
        }
    };

101
    LSPClientServer(const QStringList &server, const QUrl &root, const QJsonValue &init = QJsonValue());
Filip Gawin's avatar
Filip Gawin committed
102
    ~LSPClientServer() override;
103
104
105

    // server management
    // request start
106
    bool start(LSPClientPlugin *plugin);
107
108
109
110
111
    // 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);

112
    // properties
113
    const QStringList &cmdline() const;
114
    State state() const;
115
    Q_SIGNAL void stateChanged(LSPClientServer *server);
116

117
    const LSPServerCapabilities &capabilities() const;
118

119
    // language
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    RequestHandle documentSymbols(const QUrl &document, const QObject *context, const DocumentSymbolsReplyHandler &h);
    RequestHandle documentDefinition(const QUrl &document, const LSPPosition &pos, const QObject *context, const DocumentDefinitionReplyHandler &h);
    RequestHandle documentDeclaration(const QUrl &document, const LSPPosition &pos, const QObject *context, const DocumentDefinitionReplyHandler &h);
    RequestHandle documentHighlight(const QUrl &document, const LSPPosition &pos, const QObject *context, const DocumentHighlightReplyHandler &h);
    RequestHandle documentHover(const QUrl &document, const LSPPosition &pos, const QObject *context, const DocumentHoverReplyHandler &h);
    RequestHandle documentReferences(const QUrl &document, const LSPPosition &pos, bool decl, const QObject *context, const DocumentDefinitionReplyHandler &h);
    RequestHandle documentCompletion(const QUrl &document, const LSPPosition &pos, const QObject *context, const DocumentCompletionReplyHandler &h);
    RequestHandle signatureHelp(const QUrl &document, const LSPPosition &pos, const QObject *context, const SignatureHelpReplyHandler &h);

    RequestHandle documentFormatting(const QUrl &document, const LSPFormattingOptions &options, const QObject *context, const FormattingReplyHandler &h);
    RequestHandle documentRangeFormatting(const QUrl &document, const LSPRange &range, const LSPFormattingOptions &options, const QObject *context, const FormattingReplyHandler &h);
    RequestHandle documentOnTypeFormatting(const QUrl &document, const LSPPosition &pos, QChar lastChar, const LSPFormattingOptions &options, const QObject *context, const FormattingReplyHandler &h);
    RequestHandle documentRename(const QUrl &document, const LSPPosition &pos, const QString &newName, const QObject *context, const WorkspaceEditReplyHandler &h);

    RequestHandle documentCodeAction(const QUrl &document, const LSPRange &range, const QList<QString> &kinds, QList<LSPDiagnostic> diagnostics, const QObject *context, const CodeActionReplyHandler &h);
135
    void executeCommand(const QString &command, const QJsonValue &args);
136

137
    // sync
138
    void didOpen(const QUrl &document, int version, const QString &langId, const QString &text);
139
    // only 1 of text or changes should be non-empty and is considered
140
    void didChange(const QUrl &document, int version, const QString &text, const QList<LSPTextDocumentContentChangeEvent> &changes = {});
141
142
    void didSave(const QUrl &document, const QString &text);
    void didClose(const QUrl &document);
143

144
145
146
    // misc
    void didChangeConfiguration(const QJsonValue &settings);

Yuri Chornoivan's avatar
Yuri Chornoivan committed
147
    // notification = signal
148
Q_SIGNALS:
149
150
    void showMessage(const LSPShowMessageParams &);
    void logMessage(const LSPLogMessageParams &);
151
    void publishDiagnostics(const LSPPublishDiagnosticsParams &);
152
    void semanticHighlighting(const LSPSemanticHighlightingParams &);
153

154
    // request = signal
155
    void applyEdit(const LSPApplyWorkspaceEditParams &req, const ApplyEditReplyHandler &h, bool &handled);
156

157
158
private:
    // pimpl data holder
159
    LSPClientServerPrivate *const d;
160
161
162
};

#endif