mthread: add optional message support

This commit is contained in:
Leah Neukirchen 2017-06-30 13:28:05 +02:00
parent ef08f99d23
commit 841984f645
2 changed files with 43 additions and 3 deletions

View File

@ -7,6 +7,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl v .Op Fl v
.Op Fl S Ar msg
.Op Ar msgs\ ... .Op Ar msgs\ ...
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
@ -30,6 +31,15 @@ The options are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl v .It Fl v
Do not prune unresolved Message-IDs at the top-level. Do not prune unresolved Message-IDs at the top-level.
.It Fl S Ar msg
Treat
.Ar msg
as optional message(s) that will be added to threads only in case they
are referenced.
Threads where all messages are optional are suppressed.
You can use
.Fl S
to add outbox folders and complete threads where your replies were missing.
.El .El
.Sh EXIT STATUS .Sh EXIT STATUS
.Ex -std .Ex -std

View File

@ -21,6 +21,7 @@
#include "blaze822.h" #include "blaze822.h"
static int vflag; static int vflag;
static int optional;
struct container { struct container {
char *mid; char *mid;
@ -30,6 +31,7 @@ struct container {
struct container *parent; struct container *parent;
struct container *child; struct container *child;
struct container *next; struct container *next;
int optional;
}; };
static void *mids; static void *mids;
@ -80,6 +82,7 @@ midcont(char *mid)
c->file = 0; c->file = 0;
c->msg = 0; c->msg = 0;
c->date = -1; c->date = -1;
c->optional = 0;
c->parent = c->child = c->next = 0; c->parent = c->child = c->next = 0;
return *(struct container **)tsearch(c, &mids, midorder); return *(struct container **)tsearch(c, &mids, midorder);
} else { } else {
@ -95,6 +98,7 @@ store_id(char *file, struct message *msg)
c = midcont(mid(msg)); c = midcont(mid(msg));
c->file = strdup(file); c->file = strdup(file);
c->msg = msg; c->msg = msg;
c->optional = optional;
return c; return c;
} }
@ -279,6 +283,7 @@ find_roots()
top->date = -1; top->date = -1;
top->file = 0; top->file = 0;
top->next = top->child = top->parent = 0; top->next = top->child = top->parent = 0;
top->optional = 0;
top->mid = "(top)"; top->mid = "(top)";
lastc = top; lastc = top;
@ -301,11 +306,25 @@ prune_tree(struct container *c, int depth)
c->file = c->child->file; c->file = c->child->file;
c->msg = c->child->msg; c->msg = c->child->msg;
c->date = c->child->date; c->date = c->child->date;
c->optional = c->child->optional;
c->child = c->child->child; c->child = c->child->child;
} }
} while ((c = c->next)); } while ((c = c->next));
} }
int
alloptional(struct container *c)
{
do {
if (!c->optional && c->file)
return 0;
if (c->child && !alloptional(c->child))
return 0;
} while ((c = c->next));
return 1;
}
static int static int
dateorder(const void *a, const void *b) dateorder(const void *a, const void *b)
{ {
@ -353,6 +372,12 @@ void
print_tree(struct container *c, int depth) print_tree(struct container *c, int depth)
{ {
do { do {
// skip toplevel threads when they are unresolved or all optional
if (depth <= 1 &&
(c->optional || !c->file) &&
(!c->child || alloptional(c->child)))
continue;
if (depth >= 0) { if (depth >= 0) {
int i; int i;
for (i = 0; i < depth; i++) for (i = 0; i < depth; i++)
@ -373,14 +398,19 @@ main(int argc, char *argv[])
{ {
int c, i; int c, i;
while ((c = getopt(argc, argv, "v")) != -1) optional = 1;
while ((c = getopt(argc, argv, "S:v")) != -1)
switch(c) { switch(c) {
case 'S': blaze822_loop1(optarg, thread); break;
case 'v': vflag = 1; break; case 'v': vflag = 1; break;
default: default:
fprintf(stderr, "Usage: mthread [-v] [msgs...]\n"); fprintf(stderr, "Usage: mthread [-v] [-S dir] [msgs...]\n");
exit(1); exit(1);
} }
optional = 0;
if (argc == optind && isatty(0)) if (argc == optind && isatty(0))
i = blaze822_loop1(":", thread); i = blaze822_loop1(":", thread);
else else