Esc on a cell selection starting in a merged cell selects that cell's text

selection.cells may start at a covered grid position; the toggle now goes to
the merged cell (its owner at the top left), whose story holds the text.
Found by CodeRabbit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
moppeeerandClaude Opus 5.5 committed 2026-10-23 21:59:37 +02:00
1 parent 7a0c350114
commit f5a67336ad
2 files changed
+13 -1

No files matched your search

+7 -1
View File
@@ -1555,7 +1555,13 @@ fn toggle_selection(s: &mut Session) -> Result<Value> {
let c = t.cell.ok_or_else(|| bad(ID, "not in a cell"))?;
let cells = match st.selection.cells {
Some(cs) => {
let cell = CellAddr { table: cs.table, row: cs.range.r0, col: cs.range.c0 };
// A merged cell's text belongs to the cell at its top left.
let (row, col) = st
.doc
.story(cs.story)
.and_then(|x| x.tables.get(&cs.table))
.map_or((cs.range.r0, cs.range.c0), |tb| tb.owner(cs.range.r0, cs.range.c0));
let cell = CellAddr { table: cs.table, row, col };
let len = st.doc.text_story(cs.story, Some(cell)).map_or(0, |x| x.len());
st.selection = Selection::text(TextSel { story: cs.story, anchor: 0, focus: len, cell: Some(cell), ..t });
false
+6
View File
@@ -148,6 +148,12 @@ fn escape_toggles_text_and_cell_selection() {
assert_eq!((t.cell, t.range()), (Some(cell), 0..5), "the cell's text is selected");
s.execute("table.prevCell", &json!({})).unwrap();
assert_eq!(s.doc().unwrap().selection.text.unwrap().cell, Some(designcraft_doc::CellAddr { col: 0, ..cell }));
// A selection that starts inside a merged cell goes back to the merged cell's text.
s.execute("table.select", &json!({"rows": [0, 1], "cols": [0, 0]})).unwrap();
s.execute("table.merge", &json!({})).unwrap();
s.execute("table.select", &json!({"rows": [1, 1], "cols": [0, 1]})).unwrap();
s.execute("table.toggleSelection", &json!({})).unwrap();
assert_eq!(s.doc().unwrap().selection.text.unwrap().cell, Some(designcraft_doc::CellAddr { row: 0, col: 0, ..cell }));
// Outside a table there is nothing to toggle.
s.execute("text.select", &json!({"story": sid, "anchor": 0, "focus": 0})).unwrap();
assert!(s.execute("table.toggleSelection", &json!({})).is_err());