Expand edits correctly when there are folds or multi-byte chars

Previously, we were mistakenly adding `tab_size` to the extent
produced by the fold edits but that could cause the edit to land on
a multi-byte character (like a fold or an emoji).

In practice, we only need to expand the edit's extent by 1 because
we are operating in the fold coordinate space and all we need to
convey is that we want to encapsulate the first tab next to whatever
edit has just occurred in the `FoldMap`.
This commit is contained in:
Antonio Scandurra 2021-07-28 13:29:56 +02:00 committed by Max Brunsfeld
parent e7d1af2735
commit 169a298af1
2 changed files with 11 additions and 7 deletions

View File

@ -2,7 +2,7 @@ use parking_lot::Mutex;
use super::fold_map::{self, FoldEdit, FoldPoint, Snapshot as FoldSnapshot};
use crate::{editor::rope, settings::StyleId, util::Bias};
use std::{cmp, mem, ops::Range};
use std::{mem, ops::Range};
pub struct TabMap(Mutex<Snapshot>);
@ -36,8 +36,8 @@ impl TabMap {
let patterns: &[_] = &['\t', '\n'];
if let Some(ix) = chunk.find(patterns) {
if &chunk[ix..ix + 1] == "\t" {
fold_edit.old_bytes.end.0 += delta + ix + old_snapshot.tab_size;
fold_edit.new_bytes.end.0 += delta + ix + new_snapshot.tab_size;
fold_edit.old_bytes.end.0 += delta + ix + 1;
fold_edit.new_bytes.end.0 += delta + ix + 1;
}
break;
@ -45,10 +45,6 @@ impl TabMap {
delta += chunk.len();
}
fold_edit.old_bytes.end =
cmp::min(fold_edit.old_bytes.end, old_snapshot.fold_snapshot.len());
fold_edit.new_bytes.end =
cmp::min(fold_edit.new_bytes.end, new_snapshot.fold_snapshot.len());
}
let mut ix = 1;

View File

@ -902,6 +902,10 @@ mod tests {
});
let (mut fold_map, folds_snapshot) = cx.read(|cx| FoldMap::new(buffer.clone(), cx));
let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), settings.tab_size);
log::info!(
"Unwrapped text (no folds): {:?}",
buffer.read_with(&cx, |buf, _| buf.text())
);
log::info!(
"Unwrapped text (unexpanded tabs): {:?}",
folds_snapshot.text()
@ -957,6 +961,10 @@ mod tests {
}
}
log::info!(
"Unwrapped text (no folds): {:?}",
buffer.read_with(&cx, |buf, _| buf.text())
);
let (folds_snapshot, edits) = cx.read(|cx| fold_map.read(cx));
log::info!(
"Unwrapped text (unexpanded tabs): {:?}",