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