| 704 |
704 |
|
/// One function because two would drift: [`node_spots`] decides what the caret
|
| 705 |
705 |
|
/// can land on and `node.rs` decides what the drawing counts, and a row counted
|
| 706 |
706 |
|
/// in one and not the other shifts every stop below the table by one.
|
|
707 |
+ |
/// Whether a row offers anything of its own.
|
|
708 |
+ |
///
|
|
709 |
+ |
/// The row's members only: what it holds in its cells is a separate question,
|
|
710 |
+ |
/// and the two containers answer it differently on purpose. A table row steps
|
|
711 |
+ |
/// into its cells ([`inside`]); a list row's controls are stops of their own,
|
|
712 |
+ |
/// walked straight after it.
|
|
713 |
+ |
///
|
|
714 |
+ |
/// One predicate since the 2026-09-05 collapse, and it closes a gap. This was
|
|
715 |
+ |
/// written twice, and the copy here did not test `toggle` because a table row
|
|
716 |
+ |
/// could not carry one. Now that a row is a row, a table row that is a
|
|
717 |
+ |
/// checklist item can, and without this it would have been unreachable in a
|
|
718 |
+ |
/// terminal: nothing else about such a row is set, so no other clause fires.
|
|
719 |
+ |
pub(crate) fn row_offers(row: &Row) -> bool {
|
|
720 |
+ |
row.open.is_some()
|
|
721 |
+ |
|| row.activate.is_some()
|
|
722 |
+ |
|| row.toggle.is_some()
|
|
723 |
+ |
|| row.selected.is_some()
|
|
724 |
+ |
|| row.chosen.is_some()
|
|
725 |
+ |
|| !row.menu.is_empty()
|
|
726 |
+ |
}
|
|
727 |
+ |
|
| 707 |
728 |
|
pub(crate) fn row_reachable(cells: &Cells) -> bool {
|
| 708 |
|
- |
cells.open.is_some()
|
| 709 |
|
- |
|| cells.activate.is_some()
|
| 710 |
|
- |
|| cells.selected.is_some()
|
| 711 |
|
- |
|| cells.chosen.is_some()
|
| 712 |
|
- |
|| !cells.menu.is_empty()
|
| 713 |
|
- |
|| !inside(cells).is_empty()
|
|
729 |
+ |
row_offers(cells) || !inside(cells).is_empty()
|
| 714 |
730 |
|
}
|
| 715 |
731 |
|
|
| 716 |
732 |
|
/// The parts of a table row the caret can step into, as `(column, part)`
|
| 935 |
951 |
|
///
|
| 936 |
952 |
|
/// The row comes first because it is the whole line and the controls sit on it.
|
| 937 |
953 |
|
fn push_row(row: &Row, region: &str, local: &Local<'_>, found: &mut Vec<Reach>) {
|
| 938 |
|
- |
if row.open.is_some()
|
| 939 |
|
- |
|| row.activate.is_some()
|
| 940 |
|
- |
|| row.toggle.is_some()
|
| 941 |
|
- |
|| row.selected.is_some()
|
| 942 |
|
- |
|| row.chosen.is_some()
|
| 943 |
|
- |
|| !row.menu.is_empty()
|
| 944 |
|
- |
{
|
|
954 |
+ |
if row_offers(row) {
|
| 945 |
955 |
|
found.push(Reach {
|
| 946 |
956 |
|
region: region.to_string(),
|
| 947 |
957 |
|
spot: Spot::Row {
|