lsp_core/feature/
rename.rs

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