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