ref: b512993b0e23a11ec1de50ebc0b7fee19cf994a9
parent: 49e08b52aee80d61b1302dcf7fe28e96dd0a3973
author: Michael Misch <michaelmisch1985@gmail.com>
date: Sun Jul 7 08:43:46 EDT 2024
Add in tabs, unread counts, and fix a few error
--- a/TODO
+++ b/TODO
@@ -16,10 +16,3 @@
## Notifications:
- Create and update them, integrate with tabs
-- Install fmt for printing
-
-## Tabs:
-
-- list available buffers with unread counts, add notify `!` when applicable
-- Install fmt for printing
-- Clearing unreads on the rwakeupall
--- a/alt.h
+++ b/alt.h
@@ -8,7 +8,9 @@
char title[1024];
char status[1024];
char aside[1024];
- int fd;
+ int fd; // feed
+ int tag; // feed
+ int unread;
Channel *cmds;
Notify *notify;
Buffer *next;
@@ -23,9 +25,13 @@
Buffer *bufferCreate(Channel*);
Buffer *bufferSearch(Buffer*, char*);
+Buffer *bufferSearchTag(Buffer*, ulong);
char *bufferDrop(Buffer*, char*);
char *bufferPush(Buffer*, char*);
void bufferDestroy(Buffer*);
+
+int Tconv(Fmt*);
+int Nconv(Fmt*);
void* emalloc(int);
char* estrdup(char*);
--- a/buffer.c
+++ b/buffer.c
@@ -49,6 +49,8 @@
b = emalloc(sizeof(*b));
b->name = estrdup(name);
b->notify = nil;
+ b->unread = 0;
+ b->tag = -1;
b->rz.l = b;
memset(b->title, 0, sizeof(b->title));
memset(b->status, 0, sizeof(b->status));
@@ -74,6 +76,16 @@
return nil;
}
+Buffer *
+bufferSearchTag(Buffer *base, ulong tag)
+{+ Buffer *sp;
+ for(sp = base; sp; sp = sp->next)
+ if(sp->tag == tag)
+ return sp;
+ return nil;
+}
+
Buffer*
bufferCreate(Channel *cmds)
{@@ -85,6 +97,8 @@
memset(b->status, 0, sizeof(b->status));
memset(b->aside, 0, sizeof(b->aside));
b->cmds = cmds;
+ b->tag = -1;
+ b->unread = 0;
b->notify = nil;
b->next = nil;
b->rz.l = b;
--- a/client.c
+++ b/client.c
@@ -38,6 +38,7 @@
struct Clfid
{int level;
+ int tag;
Client *cl;
};
@@ -52,6 +53,7 @@
static Client client[256];
static Buffer *root;
+int flushtag;
static int nclient;
static int time0;
static Srv *fs;
@@ -215,6 +217,7 @@
int n;
f = r->fid->aux;
+ n = 0;
switch(f->level){case Qcroot:
dirread9p(r, rootgen, f->cl);
@@ -231,15 +234,20 @@
srvrelease(fs);
qlock(b);
Again:
- n = pread(f->cl->fd, buf, sizeof(buf), r->ifcall.offset);
- if(n){- // cut off the EOF
- r->ofcall.count = n;
- memmove(r->ofcall.data, buf, n);
- } else{- rsleep(&b->rz);
- goto Again;
- }
+ // Check if we have a tag here, abort early if so.
+ if(b->tag != flushtag){ + n = pread(f->cl->fd, buf, sizeof(buf), r->ifcall.offset);
+ if(n){+ // cut off the EOF
+ r->ofcall.count = n;
+ memmove(r->ofcall.data, buf, n);
+ } else {+ b->unread = 0;
+ rsleep(&b->rz);
+ goto Again;
+ }
+ } else
+ flushtag = -1;
qunlock(b);
memset(buf, 0, sizeof(buf));
srvacquire(fs);
@@ -254,6 +262,7 @@
respond(r, nil);
return;
}
+ break;
case Qstatus:
if(f->cl->current && f->cl->current->status){memset(buf, 0, sizeof(buf));
@@ -260,6 +269,7 @@
snprint(buf, sizeof(buf), "%s", f->cl->current->status);
goto String;
}
+ break;
case Qaside:
if(f->cl->current && f->cl->current->aside){memset(buf, 0, sizeof(buf));
@@ -266,17 +276,24 @@
snprint(buf, sizeof(buf), "%s", f->cl->current->aside);
goto String;
}
+ break;
case Qnotify:
if(f->cl->current && f->cl->current->notify){memset(buf, 0, sizeof(buf));
- for(np = f->cl->current->notify; np->next; np = np->next)
- // TODO: Move to fmt specifier for these
- snprint(buf, sizeof(buf), "%s\n", np->data);
+ for(np = f->cl->current->notify; np; np = np->next)
+ n = snprint(buf + n, sizeof(buf), "%!\n", np);
goto String;
}
- //case Qtabs:
- // Iterate through base and show up all 'o them
-
+ break;
+ case Qtabs:
+ if(f->cl->current){+ memset(buf, 0, sizeof(buf));
+ for(b = root->next; b; b = b->next){+ n = snprint(buf + n, sizeof(buf), "%t\n", b);
+ }
+ goto String;
+ }
+ break;
}
if(!f->cl->current)
respond(r, "no buffer selected");
@@ -303,6 +320,9 @@
if(f->cl->fd)
close(f->cl->fd);
f->cl->current = bufferSearch(root, s);
+ if(!f->cl->current)
+ respond(r, "No buffer for selected");
+ f->cl->current->tag = r->tag;
memset(path, sizeof(path), 0);
snprint(path, sizeof(path), "%s/%s/%s", logdir, root->name, s);
f->cl->fd = open(path, OREAD);
@@ -343,6 +363,13 @@
void
clflush(Req *r)
{+ Buffer *b;
+ flushtag = r->tag;
+ if(b = bufferSearchTag(root, flushtag)){+ qlock(b);
+ rwakeup(&b->rz);
+ qunlock(b);
+ }
respond(r, nil);
}
@@ -365,6 +392,7 @@
root = emalloc(sizeof(*root));
USED(root);
root = (Buffer*)s->aux;
+ flushtag = -1;
fs = s;
time0 = time(0);
}
--- a/fs.c
+++ b/fs.c
@@ -50,8 +50,8 @@
void
threadmain(int argc, char *argv[])
{- // We could use quotefmtinstall here
- // add in tabs at very least
+ fmtinstall('t', Tconv);+ fmtinstall('!', Nconv);user = getuser();
mtpt = "/mnt/alt";
logdir = "/tmp/alt";
--- a/mkfile
+++ b/mkfile
@@ -13,6 +13,7 @@
client.$O\
service.$O\
notification.$O\
+ tabs.$O\
</sys/src/cmd/mkmany
--- a/notification.c
+++ b/notification.c
@@ -1,0 +1,16 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+#include "alt.h"
+
+int
+Nconv(Fmt *fp)
+{+ Notify *n;
+
+ n = va_arg(fp->args, Notify*);
+ return fmtstrcpy(fp, n->data);
+}
--- a/service.c
+++ b/service.c
@@ -327,9 +327,8 @@
data[strlen(data)] = '\n';
pwrite(b->fd, data, strlen(data), d->length);
free(d);
- if(rwakeupall(&b->rz)){- print("Unlocking all threads\n");- }
+ if(rwakeupall(&b->rz) == 0)
+ b->unread++;
qunlock(b);
return nil;
}
--
⑨