ref: d765a836933a0ce07b1baaa0758be2f223dcaa3a
parent: 63b1407404f050c40ea37025e3bbcc21a69adf03
author: Ori Bernstein <[email protected]>
date: Tue Nov 17 16:01:29 EST 2020
mbox: redraw messages correctly after deletion We were accidentally deleting one too many rows when updating a message. There was also an edge case when moving an empty dummy around.
--- a/mbox.c
+++ b/mbox.c
@@ -524,7 +524,7 @@
static void
removemesg(Mesg *m)
{
- Mesg *c, *p;
+ Mesg *c, *p, *pp;
int i, j;
/* remove child, preserving order */
@@ -536,7 +536,9 @@
j++;
p->child[j] = p->child[i];
}
- p->nchild = j;
+ p->nchild--;
+ for(pp = p; pp != nil; pp = pp->parent)
+ pp->nsub--;
}
/* reparent children */
@@ -678,11 +680,27 @@
/* Bump whole thread up in list */
if(r->nsub > 0){
ln = mesglineno(r, nil);
- nr = r->nsub;
+ nr = r->nsub-1;
if(!(r->state & Sdummy))
nr++;
- fprint(mbox.addr, "%d,%d", ln, ln+nr);
- write(mbox.data, "", 0);
+ /*
+ * We can end up with an empty container
+ * in an edge case.
+ *
+ * Imagine we have a dummy message with
+ * a child, and that child gets deleted,
+ * then a new message comes in replying
+ * to that dummy.
+ *
+ * In this case, r->nsub == 1 due to the
+ * newly added message, so nr=0.
+ * in that case, skip the redraw, and
+ * reinsert the dummy in the right place.
+ */
+ if(nr > 0){
+ fprint(mbox.addr, "%d,%d", ln, ln+nr-1);
+ write(mbox.data, "", 0);
+ }
reinsert(r);
}
mbredraw(r, 1, 1);