1 //! rust-analyzer extensions to the LSP.
3 use std::{collections::HashMap, path::PathBuf};
5 use lsp_types::request::Request;
7 notification::Notification, CodeActionKind, PartialResultParams, Position, Range,
8 TextDocumentIdentifier, WorkDoneProgressParams,
10 use serde::{Deserialize, Serialize};
12 pub enum AnalyzerStatus {}
14 impl Request for AnalyzerStatus {
15 type Params = AnalyzerStatusParams;
17 const METHOD: &'static str = "rust-analyzer/analyzerStatus";
20 #[derive(Deserialize, Serialize, Debug)]
21 #[serde(rename_all = "camelCase")]
22 pub struct AnalyzerStatusParams {
23 pub text_document: Option<TextDocumentIdentifier>,
26 pub enum MemoryUsage {}
28 impl Request for MemoryUsage {
31 const METHOD: &'static str = "rust-analyzer/memoryUsage";
34 pub enum ShuffleCrateGraph {}
36 impl Request for ShuffleCrateGraph {
39 const METHOD: &'static str = "rust-analyzer/shuffleCrateGraph";
42 pub enum ReloadWorkspace {}
44 impl Request for ReloadWorkspace {
47 const METHOD: &'static str = "rust-analyzer/reloadWorkspace";
50 pub enum SyntaxTree {}
52 impl Request for SyntaxTree {
53 type Params = SyntaxTreeParams;
55 const METHOD: &'static str = "rust-analyzer/syntaxTree";
58 #[derive(Deserialize, Serialize, Debug)]
59 #[serde(rename_all = "camelCase")]
60 pub struct SyntaxTreeParams {
61 pub text_document: TextDocumentIdentifier,
62 pub range: Option<Range>,
67 impl Request for ViewHir {
68 type Params = lsp_types::TextDocumentPositionParams;
70 const METHOD: &'static str = "rust-analyzer/viewHir";
73 #[derive(Deserialize, Serialize, Debug)]
74 #[serde(rename_all = "camelCase")]
75 pub struct ViewCrateGraphParams {
76 /// Include *all* crates, not just crates in the workspace.
80 pub enum ViewCrateGraph {}
82 impl Request for ViewCrateGraph {
83 type Params = ViewCrateGraphParams;
85 const METHOD: &'static str = "rust-analyzer/viewCrateGraph";
88 #[derive(Deserialize, Serialize, Debug)]
89 #[serde(rename_all = "camelCase")]
90 pub struct ViewItemTreeParams {
91 pub text_document: TextDocumentIdentifier,
94 pub enum ViewItemTree {}
96 impl Request for ViewItemTree {
97 type Params = ViewItemTreeParams;
99 const METHOD: &'static str = "rust-analyzer/viewItemTree";
102 pub enum ExpandMacro {}
104 impl Request for ExpandMacro {
105 type Params = ExpandMacroParams;
106 type Result = Option<ExpandedMacro>;
107 const METHOD: &'static str = "rust-analyzer/expandMacro";
110 #[derive(Deserialize, Serialize, Debug)]
111 #[serde(rename_all = "camelCase")]
112 pub struct ExpandMacroParams {
113 pub text_document: TextDocumentIdentifier,
114 pub position: Position,
117 #[derive(Deserialize, Serialize, Debug)]
118 #[serde(rename_all = "camelCase")]
119 pub struct ExpandedMacro {
121 pub expansion: String,
124 pub enum MatchingBrace {}
126 impl Request for MatchingBrace {
127 type Params = MatchingBraceParams;
128 type Result = Vec<Position>;
129 const METHOD: &'static str = "experimental/matchingBrace";
132 #[derive(Deserialize, Serialize, Debug)]
133 #[serde(rename_all = "camelCase")]
134 pub struct MatchingBraceParams {
135 pub text_document: TextDocumentIdentifier,
136 pub positions: Vec<Position>,
139 pub enum ParentModule {}
141 impl Request for ParentModule {
142 type Params = lsp_types::TextDocumentPositionParams;
143 type Result = Option<lsp_types::GotoDefinitionResponse>;
144 const METHOD: &'static str = "experimental/parentModule";
147 pub enum JoinLines {}
149 impl Request for JoinLines {
150 type Params = JoinLinesParams;
151 type Result = Vec<lsp_types::TextEdit>;
152 const METHOD: &'static str = "experimental/joinLines";
155 #[derive(Deserialize, Serialize, Debug)]
156 #[serde(rename_all = "camelCase")]
157 pub struct JoinLinesParams {
158 pub text_document: TextDocumentIdentifier,
159 pub ranges: Vec<Range>,
164 impl Request for OnEnter {
165 type Params = lsp_types::TextDocumentPositionParams;
166 type Result = Option<Vec<SnippetTextEdit>>;
167 const METHOD: &'static str = "experimental/onEnter";
170 pub enum Runnables {}
172 impl Request for Runnables {
173 type Params = RunnablesParams;
174 type Result = Vec<Runnable>;
175 const METHOD: &'static str = "experimental/runnables";
178 #[derive(Serialize, Deserialize, Debug)]
179 #[serde(rename_all = "camelCase")]
180 pub struct RunnablesParams {
181 pub text_document: TextDocumentIdentifier,
182 pub position: Option<Position>,
185 #[derive(Deserialize, Serialize, Debug)]
186 #[serde(rename_all = "camelCase")]
187 pub struct Runnable {
189 #[serde(skip_serializing_if = "Option::is_none")]
190 pub location: Option<lsp_types::LocationLink>,
191 pub kind: RunnableKind,
192 pub args: CargoRunnable,
195 #[derive(Serialize, Deserialize, Debug)]
196 #[serde(rename_all = "lowercase")]
197 pub enum RunnableKind {
201 #[derive(Deserialize, Serialize, Debug)]
202 #[serde(rename_all = "camelCase")]
203 pub struct CargoRunnable {
204 // command to be executed instead of cargo
205 pub override_cargo: Option<String>,
206 #[serde(skip_serializing_if = "Option::is_none")]
207 pub workspace_root: Option<PathBuf>,
208 // command, --package and --lib stuff
209 pub cargo_args: Vec<String>,
210 // user-specified additional cargo args, like `--release`.
211 pub cargo_extra_args: Vec<String>,
213 pub executable_args: Vec<String>,
214 #[serde(skip_serializing_if = "Option::is_none")]
215 pub expect_test: Option<bool>,
218 pub enum RelatedTests {}
220 impl Request for RelatedTests {
221 type Params = lsp_types::TextDocumentPositionParams;
222 type Result = Vec<TestInfo>;
223 const METHOD: &'static str = "rust-analyzer/relatedTests";
226 #[derive(Debug, Deserialize, Serialize)]
227 pub struct TestInfo {
228 pub runnable: Runnable,
231 pub enum InlayHints {}
233 impl Request for InlayHints {
234 type Params = InlayHintsParams;
235 type Result = Vec<InlayHint>;
236 const METHOD: &'static str = "rust-analyzer/inlayHints";
239 #[derive(Serialize, Deserialize, Debug)]
240 #[serde(rename_all = "camelCase")]
241 pub struct InlayHintsParams {
242 pub text_document: TextDocumentIdentifier,
245 #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
252 #[derive(Debug, Deserialize, Serialize)]
253 pub struct InlayHint {
261 impl Request for Ssr {
262 type Params = SsrParams;
263 type Result = lsp_types::WorkspaceEdit;
264 const METHOD: &'static str = "experimental/ssr";
267 #[derive(Debug, Deserialize, Serialize)]
268 #[serde(rename_all = "camelCase")]
269 pub struct SsrParams {
271 pub parse_only: bool,
273 /// File position where SSR was invoked. Paths in `query` will be resolved relative to this
276 pub position: lsp_types::TextDocumentPositionParams,
278 /// Current selections. Search/replace will be restricted to these if non-empty.
279 pub selections: Vec<lsp_types::Range>,
282 pub enum ServerStatusNotification {}
284 impl Notification for ServerStatusNotification {
285 type Params = ServerStatusParams;
286 const METHOD: &'static str = "experimental/serverStatus";
289 #[derive(Deserialize, Serialize, PartialEq, Eq, Clone)]
290 pub struct ServerStatusParams {
293 pub message: Option<String>,
296 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
297 #[serde(rename_all = "camelCase")]
304 pub enum CodeActionRequest {}
306 impl Request for CodeActionRequest {
307 type Params = lsp_types::CodeActionParams;
308 type Result = Option<Vec<CodeAction>>;
309 const METHOD: &'static str = "textDocument/codeAction";
312 pub enum CodeActionResolveRequest {}
313 impl Request for CodeActionResolveRequest {
314 type Params = CodeAction;
315 type Result = CodeAction;
316 const METHOD: &'static str = "codeAction/resolve";
319 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
320 #[serde(rename_all = "camelCase")]
321 pub struct CodeAction {
323 #[serde(skip_serializing_if = "Option::is_none")]
324 pub group: Option<String>,
325 #[serde(skip_serializing_if = "Option::is_none")]
326 pub kind: Option<CodeActionKind>,
327 // We don't handle commands on the client-side
328 // #[serde(skip_serializing_if = "Option::is_none")]
329 // pub command: Option<lsp_types::Command>,
330 #[serde(skip_serializing_if = "Option::is_none")]
331 pub edit: Option<SnippetWorkspaceEdit>,
332 #[serde(skip_serializing_if = "Option::is_none")]
333 pub is_preferred: Option<bool>,
335 #[serde(skip_serializing_if = "Option::is_none")]
336 pub data: Option<CodeActionData>,
339 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
340 #[serde(rename_all = "camelCase")]
341 pub struct CodeActionData {
342 pub code_action_params: lsp_types::CodeActionParams,
346 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
347 #[serde(rename_all = "camelCase")]
348 pub struct SnippetWorkspaceEdit {
349 #[serde(skip_serializing_if = "Option::is_none")]
350 pub changes: Option<HashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>>,
351 #[serde(skip_serializing_if = "Option::is_none")]
352 pub document_changes: Option<Vec<SnippetDocumentChangeOperation>>,
353 #[serde(skip_serializing_if = "Option::is_none")]
354 pub change_annotations:
355 Option<HashMap<lsp_types::ChangeAnnotationIdentifier, lsp_types::ChangeAnnotation>>,
358 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
359 #[serde(untagged, rename_all = "lowercase")]
360 pub enum SnippetDocumentChangeOperation {
361 Op(lsp_types::ResourceOp),
362 Edit(SnippetTextDocumentEdit),
365 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
366 #[serde(rename_all = "camelCase")]
367 pub struct SnippetTextDocumentEdit {
368 pub text_document: lsp_types::OptionalVersionedTextDocumentIdentifier,
369 pub edits: Vec<SnippetTextEdit>,
372 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
373 #[serde(rename_all = "camelCase")]
374 pub struct SnippetTextEdit {
376 pub new_text: String,
377 #[serde(skip_serializing_if = "Option::is_none")]
378 pub insert_text_format: Option<lsp_types::InsertTextFormat>,
379 /// The annotation id if this is an annotated
380 #[serde(skip_serializing_if = "Option::is_none")]
381 pub annotation_id: Option<lsp_types::ChangeAnnotationIdentifier>,
384 pub enum HoverRequest {}
386 impl Request for HoverRequest {
387 type Params = HoverParams;
388 type Result = Option<Hover>;
389 const METHOD: &'static str = "textDocument/hover";
392 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
393 #[serde(rename_all = "camelCase")]
394 pub struct HoverParams {
395 pub text_document: TextDocumentIdentifier,
396 pub position: PositionOrRange,
399 pub work_done_progress_params: WorkDoneProgressParams,
402 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
404 pub enum PositionOrRange {
405 Position(lsp_types::Position),
406 Range(lsp_types::Range),
409 #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
412 pub hover: lsp_types::Hover,
413 #[serde(skip_serializing_if = "Vec::is_empty")]
414 pub actions: Vec<CommandLinkGroup>,
417 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
418 pub struct CommandLinkGroup {
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub title: Option<String>,
421 pub commands: Vec<CommandLink>,
424 // LSP v3.15 Command does not have a `tooltip` field, vscode supports one.
425 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
426 pub struct CommandLink {
428 pub command: lsp_types::Command,
429 #[serde(skip_serializing_if = "Option::is_none")]
430 pub tooltip: Option<String>,
433 pub enum ExternalDocs {}
435 impl Request for ExternalDocs {
436 type Params = lsp_types::TextDocumentPositionParams;
437 type Result = Option<lsp_types::Url>;
438 const METHOD: &'static str = "experimental/externalDocs";
441 pub enum OpenCargoToml {}
443 impl Request for OpenCargoToml {
444 type Params = OpenCargoTomlParams;
445 type Result = Option<lsp_types::GotoDefinitionResponse>;
446 const METHOD: &'static str = "experimental/openCargoToml";
449 #[derive(Serialize, Deserialize, Debug)]
450 #[serde(rename_all = "camelCase")]
451 pub struct OpenCargoTomlParams {
452 pub text_document: TextDocumentIdentifier,
455 /// Information about CodeLens, that is to be resolved.
456 #[derive(Debug, Serialize, Deserialize)]
457 #[serde(rename_all = "camelCase")]
458 pub(crate) enum CodeLensResolveData {
459 Impls(lsp_types::request::GotoImplementationParams),
460 References(lsp_types::TextDocumentPositionParams),
463 pub fn supports_utf8(caps: &lsp_types::ClientCapabilities) -> bool {
464 caps.offset_encoding.as_deref().unwrap_or_default().iter().any(|it| it == "utf-8")
469 impl Request for MoveItem {
470 type Params = MoveItemParams;
471 type Result = Vec<SnippetTextEdit>;
472 const METHOD: &'static str = "experimental/moveItem";
475 #[derive(Serialize, Deserialize, Debug)]
476 #[serde(rename_all = "camelCase")]
477 pub struct MoveItemParams {
478 pub direction: MoveItemDirection,
479 pub text_document: TextDocumentIdentifier,
483 #[derive(Serialize, Deserialize, Debug)]
484 pub enum MoveItemDirection {
490 pub enum WorkspaceSymbol {}
492 impl Request for WorkspaceSymbol {
493 type Params = WorkspaceSymbolParams;
494 type Result = Option<Vec<lsp_types::SymbolInformation>>;
495 const METHOD: &'static str = "workspace/symbol";
498 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
499 #[serde(rename_all = "camelCase")]
500 pub struct WorkspaceSymbolParams {
502 pub partial_result_params: PartialResultParams,
505 pub work_done_progress_params: WorkDoneProgressParams,
507 /// A non-empty query string
510 pub search_scope: Option<WorkspaceSymbolSearchScope>,
512 pub search_kind: Option<WorkspaceSymbolSearchKind>,
515 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
516 #[serde(rename_all = "camelCase")]
517 pub enum WorkspaceSymbolSearchScope {
519 WorkspaceAndDependencies,
522 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
523 #[serde(rename_all = "camelCase")]
524 pub enum WorkspaceSymbolSearchKind {
529 #[derive(Debug, Serialize, Deserialize)]
530 pub struct CompletionResolveData {
531 pub position: lsp_types::TextDocumentPositionParams,
532 pub imports: Vec<CompletionImport>,
535 #[derive(Debug, Serialize, Deserialize)]
536 pub struct CompletionImport {
537 pub full_import_path: String,
538 pub imported_name: String,
541 #[derive(Debug, Deserialize, Default)]
542 pub struct ClientCommandOptions {
543 pub commands: Vec<String>,