Merge pull request #19332 from Veykril/push-trvznlqsvtyq

Make change annotations per text-edit
This commit is contained in:
Lukas Wirth 2025-03-10 11:25:13 +00:00 committed by GitHub
commit f81fcabdf9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 53 additions and 84 deletions

View file

@ -367,14 +367,10 @@ fn rename_reference(
)
}));
let mut insert_def_edit = |def| {
let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?;
source_change.insert_source_edit(file_id, edit);
Ok(())
};
// This needs to come after the references edits, because we change the annotation of existing edits
// if a conflict is detected.
insert_def_edit(def)?;
let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?;
source_change.insert_source_edit(file_id, edit);
Ok(source_change)
}

View file

@ -18,18 +18,19 @@ pub struct Indel {
pub insert: String,
/// Refers to offsets in the original text
pub delete: TextRange,
pub annotation: Option<ChangeAnnotationId>,
}
#[derive(Default, Debug, Clone)]
pub struct TextEdit {
/// Invariant: disjoint and sorted by `delete`.
indels: Vec<Indel>,
annotation: Option<ChangeAnnotationId>,
}
#[derive(Debug, Default, Clone)]
pub struct TextEditBuilder {
indels: Vec<Indel>,
annotation: Option<ChangeAnnotationId>,
}
impl Indel {
@ -40,7 +41,7 @@ impl Indel {
Indel::replace(range, String::new())
}
pub fn replace(range: TextRange, replace_with: String) -> Indel {
Indel { delete: range, insert: replace_with, annotation: None }
Indel { delete: range, insert: replace_with }
}
pub fn apply(&self, text: &mut String) {
@ -142,12 +143,12 @@ impl TextEdit {
Some(res)
}
pub fn set_annotation(&mut self, annotation: Option<ChangeAnnotationId>) {
if annotation.is_some() {
for indel in &mut self.indels {
indel.annotation = annotation;
}
}
pub(crate) fn set_annotation(&mut self, conflict_annotation: Option<ChangeAnnotationId>) {
self.annotation = conflict_annotation;
}
pub fn change_annotation(&self) -> Option<ChangeAnnotationId> {
self.annotation
}
}
@ -183,10 +184,10 @@ impl TextEditBuilder {
self.indel(Indel::insert(offset, text));
}
pub fn finish(self) -> TextEdit {
let mut indels = self.indels;
let TextEditBuilder { mut indels, annotation } = self;
assert_disjoint_or_equal(&mut indels);
indels = coalesce_indels(indels);
TextEdit { indels }
TextEdit { indels, annotation }
}
pub fn invalidates_offset(&self, offset: TextSize) -> bool {
self.indels.iter().any(|indel| indel.delete.contains_inclusive(offset))