Charles.Forsyth20060303a828770d19 years agoHistory
262 lines · 6.8 KB · Brainfuck
RawDownload
implement Find; ## Copyright © 2003 Vita Nuova Holdings Limited.  All rights reserved.#  include "sys.m";	sys: Sys;include "draw.m";	draw: Draw;	Rect: import draw;include "tk.m";	tk: Tk;include "tkclient.m";	tkclient: Tkclient;include "arg.m";include "sh.m";include "registries.m";	registries: Registries;	Registry, Attributes, Service: import registries;include "grid/announce.m";	announce: Announce; Find: module {	init: fn(ctxt: ref Draw->Context, argv: list of string);}; init(ctxt: ref Draw->Context, argv: list of string){	sys = load Sys Sys->PATH;	sys->pctl(sys->FORKNS | sys->NEWPGRP, nil);	draw = load Draw Draw->PATH;	arg := load Arg Arg->PATH;	if (arg == nil)		badmod(Arg->PATH);	if (draw == nil)		badmod(Draw->PATH);	tk = load Tk Tk->PATH;	if (tk == nil)		badmod(Tk->PATH);	tkclient = load Tkclient Tkclient->PATH;	if (tkclient == nil)		badmod(Tkclient->PATH);	tkclient->init();	registries = load Registries Registries->PATH;	if (registries == nil)		badmod(Registries->PATH);	registries->init(); 	command := "";	attrs := Attributes.new(nil);	arg->init(argv);	arg->setusage("find [-a attributes] action1 { cmd [args...] } .. actionN { cmd [args...] }");	title := "a resource";	while ((opt := arg->opt()) != 0) {		case opt {		't' =>			title = arg->earg();		'a' =>			attr := arg->earg();			val := arg->earg();			attrs.set(attr, val);		* =>			arg->usage();		}	}	argv = arg->argv();	if (argv == nil || len argv % 2)		arg->usage();	arg = nil;		cmds := array[len argv / 2] of (string, string);	for (i := 0; i < len cmds; i++) {		cmds[i] = (hd argv, hd tl argv);		argv = tl tl argv;	} 	reg := Registry.connect(nil, nil, nil);	if (reg == nil)		error(ctxt, ((0,0),(0,0)), "Could not find registry");	(matches, err) := reg.find(attrs.attrs);	if (err != nil)		error(ctxt, ((0,0),(0,0)), "Registry error: "+err);	spawn tkwin(ctxt, matches, cmds, title);	} mainscr := array[] of {	"frame .f",	"frame .f.flb",	"listbox .f.flb.lb1 -yscrollcommand {.f.flb.sb1 set} -selectmode single -bg white -selectbackground blue -font /fonts/charon/plain.normal.font",	"bind .f.flb.lb1 <Double-Button-1> {send butchan double %y}",	"scrollbar .f.flb.sb1 -command {.f.flb.lb1 yview}",	"pack .f.flb.sb1 -fill y -side left",	"pack .f.flb.lb1 -fill both -expand 1",	"frame .f.fb",	"pack .f.flb -fill both -expand 1 -side top",	"pack .f.fb",	"pack .f -fill both -expand 1",}; errscr := array[] of {	"frame .f",	"frame .f.fl",	"label .f.fl.l1 -text {} -font /fonts/charon/plain.normal.font ",	"label .f.fl.l2 -text {Please try again later} -font /fonts/charon/plain.normal.font",	"pack .f.fl.l1 .f.fl.l2 -side top",	"button .f.b -text { Close } -command {send butchan exit} "+		"-font /fonts/charon/bold.normal.font",	"grid .f.fl -row 0 -column 0 -padx 10 -pady 5",	"grid .f.b -row 1 -column 0 -pady 5",	"pack .f",}; tkwin(ctxt: ref Draw->Context, lsrv: list of ref Service, cmds: array of (string, string), title: string){	(top, titlectl) := tkclient->toplevel(ctxt, "", "Find "+title, tkclient->Appl);	butchan := chan of string;	tk->namechan(top, butchan, "butchan");	if (lsrv == nil) {		tkcmds(top, errscr);		tkcmd(top, ".f.fl.l1 configure -text {Could not find "+title+"}");	}	else {		tkcmds(top, mainscr);		for (tmp := lsrv; tmp != nil; tmp = tl tmp)			tkcmd(top, ".f.flb.lb1 insert end {"+(hd tmp).attrs.get("name")+"}");		for (i := 0; i < len cmds; i++) {			si := string i;			tkcmd(top, "button .f.fb.b"+si+" -font /fonts/charon/bold.normal.font "+			"-text {"+cmds[i].t0+"} -command {send butchan go "+si+"}");			tkcmd(top, "grid .f.fb.b"+si+" -row 0 -column "+si+" -padx 5 -pady 5");		}		tkcmd(top, ".f.flb.lb1 selection set 0");		tkcmd(top, "pack propagate . 0");	}	tkclient->onscreen(top, nil);	tkclient->startinput(top, "kbd"::"ptr"::nil);	for(;;) alt {		s := <-top.ctxt.kbd =>			tk->keyboard(top, s);		s := <-top.ctxt.ptr =>			tk->pointer(top, *s);		inp := <- butchan =>			(nil, lst) := sys->tokenize(inp, " \t\n");			case hd lst {				"exit" =>					return;				"go" =>					n := int hd tl lst;					id := tkcmd(top, ".f.flb.lb1 curselection");					if (id != nil)						connect(ctxt, lsrv, cmds[n].t1 :: nil, tk->rect(top, ".",0), int id);				"double" =>					y := hd tl lst;					id := int tkcmd(top, ".f.flb.lb1 nearest "+y);					connect(ctxt, lsrv, cmds[0].t1 :: nil, tk->rect(top, ".",0), id);			}		s := <-top.ctxt.ctl or		s = <-top.wreq or		s = <- titlectl =>			if (s == "exit")				exit;			else				tkclient->wmctl(top, s);	}} connect(ctxt: ref Draw->Context, lsrv: list of ref Service, argv: list of string, r: Rect, id: int){	for (tmp := lsrv; tmp != nil; tmp = tl tmp) {		if (id-- == 0) {			spawn mountit(ctxt, hd tmp, argv, r);			break;		}	}} tkcmd(top: ref Tk->Toplevel, cmd: string): string{	e := tk->cmd(top, cmd);	if (e != "" && e[0] == '!') sys->print("tk error: '%s': %s\n",cmd,e);	return e;} tkcmds(top: ref Tk->Toplevel, cmds: array of string){	for (i := 0; i < len cmds; i++)		tkcmd(top, cmds[i]);} mountit(ctxt: ref Draw->Context, srv: ref Registries->Service, argv: list of string, r: Rect){	sys->pctl(Sys->FORKNS| Sys->NEWPGRP, nil);	attached := srv.attach(nil,nil);	if (attached != nil) {		if (sys->mount(attached.fd, nil, "/n/client", sys->MREPL, nil) != -1) {			sh := load Sh Sh->PATH;			if (sh == nil)				badmod(Sh->PATH);			sys->chdir("/n/client");			err := sh->run(ctxt, argv);			if (err != nil)				error(ctxt, r, "failed to run: "+err);					}		else			error(ctxt, r, sys->sprint("failed to mount: %r"));				}	else		error(ctxt, r, sys->sprint("could not connect"));} stderr(): ref Sys->FD{	return sys->fildes(2);} badmod(path: string){	sys->fprint(stderr(), "Find: cannot load %s: %r\n", path);	exit;} errorwin := array[] of {	"frame .f",	"label .f.l -font /fonts/charon/plain.normal.font",	"button .f.b -text {Ok} -font /fonts/charon/bold.normal.font "+		"-command {send butchan ok}",	"pack .f.l .f.b -side top -padx 5 -pady 5",	"pack .f",}; error(ctxt: ref Draw->Context, oldr: Draw->Rect, errstr: string){	(top, titlectl) := tkclient->toplevel(ctxt, "", "Error", tkclient->Appl);	butchan := chan of string;	tk->namechan(top, butchan, "butchan");	tkcmds(top, errorwin);	tkcmd(top, ".f.l configure -text {"+errstr+"}");	r := tk->rect(top, ".", 0);	newx := ((oldr.dx() - r.dx())/2) + oldr.min.x;	if (newx < 0)		newx = 0;	newy := ((oldr.dy() - r.dy())/2) + oldr.min.y;	if (newy < 0)		newy = 0;	tkcmd(top, ". configure -x "+string newx+" -y "+string newy);	tkclient->onscreen(top, "exact");	tkclient->startinput(top, "kbd"::"ptr"::nil);	for(;;) alt {		s := <-top.ctxt.kbd =>			tk->keyboard(top, s);		s := <-top.ctxt.ptr =>			tk->pointer(top, *s);		<- butchan =>			tkclient->wmctl(top, "exit");		s := <-top.ctxt.ctl or		s = <-top.wreq or		s = <- titlectl =>			tkclient->wmctl(top, s);	}}