shithub: Nail

Download patch

ref: 054becb7f8864898c8ba1a7086914b86d1be1184
parent: b2744a5cc8020d6407e8a1619f58ebdfd1e8bbb7
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Mar 6 12:11:59 EST 2021

message list: etter solution to previous commit

--- a/mail.h
+++ b/mail.h
@@ -15,6 +15,7 @@
 	Sdummy	= 1<<0,	/* message placeholder */
 	Stoplev	= 1<<1,	/* not a response to anything */
 	Sopen	= 1<<2,	/* opened for viewing */
+	Szap	= 1<<3, /* flushed, to be removed from list */
 };
 
 enum {
--- a/mbox.c
+++ b/mbox.c
@@ -260,15 +260,13 @@
 		mbox.mesgsz *= 2;
 		mbox.mesg = erealloc(mbox.mesg, mbox.mesgsz*sizeof(Mesg*));
 	}
-	if(ins >= 0){
-		if(ins == 0)
-			idx = slotfor(m);
-		else
-			idx = mbox.nmesg;
-		memmove(&mbox.mesg[idx + 1], &mbox.mesg[idx], (mbox.nmesg - idx)*sizeof(Mesg*));
-		mbox.mesg[idx] = m;
-		mbox.nmesg++;
-	}
+	if(ins)
+		idx = slotfor(m);
+	else
+		idx = mbox.nmesg;
+	memmove(&mbox.mesg[idx + 1], &mbox.mesg[idx], (mbox.nmesg - idx)*sizeof(Mesg*));
+	mbox.mesg[idx] = m;
+	mbox.nmesg++;
 	if(m->messageid == nil)
 		return;
 
@@ -298,7 +296,7 @@
 }
 
 static Mesg *
-placeholder(char *msgid, vlong time)
+placeholder(char *msgid, vlong time, int ins)
 {
 	Mesg *m;
 
@@ -307,6 +305,7 @@
 	m->messageid = estrdup(msgid);
 	m->hash = strhash(msgid);
 	m->time = time;
+	addmesg(m, ins);
 	return m;
 }
 
@@ -382,10 +381,8 @@
 		return m;
 	}
 	p = lookupid(m->inreplyto);
-	if(p == nil){
-		p = placeholder(m->inreplyto, m->time);
-		addmesg(m, ins);
-	}
+	if(p == nil)
+		p = placeholder(m->inreplyto, m->time, ins);
 	if(!addchild(p, m, d))
 		m->state |= Stoplev;
 	return m;
@@ -659,8 +656,6 @@
 
 	/* remove child, preserving order */
 	j = 0;
-	if(p == nil || m == nil)
-		return;
 	for(i = 0; p && i < p->nchild; i++){
 		if(p->child[i] != m)
 			p->child[j++] = p->child[i];
@@ -680,22 +675,21 @@
 static void
 mbflush(char **, int)
 {
-	int i, j, ln, fd, dummy;
+	int i, j, ln, fd;
 	char *path;
 	Mesg *m, *p;
 
-	i = 0;
 	path = estrjoin(maildir, "/ctl", nil);
 	fd = open(path, OWRITE);
 	free(path);
 	if(fd == -1)
 		sysfatal("open mbox: %r");
-	while(i < mbox.nmesg){
+	for(i = 0; i < mbox.nmesg; i++){
 		m = mbox.mesg[i];
-		if((m->state & (Sopen|Sdummy)) || !(m->flags & (Fdel|Ftodel))){
-			i++;
+		p = m->parent;
+		if(m->state & (Sopen|Szap) || (m->flags & (Fdel|Ftodel)) == 0)
 			continue;
-		}
+
 		ln = mesglineno(m, nil);
 		fprint(mbox.addr, "%d,%d", ln, ln+m->nsub);
 		write(mbox.data, "", 0);
@@ -702,25 +696,26 @@
 		if(m->flags & Ftodel)
 			fprint(fd, "delete %s %d", mailbox, atoi(m->name));
 
-		p = m->parent;
-		dummy = 0;
 		removeid(m);
+		m->state |= Szap;
 		if(p == nil && m->nsub != 0){
-			p = placeholder(m->messageid, m->time);
+			p = placeholder(m->messageid, m->time, 1);
 			p->nsub = m->nsub + 1;
-			addmesg(p, -1);
-			mbox.mesg[i] = p;
-			dummy = 1;
 		}
-		relinkmsg(p, m);
+		if(p != nil)
+			relinkmsg(p, m);
 		for(j = 0; j < m->nchild; j++)
 			mbredraw(m->child[j], 1, 1);
-		if(!dummy){
-			memmove(&mbox.mesg[i], &mbox.mesg[i+1], (mbox.nmesg - i)*sizeof(Mesg*));
-			mbox.nmesg--;
-		}
-		mesgfree(m);
  	}
+
+	for(i = 0, j = 0; i < mbox.nmesg; i++){
+		m = mbox.mesg[i];
+		if((m->state & Szap) != 0)
+			mesgfree(m);
+		else
+			mbox.mesg[j++] = m;
+	}
+		
 	close(fd);
 	fprint(mbox.ctl, "clean\n");
 }