C14.9 r1: tables keep extra cells and quote marks; preview refuses edits; lists only in list items; replace moves past its text (library edc328a)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-12 06:43:23 -04:00
1 parent d4a7d3ebd7
commit 2aa4a080bb
9 files changed
+120 -23

No files matched your search

+20 -9
View File
@@ -140,17 +140,28 @@ impl Desk {
if edits.is_empty() {
return;
}
// The next match starts past the replaced text.
let after = edits[0].0.start + edits[0].1.len();
let document = view.read(cx).document().clone();
document.update(cx, |document, cx| document.replace(edits, cx));
self.count(cx);
// The next match takes the replaced one's place.
let next = self
.finding
.as_ref()
.and_then(|find| find.current.and_then(|at| find.hits.get(at)).cloned());
if let Some(range) = next.filter(|_| !every) {
document.update(cx, |document, cx| document.show_match(range, window, cx));
if !document.update(cx, |document, cx| document.replace(edits, cx)) {
let said = text(cx, "mark.preview.read_only", &[]);
return self.toast(said, Severity::Info, cx);
}
self.count(cx);
if every {
return;
}
let Some(find) = self.finding.as_mut() else {
return;
};
let next = find.hits.iter().position(|hit| hit.start >= after);
find.current = next.or((!find.hits.is_empty()).then_some(0));
let Some(range) = find.current.map(|at| find.hits[at].clone()) else {
return;
};
let hits = find.hits.clone();
mark(&document, &hits, find.current, cx);
document.update(cx, |document, cx| document.show_match(range, window, cx));
}
fn close_find(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+57
View File
@@ -118,3 +118,60 @@ fn the_table_menu_inserts_and_edits_a_table(cx: &mut TestAppContext) {
current_text(&desk, cx)
);
}
fn replace_one(desk: &Entity<Desk>, with: &str, cx: &mut VisualTestContext) {
desk.update_in(cx, |desk, window, cx| {
let field = cx.new(|cx| TextInput::new(window, cx));
field.update(cx, |field, cx| field.set_text(with, cx));
desk.finding.as_mut().expect("open").replace = Some(field);
desk.replace(false, window, cx);
});
cx.run_until_parked();
}
fn current_hit(desk: &Entity<Desk>, cx: &mut VisualTestContext) -> Option<std::ops::Range<usize>> {
desk.read_with(cx, |desk, _| {
let find = desk.finding.as_ref()?;
find.current.map(|at| find.hits[at].clone())
})
}
#[gpui::test]
fn a_replacement_that_still_matches_moves_on(cx: &mut TestAppContext) {
let (desk, cx, _files) = opened("a a\n", cx);
query(&desk, "a", cx);
desk.update_in(cx, |desk, window, cx| desk.step(true, window, cx));
replace_one(&desk, "aa", cx);
assert_eq!(current_text(&desk, cx), "aa a\n");
assert_eq!(
current_hit(&desk, cx),
Some(3..4),
"the next original match"
);
}
#[gpui::test]
fn replacing_the_last_match_wraps_to_the_first(cx: &mut TestAppContext) {
let (desk, cx, _files) = opened("a b a\n", cx);
query(&desk, "a", cx);
desk.update_in(cx, |desk, window, cx| desk.step(false, window, cx));
replace_one(&desk, "x", cx);
assert_eq!(current_text(&desk, cx), "a b x\n");
assert_eq!(current_hit(&desk, cx), Some(0..1));
}
#[gpui::test]
fn preview_keeps_its_text_from_tables_and_replacement(cx: &mut TestAppContext) {
let (desk, cx, _files) = opened("a\n", cx);
let view = desk.read_with(cx, |desk, _| desk.active_view().expect("a tab"));
view.update_in(cx, |view, window, cx| {
view.switch(crate::view::Mode::Preview, window, cx)
});
let focus = desk.read_with(cx, |desk, _| desk.core.focus.clone());
cx.update(|window, cx| window.focus(&focus, cx));
cx.dispatch_action(crate::tools::InsertTable);
query(&desk, "a", cx);
desk.update_in(cx, |desk, window, cx| desk.step(true, window, cx));
replace_one(&desk, "x", cx);
assert_eq!(current_text(&desk, cx), "a\n");
}
+17 -9
View File
@@ -1,6 +1,9 @@
//! The table menu's work on the shown file (MARK-06).
use ely_gpui_component::{documents::TableEdit, primitives::Severity};
use ely_gpui_component::{
documents::{TableEdit, TableRefusal},
primitives::Severity,
};
use ely_office::prelude::*;
use ely_ui::i18n::text;
use gpui::{Context, InteractiveElement as _, actions};
@@ -29,15 +32,20 @@ impl Desk {
let document = view.read(cx).document().clone();
let done = document.update(cx, |document, cx| match edit {
Some(edit) => document.edit_table(edit, cx),
None => {
document.insert_table(cx);
true
}
None => document.insert_table(cx),
});
if !done {
let said = text(cx, "mark.table.none", &[]);
self.toast(said, Severity::Info, cx);
}
let Err(refusal) = done else {
return;
};
let key = match refusal {
TableRefusal::Outside => "mark.table.none",
TableRefusal::Kept => "mark.table.kept",
TableRefusal::Beyond => "mark.table.beyond",
TableRefusal::Mixed => "mark.table.mixed",
TableRefusal::Preview => "mark.preview.read_only",
};
let said = text(cx, key, &[]);
self.toast(said, Severity::Info, cx);
}
pub fn table_actions(element: gpui::Div, cx: &mut Context<Self>) -> gpui::Div {