diff options
Diffstat (limited to 'support/texlab/crates/rename/src/label.rs')
-rw-r--r-- | support/texlab/crates/rename/src/label.rs | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/support/texlab/crates/rename/src/label.rs b/support/texlab/crates/rename/src/label.rs index b21e1b795e..1d82f5e2b4 100644 --- a/support/texlab/crates/rename/src/label.rs +++ b/support/texlab/crates/rename/src/label.rs @@ -3,22 +3,65 @@ use base_db::{ util::queries::{self, Object}, }; -use crate::{RenameBuilder, RenameParams}; +use crate::{RenameBuilder, RenameInformation, RenameParams}; + +struct PrefixInformation<'a> { + def_prefixes: &'a Vec<(String, String)>, + ref_prefixes: &'a Vec<(String, String)>, +} + +fn label_has_prefix(pref_info: &PrefixInformation, label: &tex::Label) -> Option<String> { + match label.kind { + tex::LabelKind::Definition => pref_info.def_prefixes.iter(), + _ => pref_info.ref_prefixes.iter(), + } + .find_map(|(k, v)| { + if k == &label.cmd.clone().unwrap_or(String::new()) { + Some(v) + } else { + None + } + }) + .cloned() +} + +fn find_prefix_in_any( + builder: &mut RenameBuilder, + pref_info: &PrefixInformation, + name: &str, +) -> Option<String> { + let project = &builder.params.feature.project; + queries::objects_with_name::<tex::Label>(project, name) + .find_map(|(_, label)| label_has_prefix(&pref_info, label)) +} pub(super) fn prepare_rename(params: &RenameParams) -> Option<Span> { let data = params.feature.document.data.as_tex()?; let labels = &data.semantics.labels; let label = queries::object_at_cursor(labels, params.offset, queries::SearchMode::Name)?; + Some(Span::new(label.object.name.text.clone(), label.range)) } pub(super) fn rename(builder: &mut RenameBuilder) -> Option<()> { let name = prepare_rename(&builder.params)?; + let syn = &builder.params.feature.workspace.config().syntax; + let pref_info = PrefixInformation { + def_prefixes: &syn.label_definition_prefixes, + ref_prefixes: &syn.label_reference_prefixes, + }; + let prefix = find_prefix_in_any(builder, &pref_info, &name.text); + let project = &builder.params.feature.project; for (document, label) in queries::objects_with_name::<tex::Label>(project, &name.text) { + let prefix = label_has_prefix(&pref_info, label).map_or(prefix.clone(), |_| None); + let entry = builder.result.changes.entry(document); - entry.or_default().push(label.name_range()); + entry.or_default().push(RenameInformation { + range: label.name_range(), + prefix: prefix.clone(), + }); } Some(()) |