sync_lsp/workspace/apply_edit.rs
1//! Implementation of the `workspace/applyEdit` request.
2//!
3//! # Usage
4//! Many `Command` implementations will want to apply edits to the workspace and
5//! may do so by using this request via [`Connection::apply_edit`].
6//! The server shouldn't assume that the edit will be immediately applied.
7//! Instead, the [`Server::on_apply_edit_response`] callback should be used to check whether
8//! the edit was applied or not.
9
10use std::collections::HashMap;
11use crate::text_document::{DocumentUri, TextEdit};
12use serde::{Serialize, Deserialize};
13use crate::connection::{RpcConnection, Callback};
14use crate::{Server, Connection, TypeProvider};
15
16/// A workspace edit represents changes to many resources managed in the workspace.
17#[derive(Serialize, Debug, Default)]
18pub struct WorkspaceEdit {
19 /// Holds changes to existing resources.
20 pub changes: HashMap<DocumentUri, Vec<TextEdit>>
21}
22
23pub(super) struct ApplyEdit<T: TypeProvider> {
24 callback: Callback<Server<T>>
25}
26
27#[derive(Serialize)]
28struct ApplyWorkspaceEditParams {
29 edit: WorkspaceEdit
30}
31
32/// This response is sent when the [`Connection::apply_edit`] request has been completed
33/// and the edit has been applied.
34#[derive(Deserialize, Debug, Default)]
35pub struct ApplyWorkspaceEditResponse {
36 /// Indicates whether the edit was applied or not.
37 pub applied: bool
38}
39
40impl<T: TypeProvider> Connection<T> {
41
42 /// Request the [application of a workspace edit](self)
43 ///
44 /// # Arguments
45 /// * `tag` - A tag of type [`TypeProvider::ApplyEditData`] preserved throughout the request.
46 /// * `edit` - The workspace edit to apply.
47 /// * `result` - A boolean indicating whether the request was sent.
48
49 pub fn apply_edit(&mut self, tag: T::ApplyEditData, edit: WorkspaceEdit) -> bool {
50 self.request(
51 ApplyEdit::<T>::METHOD,
52 tag,
53 ApplyWorkspaceEditParams { edit }
54 )
55 }
56}
57
58impl<T: TypeProvider> Server<T> {
59
60 /// Set the response handler for [applying a workspace edit](self)
61 ///
62 /// # Argument
63 /// * `callback` - A callback which is called with the following parameters as soon as a response from [`Connection::apply_edit`] is received:
64 /// * The server instance receiving the response.
65 /// * A tag of type [`TypeProvider::ApplyEditData`] that was passed to the request.
66 /// * The response data of the client.
67
68 pub fn on_apply_edit_response(&mut self, callback: fn(&mut Server<T>, T::ApplyEditData, ApplyWorkspaceEditResponse)) {
69 self.workspace.apply_edit.callback = Callback::response(callback);
70 }
71}
72
73impl<T: TypeProvider> Default for ApplyEdit<T> {
74 fn default() -> Self {
75 Self {
76 callback: Callback::response(|_, _: T::ApplyEditData, _: ApplyWorkspaceEditResponse| ())
77 }
78 }
79}
80
81impl<T: TypeProvider> ApplyEdit<T> {
82 pub(super) const METHOD: &'static str = "workspace/applyEdit";
83
84 pub(crate) fn callback(&self) -> Callback<Server<T>> {
85 self.callback.clone()
86 }
87}