lsp_max/service/client/lsp_methods.rs
1use lsp_types_max::*;
2use serde::Serialize;
3use serde_json::Value;
4use std::fmt::Display;
5
6use super::Client;
7use crate::jsonrpc;
8
9impl Client {
10 // Lifecycle Messages
11
12 /// Registers a new capability with the client.
13 ///
14 /// This corresponds to the [`client/registerCapability`] request.
15 ///
16 /// [`client/registerCapability`]: https://microsoft.github.io/language-server-protocol/specification#client_registerCapability
17 ///
18 /// # Initialization
19 ///
20 /// If the request is sent to the client before the server has been initialized, this will
21 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
22 ///
23 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
24 pub async fn register_capability(
25 &self,
26 registrations: Vec<Registration>,
27 ) -> jsonrpc::Result<()> {
28 use lsp_types_max::request::RegisterCapability;
29 self.send_request::<RegisterCapability>(RegistrationParams { registrations })
30 .await
31 }
32
33 /// Unregisters a capability with the client.
34 ///
35 /// This corresponds to the [`client/unregisterCapability`] request.
36 ///
37 /// [`client/unregisterCapability`]: https://microsoft.github.io/language-server-protocol/specification#client_unregisterCapability
38 ///
39 /// # Initialization
40 ///
41 /// If the request is sent to the client before the server has been initialized, this will
42 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
43 ///
44 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
45 pub async fn unregister_capability(
46 &self,
47 unregisterations: Vec<Unregistration>,
48 ) -> jsonrpc::Result<()> {
49 use lsp_types_max::request::UnregisterCapability;
50 self.send_request::<UnregisterCapability>(UnregistrationParams { unregisterations })
51 .await
52 }
53
54 // Window Features
55
56 /// Notifies the client to display a particular message in the user interface.
57 ///
58 /// This corresponds to the [`window/showMessage`] notification.
59 ///
60 /// [`window/showMessage`]: https://microsoft.github.io/language-server-protocol/specification#window_showMessage
61 pub async fn show_message<M: Display>(&self, typ: MessageType, message: M) {
62 use lsp_types_max::notification::ShowMessage;
63 self.send_notification_unchecked::<ShowMessage>(ShowMessageParams {
64 typ,
65 message: message.to_string(),
66 })
67 .await;
68 }
69
70 /// Requests the client to display a particular message in the user interface.
71 ///
72 /// Unlike the `show_message` notification, this request can also pass a list of actions and
73 /// wait for an answer from the client.
74 ///
75 /// This corresponds to the [`window/showMessageRequest`] request.
76 ///
77 /// [`window/showMessageRequest`]: https://microsoft.github.io/language-server-protocol/specification#window_showMessageRequest
78 pub async fn show_message_request<M: Display>(
79 &self,
80 typ: MessageType,
81 message: M,
82 actions: Option<Vec<MessageActionItem>>,
83 ) -> jsonrpc::Result<Option<MessageActionItem>> {
84 use lsp_types_max::request::ShowMessageRequest;
85 self.send_request_unchecked::<ShowMessageRequest>(ShowMessageRequestParams {
86 typ,
87 message: message.to_string(),
88 actions,
89 })
90 .await
91 }
92
93 /// Notifies the client to log a particular message.
94 ///
95 /// This corresponds to the [`window/logMessage`] notification.
96 ///
97 /// [`window/logMessage`]: https://microsoft.github.io/language-server-protocol/specification#window_logMessage
98 pub async fn log_message<M: Display>(&self, typ: MessageType, message: M) {
99 use lsp_types_max::notification::LogMessage;
100 self.send_notification_unchecked::<LogMessage>(LogMessageParams {
101 typ,
102 message: message.to_string(),
103 })
104 .await;
105 }
106
107 /// Notifies the client to log a trace.
108 ///
109 /// This corresponds to the [`$/logTrace`] notification.
110 ///
111 /// [`$/logTrace`]: https://microsoft.github.io/language-server-protocol/specification#logTrace
112 pub async fn log_trace(&self, params: LogTraceParams) {
113 use lsp_types_max::notification::LogTrace;
114 self.send_notification_unchecked::<LogTrace>(params).await;
115 }
116
117 /// Asks the client to display a particular resource referenced by a URI in the user interface.
118 ///
119 /// Returns `Ok(true)` if the document was successfully shown, or `Ok(false)` otherwise.
120 ///
121 /// This corresponds to the [`window/showDocument`] request.
122 ///
123 /// [`window/showDocument`]: https://microsoft.github.io/language-server-protocol/specification#window_showDocument
124 ///
125 /// # Initialization
126 ///
127 /// If the request is sent to the client before the server has been initialized, this will
128 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
129 ///
130 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
131 ///
132 /// # Compatibility
133 ///
134 /// This request was introduced in specification version 3.16.0.
135 pub async fn show_document(&self, params: ShowDocumentParams) -> jsonrpc::Result<bool> {
136 use lsp_types_max::request::ShowDocument;
137 let response = self.send_request::<ShowDocument>(params).await?;
138 Ok(response.success)
139 }
140
141 /// Asks the client to create a work done progress token.
142 ///
143 /// This corresponds to the [`window/workDoneProgress/create`] request.
144 ///
145 /// [`window/workDoneProgress/create`]: https://microsoft.github.io/language-server-protocol/specification#window_workDoneProgress_create
146 ///
147 /// # Compatibility
148 ///
149 /// This request was introduced in specification version 3.15.0.
150 pub async fn work_done_progress_create(
151 &self,
152 params: WorkDoneProgressCreateParams,
153 ) -> jsonrpc::Result<()> {
154 use lsp_types_max::request::WorkDoneProgressCreate;
155 self.send_request::<WorkDoneProgressCreate>(params).await
156 }
157
158 /// Notifies the client to log a telemetry event.
159 ///
160 /// This corresponds to the [`telemetry/event`] notification.
161 ///
162 /// [`telemetry/event`]: https://microsoft.github.io/language-server-protocol/specification#telemetry_event
163 pub async fn telemetry_event<S: Serialize>(&self, data: S) {
164 use lsp_types_max::notification::TelemetryEvent;
165 match serde_json::to_value(data) {
166 Err(e) => tracing::error!("invalid JSON in `telemetry/event` notification: {}", e),
167 Ok(mut value) => {
168 if !value.is_null() && !value.is_array() && !value.is_object() {
169 value = Value::Array(vec![value]);
170 }
171 let params = match value {
172 Value::Object(map) => OneOf::Left(map),
173 Value::Array(vec) => OneOf::Right(vec),
174 _ => OneOf::Right(Vec::new()),
175 };
176 self.send_notification_unchecked::<TelemetryEvent>(params)
177 .await;
178 }
179 }
180 }
181
182 /// Asks the client to refresh the code lenses currently shown in editors. As a result, the
183 /// client should ask the server to recompute the code lenses for these editors.
184 ///
185 /// This is useful if a server detects a configuration change which requires a re-calculation
186 /// of all code lenses.
187 ///
188 /// Note that the client still has the freedom to delay the re-calculation of the code lenses
189 /// if for example an editor is currently not visible.
190 ///
191 /// This corresponds to the [`workspace/codeLens/refresh`] request.
192 ///
193 /// [`workspace/codeLens/refresh`]: https://microsoft.github.io/language-server-protocol/specification#codeLens_refresh
194 ///
195 /// # Initialization
196 ///
197 /// If the request is sent to the client before the server has been initialized, this will
198 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
199 ///
200 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
201 ///
202 /// # Compatibility
203 ///
204 /// This request was introduced in specification version 3.16.0.
205 pub async fn code_lens_refresh(&self) -> jsonrpc::Result<()> {
206 use lsp_types_max::request::CodeLensRefresh;
207 self.send_request::<CodeLensRefresh>(()).await
208 }
209
210 /// Asks the client to refresh the editors for which this server provides semantic tokens. As a
211 /// result, the client should ask the server to recompute the semantic tokens for these
212 /// editors.
213 ///
214 /// This is useful if a server detects a project-wide configuration change which requires a
215 /// re-calculation of all semantic tokens. Note that the client still has the freedom to delay
216 /// the re-calculation of the semantic tokens if for example an editor is currently not visible.
217 ///
218 /// This corresponds to the [`workspace/semanticTokens/refresh`] request.
219 ///
220 /// [`workspace/semanticTokens/refresh`]: https://microsoft.github.io/language-server-protocol/specification#textDocument_semanticTokens
221 ///
222 /// # Initialization
223 ///
224 /// If the request is sent to the client before the server has been initialized, this will
225 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
226 ///
227 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
228 ///
229 /// # Compatibility
230 ///
231 /// This request was introduced in specification version 3.16.0.
232 pub async fn semantic_tokens_refresh(&self) -> jsonrpc::Result<()> {
233 use lsp_types_max::request::SemanticTokensRefresh;
234 self.send_request::<SemanticTokensRefresh>(()).await
235 }
236
237 /// Asks the client to refresh the inline values currently shown in editors. As a result, the
238 /// client should ask the server to recompute the inline values for these editors.
239 ///
240 /// This is useful if a server detects a configuration change which requires a re-calculation
241 /// of all inline values. Note that the client still has the freedom to delay the
242 /// re-calculation of the inline values if for example an editor is currently not visible.
243 ///
244 /// This corresponds to the [`workspace/inlineValue/refresh`] request.
245 ///
246 /// [`workspace/inlineValue/refresh`]: https://microsoft.github.io/language-server-protocol/specification#workspace_inlineValue_refresh
247 ///
248 /// # Initialization
249 ///
250 /// If the request is sent to the client before the server has been initialized, this will
251 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
252 ///
253 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
254 ///
255 /// # Compatibility
256 ///
257 /// This request was introduced in specification version 3.17.0.
258 pub async fn inline_value_refresh(&self) -> jsonrpc::Result<()> {
259 use lsp_types_max::request::InlineValueRefreshRequest;
260 self.send_request::<InlineValueRefreshRequest>(()).await
261 }
262
263 /// Asks the client to refresh the inlay hints currently shown in editors. As a result, the
264 /// client should ask the server to recompute the inlay hints for these editors.
265 ///
266 /// This is useful if a server detects a configuration change which requires a re-calculation
267 /// of all inlay hints. Note that the client still has the freedom to delay the re-calculation
268 /// of the inlay hints if for example an editor is currently not visible.
269 ///
270 /// This corresponds to the [`workspace/inlayHint/refresh`] request.
271 ///
272 /// [`workspace/inlayHint/refresh`]: https://microsoft.github.io/language-server-protocol/specification#workspace_inlayHint_refresh
273 ///
274 /// # Initialization
275 ///
276 /// If the request is sent to the client before the server has been initialized, this will
277 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
278 ///
279 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
280 ///
281 /// # Compatibility
282 ///
283 /// This request was introduced in specification version 3.17.0.
284 pub async fn inlay_hint_refresh(&self) -> jsonrpc::Result<()> {
285 use lsp_types_max::request::InlayHintRefreshRequest;
286 self.send_request::<InlayHintRefreshRequest>(()).await
287 }
288
289 /// Asks the client to refresh all folding ranges.
290 ///
291 /// This corresponds to the [`workspace/foldingRange/refresh`] request.
292 ///
293 /// [`workspace/foldingRange/refresh`]: https://microsoft.github.io/language-server-protocol/specification#workspace_foldingRange_refresh
294 ///
295 /// # Initialization
296 ///
297 /// If the request is sent to the client before the server has been initialized, this will
298 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
299 ///
300 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
301 ///
302 /// # Compatibility
303 ///
304 /// This request was introduced in specification version 3.18.0.
305 pub async fn folding_range_refresh(&self) -> jsonrpc::Result<()> {
306 self.send_request::<super::FoldingRangeRefresh>(()).await
307 }
308
309 /// Asks the client to refresh all needed document and workspace diagnostics.
310 ///
311 /// This is useful if a server detects a project wide configuration change which requires a
312 /// re-calculation of all diagnostics.
313 ///
314 /// This corresponds to the [`workspace/diagnostic/refresh`] request.
315 ///
316 /// [`workspace/diagnostic/refresh`]: https://microsoft.github.io/language-server-protocol/specification#diagnostic_refresh
317 ///
318 /// # Initialization
319 ///
320 /// If the request is sent to the client before the server has been initialized, this will
321 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
322 ///
323 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
324 ///
325 /// # Compatibility
326 ///
327 /// This request was introduced in specification version 3.17.0.
328 pub async fn workspace_diagnostic_refresh(&self) -> jsonrpc::Result<()> {
329 use lsp_types_max::request::WorkspaceDiagnosticRefresh;
330 self.send_request::<WorkspaceDiagnosticRefresh>(()).await
331 }
332
333 /// Asks the client to refresh the content of a text document.
334 ///
335 /// This corresponds to the [`workspace/textDocumentContent/refresh`](lsp_max_protocol::lsp_3_18::TextDocumentContentRefreshRequest) request.
336 pub async fn text_document_content_refresh(
337 &self,
338 params: lsp_max_protocol::lsp_3_18::TextDocumentContentRefreshParams,
339 ) -> jsonrpc::Result<()> {
340 self.send_request::<lsp_max_protocol::lsp_3_18::TextDocumentContentRefreshRequest>(params)
341 .await
342 }
343
344 /// Submits validation diagnostics for an open file with the given URI.
345 ///
346 /// This corresponds to the [`textDocument/publishDiagnostics`] notification.
347 ///
348 /// [`textDocument/publishDiagnostics`]: https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics
349 ///
350 /// # Initialization
351 ///
352 /// This notification will only be sent if the server is initialized.
353 pub async fn publish_diagnostics(
354 &self,
355 uri: Uri,
356 mut diags: Vec<Diagnostic>,
357 version: Option<i32>,
358 ) {
359 use lsp_types_max::notification::PublishDiagnostics;
360
361 let mut missing_push = false;
362
363 // Track the pushes we made in the inner state, or simply assume that
364 // any ERROR diagnostic should be flagged if not generated via Andon event.
365 // For now, if there is a blocking diagnostic but no push was tracked...
366
367 // Let's check if the diagnostic has an ANDON code
368 for diag in &diags {
369 if let Some(severity) = diag.severity {
370 if severity == DiagnosticSeverity::ERROR {
371 // Check if it's an ANDON diagnostic
372 if let Some(source) = &diag.source {
373 if source != "lsp-max-andon" {
374 missing_push = true;
375 }
376 } else {
377 missing_push = true;
378 }
379 }
380 }
381 }
382
383 if missing_push {
384 diags.push(Diagnostic {
385 range: Default::default(),
386 severity: Some(DiagnosticSeverity::ERROR),
387 code: Some(lsp_types_max::NumberOrString::String(
388 "LSPMAX-ANDON-PUSH-MISSING".to_string(),
389 )),
390 source: Some("lsp-max-andon".to_string()),
391 message:
392 "A blocking diagnostic was emitted without a corresponding ANDON push event."
393 .to_string(),
394 related_information: None,
395 tags: None,
396 code_description: None,
397 data: None,
398 });
399 }
400
401 self.send_notification_unchecked::<PublishDiagnostics>(PublishDiagnosticsParams::new(
402 uri, diags, version,
403 ))
404 .await;
405 }
406
407 /// `lspMax/andonRaised` notification
408 pub async fn andon_raised(&self, event: crate::andon::andon::AndonEvent) {
409 use crate::andon::lsp::LspMaxAndonRaised;
410 self.send_notification_unchecked::<LspMaxAndonRaised>(event)
411 .await;
412 }
413
414 /// `lspMax/admissionChanged` notification
415 pub async fn admission_changed(&self, status: String) {
416 use crate::andon::lsp::{AdmissionChangedParams, LspMaxAdmissionChanged};
417 self.send_notification_unchecked::<LspMaxAdmissionChanged>(AdmissionChangedParams {
418 status,
419 })
420 .await;
421 }
422
423 /// `lspMax/truthTableChanged` notification
424 pub async fn truth_table_changed(&self, uri: String) {
425 use crate::andon::lsp::{LspMaxTruthTableChanged, TruthTableChangedParams};
426 self.send_notification_unchecked::<LspMaxTruthTableChanged>(TruthTableChangedParams {
427 uri,
428 })
429 .await;
430 }
431
432 /// `lspMax/counterfactualFailed` notification
433 pub async fn counterfactual_failed(&self, invariant_id: String) {
434 use crate::andon::lsp::{CounterfactualFailedParams, LspMaxCounterfactualFailed};
435 self.send_notification_unchecked::<LspMaxCounterfactualFailed>(
436 CounterfactualFailedParams { invariant_id },
437 )
438 .await;
439 }
440
441 /// `lspMax/nextLawfulStepChanged` notification
442 pub async fn next_lawful_step_changed(&self, step: String) {
443 use crate::andon::lsp::{LspMaxNextLawfulStepChanged, NextLawfulStepChangedParams};
444 self.send_notification_unchecked::<LspMaxNextLawfulStepChanged>(
445 NextLawfulStepChangedParams { step },
446 )
447 .await;
448 }
449
450 // Workspace Features
451
452 /// Fetches configuration settings from the client.
453 ///
454 /// The request can fetch several configuration settings in one roundtrip. The order of the
455 /// returned configuration settings correspond to the order of the passed
456 /// [`ConfigurationItem`]s (e.g. the first item in the response is the result for the first
457 /// configuration item in the params).
458 ///
459 /// This corresponds to the [`workspace/configuration`] request.
460 ///
461 /// [`workspace/configuration`]: https://microsoft.github.io/language-server-protocol/specification#workspace_configuration
462 ///
463 /// # Initialization
464 ///
465 /// If the request is sent to the client before the server has been initialized, this will
466 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
467 ///
468 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
469 ///
470 /// # Compatibility
471 ///
472 /// This request was introduced in specification version 3.6.0.
473 pub async fn configuration(
474 &self,
475 items: Vec<ConfigurationItem>,
476 ) -> jsonrpc::Result<Vec<Value>> {
477 use lsp_types_max::request::WorkspaceConfiguration;
478 self.send_request::<WorkspaceConfiguration>(ConfigurationParams { items })
479 .await
480 }
481
482 /// Fetches the current open list of workspace folders.
483 ///
484 /// Returns `None` if only a single file is open in the tool. Returns an empty `Vec` if a
485 /// workspace is open but no folders are configured.
486 ///
487 /// This corresponds to the [`workspace/workspaceFolders`] request.
488 ///
489 /// [`workspace/workspaceFolders`]: https://microsoft.github.io/language-server-protocol/specification#workspace_workspaceFolders
490 ///
491 /// # Initialization
492 ///
493 /// If the request is sent to the client before the server has been initialized, this will
494 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
495 ///
496 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
497 ///
498 /// # Compatibility
499 ///
500 /// This request was introduced in specification version 3.6.0.
501 pub async fn workspace_folders(&self) -> jsonrpc::Result<Option<Vec<WorkspaceFolder>>> {
502 use lsp_types_max::request::WorkspaceFoldersRequest;
503 self.send_request::<WorkspaceFoldersRequest>(()).await
504 }
505
506 /// Requests a workspace resource be edited on the client side and returns whether the edit was
507 /// applied.
508 ///
509 /// This corresponds to the [`workspace/applyEdit`] request.
510 ///
511 /// [`workspace/applyEdit`]: https://microsoft.github.io/language-server-protocol/specification#workspace_applyEdit
512 ///
513 /// # Initialization
514 ///
515 /// If the request is sent to the client before the server has been initialized, this will
516 /// immediately return `Err` with JSON-RPC error code `-32002` ([read more]).
517 ///
518 /// [read more]: https://microsoft.github.io/language-server-protocol/specification#initialize
519 pub async fn apply_edit(
520 &self,
521 edit: WorkspaceEdit,
522 ) -> jsonrpc::Result<ApplyWorkspaceEditResponse> {
523 use lsp_types_max::request::ApplyWorkspaceEdit;
524 self.send_request::<ApplyWorkspaceEdit>(ApplyWorkspaceEditParams { edit, label: None })
525 .await
526 }
527
528 /// Starts a stream of `$/progress` notifications for a client-provided [`ProgressToken`].
529 ///
530 /// This method also takes a `title` argument briefly describing the kind of operation being
531 /// performed, e.g. "Indexing" or "Linking Dependencies".
532 ///
533 /// [`ProgressToken`]: https://docs.rs/lsp-types/latest/lsp_types/type.ProgressToken.html
534 ///
535 /// # Initialization
536 ///
537 /// These notifications will only be sent if the server is initialized.
538 pub fn progress<T>(&self, token: ProgressToken, title: T) -> super::Progress
539 where
540 T: Into<String>,
541 {
542 super::Progress::new(self.clone(), token, title.into())
543 }
544}