ref: d50f1886ac392bb53226bcdee649cad221a05e73
parent: 3dfdd6d6c595da74ac627548a9f7e939ab039ab7
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Jan 27 11:23:18 EST 2021
nail: fix reordering on deletion When deleting the root of a thread with multiple children, we need to replace it with a dummy so that the ordering stays intact.
--- a/mbox.c
+++ b/mbox.c
@@ -382,7 +382,7 @@
}
p = lookupid(m->inreplyto);
if(p == nil)
- p = placeholder(m->inreplyto, m->time, ins);
+ p = placeholder(m->inreplyto, m->time);
if(!addchild(p, m, d))
m->state |= Stoplev;
return m;
@@ -649,32 +649,26 @@
}
static void
-removemesg(Mesg *m)
+relinkmsg(Mesg *p, Mesg *m)
{
- Mesg *c, *p, *pp;
+ Mesg *c, *pp;
int i, j;
/* remove child, preserving order */
j = 0;
- p = m->parent;
- if(p != nil){
- for(i = 0; p && i < p->nchild; i++){
- if(p->child[i] != m)
- p->child[j++] = p->child[i];
- }
- p->nchild = j;
- for(pp = p; pp != nil; pp = pp->parent)
- pp->nsub--;
+ for(i = 0; p && i < p->nchild; i++){
+ if(p->child[i] != m)
+ p->child[j++] = p->child[i];
}
+ p->nchild = j;
+ for(pp = p; pp != nil; pp = pp->parent)
+ pp->nsub -= m->nsub + 1;
/* reparent children */
for(i = 0; i < m->nchild; i++){
c = m->child[i];
c->parent = nil;
- if(p != nil)
- addchild(p, c, 1);
- else
- c->state |= Stoplev;
+ addchild(p, c, c->nsub + 1);
}
}
@@ -683,7 +677,7 @@
{
int i, j, ln, fd;
char *path;
- Mesg *m;
+ Mesg *m, *p;
i = 0;
path = estrjoin(maildir, "/ctl", nil);
@@ -703,14 +697,20 @@
if(m->flags & Ftodel)
fprint(fd, "delete %s %d", mailbox, atoi(m->name));
- removemesg(m);
+ p = m->parent;
removeid(m);
+ if(p == nil && m->nsub != 0){
+ p = placeholder(m->messageid, m->time);
+ p->nsub = m->nsub + 1;
+ mbox.mesg[i] = p;
+ }
+ if(p != nil)
+ relinkmsg(p, m);
for(j = 0; j < m->nchild; j++)
mbredraw(m->child[j], 1, 1);
memmove(&mbox.mesg[i], &mbox.mesg[i+1], (mbox.nmesg - i)*sizeof(Mesg*));
mbox.nmesg--;
- mesgfree(m);
- }
+ }
close(fd);
fprint(mbox.ctl, "clean\n");
}