lsp_core/feature/
rename.rs1use 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#[derive(Component, Debug)]
13pub struct PrepareRenameRequest {
14 pub range: lsp_types::Range,
15 pub placeholder: String,
16}
17
18#[derive(ScheduleLabel, Clone, Eq, PartialEq, Debug, Hash)]
20pub struct PrepareRename;
21
22#[derive(Component, Debug)]
25pub struct RenameEdits(pub Vec<(lsp_types::Url, lsp_types::TextEdit)>, pub String);
26
27#[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}