512 lines · 10.2 KB · C
RawDownload
#include "a.h" static longdirlist(Dirpanel *p, Dir **d){	long n; 	n = dirmodelmarklist(p->model, d);	if(n == 0){		n = dirpanelselectedindex(p);		if(n == 0 && !p->model->isroot) /* up dir */			return 0;		*d = emalloc(sizeof(Dir));		**d = dirmodelgetdir(p->model, n);		n = 1;	}	return n;} static voidcmdhelp(void){	textset(text, "Help", help, strlen(help));	setmode(Mhelp);} static voidcmdview(void){	Dirpanel *p;	Dir d;	char *s, *t; 	p = dirviewcurrentpanel(dview);	d = dirmodelgetdir(p->model, dirpanelselectedindex(p));	if(d.qid.type&QTDIR){		p->cursor = 0;		p->offset = 0;		dirmodelcd(p->model, d.name);	}else{		t = smprint("%s/%s", p->model->path, d.name);		s = slurp(t);		textset(text, t, s, strlen(s));		setmode(Mview);	}} static voidcmdplumb(void){	Dirpanel *p;	Dir d;	int fd;	char buf[1024];		p = dirviewcurrentpanel(dview);	d = dirmodelgetdir(p->model, dirpanelselectedindex(p));	fd = plumbopen("send", OWRITE|OCEXEC);	snprint(buf, sizeof buf, "%s/%s", p->model->path, d.name);	if(d.qid.type&QTDIR)		plumbsendtext(fd, "nc", nil, nil, buf);	else		plumbsendtext(fd, "nc", nil, p->model->path, buf);	close(fd);} static voidcmdcopy(void){	Dirpanel *p, *o;	Dir *d;	int nd, n;	char buf[1024] = {0};		p = dirviewcurrentpanel(dview);	o = dirviewotherpanel(dview);	if(dirmodeleq(p->model, o->model)){		errormessage("cannot copy files to the same directory.", mc, kc);		return;	}	nd = dirlist(p, &d);	if(nd == 1)		snprint(buf, sizeof buf, "copy %s '%s' to '%s' ?", 			(d[0].qid.type&QTDIR) ? "directory" : "file", d[0].name, o->model->path);	else		snprint(buf, sizeof buf, "copy %d files/directories ?", nd);	if(message(Dconfirm, buf, mc, kc) == Bno)		return;	for(n = 0; n < nd; n++){		if(cp(p->model->path, d[n], o->model->path, nil) < 0){			errormessage("copy failed: %r", mc, kc);			return;		}	}	dirmodelreload(o->model);} static voidcmdrenmov(void){	Dirpanel *p, *o;	Dir *d, null;	char opath[1024] = {0}, buf[255] = {0};	int i, n; 	p = dirviewcurrentpanel(dview);	o = dirviewotherpanel(dview);	n = dirlist(p, &d);	if(dirmodeleq(p->model, o->model)){		if(n > 1){			errormessage("cannot rename multiple files/directories.", mc, kc);			return;		}		snprint(buf, sizeof buf, d[0].name);		if(input("rename to:", buf, sizeof buf, mc, kc) <= 0)			return;		if(strcmp(buf, d[0].name) == 0){			errormessage("target file name should be different.", mc, kc);			return;		}		if(d[0].qid.type&QTDIR){			if(cp(p->model->path, d[0], o->model->path, buf) < 0){				errormessage("rename failed: %r", mc, kc);				return;			}			if(rm(p->model->path, d[0]) < 0){				errormessage("rename failed: %r", mc, kc);				return;			}		}else{			snprint(opath, sizeof opath, "%s/%s", p->model->path, d[0].name);			nulldir(&null);			null.name = buf;			if(dirwstat(opath, &null) < 0){				errormessage("rename failed: %r", mc, kc);				return;			}		}	}else{		if(n == 1)			snprint(buf, sizeof buf, "move %s '%s' to '%s' ?", 				(d[0].qid.type&QTDIR) ? "directory" : "file", d[0].name, o->model->path);		else			snprint(buf, sizeof buf, "move %d files/directories ?", n);		if(message(Dconfirm, buf, mc, kc) == Bno)			return;		for(i = 0; i < n; i++){			if(cp(p->model->path, d[i], o->model->path, nil) < 0){				errormessage("move failed: %r", mc, kc);				return;			}			if(rm(p->model->path, d[i]) < 0){				errormessage("move failed: %r", mc, kc);				return;			}		}	}	dirmodelreload(p->model);	dirmodelreload(o->model);			return;	} static voidcmdmkdir(void){	Dirpanel *p;	char buf[1024] = {0}; 	p = dirviewcurrentpanel(dview);	if(input("create directory:", buf, sizeof buf, mc, kc) <= 0)		return;	if(mkdir(p->model->path, buf) < 0){		errormessage("directory creation failed: %r", mc, kc);		return;	}	dirmodelreload(p->model);	dirmodelreloadifsame(p->model, dirviewotherpanel(dview)->model);} static voidcmddelete(void){	Dirpanel *p, *o;	Dir *d;	char buf[1024] = {0};	int i, n; 	p = dirviewcurrentpanel(dview);	o = dirviewotherpanel(dview);	n = dirlist(p, &d);	if(n == 1)		snprint(buf, sizeof buf, "delete %s '%s' ?", (d[0].qid.type&QTDIR) ? "directory" : "file", d[0].name);	else		snprint(buf, sizeof buf, "delete %d files/directories ?", n);	if(message(Dconfirm, buf, mc, kc) == Bno)		return;	for(i = 0; i < n; i++){		if(rm(p->model->path, d[i]) < 0){			errormessage("delete failed: %r", mc, kc);			return;		}	}	dirmodelreload(p->model);	dirmodelreloadifsame(p->model, o->model);} static voidcmdquit(void){	threadexitsall(nil);} static voidcmdswitchfocus(void){	dview->leftp->focused = !dview->leftp->focused;	dview->rightp->focused = !dview->rightp->focused;	dirviewredraw(dview);	sendul(dview->c, 1);} static voidcmdreload(void){	Dirpanel *p;		p = dirviewcurrentpanel(dview);	dirmodelreload(p->model);} static voidcmdcd(void){	Dirpanel *p;	char buf[1024] = {0}; 	p = dirviewcurrentpanel(dview);	if(input("go to directory:", buf, sizeof buf, mc, kc) <= 0)		return;	dirpanelresetcursor(p);	dirmodelcd(p->model, buf);} static voidcmdcdo(void){	Dirpanel *p;	char buf[1024] = {0}; 	p = dirviewotherpanel(dview);	if(input("go to directory:", buf, sizeof buf, mc, kc) <= 0)		return;	dirpanelresetcursor(p);	dirmodelcd(p->model, buf);} static voidcmdcdmatch(void){	Dirpanel *o;	char *path; 	path = dirviewcurrentpanel(dview)->model->path;	o = dirviewotherpanel(dview);	dirpanelresetcursor(o);	dirmodelcd(o->model, path);} static voidcmdselectgroup(void){	Dirpanel *p;	Dir d;	int i;	char buf[256] = {0}; 	p = dirviewcurrentpanel(dview);	if(input("select pattern:", buf, sizeof(buf), mc, kc) <= 0)		return;	for(i = !p->model->isroot; i < dirmodelcount(p->model); i++){		d = dirmodelgetdir(p->model, i);		p->model->sel[i] = match(d.name, buf);	}	dirpanelredrawnotify(p);} static voidcmdunselectgroup(void){	Dirpanel *p;	Dir d;	int i, r;	char buf[256] = {0}; 	p = dirviewcurrentpanel(dview);	if(input("unselect pattern:", buf, sizeof(buf), mc, kc) <= 0)		return;	r = 0;	for(i = !p->model->isroot; i < dirmodelcount(p->model); i++){		d = dirmodelgetdir(p->model, i);		if(match(d.name, buf) && p->model->sel[i]){			p->model->sel[i] = 0;			r = 1;		}	}	if(r)		dirpanelredrawnotify(p);} static voidcmdinvertselection(void){	Dirpanel *p;	int i; 	p = dirviewcurrentpanel(dview);	for(i = !p->model->isroot; i < dirmodelcount(p->model); i++)		p->model->sel[i] = !p->model->sel[i];	dirpanelredrawnotify(p);} static voidcmdselect(void){	Dirpanel *p;	Dir d;	int i; 	p = dirviewcurrentpanel(dview);	i = p->offset + p->cursor;	d = dirmodelgetdir(p->model, i);	if(i == 0 && !p->model->isroot)		return;	p->model->sel[i] = !p->model->sel[i];	if(p->cursor == p->nlines - 1 && (p->offset + p->nlines >= dirmodelcount(p->model)))		goto Draw;	if(p->offset + p->cursor + 1 >= dirmodelcount(p->model))		goto Draw;	if(p->cursor == p->nlines - 1){		p->offset += p->nlines;		p->cursor = 0;	}else{		p->cursor += 1;	}Draw:	dirpanelredrawnotify(p);} static voidcmdfilter(void){	Dirpanel *p;	char buf[256] = {0}; 	p = dirviewcurrentpanel(dview);	if(input("filter pattern:", buf, sizeof buf, mc, kc) <= 0){		if(p->model->filter != nil){			dirpanelresetcursor(p);			dirmodelfilter(p->model, nil);		}	}else{		dirpanelresetcursor(p);		dirmodelfilter(p->model, buf);	}} static voidcmdup(void){	Dirpanel *p; 	p = dirviewcurrentpanel(dview);	if(p->cursor == 0 && p->offset == 0)		return;	if(p->cursor == 0){		p->offset -= p->nlines;		if(p->offset < 0)			p->offset = 0;		p->cursor = p->nlines -1;	}else{		p->cursor -= 1;	}	dirpanelredrawnotify(p);} static voidcmddown(void){	Dirpanel *p; 	p = dirviewcurrentpanel(dview);	if(p->cursor == p->nlines - 1 && (p->offset + p->nlines >= dirmodelcount(p->model)))		return;	if(p->offset + p->cursor + 1 >= dirmodelcount(p->model))		return;	if(p->cursor == p->nlines - 1){		p->offset += p->nlines;		p->cursor = 0;		if(dirmodelcount(p->model)-p->offset < p->nlines)			p->offset = dirmodelcount(p->model) - p->nlines;	}else{		p->cursor += 1;	}	dirpanelredrawnotify(p);} static voidcmdhome(void){	Dirpanel *p; 	p = dirviewcurrentpanel(dview);	dirpanelresetcursor(p);	dirpanelredrawnotify(p);} static voidcmdend(void){	Dirpanel *p; 	p = dirviewcurrentpanel(dview);	p->offset = p->nlines * (dirmodelcount(p->model) / p->nlines);	if(dirmodelcount(p->model)-p->offset < p->nlines)		p->offset = dirmodelcount(p->model) - p->nlines;	if(p->offset < 0)		p->offset = 0;	p->cursor = dirmodelcount(p->model) - p->offset - 1;	dirpanelredrawnotify(p);} static voidcmdpageup(void){	Dirpanel *p; 	p = dirviewcurrentpanel(dview);	if(p->offset == 0 && p->cursor == 0)		return;	if(p->offset == 0)		p->cursor = 0;	else		p->offset -= p->nlines;	if(p->offset < 0)		p->offset = 0;	dirpanelredrawnotify(p);} static voidcmdpagedown(void){	Dirpanel *p;	int end; 	p = dirviewcurrentpanel(dview);	end = dirmodelcount(p->model) - p->offset - 1;	if(p->offset + p->nlines >= dirmodelcount(p->model) && p->cursor == end)		return;	if(p->offset + p->nlines < dirmodelcount(p->model)){		p->offset += p->nlines;		if(dirmodelcount(p->model)-p->offset < p->nlines)			p->offset = dirmodelcount(p->model) - p->nlines;			}else		p->cursor = end;	if(p->cursor > end)		p->cursor = end;	dirpanelredrawnotify(p);} Binding	dirviewbindings[] = {	{ KF|1,		cmdhelp },	{ KF|3,		cmdview },	{ KF|4,		cmdplumb },	{ KF|5,		cmdcopy },	{ KF|6,		cmdrenmov },	{ KF|7,		cmdmkdir },	{ KF|8,		cmddelete },	{ KF|10,	cmdquit },	{ '\t',		cmdswitchfocus },	{ 'r',		cmdreload },	{ 'c',		cmdcd },	{ 'C',		cmdcdo },	{ '=',		cmdcdmatch },	{ '\n',		cmdview },	{ '+',		cmdselectgroup },	{ '-',		cmdunselectgroup },	{ '*',		cmdinvertselection },	{ Kins,		cmdselect },	{ 'f',		cmdfilter },	{ Kup,		cmdup },	{ Kdown,	cmddown },	{ Khome,	cmdhome },	{ Kend,		cmdend },	{ Kpgup,	cmdpageup },	{ Kpgdown,	cmdpagedown },	nil}; voidsetupdirviewbindings(void)

Lines 1–500 of 512.