tinymist_query/
will_rename_files.rs

1use lsp_types::ChangeAnnotation;
2
3use crate::{do_rename_file, edits_to_document_changes, prelude::*};
4
5/// Handle [`workspace/willRenameFiles`] request is sent from the client to the
6/// server.
7///
8/// [`workspace/willRenameFiles`]: https://microsoft.github.io/language-server-protocol/specification#workspace_willRenameFiles
9#[derive(Debug, Clone)]
10pub struct WillRenameFilesRequest {
11    /// rename paths from `left` to `right`
12    pub paths: Vec<(PathBuf, PathBuf)>,
13}
14
15impl StatefulRequest for WillRenameFilesRequest {
16    type Response = WorkspaceEdit;
17
18    fn request(self, ctx: &mut LocalContext, _graph: LspComputeGraph) -> Option<Self::Response> {
19        let mut edits: HashMap<Url, Vec<TextEdit>> = HashMap::new();
20
21        self.paths
22            .into_iter()
23            .map(|(left, right)| {
24                let diff = tinymist_std::path::diff(&right, &left)?;
25                log::info!("did rename diff: {diff:?}");
26                if diff.is_absolute() {
27                    log::info!(
28                        "bad rename: absolute path, base: {left:?}, new: {right:?}, diff: {diff:?}"
29                    );
30                    return None;
31                }
32
33                let def_fid = ctx.file_id_by_path(&left).ok()?;
34                log::info!("did rename def_fid: {def_fid:?}");
35
36                do_rename_file(ctx, def_fid, diff, &mut edits)
37            })
38            .collect::<Option<Vec<()>>>()?;
39        log::info!("did rename edits: {edits:?}");
40        let document_changes = edits_to_document_changes(edits);
41        if document_changes.is_empty() {
42            return None;
43        }
44
45        let mut change_annotations = HashMap::new();
46        change_annotations.insert(
47            "Typst Rename Files".to_string(),
48            ChangeAnnotation {
49                label: "Typst Rename Files".to_string(),
50                needs_confirmation: Some(true),
51                description: Some("Rename files should update imports".to_string()),
52            },
53        );
54
55        Some(WorkspaceEdit {
56            changes: None,
57            document_changes: Some(lsp_types::DocumentChanges::Operations(document_changes)),
58            change_annotations: Some(change_annotations),
59        })
60    }
61}