-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlanguageserverclient.h
More file actions
144 lines (119 loc) · 4.47 KB
/
Copy pathlanguageserverclient.h
File metadata and controls
144 lines (119 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef LANGUAGESERVERCLIENT_H
#define LANGUAGESERVERCLIENT_H
#include <queue>
#include <string>
#include <vector>
#include <map>
#include <functional>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <variant>
// Forward declarations for JSON library (assuming nlohmann/json or similar)
#include "json.hpp"
#include "widget.h"
using json = nlohmann::json;
using LspId = std::variant<std::nullptr_t, int, std::string>;
enum class LineEditType {
InsertLine,
DeleteLine,
ChangeLine
};
// Process wrapper class
class Process {
public:
Process();
~Process();
bool start(const std::string& program, const std::vector<std::string>& arguments);
void write(const std::string& data);
std::string readAll();
int bytesAvailable();
void terminate();
void kill();
bool waitForStarted(int timeout = 30000);
bool waitForFinished(int timeout = 30000);
void close();
std::string errorString() const;
enum ProcessError {
FailedToStart,
Crashed,
Timedout,
WriteError,
ReadError,
UnknownError
};
enum ExitStatus {
NormalExit,
CrashExit
};
std::function<void()> readyReadCallback;
std::function<void(ProcessError)> errorCallback;
std::function<void(int, ExitStatus)> finishedCallback;
private:
class ProcessImpl;
std::unique_ptr<ProcessImpl> impl;
};
class LanguageServerClient
{
public:
explicit LanguageServerClient(const std::string &serverPath, std::function<void(const std::string&)> logCallback = nullptr);
~LanguageServerClient();
void initialize(const std::string &rootUri);
void openDocument(const std::string &uri, const std::string &languageId, const std::string &content);
void closeDocument(const std::string &uri);
void updateDocument(const std::string &uri, const std::string &content);
void applyDocumentEdit(const std::string &uri, const LineEditType &type, const std::string &newtext, int index);
int requestCompletion(const std::string &uri, int line, int character);
int requestHover(const std::string &uri, int line, int character);
int requestGotoDefinition(const std::string &uri, int line, int character);
int requestActions(const std::string &uri, int line, int character, int line2, int character2);
int requestRename(const std::string &uri, int line, int character, const std::string& newName);
void documentSaved(const std::string &uri, const std::string& text);
void shutdown();
void changeFolder(const std::string& oldUri, const std::string& newUri);
std::vector<Widget*> connected_edits = {};
bool isInitialized = false;
std::string lspPath;
std::vector<std::string> triggerChars;
// Callback functions to replace Qt signals
std::function<void(const std::vector<std::string>&, int)> completionReceivedCallback;
std::function<void(int, int, int, int, const std::string&)> gotoDefinitionsReceivedCallback;
std::function<void(const std::vector<std::string>&, const std::vector<int>&, const std::vector<int>&,
const std::vector<int>&, const std::vector<int>&, const std::vector<int>&)> receivedDiagnosticsCallback;
std::function<void(const std::string&)> serverErrorOccurredCallback;
std::function<void(int, Process::ExitStatus)> serverFinishedCallback;
std::function<void()> initializeResponseReceivedCallback;
std::function<void(const std::string&, const std::string&, int)> hoverInformationReceivedCallback;
std::function<void(const json&)> codeActionsReceivedCallback;
std::function<void(const json&)> renameReceivedCallback;
std::string fromLocalFile(const std::string& path);
bool supportsIncrementalChanges = false;
private:
void writerLoop();
void onServerReadyRead();
void onServerErrorOccurred(Process::ProcessError error);
void onServerFinished(int exitCode, Process::ExitStatus exitStatus);
json filterDiagnostics(const json &diagnostics, int lineStart, int columnStart, int lineEnd, int columnEnd);
void sendMessage(const json &message);
json readMessage();
Process serverProcess;
int requestId;
int documentVersion;
// For writer thread
std::thread writerThread;
std::queue<json> messageQueue;
std::mutex queueMutex;
std::condition_variable queueCond;
std::atomic<bool> stopWriter{false};
// Replace QEventLoop with condition variables
std::mutex initializeMutex;
std::condition_variable initializeCondition;
std::atomic<bool> initializeComplete{false};
std::mutex shutdownMutex;
std::condition_variable shutdownCondition;
std::atomic<bool> shutdownComplete{false};
std::function<void(const std::string&)> logCallback;
};
#endif // LANGUAGESERVERCLIENT_H