diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/abaco/exec.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/abaco/exec.c')
-rwxr-xr-x | sys/src/cmd/abaco/exec.c | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/sys/src/cmd/abaco/exec.c b/sys/src/cmd/abaco/exec.c new file mode 100755 index 000000000..59c8f03d2 --- /dev/null +++ b/sys/src/cmd/abaco/exec.c @@ -0,0 +1,531 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <memdraw.h> +#include <thread.h> +#include <cursor.h> +#include <mouse.h> +#include <keyboard.h> +#include <frame.h> +#include <plumb.h> +#include <html.h> +#include "dat.h" +#include "fns.h" + +void del(Text *, Text *, int, int, Rune *, int); +void delcol(Text *, Text *, int, int, Rune *, int); +void cut(Text *, Text *, int, int, Rune *, int); +void exit(Text *, Text *, int, int, Rune *, int); +void get(Text *, Text *, int, int, Rune *, int); +void go(Text *,Text *, int, int, Rune *, int); +void google(Text *,Text *, int, int, Rune *, int); +void new(Text*, Text *, int, int, Rune *, int); +void newcol(Text*, Text *, int, int, Rune *, int); +void paste(Text *, Text *, int, int, Rune *, int); +void sort(Text *, Text *, int, int, Rune *, int); +void stop(Text *, Text *, int, int, Rune *, int); +void debug(Text *, Text *, int, int, Rune *, int); + +typedef struct Exectab Exectab; +struct Exectab +{ + Rune *name; + void (*fn)(Text *, Text *, int, int, Rune *, int); + int flag1; + int flag2; +}; + +Exectab exectab[] = { + { L"Back", go, FALSE, XXX }, + { L"Cut", cut, TRUE, TRUE }, + { L"Debug", debug, XXX, XXX }, + { L"Del", del, XXX, XXX }, + { L"Delcol", delcol, FALSE, TRUE }, + { L"Exit", exit, XXX, XXX }, + { L"Get", get, XXX, XXX }, + { L"Google", google, XXX, XXX }, + { L"New", new, XXX, XXX }, + { L"Newcol", newcol, XXX, XXX }, + { L"Next", go, TRUE, XXX }, + { L"Paste", paste, TRUE, XXX }, + { L"Snarf", cut, TRUE, FALSE }, + { L"Stop", stop, XXX, XXX }, + { L"Sort", sort, XXX, XXX }, + { nil, nil, 0, 0 }, +}; + +static +Exectab* +lookup(Rune *r, int n) +{ + Exectab *e; + int nr; + + r = skipbl(r, n, &n); + if(n == 0) + return nil; + findbl(r, n, &nr); + nr = n-nr; + for(e=exectab; e->name; e++) + if(runeeq(r, nr, e->name, runestrlen(e->name)) == TRUE) + return e; + return nil; +} + +int +isexecc(int c) +{ + if(isalnum(c)) + return 1; + return c=='<' || c=='|' || c=='>'; +} + +void +execute(Text *t, uint aq0, uint aq1, Text *) +{ + uint q0, q1; + Rune *r, *s; + Exectab *e; + int c, n; + + q0 = aq0; + q1 = aq1; + if(q1 == q0){ /* expand to find word (actually file name) */ + /* if in selection, choose selection */ + if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){ + q0 = t->q0; + q1 = t->q1; + }else{ + while(q1<t->rs.nr && isexecc(c=t->rs.r[q1]) && c!=':') + q1++; + while(q0>0 && isexecc(c=t->rs.r[q0-1]) && c!=':') + q0--; + if(q1 == q0) + return; + } + } + r = runemalloc(q1-q0); + runemove(r, t->rs.r+q0, q1-q0); + e = lookup(r, q1-q0); + if(e){ + s = skipbl(r, q1-q0, &n); + s = findbl(s, n, &n); + s = skipbl(s, n, &n); + (*e->fn)(t, seltext, e->flag1, e->flag2, s, n); + } + free(r); +} + +void +newcol(Text *et, Text *, int, int, Rune *, int) +{ + Column *c; + + c = rowadd(et->row, nil, -1); + if(c) + winsettag(coladd(c, nil, nil, -1)); +} + +void +delcol(Text *t, Text *, int, int, Rune *, int) +{ + Column *c; + + c = t->col; + if(c==nil || colclean(c)==0) + return; + + rowclose(c->row, c, TRUE); +} + +void +del(Text *et, Text *, int flag1, int, Rune *, int) +{ + if(et->w==nil) + return; + + if(flag1 || winclean(et->w, FALSE)) + colclose(et->col, et->w, TRUE); +} + +void +sort(Text *et, Text *, int, int, Rune *, int) +{ + if(et->col) + colsort(et->col); +} + +void +exit(Text *, Text *, int, int, Rune *, int) +{ + sendul(cexit, 0); + threadexits(nil); +} + +void +debug(Text *, Text *, int, int, Rune *, int) +{ + Column *c; + int i, j; + + for(j=0; j<row.ncol; j++){ + c = row.col[j]; + for(i=0; i<c->nw; i++){ + fprint(2, "Col: %d; Win: %d\n", j, i); + windebug(c->w[i]); + } + } +} + +void +stop(Text *t, Text *, int, int, Rune *, int) +{ + if(t==nil || t->w==nil) + return; + + pageabort(&t->w->page); +} + +void +get(Text *t, Text *, int, int, Rune *, int) +{ + Window *w; + int dohist; + + if(t==nil || t->w==nil) + return; + w = t->w; + if(w->url.rs.nr == 0) + return; + + dohist = FALSE; + if(w->page.url==nil || runestreq(w->page.url->act, w->url.rs)==FALSE) + dohist = TRUE; + + pageget(&w->page, &w->url.rs, nil, HGet, dohist); +} + +void +go(Text *et, Text *t, int isnext, int, Rune *, int) +{ + if(et!=nil && et->w!=nil) + t = et; + if(t==nil || t->w==nil) + return; + + wingohist(t->w, isnext); +} + +void +cut(Text *, Text *t, int dosnarf, int docut, Rune *, int) +{ + Runestr rs; + uint u; + + if(selpage){ + if(dosnarf && !docut && !eqpt(selpage->top, selpage->bot)) + pagesnarf(selpage); + return; + } + if(t==nil){ + /* can only happen if seltext == nil */ + return; + } + if(t->q0 > t->q1){ + u = t->q0; + t->q0 = t->q1; + t->q1 =u; + } + + if(t->q0 == t->q1) + return; + + if(dosnarf){ + rs.nr = t->q1-t->q0; + rs.r = runemalloc(rs.nr); + runemove(rs.r, t->rs.r+t->q0, rs.nr); + putsnarf(&rs); + closerunestr(&rs); + } + if(docut){ + textdelete(t, t->q0, t->q1); + textsetselect(t, t->q0, t->q0); + if(t->w) + textscrdraw(t); + }else if(dosnarf) /* Snarf command */ + argtext = t; +} + +void +paste(Text *, Text *t, int selectall, int, Rune *, int) +{ + Runestr rs; + uint q1; + + if(t == nil) + return; + + getsnarf(&rs); + if(rs.nr == 0) + return; + + cut(t, t, FALSE, TRUE, nil, 0); + textinsert(t, t->q0, rs.r, rs.nr); + q1 = t->q0+rs.nr; + if(selectall) + textsetselect(t, t->q0, q1); + else + textsetselect(t, q1, q1); + if(t->w) + textscrdraw(t); + + closerunestr(&rs); +} + +typedef struct Expand Expand; + +struct Expand +{ + uint q0; + uint q1; + Rune *name; + int nname; + int jump; + union{ + Text *at; + Rune *ar; + }; + int (*agetc)(void*, uint); + int a0; + int a1; +}; + +int +expand(Text *t, uint q0, uint q1, Expand *e) +{ + memset(e, 0, sizeof *e); + + /* if in selection, choose selection */ + e->jump = TRUE; + if(q1==q0 && t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){ + q0 = t->q0; + q1 = t->q1; + if(t->what == Tag) + e->jump = FALSE; + } + if(q0 == q1){ + while(q1<t->rs.nr && isalnum(t->rs.r[q1])) + q1++; + while(q0>0 && isalnum(t->rs.r[q0-1])) + q0--; + } + e->q0 = q0; + e->q1 = q1; + return q1 > q0; +} + +void +look3(Text *t, uint q0, uint q1) +{ + Expand e; + Text *ct; + Runestr rs; + char buf[32]; + Rune *r, c; + uint p; + int n; + + ct = seltext; + if(ct == nil) + ct = seltext = t; + if(expand(t, q0, q1, &e) == FALSE) + return; + if(plumbsendfd >= 0){ + /* send whitespace-delimited word to plumber */ + buf[0] = '\0'; + if(q1 == q0){ + if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){ + q0 = t->q0; + q1 = t->q1; + }else{ + p = q0; + while(q0>0 && (c=t->rs.r[q0-1])!=L' ' && c!=L'\t' && c!=L'\n') + q0--; + while(q1<t->rs.nr && (c=t->rs.r[q1])!=L' ' && c!=L'\t' && c!=L'\n') + q1++; + if(q1 == q0) + return; + sprint(buf, "click=%d", p-q0); + } + } + rs.r = runemalloc(q1-q0); + runemove(rs.r, t->rs.r+q0, q1-q0); + rs.nr = q1-q0; + if(plumbrunestr(&rs, buf) >= 0){ + closerunestr(&rs); + return; + } + /* plumber failed to match; fall through */ + } + if(t == ct) + textsetselect(ct, e.q1, e.q1); + n = e.q1 - e.q0; + r = runemalloc(n); + runemove(r, t->rs.r+e.q0, n); + if(search(ct, r, n) && e.jump) + moveto(mousectl, addpt(frptofchar(ct, ct->p0), Pt(4, ct->font->height-4))); + + free(r); +} + +int +search(Text *ct, Rune *r, uint n) +{ + uint q, nb, maxn; + int around; + Rune *s, *b, *c; + + if(n==0 || n>ct->rs.nr || 2*n>RBUFSIZE) + return FALSE; + + maxn = max(n*2, RBUFSIZE); + s = runemalloc(RBUFSIZE); + b = s; + nb = 0; + b[nb] = 0; + around = 0; + q = ct->q1; + for(;;){ + if(q >= ct->rs.nr){ + q = 0; + around = 1; + nb = 0; + b[nb] = 0; + } + if(nb > 0){ + c = runestrchr(b, r[0]); + if(c == nil){ + q += nb; + nb = 0; + b[nb] = 0; + if(around && q>=ct->q1) + break; + continue; + } + q += (c-b); + nb -= (c-b); + b = c; + } + /* reload if buffer covers neither string nor rest of file */ + if(nb<n && nb!=ct->rs.nr-q){ + nb = ct->rs.nr-q; + if(nb >= maxn) + nb = maxn-1; + runemove(s, ct->rs.r+q, nb); + b = s; + b[nb] = '\0'; + } + /* this runeeq is fishy but the null at b[nb] makes it safe */ + if(runeeq(b, n, r, n) == TRUE){ + if(ct->w) + textshow(ct, q, q+n, 1); + else{ + ct->q0 = q; + ct->q1 = q+n; + } + seltext = ct; + free(s); + return TRUE; + } + if(around && q>=ct->q1) + break; + --nb; + b++; + q++; + } + free(s); + return FALSE; +} + +Window* +lookpage(Rune *s, int n) +{ + int i, j; + Window *w; + Column *c; + Page *p; + + /* avoid terminal slash on directories */ + if(n>1 && s[n-1] == '/') + --n; + for(j=0; j<row.ncol; j++){ + c = row.col[j]; + for(i=0; i<c->nw; i++){ + w = c->w[i]; + p = &w->page; + if(p->url && runeeq(p->url->src.r, p->url->src.nr, s, n)) + if(w->col != nil) + return w; + } + } + return nil; +} + +Window * +openpage(Page *p, Runestr *rs) +{ + Window *w; + + if(!validurl(rs->r)) + return nil; + + w = lookpage(rs->r, rs->nr); + if(w){ + p = &w->page; + if(!p->col->safe && Dy(p->r)==0) /* window is obscured by full-column window */ + colgrow(p->col, p->col->w[0], 1); + }else{ + w = makenewwindow(p); + winsettag(w); + pageget(&w->page, rs, nil, HGet, TRUE); + } + return w; +} + +void +plumblook(Plumbmsg *m) +{ + Runestr rs; + + if(m->ndata >= BUFSIZE){ + fprint(2, "insanely long file name (%d bytes) in plumb message (%.32s...)\n", m->ndata, m->data); + return; + } + if(m->data[0] == '\0') + return; + + bytetorunestr(m->data, &rs); + openpage(nil, &rs); + closerunestr(&rs); +} + +void +new(Text *et, Text *, int, int, Rune *, int) +{ + if(et->col != nil) + winsettag(coladd(et->col, nil, nil, -1)); +} + +void +google(Text *, Text *, int, int, Rune *arg, int narg) +{ + Runestr rs; + Rune *s; + + s = ucvt(arg); + rs.r = runesmprint("http://www.google.com/search?hl=en&ie=UTF-8&q=%.*S", narg, s); + rs.nr = runestrlen(rs.r); + openpage(nil, &rs); + free(s); + closerunestr(&rs); +} |