]> git.lizzy.rs Git - rust.git/blob - crates/rust-analyzer/src/lsp_ext.rs
a3e12c046b5db7f4d70e46b5ba19733f714ed6bc
[rust.git] / crates / rust-analyzer / src / lsp_ext.rs
1 //! rust-analyzer extensions to the LSP.
2
3 use std::{collections::HashMap, path::PathBuf};
4
5 use lsp_types::request::Request;
6 use lsp_types::{notification::Notification, Position, Range, TextDocumentIdentifier};
7 use serde::{Deserialize, Serialize};
8
9 pub enum AnalyzerStatus {}
10
11 impl Request for AnalyzerStatus {
12     type Params = ();
13     type Result = String;
14     const METHOD: &'static str = "rust-analyzer/analyzerStatus";
15 }
16
17 pub enum MemoryUsage {}
18
19 impl Request for MemoryUsage {
20     type Params = ();
21     type Result = String;
22     const METHOD: &'static str = "rust-analyzer/memoryUsage";
23 }
24
25 pub enum ReloadWorkspace {}
26
27 impl Request for ReloadWorkspace {
28     type Params = ();
29     type Result = ();
30     const METHOD: &'static str = "rust-analyzer/reloadWorkspace";
31 }
32
33 pub enum SyntaxTree {}
34
35 impl Request for SyntaxTree {
36     type Params = SyntaxTreeParams;
37     type Result = String;
38     const METHOD: &'static str = "rust-analyzer/syntaxTree";
39 }
40
41 #[derive(Deserialize, Serialize, Debug)]
42 #[serde(rename_all = "camelCase")]
43 pub struct SyntaxTreeParams {
44     pub text_document: TextDocumentIdentifier,
45     pub range: Option<Range>,
46 }
47
48 pub enum ExpandMacro {}
49
50 impl Request for ExpandMacro {
51     type Params = ExpandMacroParams;
52     type Result = Option<ExpandedMacro>;
53     const METHOD: &'static str = "rust-analyzer/expandMacro";
54 }
55
56 #[derive(Deserialize, Serialize, Debug)]
57 #[serde(rename_all = "camelCase")]
58 pub struct ExpandMacroParams {
59     pub text_document: TextDocumentIdentifier,
60     pub position: Position,
61 }
62
63 #[derive(Deserialize, Serialize, Debug)]
64 #[serde(rename_all = "camelCase")]
65 pub struct ExpandedMacro {
66     pub name: String,
67     pub expansion: String,
68 }
69
70 pub enum MatchingBrace {}
71
72 impl Request for MatchingBrace {
73     type Params = MatchingBraceParams;
74     type Result = Vec<Position>;
75     const METHOD: &'static str = "experimental/matchingBrace";
76 }
77
78 #[derive(Deserialize, Serialize, Debug)]
79 #[serde(rename_all = "camelCase")]
80 pub struct MatchingBraceParams {
81     pub text_document: TextDocumentIdentifier,
82     pub positions: Vec<Position>,
83 }
84
85 pub enum ParentModule {}
86
87 impl Request for ParentModule {
88     type Params = lsp_types::TextDocumentPositionParams;
89     type Result = Option<lsp_types::GotoDefinitionResponse>;
90     const METHOD: &'static str = "experimental/parentModule";
91 }
92
93 pub enum JoinLines {}
94
95 impl Request for JoinLines {
96     type Params = JoinLinesParams;
97     type Result = Vec<lsp_types::TextEdit>;
98     const METHOD: &'static str = "experimental/joinLines";
99 }
100
101 #[derive(Deserialize, Serialize, Debug)]
102 #[serde(rename_all = "camelCase")]
103 pub struct JoinLinesParams {
104     pub text_document: TextDocumentIdentifier,
105     pub ranges: Vec<Range>,
106 }
107
108 pub enum ResolveCodeActionRequest {}
109
110 impl Request for ResolveCodeActionRequest {
111     type Params = ResolveCodeActionParams;
112     type Result = Option<SnippetWorkspaceEdit>;
113     const METHOD: &'static str = "experimental/resolveCodeAction";
114 }
115
116 /// Params for the ResolveCodeActionRequest
117 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
118 #[serde(rename_all = "camelCase")]
119 pub struct ResolveCodeActionParams {
120     pub code_action_params: lsp_types::CodeActionParams,
121     pub id: String,
122 }
123
124 pub enum OnEnter {}
125
126 impl Request for OnEnter {
127     type Params = lsp_types::TextDocumentPositionParams;
128     type Result = Option<Vec<SnippetTextEdit>>;
129     const METHOD: &'static str = "experimental/onEnter";
130 }
131
132 pub enum Runnables {}
133
134 impl Request for Runnables {
135     type Params = RunnablesParams;
136     type Result = Vec<Runnable>;
137     const METHOD: &'static str = "experimental/runnables";
138 }
139
140 #[derive(Serialize, Deserialize, Debug)]
141 #[serde(rename_all = "camelCase")]
142 pub struct RunnablesParams {
143     pub text_document: TextDocumentIdentifier,
144     pub position: Option<Position>,
145 }
146
147 #[derive(Deserialize, Serialize, Debug)]
148 #[serde(rename_all = "camelCase")]
149 pub struct Runnable {
150     pub label: String,
151     #[serde(skip_serializing_if = "Option::is_none")]
152     pub location: Option<lsp_types::LocationLink>,
153     pub kind: RunnableKind,
154     pub args: CargoRunnable,
155 }
156
157 #[derive(Serialize, Deserialize, Debug)]
158 #[serde(rename_all = "lowercase")]
159 pub enum RunnableKind {
160     Cargo,
161 }
162
163 #[derive(Deserialize, Serialize, Debug)]
164 #[serde(rename_all = "camelCase")]
165 pub struct CargoRunnable {
166     #[serde(skip_serializing_if = "Option::is_none")]
167     pub workspace_root: Option<PathBuf>,
168     // command, --package and --lib stuff
169     pub cargo_args: Vec<String>,
170     // stuff after --
171     pub executable_args: Vec<String>,
172     #[serde(skip_serializing_if = "Option::is_none")]
173     pub expect_test: Option<bool>,
174 }
175
176 pub enum InlayHints {}
177
178 impl Request for InlayHints {
179     type Params = InlayHintsParams;
180     type Result = Vec<InlayHint>;
181     const METHOD: &'static str = "rust-analyzer/inlayHints";
182 }
183
184 #[derive(Serialize, Deserialize, Debug)]
185 #[serde(rename_all = "camelCase")]
186 pub struct InlayHintsParams {
187     pub text_document: TextDocumentIdentifier,
188 }
189
190 #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
191 pub enum InlayKind {
192     TypeHint,
193     ParameterHint,
194     ChainingHint,
195 }
196
197 #[derive(Debug, Deserialize, Serialize)]
198 pub struct InlayHint {
199     pub range: Range,
200     pub kind: InlayKind,
201     pub label: String,
202 }
203
204 pub enum Ssr {}
205
206 impl Request for Ssr {
207     type Params = SsrParams;
208     type Result = lsp_types::WorkspaceEdit;
209     const METHOD: &'static str = "experimental/ssr";
210 }
211
212 #[derive(Debug, Deserialize, Serialize)]
213 #[serde(rename_all = "camelCase")]
214 pub struct SsrParams {
215     pub query: String,
216     pub parse_only: bool,
217 }
218
219 pub enum StatusNotification {}
220
221 #[serde(rename_all = "camelCase")]
222 #[derive(Serialize, Deserialize)]
223 pub enum Status {
224     Loading,
225     Ready,
226     NeedsReload,
227     Invalid,
228 }
229
230 impl Notification for StatusNotification {
231     type Params = Status;
232     const METHOD: &'static str = "rust-analyzer/status";
233 }
234
235 pub enum CodeActionRequest {}
236
237 impl Request for CodeActionRequest {
238     type Params = lsp_types::CodeActionParams;
239     type Result = Option<Vec<CodeAction>>;
240     const METHOD: &'static str = "textDocument/codeAction";
241 }
242
243 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
244 pub struct CodeAction {
245     pub title: String,
246     #[serde(skip_serializing_if = "Option::is_none")]
247     pub id: Option<String>,
248     #[serde(skip_serializing_if = "Option::is_none")]
249     pub group: Option<String>,
250     #[serde(skip_serializing_if = "Option::is_none")]
251     pub kind: Option<String>,
252     // We don't handle commands on the client-side
253     // #[serde(skip_serializing_if = "Option::is_none")]
254     // pub command: Option<lsp_types::Command>,
255     #[serde(skip_serializing_if = "Option::is_none")]
256     pub edit: Option<SnippetWorkspaceEdit>,
257 }
258
259 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
260 #[serde(rename_all = "camelCase")]
261 pub struct SnippetWorkspaceEdit {
262     #[serde(skip_serializing_if = "Option::is_none")]
263     pub changes: Option<HashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>>,
264     #[serde(skip_serializing_if = "Option::is_none")]
265     pub document_changes: Option<Vec<SnippetDocumentChangeOperation>>,
266 }
267
268 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
269 #[serde(untagged, rename_all = "lowercase")]
270 pub enum SnippetDocumentChangeOperation {
271     Op(lsp_types::ResourceOp),
272     Edit(SnippetTextDocumentEdit),
273 }
274
275 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
276 #[serde(rename_all = "camelCase")]
277 pub struct SnippetTextDocumentEdit {
278     pub text_document: lsp_types::VersionedTextDocumentIdentifier,
279     pub edits: Vec<SnippetTextEdit>,
280 }
281
282 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
283 #[serde(rename_all = "camelCase")]
284 pub struct SnippetTextEdit {
285     pub range: Range,
286     pub new_text: String,
287     #[serde(skip_serializing_if = "Option::is_none")]
288     pub insert_text_format: Option<lsp_types::InsertTextFormat>,
289 }
290
291 pub enum HoverRequest {}
292
293 impl Request for HoverRequest {
294     type Params = lsp_types::HoverParams;
295     type Result = Option<Hover>;
296     const METHOD: &'static str = "textDocument/hover";
297 }
298
299 #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
300 pub struct Hover {
301     #[serde(flatten)]
302     pub hover: lsp_types::Hover,
303     #[serde(skip_serializing_if = "Vec::is_empty")]
304     pub actions: Vec<CommandLinkGroup>,
305 }
306
307 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
308 pub struct CommandLinkGroup {
309     #[serde(skip_serializing_if = "Option::is_none")]
310     pub title: Option<String>,
311     pub commands: Vec<CommandLink>,
312 }
313
314 // LSP v3.15 Command does not have a `tooltip` field, vscode supports one.
315 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
316 pub struct CommandLink {
317     #[serde(flatten)]
318     pub command: lsp_types::Command,
319     #[serde(skip_serializing_if = "Option::is_none")]
320     pub tooltip: Option<String>,
321 }