Compare commits

..

No commits in common. "56c17f8131f82c7fd529521c1aba38ecb148ded8" and "f725e8b4336ec58db54ae945fc7523bd06ae59a9" have entirely different histories.

4 changed files with 8 additions and 303 deletions

View file

@ -36,7 +36,7 @@ plumb start window rc -c '''echo % mail '''$0'; mail '$0
# audio
type is text
data matches '[a-zA-Z¡-￿0-9_\-.,/]+'
data matches '([a-zA-Z¡-￿0-9_\-.,/]+)\.(mp3|MP3|ogg|OGG|flac|FLAC|wav|WAV|au|AU|mid|MID|mus|MUS|m3u|M3U|pls|PLS|opus|OPUS)'
data matches '([a-zA-Z¡-￿0-9_\-.,/]+)\.(mp3|MP3|ogg|OGG|flac|FLAC|wav|WAV|au|AU|mid|MID|mus|MUS|m3u|M3U|pls|PLS)'
arg isfile $0
plumb to audio
plumb start window -scroll play $file
@ -44,7 +44,7 @@ plumb start window -scroll play $file
# image files go to page
type is text
data matches '[a-zA-Z¡-￿0-9_\-.,/]+'
data matches '([a-zA-Z¡-￿0-9_\-.,/]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|PPM|bit|BIT|png|PNG|pgm|PGM|bmp|BMP|yuv|YUV|tga|TGA|webp|WEBP|img|IMG)'
data matches '([a-zA-Z¡-￿0-9_\-.,/]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|PPM|bit|BIT|png|PNG|pgm|PGM|bmp|BMP|yuv|YUV|tga|TGA)'
arg isfile $0
plumb to image
plumb client page -wi
@ -108,11 +108,11 @@ plumb start rc -c 'man -b '$2' '$1'
# RFC references are looked up in /lib/rfc and passed to editor
type is text
data matches '[Rr][Ff][Cc] ?([0-9]+)'
arg isfile /lib/rfc/rfc$1.html
data set file:///$file
plumb to web
plumb client window $browser -a
data matches 'RFC ?([0-9]+)'
arg isfile /lib/rfc/rfc$1
data set $file
plumb to edit
plumb client window $editor
# start rule for images without known suffixes
dst is image

View file

@ -1,14 +0,0 @@
</$objtype/mkfile
TARG=watch
OFILES=$TARG.$O
BIN=$home/bin/$objtype
MAN=/sys/man/1
</sys/src/cmd/mkone
install:V: man
uninstall:V:
rm -f $BIN/$TARG
rm -f $MAN/$TARG

View file

@ -1,213 +0,0 @@
#include <u.h>
#include <libc.h>
#include <regexp.h>
typedef struct List List;
struct List {
List *next;
union {
Dir;
Reprog *re;
};
};
char pwd[1024];
int period = 1000;
int noregroup = 0;
int once = 0;
List *expl;
List *filel;
void
usage(void)
{
fprint(2, "usage: %s [-G] [[-e expr] ...] [-t sec] [cmd]\n", argv0);
exits("usage");
}
void*
emalloc(ulong sz)
{
void *v = malloc(sz);
if(v == nil)
sysfatal("malloc: %r");
setmalloctag(v, getcallerpc(&sz));
memset(v, 0, sz);
return v;
}
char*
estrdup(char *s)
{
if((s = strdup(s)) == nil)
sysfatal("strdup: %r");
setmalloctag(s, getcallerpc(&s));
return s;
}
char*
join(char **arg)
{
int i;
char *s, *p;
s = estrdup("");
for(i = 0; arg[i]; i++){
p = s;
if((s = smprint("%s %s", s, arg[i])) == nil)
sysfatal("smprint: %r");
free(p);
}
return s;
}
void
eadd(char *exp)
{
List *r;
r = emalloc(sizeof(*r));
r->re = regcomp(exp);
r->next = expl;
expl = r;
}
void
fadd(Dir *d)
{
List *f;
f = emalloc(sizeof(*f));
f->Dir = *d;
f->next = filel;
filel = f;
}
int
tracked(char *name)
{
List *r;
for(r = expl; r; r = r->next)
if(regexec(r->re, name, nil, 0))
return 1;
return 0;
}
int
changed(Dir *d)
{
List *f;
for(f = filel; f; f = f->next)
if(f->type == d->type)
if(f->dev == d->dev)
if(f->qid.path == d->qid.path)
if(f->qid.type == d->qid.type)
if(f->qid.vers == d->qid.vers)
return 0;
else{
f->Dir = *d;
return 1;
}
fadd(d);
return 1;
}
void
watch(void)
{
static int first = 1;
long fd, n;
Dir *d, *p;
for(;;){
sleep(period);
if((fd = open(pwd, OREAD)) < 0)
sysfatal("open: %r");
if((n = dirreadall(fd, &d)) < 0)
sysfatal("dirreadall: %r");
close(fd);
for(p = d; n--; p++){
if(tracked(p->name)){
if(first){
fadd(p);
continue;
}
if(changed(p)){
free(d);
return;
}
}
}
first = 0;
free(d);
}
}
void
rc(char *cmd)
{
Waitmsg *m;
switch(fork()){
case -1: sysfatal("fork: %r");
case 0:
execl("/bin/rc", "rc", "-c", cmd, nil);
sysfatal("execl: %r");
}
if((m = wait()) && m->msg[0])
fprint(2, "watch: %s\n", m->msg);
free(m);
}
void
regroup(void)
{
char *cmd;
cmd = smprint("cat /proc/%d/noteid >/proc/%d/noteid",
getppid(), getpid());
rc(cmd);
free(cmd);
}
void
main(int argc, char *argv[])
{
int t;
char *unit;
char *cmd;
cmd = "mk";
ARGBEGIN{
case 'e':
eadd(EARGF(usage())); break;
case 't':
t = strtol(EARGF(usage()), &unit, 10);
if(t < 0)
t = -t;
if(unit != nil && strncmp(unit, "ms", 2) == 0)
period = t;
else
period = t*1000;
break;
case 'G':
noregroup = 1; break;
case '1':
once = 1; break;
default: usage();
}ARGEND;
if(expl == nil)
eadd("\.[chsy]$");
if(argc > 0)
cmd = join(argv);
if(getwd(pwd, sizeof pwd) == nil)
sysfatal("getwd: %r");
if(noregroup == 0) regroup();
for(;;){
watch();
rc(cmd);
if(once) exits(nil);
}
}

View file

@ -1,68 +0,0 @@
.TH WATCH 1
.SH NAME
watch \- run a command on file change
.SH SYNOPSIS
.B watch
[
.B -G
] [
.B -t
sec
] [[
.B -e
pattern
] ... ] [
.B command
]
.SH DESCRIPTION
.PP
Run
.IR command
.RB ( mk
by default) when a change to files
in the current directory is detected.
.PP
The options are as follows:
.TF "-e pattern"
.TP
.BI -e pattern
Watch files matching a
.IR pattern ;
it may be given multiple times and
defaults to
.BR \e.[chsy]$
.TP
.BI -t period
Sets the polling
.IR period
in seconds (one second by default).
\'ms' can be appended to the value
to specify time in miliseconds.
.TP
.B -G
Prevents regrouping to the parent
process' note group. The default
to regroup was chosen to make it
easy to kill
.I watch
in common use by interrupting the
parent shell.
.SH EXAMPLES
.EX
watch -e '\e.man$' 'mk install; window man -P prog' &
.EE
.SH SEE ALSO
.SH SOURCE
.B git://code.a-b.xyz/watch
.SH BUGS
.I Watch
will not react on file removal.
.PP
.I Qid.vers
is watched for changes, which is
not maintained by every file server.
.PP
The polling period is actually
.I sec
plus the time it takes to run
.IR command .