1 //! rust-analyzer extensions to the LSP.
3 use std::{collections::HashMap, path::PathBuf};
5 use lsp_types::request::Request;
7 notification::Notification, CodeActionKind, DocumentOnTypeFormattingParams,
8 PartialResultParams, Position, Range, 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 CancelFlycheck {}
134 impl Request for CancelFlycheck {
137 const METHOD: &'static str = "rust-analyzer/cancelFlycheck";
140 pub enum MatchingBrace {}
142 impl Request for MatchingBrace {
143 type Params = MatchingBraceParams;
144 type Result = Vec<Position>;
145 const METHOD: &'static str = "experimental/matchingBrace";
148 #[derive(Deserialize, Serialize, Debug)]
149 #[serde(rename_all = "camelCase")]
150 pub struct MatchingBraceParams {
151 pub text_document: TextDocumentIdentifier,
152 pub positions: Vec<Position>,
155 pub enum ParentModule {}
157 impl Request for ParentModule {
158 type Params = lsp_types::TextDocumentPositionParams;
159 type Result = Option<lsp_types::GotoDefinitionResponse>;
160 const METHOD: &'static str = "experimental/parentModule";
163 pub enum JoinLines {}
165 impl Request for JoinLines {
166 type Params = JoinLinesParams;
167 type Result = Vec<lsp_types::TextEdit>;
168 const METHOD: &'static str = "experimental/joinLines";
171 #[derive(Deserialize, Serialize, Debug)]
172 #[serde(rename_all = "camelCase")]
173 pub struct JoinLinesParams {
174 pub text_document: TextDocumentIdentifier,
175 pub ranges: Vec<Range>,
180 impl Request for OnEnter {
181 type Params = lsp_types::TextDocumentPositionParams;
182 type Result = Option<Vec<SnippetTextEdit>>;
183 const METHOD: &'static str = "experimental/onEnter";
186 pub enum Runnables {}
188 impl Request for Runnables {
189 type Params = RunnablesParams;
190 type Result = Vec<Runnable>;
191 const METHOD: &'static str = "experimental/runnables";
194 #[derive(Serialize, Deserialize, Debug)]
195 #[serde(rename_all = "camelCase")]
196 pub struct RunnablesParams {
197 pub text_document: TextDocumentIdentifier,
198 pub position: Option<Position>,
201 #[derive(Deserialize, Serialize, Debug)]
202 #[serde(rename_all = "camelCase")]
203 pub struct Runnable {
205 #[serde(skip_serializing_if = "Option::is_none")]
206 pub location: Option<lsp_types::LocationLink>,
207 pub kind: RunnableKind,
208 pub args: CargoRunnable,
211 #[derive(Serialize, Deserialize, Debug)]
212 #[serde(rename_all = "lowercase")]
213 pub enum RunnableKind {
217 #[derive(Deserialize, Serialize, Debug)]
218 #[serde(rename_all = "camelCase")]
219 pub struct CargoRunnable {
220 // command to be executed instead of cargo
221 pub override_cargo: Option<String>,
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub workspace_root: Option<PathBuf>,
224 // command, --package and --lib stuff
225 pub cargo_args: Vec<String>,
226 // user-specified additional cargo args, like `--release`.
227 pub cargo_extra_args: Vec<String>,
229 pub executable_args: Vec<String>,
230 #[serde(skip_serializing_if = "Option::is_none")]
231 pub expect_test: Option<bool>,
234 pub enum RelatedTests {}
236 impl Request for RelatedTests {
237 type Params = lsp_types::TextDocumentPositionParams;
238 type Result = Vec<TestInfo>;
239 const METHOD: &'static str = "rust-analyzer/relatedTests";
242 #[derive(Debug, Deserialize, Serialize)]
243 pub struct TestInfo {
244 pub runnable: Runnable,
247 #[derive(Serialize, Deserialize, Debug)]
248 #[serde(rename_all = "camelCase")]
249 pub struct InlayHintsParams {
250 pub text_document: TextDocumentIdentifier,
251 pub range: Option<lsp_types::Range>,
256 impl Request for Ssr {
257 type Params = SsrParams;
258 type Result = lsp_types::WorkspaceEdit;
259 const METHOD: &'static str = "experimental/ssr";
262 #[derive(Debug, Deserialize, Serialize)]
263 #[serde(rename_all = "camelCase")]
264 pub struct SsrParams {
266 pub parse_only: bool,
268 /// File position where SSR was invoked. Paths in `query` will be resolved relative to this
271 pub position: lsp_types::TextDocumentPositionParams,
273 /// Current selections. Search/replace will be restricted to these if non-empty.
274 pub selections: Vec<lsp_types::Range>,
277 pub enum ServerStatusNotification {}
279 impl Notification for ServerStatusNotification {
280 type Params = ServerStatusParams;
281 const METHOD: &'static str = "experimental/serverStatus";
284 #[derive(Deserialize, Serialize, PartialEq, Eq, Clone)]
285 pub struct ServerStatusParams {
288 pub message: Option<String>,
291 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
292 #[serde(rename_all = "camelCase")]
299 pub enum CodeActionRequest {}
301 impl Request for CodeActionRequest {
302 type Params = lsp_types::CodeActionParams;
303 type Result = Option<Vec<CodeAction>>;
304 const METHOD: &'static str = "textDocument/codeAction";
307 pub enum CodeActionResolveRequest {}
308 impl Request for CodeActionResolveRequest {
309 type Params = CodeAction;
310 type Result = CodeAction;
311 const METHOD: &'static str = "codeAction/resolve";
314 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
315 #[serde(rename_all = "camelCase")]
316 pub struct CodeAction {
318 #[serde(skip_serializing_if = "Option::is_none")]
319 pub group: Option<String>,
320 #[serde(skip_serializing_if = "Option::is_none")]
321 pub kind: Option<CodeActionKind>,
322 #[serde(skip_serializing_if = "Option::is_none")]
323 pub command: Option<lsp_types::Command>,
324 #[serde(skip_serializing_if = "Option::is_none")]
325 pub edit: Option<SnippetWorkspaceEdit>,
326 #[serde(skip_serializing_if = "Option::is_none")]
327 pub is_preferred: Option<bool>,
329 #[serde(skip_serializing_if = "Option::is_none")]
330 pub data: Option<CodeActionData>,
333 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
334 #[serde(rename_all = "camelCase")]
335 pub struct CodeActionData {
336 pub code_action_params: lsp_types::CodeActionParams,
340 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
341 #[serde(rename_all = "camelCase")]
342 pub struct SnippetWorkspaceEdit {
343 #[serde(skip_serializing_if = "Option::is_none")]
344 pub changes: Option<HashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>>,
345 #[serde(skip_serializing_if = "Option::is_none")]
346 pub document_changes: Option<Vec<SnippetDocumentChangeOperation>>,
347 #[serde(skip_serializing_if = "Option::is_none")]
348 pub change_annotations:
349 Option<HashMap<lsp_types::ChangeAnnotationIdentifier, lsp_types::ChangeAnnotation>>,
352 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
353 #[serde(untagged, rename_all = "lowercase")]
354 pub enum SnippetDocumentChangeOperation {
355 Op(lsp_types::ResourceOp),
356 Edit(SnippetTextDocumentEdit),
359 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
360 #[serde(rename_all = "camelCase")]
361 pub struct SnippetTextDocumentEdit {
362 pub text_document: lsp_types::OptionalVersionedTextDocumentIdentifier,
363 pub edits: Vec<SnippetTextEdit>,
366 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
367 #[serde(rename_all = "camelCase")]
368 pub struct SnippetTextEdit {
370 pub new_text: String,
371 #[serde(skip_serializing_if = "Option::is_none")]
372 pub insert_text_format: Option<lsp_types::InsertTextFormat>,
373 /// The annotation id if this is an annotated
374 #[serde(skip_serializing_if = "Option::is_none")]
375 pub annotation_id: Option<lsp_types::ChangeAnnotationIdentifier>,
378 pub enum HoverRequest {}
380 impl Request for HoverRequest {
381 type Params = HoverParams;
382 type Result = Option<Hover>;
383 const METHOD: &'static str = "textDocument/hover";
386 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
387 #[serde(rename_all = "camelCase")]
388 pub struct HoverParams {
389 pub text_document: TextDocumentIdentifier,
390 pub position: PositionOrRange,
393 pub work_done_progress_params: WorkDoneProgressParams,
396 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
398 pub enum PositionOrRange {
399 Position(lsp_types::Position),
400 Range(lsp_types::Range),
403 #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
406 pub hover: lsp_types::Hover,
407 #[serde(skip_serializing_if = "Vec::is_empty")]
408 pub actions: Vec<CommandLinkGroup>,
411 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
412 pub struct CommandLinkGroup {
413 #[serde(skip_serializing_if = "Option::is_none")]
414 pub title: Option<String>,
415 pub commands: Vec<CommandLink>,
418 // LSP v3.15 Command does not have a `tooltip` field, vscode supports one.
419 #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
420 pub struct CommandLink {
422 pub command: lsp_types::Command,
423 #[serde(skip_serializing_if = "Option::is_none")]
424 pub tooltip: Option<String>,
427 pub enum ExternalDocs {}
429 impl Request for ExternalDocs {
430 type Params = lsp_types::TextDocumentPositionParams;
431 type Result = Option<lsp_types::Url>;
432 const METHOD: &'static str = "experimental/externalDocs";
435 pub enum OpenCargoToml {}
437 impl Request for OpenCargoToml {
438 type Params = OpenCargoTomlParams;
439 type Result = Option<lsp_types::GotoDefinitionResponse>;
440 const METHOD: &'static str = "experimental/openCargoToml";
443 #[derive(Serialize, Deserialize, Debug)]
444 #[serde(rename_all = "camelCase")]
445 pub struct OpenCargoTomlParams {
446 pub text_document: TextDocumentIdentifier,
449 /// Information about CodeLens, that is to be resolved.
450 #[derive(Debug, Serialize, Deserialize)]
451 #[serde(rename_all = "camelCase")]
452 pub(crate) enum CodeLensResolveData {
453 Impls(lsp_types::request::GotoImplementationParams),
454 References(lsp_types::TextDocumentPositionParams),
457 pub fn supports_utf8(caps: &lsp_types::ClientCapabilities) -> bool {
458 caps.offset_encoding.as_deref().unwrap_or_default().iter().any(|it| it == "utf-8")
463 impl Request for MoveItem {
464 type Params = MoveItemParams;
465 type Result = Vec<SnippetTextEdit>;
466 const METHOD: &'static str = "experimental/moveItem";
469 #[derive(Serialize, Deserialize, Debug)]
470 #[serde(rename_all = "camelCase")]
471 pub struct MoveItemParams {
472 pub direction: MoveItemDirection,
473 pub text_document: TextDocumentIdentifier,
477 #[derive(Serialize, Deserialize, Debug)]
478 pub enum MoveItemDirection {
484 pub enum WorkspaceSymbol {}
486 impl Request for WorkspaceSymbol {
487 type Params = WorkspaceSymbolParams;
488 type Result = Option<Vec<lsp_types::SymbolInformation>>;
489 const METHOD: &'static str = "workspace/symbol";
492 #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
493 #[serde(rename_all = "camelCase")]
494 pub struct WorkspaceSymbolParams {
496 pub partial_result_params: PartialResultParams,
499 pub work_done_progress_params: WorkDoneProgressParams,
501 /// A non-empty query string
504 pub search_scope: Option<WorkspaceSymbolSearchScope>,
506 pub search_kind: Option<WorkspaceSymbolSearchKind>,
509 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
510 #[serde(rename_all = "camelCase")]
511 pub enum WorkspaceSymbolSearchScope {
513 WorkspaceAndDependencies,
516 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
517 #[serde(rename_all = "camelCase")]
518 pub enum WorkspaceSymbolSearchKind {
523 /// The document on type formatting request is sent from the client to
524 /// the server to format parts of the document during typing. This is
525 /// almost same as lsp_types::request::OnTypeFormatting, but the
526 /// result has SnippetTextEdit in it instead of TextEdit.
528 pub enum OnTypeFormatting {}
530 impl Request for OnTypeFormatting {
531 type Params = DocumentOnTypeFormattingParams;
532 type Result = Option<Vec<SnippetTextEdit>>;
533 const METHOD: &'static str = "textDocument/onTypeFormatting";
536 #[derive(Debug, Serialize, Deserialize)]
537 pub struct CompletionResolveData {
538 pub position: lsp_types::TextDocumentPositionParams,
539 pub imports: Vec<CompletionImport>,
542 #[derive(Debug, Serialize, Deserialize)]
543 pub struct InlayHintResolveData {
544 pub text_document: TextDocumentIdentifier,
545 pub position: PositionOrRange,
548 #[derive(Debug, Serialize, Deserialize)]
549 pub struct CompletionImport {
550 pub full_import_path: String,
551 pub imported_name: String,
554 #[derive(Debug, Deserialize, Default)]
555 pub struct ClientCommandOptions {
556 pub commands: Vec<String>,