shithub: Nail

Download patch

ref: 8328c8f5fdbf2c8a20865989900b98ed449068e7
parent: 6ab2f11bb9cf9c49e15b8b83fe44a3e9d549425b
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Nov 9 00:22:34 EST 2020

Mark: implement multi-message marks

--- a/mail.h
+++ b/mail.h
@@ -175,6 +175,7 @@
 void	mesgclear(Mesg*);
 void	mesgfree(Mesg*);
 void	mesgpath2name(char*, int, char*);
+int	mesgflagparse(char*, int*);
 
 /* mailbox */
 void	mbredraw(Mesg*, int, int);
--- a/mbox.c
+++ b/mbox.c
@@ -465,12 +465,14 @@
 }
 
 static void
-mark(char **f, int nf, int flags, int add)
+mark(char **f, int nf, char *fstr, int flags, int add)
 {
-	char *sel, *p, *q, *e;
-	int i, q0, q1;
+	char *sel, *p, *q, *e, *path;
+	int i, q0, q1, fd;
 	Mesg *m;
 
+	if(flags == 0)
+		return;
 	wingetsel(&mbox, &q0, &q1);
 	if(nf == 0){
 		sel = winreadsel(&mbox);
@@ -486,6 +488,14 @@
 					m->flags |= flags;
 				else
 					m->flags &= ~flags;
+				if(fstr != nil && strlen(fstr) != 0){
+					path = estrjoin(mbox.path, "/", m->name, "/flags", nil);
+					if((fd = open(path, OWRITE)) != -1){
+						fprint(fd, fstr);
+						close(fd);
+					}
+					free(path);
+				}
 				mbredraw(m, 0, 0);
 			}
 		}
@@ -492,7 +502,7 @@
 		free(sel);
 	}else for(i = 0; i < nf; i++){
 		if((m = mesglookup(f[i], nil)) != nil){
-			m->flags |= Ftodel;
+			m->flags |= flags;
 			mbredraw(m, 0, 0);
 		}
 	}
@@ -500,6 +510,22 @@
 }
 
 static void
+mbmark(char **f, int nf)
+{
+	int add, flg;
+
+	if(nf == 0){
+		fprint(2, "missing fstr");
+		return;
+	}
+	if((flg = mesgflagparse(f[0], &add)) == -1){
+		fprint(2, "Mark: invalid flags %s\n", f[0]);
+		return;
+	}
+	mark(f+1, nf-1, f[0], flg, add);
+}
+
+static void
 removemesg(Mesg *m)
 {
 	Mesg *c, *p;
@@ -565,13 +591,13 @@
 static void
 delmesg(char **f, int nf)
 {
-	mark(f, nf, Ftodel, 1);
+	mark(f, nf, nil, Ftodel, 1);
 }
 
 static void
 undelmesg(char **f, int nf)
 {
-	mark(f, nf, Ftodel, 0);
+	mark(f, nf, nil, Ftodel, 0);
 }
 
 static void
@@ -696,6 +722,7 @@
 	{"Del", quitall},
 	{"Redraw", redraw},
 	{"Next", nextunread},
+	{"Mark", mbmark},
 #ifdef NOTYET
 	{"Filter", filter},
 	{"Get", mbrefresh},
@@ -756,7 +783,7 @@
 
 	threadsetname("mbox %s", mbox.path);
 	wininit(&mbox, mbox.path);
-	wintagwrite(&mbox, "Put Mail Delmesg Undelmesg Save Next ");
+	wintagwrite(&mbox, "Put Mail Delmesg Undelmesg Next ");
 	showlist();
 	fprint(mbox.ctl, "clean\n");
 	proccreate(eventread, nil, Stack);
--- a/mesg.c
+++ b/mesg.c
@@ -325,6 +325,37 @@
 }
 
 static void
+markone(Mesg *m, char **f, int nf)
+{
+	int add, flg, fd;
+	char *path;
+
+	if(nf != 1){
+		fprint(2, "Mark: invalid arguments");
+		return;
+	}
+
+	if((flg = mesgflagparse(f[0], &add)) == -1){
+		fprint(2, "Mark: invalid flags %s\n", f[0]);
+		return;
+	}
+	if(add)
+		m->flags |= flg;
+	else
+		m->flags &= ~flg;
+	if(strlen(f[0]) != 0){
+		path = estrjoin(mbox.path, "/", m->name, "/flags", nil);
+		if((fd = open(path, OWRITE)) != -1){
+			fprint(fd, f[0]);
+			close(fd);
+		}
+		free(path);
+	}
+	mbredraw(m, 0, 0);
+}
+
+
+static void
 mesgquit(Mesg *m, char **, int)
 {
 	if(fprint(m->ctl, "del\n") == -1)
@@ -338,6 +369,7 @@
 	{"Reply",	reply},
 	{"Delmesg",	delmesg},
 	{"Del", 	mesgquit},
+	{"Mark",	markone},
 #ifdef NOTYET
 	{"Save",	nil},
 #endif
@@ -407,6 +439,35 @@
 	m->flags &= ~Fopen;
 	winclose(m);
 	threadexits(nil);
+}
+
+int
+mesgflagparse(char *fstr, int *add)
+{
+	int flg;
+
+	flg = 0;
+	*add = (*fstr == '+');
+	if(*fstr == '-' || *fstr == '+')
+		fstr++;
+	for(; *fstr; fstr++){
+		switch(*fstr){
+		case 'a':
+			flg |= Fresp;
+			break;
+		case 's':
+			flg |= Fseen;
+			break;
+		case 'D':
+			flg |= Ftodel;
+			memcpy(fstr, fstr +1, strlen(fstr));
+			break;
+		default:
+			fprint(2, "unknown flag %c", *fstr);
+			return -1;
+		}
+	}
+	return flg;
 }
 
 void