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 pub enum ViewFileText {}
75 impl Request for ViewFileText {
76 type Params = lsp_types::TextDocumentIdentifier;
78 const METHOD: &'static str = "rust-analyzer/viewFileText";
81 #[derive(Deserialize, Serialize, Debug)]
82 #[serde(rename_all = "camelCase")]
83 pub struct ViewCrateGraphParams {
84 /// Include *all* crates, not just crates in the workspace.
88 pub enum ViewCrateGraph {}
90 impl Request for ViewCrateGraph {
91 type Params = ViewCrateGraphParams;
93 const METHOD: &'static str = "rust-analyzer/viewCrateGraph";
96 #[derive(Deserialize, Serialize, Debug)]
97 #[serde(rename_all = "camelCase")]
98 pub struct ViewItemTreeParams {
99 pub text_document: TextDocumentIdentifier,
102 pub enum ViewItemTree {}
104 impl Request for ViewItemTree {
105 type Params = ViewItemTreeParams;
106 type Result = String;
107 const METHOD: &'static str = "rust-analyzer/viewItemTree";
110 pub enum ExpandMacro {}
112 impl Request for ExpandMacro {
113 type Params = ExpandMacroParams;
114 type Result = Option<ExpandedMacro>;
115 const METHOD: &'static str = "rust-analyzer/expandMacro";
118 #[derive(Deserialize, Serialize, Debug)]
119 #[serde(rename_all = "camelCase")]
120 pub struct ExpandMacroParams {
121 pub text_document: TextDocumentIdentifier,
122 pub position: Position,
125 #[derive(Deserialize, Serialize, Debug)]
126 #[serde(rename_all = "camelCase")]
127 pub struct ExpandedMacro {
129 pub expansion: String,
132 pub enum MatchingBrace {}
134 impl Request for MatchingBrace {
135 type Params = MatchingBraceParams;
136 type Result = Vec<Position>;
137 const METHOD: &'static str = "experimental/matchingBrace";
140 #[derive(Deserialize, Serialize, Debug)]
141 #[serde(rename_all = "camelCase")]
142 pub struct MatchingBraceParams {
143 pub text_document: TextDocumentIdentifier,
144 pub positions: Vec<Position>,
147 pub enum ParentModule {}
149 impl Request for ParentModule {
150 type Params = lsp_types::TextDocumentPositionParams;
151 type Result = Option<lsp_types::GotoDefinitionResponse>;
152 const METHOD: &'static str = "experimental/parentModule";
155 pub enum JoinLines {}
157 impl Request for JoinLines {
158 type Params = JoinLinesParams;
159 type Result = Vec<lsp_types::TextEdit>;
160 const METHOD: &'static str = "experimental/joinLines";
163 #[derive(Deserialize, Serialize, Debug)]
164 #[serde(rename_all = "camelCase")]
165 pub struct JoinLinesParams {
166 pub text_document: TextDocumentIdentifier,
167 pub ranges: Vec<Range>,
172 impl Request for OnEnter {
173 type Params = lsp_types::TextDocumentPositionParams;
174 type Result = Option<Vec<SnippetTextEdit>>;
175 const METHOD: &'static str = "experimental/onEnter";
178 pub enum Runnables {}
180 impl Request for Runnables {
181 type Params = RunnablesParams;
182 type Result = Vec<Runnable>;
183 const METHOD: &'static str = "experimental/runnables";
186 #[derive(Serialize, Deserialize, Debug)]
187 #[serde(rename_all = "camelCase")]
188 pub struct RunnablesParams {
189 pub text_document: TextDocumentIdentifier,
190 pub position: Option<Position>,
193 #[derive(Deserialize, Serialize, Debug)]
194 #[serde(rename_all = "camelCase")]
195 pub struct Runnable {
197 #[serde(skip_serializing_if = "Option::is_none")]
198 pub location: Option<lsp_types::LocationLink>,
199 pub kind: RunnableKind,
200 pub args: CargoRunnable,
203 #[derive(Serialize, Deserialize, Debug)]
204 #[serde(rename_all = "lowercase")]
205 pub enum RunnableKind {
209 #[derive(Deserialize, Serialize, Debug)]
210 #[serde(rename_all = "camelCase")]
211 pub struct CargoRunnable {
212 // command to be executed instead of cargo
213 pub override_cargo: Option<String>,
214 #[serde(skip_serializing_if = "Option::is_none")]
215 pub workspace_root: Option<PathBuf>,
216 // command, --package and --lib stuff
217 pub cargo_args: Vec<String>,
218 // user-specified additional cargo args, like `--release`.
219 pub cargo_extra_args: Vec<String>,
221 pub executable_args: Vec<String>,
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub expect_test: Option<bool>,
226 pub enum RelatedTests {}
228 impl Request for RelatedTests {
229 type Params = lsp_types::TextDocumentPositionParams;
230 type Result = Vec<TestInfo>;
231 const METHOD: &'static str = "rust-analyzer/relatedTests";
234 #[derive(Debug, Deserialize, Serialize)]
235 pub struct TestInfo {
236 pub runnable: Runnable,
239 #[derive(Serialize, Deserialize, Debug)]
240 #[serde(rename_all = "camelCase")]
241 pub struct InlayHintsParams {
242 pub text_document: TextDocumentIdentifier,
243 pub range: Option<lsp_types::Range>,
248 impl Request for Ssr {
249 type Params = SsrParams;
250 type Result = lsp_types::WorkspaceEdit;
251 const METHOD: &'static str = "experimental/ssr";
254 #[derive(Debug, Deserialize, Serialize)]
255 #[serde(rename_all = "camelCase")]
256 pub struct SsrParams {
258 pub parse_only: bool,
260 /// File position where SSR was invoked. Paths in `query` will be resolved relative to this
263 pub position: lsp_types::TextDocumentPositionParams,
265 /// Current selections. Search/replace will be restricted to these if non-empty.
266 pub selections: Vec<lsp_types::Range>,
269 pub enum ServerStatusNotification {}
271 impl Notification for ServerStatusNotification {
272 type Params = ServerStatusParams;
273 const METHOD: &'static str = "experimental/serverStatus";
276 #[derive(Deserialize, Serialize, PartialEq, Eq, Clone)]
277 pub struct ServerStatusParams {
280 pub message: Option<String>,
283 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
284 #[serde(rename_all = "camelCase")]
291 pub enum CodeActionRequest {}
293 impl Request for CodeActionRequest {
294 type Params = lsp_types::CodeActionParams;
295 type Result = Option<Vec<CodeAction>>;
296 const METHOD: &'static str = "textDocument/codeAction";
299 pub enum CodeActionResolveRequest {}
300 impl Request for CodeActionResolveRequest {
301 type Params = CodeAction;
302 type Result = CodeAction;
303 const METHOD: &'static str = "codeAction/resolve";
306 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
307 #[serde(rename_all = "camelCase")]
308 pub struct CodeAction {
310 #[serde(skip_serializing_if = "Option::is_none")]
311 pub group: Option<String>,
312 #[serde(skip_serializing_if = "Option::is_none")]
313 pub kind: Option<CodeActionKind>,
314 #[serde(skip_serializing_if = "Option::is_none")]
315 pub command: Option<lsp_types::Command>,
316 #[serde(skip_serializing_if = "Option::is_none")]
317 pub edit: Option<SnippetWorkspaceEdit>,
318 #[serde(skip_serializing_if = "Option::is_none")]
319 pub is_preferred: Option<bool>,
321 #[serde(skip_serializing_if = "Option::is_none")]
322 pub data: Option<CodeActionData>,
325 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
326 #[serde(rename_all = "camelCase")]
327 pub struct CodeActionData {
328 pub code_action_params: lsp_types::CodeActionParams,
332 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
333 #[serde(rename_all = "camelCase")]
334 pub struct SnippetWorkspaceEdit {
335 #[serde(skip_serializing_if = "Option::is_none")]
336 pub changes: Option<HashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>>,
337 #[serde(skip_serializing_if = "Option::is_none")]
338 pub document_changes: Option<Vec<SnippetDocumentChangeOperation>>,
339 #[serde(skip_serializing_if = "Option::is_none")]
340 pub change_annotations:
341 Option<HashMap<lsp_types::ChangeAnnotationIdentifier, lsp_types::ChangeAnnotation>>,
344 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
345 #[serde(untagged, rename_all = "lowercase")]
346 pub enum SnippetDocumentChangeOperation {
347 Op(lsp_types::ResourceOp),
348 Edit(SnippetTextDocumentEdit),
351 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
352 #[serde(rename_all = "camelCase")]
353 pub struct SnippetTextDocumentEdit {
354 pub text_document: lsp_types::OptionalVersionedTextDocumentIdentifier,
355 pub edits: Vec<SnippetTextEdit>,
358 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
359 #[serde(rename_all = "camelCase")]
360 pub struct SnippetTextEdit {
362 pub new_text: String,
363 #[serde(skip_serializing_if = "Option::is_none")]
364 pub insert_text_format: Option<lsp_types::InsertTextFormat>,
365 /// The annotation id if this is an annotated
366 #[serde(skip_serializing_if = "Option::is_none")]
367 pub annotation_id: Option<lsp_types::ChangeAnnotationIdentifier>,
370 pub enum HoverRequest {}
372 impl Request for HoverRequest {
373 type Params = HoverParams;
374 type Result = Option<Hover>;
375 const METHOD: &'static str = "textDocument/hover";
378 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
379 #[serde(rename_all = "camelCase")]
380 pub struct HoverParams {
381 pub text_document: TextDocumentIdentifier,
382 pub position: PositionOrRange,
385 pub work_done_progress_params: WorkDoneProgressParams,
388 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
390 pub enum PositionOrRange {
391 Position(lsp_types::Position),
392 Range(lsp_types::Range),
395 #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
398 pub hover: lsp_types::Hover,
399 #[serde(skip_serializing_if = "Vec::is_empty")]
400 pub actions: Vec<CommandLinkGroup>,
403 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
404 pub struct CommandLinkGroup {
405 #[serde(skip_serializing_if = "Option::is_none")]
406 pub title: Option<String>,
407 pub commands: Vec<CommandLink>,
410 // LSP v3.15 Command does not have a `tooltip` field, vscode supports one.
411 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
412 pub struct CommandLink {
414 pub command: lsp_types::Command,
415 #[serde(skip_serializing_if = "Option::is_none")]
416 pub tooltip: Option<String>,
419 pub enum ExternalDocs {}
421 impl Request for ExternalDocs {
422 type Params = lsp_types::TextDocumentPositionParams;
423 type Result = Option<lsp_types::Url>;
424 const METHOD: &'static str = "experimental/externalDocs";
427 pub enum OpenCargoToml {}
429 impl Request for OpenCargoToml {
430 type Params = OpenCargoTomlParams;
431 type Result = Option<lsp_types::GotoDefinitionResponse>;
432 const METHOD: &'static str = "experimental/openCargoToml";
435 #[derive(Serialize, Deserialize, Debug)]
436 #[serde(rename_all = "camelCase")]
437 pub struct OpenCargoTomlParams {
438 pub text_document: TextDocumentIdentifier,
441 /// Information about CodeLens, that is to be resolved.
442 #[derive(Debug, Serialize, Deserialize)]
443 #[serde(rename_all = "camelCase")]
444 pub(crate) enum CodeLensResolveData {
445 Impls(lsp_types::request::GotoImplementationParams),
446 References(lsp_types::TextDocumentPositionParams),
449 pub fn supports_utf8(caps: &lsp_types::ClientCapabilities) -> bool {
450 caps.offset_encoding.as_deref().unwrap_or_default().iter().any(|it| it == "utf-8")
455 impl Request for MoveItem {
456 type Params = MoveItemParams;
457 type Result = Vec<SnippetTextEdit>;
458 const METHOD: &'static str = "experimental/moveItem";
461 #[derive(Serialize, Deserialize, Debug)]
462 #[serde(rename_all = "camelCase")]
463 pub struct MoveItemParams {
464 pub direction: MoveItemDirection,
465 pub text_document: TextDocumentIdentifier,
469 #[derive(Serialize, Deserialize, Debug)]
470 pub enum MoveItemDirection {
476 pub enum WorkspaceSymbol {}
478 impl Request for WorkspaceSymbol {
479 type Params = WorkspaceSymbolParams;
480 type Result = Option<Vec<lsp_types::SymbolInformation>>;
481 const METHOD: &'static str = "workspace/symbol";
484 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
485 #[serde(rename_all = "camelCase")]
486 pub struct WorkspaceSymbolParams {
488 pub partial_result_params: PartialResultParams,
491 pub work_done_progress_params: WorkDoneProgressParams,
493 /// A non-empty query string
496 pub search_scope: Option<WorkspaceSymbolSearchScope>,
498 pub search_kind: Option<WorkspaceSymbolSearchKind>,
501 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
502 #[serde(rename_all = "camelCase")]
503 pub enum WorkspaceSymbolSearchScope {
505 WorkspaceAndDependencies,
508 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
509 #[serde(rename_all = "camelCase")]
510 pub enum WorkspaceSymbolSearchKind {
515 #[derive(Debug, Serialize, Deserialize)]
516 pub struct CompletionResolveData {
517 pub position: lsp_types::TextDocumentPositionParams,
518 pub imports: Vec<CompletionImport>,
521 #[derive(Debug, Serialize, Deserialize)]
522 pub struct InlayHintResolveData {
523 pub position: lsp_types::TextDocumentPositionParams,
526 #[derive(Debug, Serialize, Deserialize)]
527 pub struct CompletionImport {
528 pub full_import_path: String,
529 pub imported_name: String,
532 #[derive(Debug, Deserialize, Default)]
533 pub struct ClientCommandOptions {
534 pub commands: Vec<String>,