T21a round 3 fix, after the cap
- TextInput records the selection each edit replaces, where every edit passes; the block editor's undo goes back to it, for typing, delete, cut and paste - TextInput's layout geometry moves to forms/text/geometry.rs - Reviews: T21a done, fixed after the cap, no fourth review
This commit is contained in:
1 parent
187f54253e
commit
14a8990793
7 files changed
+109
-74
No files matched your search
@@ -174,14 +174,6 @@ impl BlockEditor {
|
||||
}
|
||||
}
|
||||
|
||||
/// Where a key went down, before the field acts on it: the start a typing burst's undo goes back to.
|
||||
pub(crate) fn note_key(&mut self, key: u64, field: usize, cx: &Context<Self>) {
|
||||
let selection = self.blocks[self.index(key)].fields[field]
|
||||
.read(cx)
|
||||
.selection();
|
||||
self.typed_from = Some((key, field, selection));
|
||||
}
|
||||
|
||||
/// Records the document before a change to its blocks.
|
||||
pub(crate) fn before_change(&mut self, cx: &mut Context<Self>) {
|
||||
self.settle(true, cx);
|
||||
|
||||
@@ -76,7 +76,7 @@ pub struct BlockEditor {
|
||||
current: Snapshot,
|
||||
/// The field that last held focus, as block and field.
|
||||
caret: Option<(u64, usize)>,
|
||||
/// The selection a key went down on, before its field changed.
|
||||
/// The selection the last edit in a field replaced.
|
||||
typed_from: Option<(u64, usize, std::ops::Range<usize>)>,
|
||||
pub(crate) people: Vec<SharedString>,
|
||||
pub(crate) diagram: Option<RenderDiagram>,
|
||||
@@ -288,6 +288,8 @@ impl BlockEditor {
|
||||
.insert(name.clone(), text);
|
||||
}
|
||||
}
|
||||
let at = self.blocks[ix].fields.iter().position(|each| each == field);
|
||||
self.typed_from = at.map(|at| (key, at, field.read(cx).edited_from()));
|
||||
self.settle(true, cx);
|
||||
}
|
||||
InputEvent::Focus => {
|
||||
|
||||
@@ -114,7 +114,6 @@ impl BlockEditor {
|
||||
cx.stop_propagation();
|
||||
editor.on_submit(key, window, cx);
|
||||
}))
|
||||
.capture_key_down(cx.listener(move |editor, _, _, cx| editor.note_key(key, ix, cx)))
|
||||
.on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation())
|
||||
.child(field.clone());
|
||||
let slash = move |query: &str, at: usize, caret: usize| -> (Vec<Choice>, Pick) {
|
||||
|
||||
@@ -344,3 +344,30 @@ fn up_into_a_table_skips_its_hidden_cells(cx: &mut TestAppContext) {
|
||||
"up lands on the cell that shows in the last row"
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn undo_of_a_delete_or_a_paste_restores_the_selection(cx: &mut TestAppContext) {
|
||||
let (editor, cx) = open(vec![BlockData::new(BlockKind::Paragraph, ["abcdef"])], cx);
|
||||
let selection = |cx: &mut VisualTestContext| {
|
||||
cx.update(|_, cx| editor.read(cx).blocks[0].fields[0].read(cx).selection())
|
||||
};
|
||||
select(&editor, 0, 0, 2..4, cx);
|
||||
cx.simulate_keystrokes("backspace");
|
||||
settle(cx);
|
||||
assert_eq!(blocks(&editor, cx), [text(BlockKind::Paragraph, "abef")]);
|
||||
cx.simulate_keystrokes("cmd-z");
|
||||
settle(cx);
|
||||
assert_eq!(selection(cx), 2..4, "undo of a delete selects what it took");
|
||||
cx.update(|_, cx| cx.write_to_clipboard(gpui::ClipboardItem::new_string("xy".into())));
|
||||
select(&editor, 0, 0, 2..4, cx);
|
||||
cx.simulate_keystrokes("cmd-v");
|
||||
settle(cx);
|
||||
assert_eq!(blocks(&editor, cx), [text(BlockKind::Paragraph, "abxyef")]);
|
||||
cx.simulate_keystrokes("cmd-z");
|
||||
settle(cx);
|
||||
assert_eq!(
|
||||
selection(cx),
|
||||
2..4,
|
||||
"undo of a paste selects what it replaced"
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user