From c1973705501d05e906bd14a0dc25cc4472b5871f Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 9 Feb 2004 19:32:18 +0000 Subject: completion, pageup/pagedown --- src/cmd/acme/acme.c | 2 + src/cmd/acme/cols.c | 1 + src/cmd/acme/mkfile | 2 +- src/cmd/acme/text.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/cmd/acme/wind.c | 5 ++ 5 files changed, 139 insertions(+), 7 deletions(-) (limited to 'src/cmd') diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c index d9412c4e..0ac66e12 100644 --- a/src/cmd/acme/acme.c +++ b/src/cmd/acme/acme.c @@ -138,6 +138,7 @@ threadmain(int argc, char *argv[]) d = display; font = d->defaultfont; +//assert(font); reffont.f = font; reffonts[0] = &reffont; @@ -790,6 +791,7 @@ rfget(int fix, int save, int setfont, char *name) } f = openfont(display, name); if(f == nil){ + fprint(2, "can't open font file %s: %r\n", name); warning(nil, "can't open font file %s: %r\n", name); return nil; } diff --git a/src/cmd/acme/cols.c b/src/cmd/acme/cols.c index 0e6ff409..14a715b3 100644 --- a/src/cmd/acme/cols.c +++ b/src/cmd/acme/cols.c @@ -102,6 +102,7 @@ coladd(Column *c, Window *w, Window *clone, int y) w->col = c; winresize(w, r, FALSE); } +//assert(w->body.w == w); w->tag.col = c; w->tag.row = c->row; w->body.col = c; diff --git a/src/cmd/acme/mkfile b/src/cmd/acme/mkfile index f92f903a..cb72fea0 100644 --- a/src/cmd/acme/mkfile +++ b/src/cmd/acme/mkfile @@ -36,6 +36,6 @@ UPDATE=\ <$PLAN9/src/mkone -LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11 +LDFLAGS=$LDFLAGS -lcomplete -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11 edit.$O ecmd.$O elog.$O: edit.h diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c index c38773ea..0b9f7cc6 100644 --- a/src/cmd/acme/text.c +++ b/src/cmd/acme/text.c @@ -8,11 +8,13 @@ #include #include #include +#include #include "dat.h" #include "fns.h" Image *tagcols[NCOL]; Image *textcols[NCOL]; +static Rune Ldot[] = { '.', 0 }; enum{ TABDIR = 3 /* width of tabs in directory windows */ @@ -526,24 +528,136 @@ textbswidth(Text *t, Rune c) return t->q0-q; } +int +textfilewidth(Text *t, uint q0, int oneelement) +{ + uint q; + Rune r; + + q = q0; + while(q > 0){ + r = textreadc(t, q-1); + if(r<=' ') + break; + if(oneelement && r=='/') + break; + --q; + } + return q0-q; +} + +Rune* +textcomplete(Text *t) +{ + int i, nstr, npath; + uint q; + Rune tmp[200]; + Rune *str, *path; + Rune *rp; + Completion *c; + char *s, *dirs; + Runestr dir; + + /* control-f: filename completion; works back to white space or / */ + if(t->q0file->b.nc && textreadc(t, t->q0)>' ') /* must be at end of word */ + return nil; + nstr = textfilewidth(t, t->q0, TRUE); + str = runemalloc(nstr); + npath = textfilewidth(t, t->q0-nstr, FALSE); + path = runemalloc(npath); + + c = nil; + rp = nil; + dirs = nil; + + q = t->q0-nstr; + for(i=0; iq0-nstr-npath; + for(i=0; i0 && path[0]=='/') + dir = (Runestr){path, npath}; + else{ + dir = dirname(t, nil, 0); + if(dir.nr + 1 + npath > nelem(tmp)){ + free(dir.r); + goto Return; + } + if(dir.nr == 0){ + dir.nr = 1; + dir.r = runestrdup(Ldot); + } + runemove(tmp, dir.r, dir.nr); + tmp[dir.nr] = '/'; + runemove(tmp+dir.nr+1, path, npath); + free(dir.r); + dir.r = tmp; + dir.nr += 1+npath; + dir = cleanrname(dir); + } + + s = smprint("%.*S", nstr, str); + dirs = smprint("%.*S", dir.nr, dir.r); + c = complete(dirs, s); + free(s); + if(c == nil){ + warning(nil, "error attempting completion: %r\n"); + goto Return; + } + + if(!c->advance){ + warning(nil, "%.*S%s%.*S*\n", + dir.nr, dir.r, + dir.nr>0 && dir.r[dir.nr-1]!='/' ? "/" : "", + nstr, str); + for(i=0; infile; i++) + warning(nil, " %s\n", c->filename[i]); + } + + if(c->advance) + rp = runesmprint("%s", c->string); + else + rp = nil; + Return: + freecompletion(c); + free(dirs); + free(str); + free(path); + return rp; +} + void texttype(Text *t, Rune r) { uint q0, q1; int nnb, nb, n, i; + int nr; + Rune *rp; Text *u; if(t->what!=Body && r=='\n') return; + nr = 1; + rp = &r; switch(r){ - case Kdown: case Kleft: + if(t->q0 > 0) + textshow(t, t->q0-1, t->q0-1, TRUE); + return; case Kright: + if(t->q1 < t->file->b.nc) + textshow(t, t->q1+1, t->q1+1, TRUE); + return; + case Kdown: + case Kpgdown: n = t->fr.maxlines/2; q0 = t->org+frcharofpt(&t->fr, Pt(t->fr.r.min.x, t->fr.r.min.y+n*t->fr.font->height)); textsetorigin(t, q0, FALSE); return; case Kup: + case Kpgup: n = t->fr.maxlines/2; q0 = textbacknl(t, t->org, n); textsetorigin(t, q0, FALSE); @@ -561,6 +675,13 @@ texttype(Text *t, Rune r) } textshow(t, t->q0, t->q0, 1); switch(r){ + case 0x06: /* ^F: complete */ + case Kins: + rp = textcomplete(t); + if(rp == nil) + return; + nr = runestrlen(rp); + break; /* fall through to normal insertion case */ case 0x1B: if(t->eq0 != ~0) textsetselect(t, t->eq0, t->q0); @@ -623,16 +744,19 @@ texttype(Text *t, Rune r) u->cq0 = t->q0; else if(t->q0 != u->cq0+u->ncache) error("text.type cq1"); - textinsert(u, t->q0, &r, 1, FALSE); + textinsert(u, t->q0, rp, nr, FALSE); if(u != t) textsetselect(u, u->q0, u->q1); - if(u->ncache == u->ncachealloc){ - u->ncachealloc += 10; + if(u->ncache+nr > u->ncachealloc){ + u->ncachealloc += 10 + nr; u->cache = runerealloc(u->cache, u->ncachealloc); } - u->cache[u->ncache++] = r; + runemove(u->cache+u->ncache, rp, nr); + u->ncache += nr; } - textsetselect(t, t->q0+1, t->q0+1); + if(rp != &r) + free(rp); + textsetselect(t, t->q0+nr, t->q0+nr); if(r=='\n' && t->w!=nil) wincommit(t->w, t); } diff --git a/src/cmd/acme/wind.c b/src/cmd/acme/wind.c index a9a1c4bf..06a815e9 100644 --- a/src/cmd/acme/wind.c +++ b/src/cmd/acme/wind.c @@ -45,6 +45,7 @@ wininit(Window *w, Window *clone, Rectangle r) filereset(w->tag.file); textsetselect(&w->tag, nc, nc); } +//assert(w->body.w == w); r1 = r; r1.min.y += font->height + 1; if(r1.max.y < r1.min.y) @@ -57,6 +58,7 @@ wininit(Window *w, Window *clone, Rectangle r) rf = rfget(FALSE, FALSE, FALSE, clone->body.reffont->f->name); }else rf = rfget(FALSE, FALSE, FALSE, nil); +//assert(w->body.w == w); f = fileaddtext(f, &w->body); w->body.what = Body; textinit(&w->body, f, r1, rf, textcols); @@ -72,6 +74,7 @@ wininit(Window *w, Window *clone, Rectangle r) draw(screen, br, button, nil, button->r.min); w->filemenu = TRUE; w->maxlines = w->body.fr.maxlines; +//assert(w->body.w == w); if(clone){ w->dirty = clone->dirty; textsetselect(&w->body, clone->body.q0, clone->body.q1); @@ -138,6 +141,7 @@ winlock(Window *w, int owner) int i; File *f; +fprint(2, "winlock %p %d %lux\n", w, owner, getcallerpc(&w)); f = w->body.file; for(i=0; intext; i++) winlock1(f->text[i]->w, owner); @@ -149,6 +153,7 @@ winunlock(Window *w) int i; File *f; +fprint(2, "winunlock %p %lux\n", w, getcallerpc(&w)); f = w->body.file; for(i=0; intext; i++){ w = f->text[i]->w; -- cgit v1.2.3