Remove Option from Buffer edit APIs
Previously, buffer edits represented empty strings as None variants of an Option. Now, the edit logic just explicitly checks for empty strings. Co-authored-by: Keith Simmons <keith@zed.dev>
This commit is contained in:
parent
04fc1d5982
commit
e05793b52a
2 changed files with 20 additions and 25 deletions
|
@ -81,10 +81,7 @@ pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::
|
||||||
new_text: operation
|
new_text: operation
|
||||||
.new_text
|
.new_text
|
||||||
.iter()
|
.iter()
|
||||||
.map(|text| {
|
.map(|text| text.to_string())
|
||||||
text.as_ref()
|
|
||||||
.map_or_else(String::new, |text| text.to_string())
|
|
||||||
})
|
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +247,7 @@ pub fn deserialize_edit_operation(edit: proto::operation::Edit) -> EditOperation
|
||||||
},
|
},
|
||||||
version: deserialize_version(edit.version),
|
version: deserialize_version(edit.version),
|
||||||
ranges: edit.ranges.into_iter().map(deserialize_range).collect(),
|
ranges: edit.ranges.into_iter().map(deserialize_range).collect(),
|
||||||
new_text: edit.new_text.into_iter().map(|t| Some(t.into())).collect(),
|
new_text: edit.new_text.into_iter().map(Arc::from).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl HistoryEntry {
|
||||||
self_range.end += delta;
|
self_range.end += delta;
|
||||||
|
|
||||||
while let Some((other_range, new_text)) = edits.peek() {
|
while let Some((other_range, new_text)) = edits.peek() {
|
||||||
let insertion_len = new_text.as_ref().map_or(0, |t| t.len());
|
let insertion_len = new_text.len();
|
||||||
let mut other_range = (*other_range).clone();
|
let mut other_range = (*other_range).clone();
|
||||||
other_range.start += delta;
|
other_range.start += delta;
|
||||||
other_range.end += delta;
|
other_range.end += delta;
|
||||||
|
@ -138,7 +138,7 @@ impl HistoryEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (other_range, new_text) in edits {
|
for (other_range, new_text) in edits {
|
||||||
let insertion_len = new_text.as_ref().map_or(0, |t| t.len());
|
let insertion_len = new_text.len();
|
||||||
new_ranges.push(other_range.start + delta..other_range.end + delta + insertion_len);
|
new_ranges.push(other_range.start + delta..other_range.end + delta + insertion_len);
|
||||||
delta += insertion_len;
|
delta += insertion_len;
|
||||||
}
|
}
|
||||||
|
@ -524,7 +524,7 @@ pub struct EditOperation {
|
||||||
pub timestamp: InsertionTimestamp,
|
pub timestamp: InsertionTimestamp,
|
||||||
pub version: clock::Global,
|
pub version: clock::Global,
|
||||||
pub ranges: Vec<Range<FullOffset>>,
|
pub ranges: Vec<Range<FullOffset>>,
|
||||||
pub new_text: Vec<Option<Arc<str>>>,
|
pub new_text: Vec<Arc<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -630,15 +630,9 @@ impl Buffer {
|
||||||
S: ToOffset,
|
S: ToOffset,
|
||||||
T: Into<Arc<str>>,
|
T: Into<Arc<str>>,
|
||||||
{
|
{
|
||||||
let edits = edits.into_iter().map(|(range, new_text)| {
|
let edits = edits
|
||||||
let possibly_empty_arc_str = new_text.into();
|
.into_iter()
|
||||||
let non_empty_text = if possibly_empty_arc_str.len() > 0 {
|
.map(|(range, new_text)| (range, new_text.into()));
|
||||||
Some(possibly_empty_arc_str)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
(range, non_empty_text)
|
|
||||||
});
|
|
||||||
|
|
||||||
self.start_transaction();
|
self.start_transaction();
|
||||||
let timestamp = InsertionTimestamp {
|
let timestamp = InsertionTimestamp {
|
||||||
|
@ -657,7 +651,7 @@ impl Buffer {
|
||||||
|
|
||||||
fn apply_local_edit<S: ToOffset, T: Into<Arc<str>>>(
|
fn apply_local_edit<S: ToOffset, T: Into<Arc<str>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
edits: impl ExactSizeIterator<Item = (Range<S>, Option<T>)>,
|
edits: impl ExactSizeIterator<Item = (Range<S>, T)>,
|
||||||
timestamp: InsertionTimestamp,
|
timestamp: InsertionTimestamp,
|
||||||
) -> EditOperation {
|
) -> EditOperation {
|
||||||
let mut edits_patch = Patch::default();
|
let mut edits_patch = Patch::default();
|
||||||
|
@ -683,7 +677,7 @@ impl Buffer {
|
||||||
|
|
||||||
let mut fragment_start = old_fragments.start().visible;
|
let mut fragment_start = old_fragments.start().visible;
|
||||||
for (range, new_text) in ranges {
|
for (range, new_text) in ranges {
|
||||||
let new_text = new_text.map(|t| t.into());
|
let new_text = new_text.into();
|
||||||
let fragment_end = old_fragments.end(&None).visible;
|
let fragment_end = old_fragments.end(&None).visible;
|
||||||
|
|
||||||
// If the current fragment ends before this range, then jump ahead to the first fragment
|
// If the current fragment ends before this range, then jump ahead to the first fragment
|
||||||
|
@ -724,7 +718,7 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the new text before any existing fragments within the range.
|
// Insert the new text before any existing fragments within the range.
|
||||||
if let Some(new_text) = new_text.as_deref() {
|
if !new_text.is_empty() {
|
||||||
let new_start = new_fragments.summary().text.visible;
|
let new_start = new_fragments.summary().text.visible;
|
||||||
edits_patch.push(Edit {
|
edits_patch.push(Edit {
|
||||||
old: fragment_start..fragment_start,
|
old: fragment_start..fragment_start,
|
||||||
|
@ -745,7 +739,7 @@ impl Buffer {
|
||||||
visible: true,
|
visible: true,
|
||||||
};
|
};
|
||||||
new_insertions.push(InsertionFragment::insert_new(&fragment));
|
new_insertions.push(InsertionFragment::insert_new(&fragment));
|
||||||
new_ropes.push_str(new_text);
|
new_ropes.push_str(new_text.as_ref());
|
||||||
new_fragments.push(fragment, &None);
|
new_fragments.push(fragment, &None);
|
||||||
insertion_offset += new_text.len();
|
insertion_offset += new_text.len();
|
||||||
}
|
}
|
||||||
|
@ -870,7 +864,7 @@ impl Buffer {
|
||||||
&mut self,
|
&mut self,
|
||||||
version: &clock::Global,
|
version: &clock::Global,
|
||||||
ranges: &[Range<FullOffset>],
|
ranges: &[Range<FullOffset>],
|
||||||
new_text: &[Option<Arc<str>>],
|
new_text: &[Arc<str>],
|
||||||
timestamp: InsertionTimestamp,
|
timestamp: InsertionTimestamp,
|
||||||
) {
|
) {
|
||||||
if ranges.is_empty() {
|
if ranges.is_empty() {
|
||||||
|
@ -963,7 +957,7 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the new text before any existing fragments within the range.
|
// Insert the new text before any existing fragments within the range.
|
||||||
if let Some(new_text) = new_text {
|
if !new_text.is_empty() {
|
||||||
let mut old_start = old_fragments.start().1;
|
let mut old_start = old_fragments.start().1;
|
||||||
if old_fragments.item().map_or(false, |f| f.visible) {
|
if old_fragments.item().map_or(false, |f| f.visible) {
|
||||||
old_start += fragment_start.0 - old_fragments.start().0.full_offset().0;
|
old_start += fragment_start.0 - old_fragments.start().0.full_offset().0;
|
||||||
|
@ -1055,7 +1049,7 @@ impl Buffer {
|
||||||
self.snapshot.visible_text = visible_text;
|
self.snapshot.visible_text = visible_text;
|
||||||
self.snapshot.deleted_text = deleted_text;
|
self.snapshot.deleted_text = deleted_text;
|
||||||
self.snapshot.insertions.edit(new_insertions, &());
|
self.snapshot.insertions.edit(new_insertions, &());
|
||||||
self.subscriptions.publish_mut(&edits_patch);
|
self.subscriptions.publish_mut(&edits_patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_undo(&mut self, undo: &UndoOperation) -> Result<()> {
|
fn apply_undo(&mut self, undo: &UndoOperation) -> Result<()> {
|
||||||
|
@ -1400,7 +1394,11 @@ impl Buffer {
|
||||||
&(),
|
&(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(insertion_fragment.fragment_id, fragment.id);
|
assert_eq!(
|
||||||
|
insertion_fragment.fragment_id, fragment.id,
|
||||||
|
"fragment: {:?}\ninsertion: {:?}",
|
||||||
|
fragment, insertion_fragment
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>();
|
let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue