lsp_core/feature/
rename.rs

1use bevy_ecs::{
2    prelude::*,
3    schedule::{IntoScheduleConfigs, ScheduleLabel},
4};
5use tracing::instrument;
6
7pub use crate::util::token::get_current_token;
8use crate::{lsp_types::TextEdit, prelude::*};
9
10/// [`Component`] indicating that the current document is currently handling a PrepareRename request.
11#[derive(Component, Debug)]
12pub struct PrepareRenameRequest {
13    pub range: crate::lsp_types::Range,
14    pub placeholder: String,
15}
16
17/// [`ScheduleLabel`] related to the PrepareRename schedule
18#[derive(ScheduleLabel, Clone, Eq, PartialEq, Debug, Hash)]
19pub struct PrepareRename;
20
21/// [`Component`] indicating that the current document is currently handling a Rename request,
22/// collecting [TextEdits](`lsp_types::TextEdit`).
23#[derive(Component, Debug)]
24pub struct RenameEdits(
25    pub Vec<(crate::lsp_types::Url, crate::lsp_types::TextEdit)>,
26    pub String,
27);
28
29/// [`ScheduleLabel`] related to the Rename schedule
30#[derive(ScheduleLabel, Clone, Eq, PartialEq, Debug, Hash)]
31pub struct Rename;
32
33pub fn setup_schedules(world: &mut World) {
34    let mut prepare_rename_schedule = Schedule::new(PrepareRename);
35    prepare_rename_schedule
36        .add_systems((get_current_token, prepare_rename.after(get_current_token)));
37    world.add_schedule(prepare_rename_schedule);
38
39    let mut rename_schedule = Schedule::new(Rename);
40    rename_schedule.add_systems((get_current_token, rename.after(get_current_token)));
41    world.add_schedule(rename_schedule);
42}
43
44#[instrument(skip(query, commands,))]
45pub fn prepare_rename(query: Query<(Entity, Option<&TokenComponent>)>, mut commands: Commands) {
46    for (e, m_token) in &query {
47        commands.entity(e).remove::<(PrepareRenameRequest,)>();
48        if let Some(token) = m_token {
49            let renameable = match token.token.value() {
50                Token::Variable(_) => true,
51                Token::IRIRef(_) => true,
52                Token::PNameLN(_, _) => true,
53                Token::BlankNodeLabel(_) => true,
54                _ => false,
55            };
56
57            if renameable {
58                commands.entity(e).insert(PrepareRenameRequest {
59                    range: token.range.clone(),
60                    placeholder: token.text.clone(),
61                });
62                continue;
63            }
64        }
65        tracing::debug!("Didn't find a good token");
66    }
67}
68
69#[instrument(skip(query,))]
70pub fn rename(mut query: Query<(&TokenComponent, &Tokens, &RopeC, &Label, &mut RenameEdits)>) {
71    for (token, tokens, rope, label, mut edits) in &mut query {
72        tracing::debug!("Token {:?}", token);
73        let new_text = edits.1.clone();
74        for t in tokens.0.iter().filter(|x| x.value() == token.token.value()) {
75            tracing::debug!("Changing {:?}", t);
76            if let Some(range) = range_to_range(t.span(), &rope.0) {
77                edits.0.push((
78                    label.0.clone(),
79                    TextEdit {
80                        range,
81                        new_text: new_text.clone(),
82                    },
83                ))
84            }
85        }
86    }
87}