From a2db69c8bda889f30ea38dae5473689cde108458 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 7 Mar 2008 11:07:17 -0500 Subject: acme: revise multiline tag code --- src/cmd/acme/cols.c | 53 ++++++++++++++++++++++++++--------------------------- src/cmd/acme/mkfile | 16 ++++++++++++++++ src/cmd/acme/rows.c | 23 ++++++----------------- src/cmd/acme/text.c | 31 ++++--------------------------- src/cmd/acme/wind.c | 42 ++++++++++++++---------------------------- 5 files changed, 66 insertions(+), 99 deletions(-) diff --git a/src/cmd/acme/cols.c b/src/cmd/acme/cols.c index 31b2780f..be5a2aa8 100644 --- a/src/cmd/acme/cols.c +++ b/src/cmd/acme/cols.c @@ -53,7 +53,7 @@ coladd(Column *c, Window *w, Window *clone, int y) { Rectangle r, r1; Window *v; - int i, j, minht, t; + int i, j, minht, ymax; v = nil; r = c->r; @@ -72,31 +72,38 @@ coladd(Column *c, Window *w, Window *clone, int y) if(i < c->nw) i++; /* new window will go after v */ /* - * if v's too small, grow it first. + * if landing window (v) is too small, grow it first. */ minht = v->tag.fr.font->height+Border+1; j = 0; while(!c->safe || v->body.fr.maxlines<=3 || Dy(v->body.all) <= minht){ if(++j > 10){ -fprint(2, "oops: dy=%d\n", Dy(v->body.all)); + fprint(2, "coladd: bug dy=%d\n", Dy(v->body.all)); break; } colgrow(c, v, 1); } + + /* + * figure out where to split v to make room for w + */ if(i == c->nw) - t = c->r.max.y; + ymax = c->r.max.y; else - t = c->w[i]->r.min.y-Border; + ymax = c->w[i]->r.min.y-Border; y = min(y, v->body.all.min.y+Dy(v->body.all)/2); - if(t - y < minht) - y = t - minht; - if(y < v->body.all.min.y) - y = v->body.all.min.y; + y = min(y, ymax - minht); + y = max(y, v->body.all.min.y); + ymax = max(ymax, y+minht); r = v->r; - r.max.y = t; + r.max.y = ymax; + + /* + * redraw w + */ draw(screen, r, textcols[BACK], nil, ZP); r1 = r; - y = min(y, t-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1)); + y = min(y, ymax-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1)); r1.max.y = min(y, v->body.fr.r.min.y+v->body.fr.nlines*v->body.fr.font->height); r1.min.y = winresize(v, r1, FALSE, FALSE); r1.max.y = r1.min.y+Border; @@ -151,8 +158,8 @@ colclose(Column *c, Window *w, int dofree) windelete(w); winclose(w); } - memmove(c->w+i, c->w+i+1, (c->nw-i-1)*sizeof(Window*)); c->nw--; + memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*)); c->w = realloc(c->w, c->nw*sizeof(Window*)); if(c->nw == 0){ draw(screen, r, display->white, nil, ZP); @@ -219,8 +226,7 @@ colresize(Column *c, Rectangle r) r1.max.y = r.max.y; else r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r); - if(Dy(r1) < Border+font->height) - r1.max.y = r1.min.y + Border+font->height; + r1.max.y = max(r1.max.y, r1.min.y + Border+font->height); r2 = r1; r2.max.y = r2.min.y+Border; draw(screen, r2, display->black, nil, ZP); @@ -307,7 +313,7 @@ colgrow(Column *c, Window *w, int but) if(i==c->nw-1 || c->safe==FALSE) r.max.y = cr.max.y; else - r.max.y = c->w[i+1]->r.min.y-Border; + r.max.y = c->w[i+1]->r.min.y - Border; winresize(w, r, FALSE, TRUE); return; } @@ -342,7 +348,7 @@ colgrow(Column *c, Window *w, int but) } nnl = min(onl + max(min(5, w->taglines-1+w->maxlines), onl/2), tot); if(nnl < w->taglines-1+w->maxlines) - nnl = (w->taglines-1+w->maxlines+nnl)/2; + nnl = (w->taglines-1+w->maxlines + nnl)/2; if(nnl == 0) nnl = 2; dnl = nnl - onl; @@ -400,7 +406,7 @@ colgrow(Column *c, Window *w, int but) if(Dy(r) < Dy(w->tagtop)+1+h+Border) r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border; /* draw window */ - winresize(w, r, c->safe, TRUE); + r.max.y = winresize(w, r, c->safe, i==c->nw-1); if(i < c->nw-1){ r.min.y = r.max.y; r.max.y += Border; @@ -417,7 +423,7 @@ colgrow(Column *c, Window *w, int but) r.max.y = y1+Dy(v->tagtop); if(nl[j]) r.max.y += 1 + nl[j]*v->body.fr.font->height; - y1 = winresize(v, r, c->safe, j+1==c->nw); + y1 = winresize(v, r, c->safe, j==c->nw-1); if(j < c->nw-1){ /* no border on last window */ r.min.y = y1; r.max.y += Border; @@ -425,12 +431,6 @@ colgrow(Column *c, Window *w, int but) y1 = r.max.y; } } -/* - r = w->r; - r.min.y = y1; - r.max.y = c->r.max.y; - draw(screen, r, textcols[BACK], nil, ZP); -*/ free(nl); free(ny); c->safe = TRUE; @@ -465,9 +465,8 @@ coldragwin(Column *c, Window *w, int but) error("can't find window"); Found: -/* TAG - force recompute tag size (if in auto-expand mode) on mouse op. */ - w->taglines = 1; -/* END TAG */ + if(w->tagexpand) /* force recomputation of window tag size */ + w->taglines = 1; p = mouse->xy; if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){ colgrow(c, w, but); diff --git a/src/cmd/acme/mkfile b/src/cmd/acme/mkfile index 47ff8d6e..a8696a15 100644 --- a/src/cmd/acme/mkfile +++ b/src/cmd/acme/mkfile @@ -33,3 +33,19 @@ HFILES=dat.h\ <$PLAN9/src/mkdirs edit.$O ecmd.$O elog.$O: edit.h + +likeplan9:V: + mkdir -p likeplan9 + rm -f likeplan9/* + for i in *.c + do + 9 sed 's/->(fcall|lk|b|fr|ref|m|u|u1)\./->/g; + s/\.(fcall|lk|b|fr|ref|m|u|u1)([^a-zA-Z0-9_])/\2/g + s/&(([a-zA-Z0-9_]|->|\.)*)->(fcall|lk|b|fr|ref|m|u|u1)([^a-zA-Z0-9_])/\1\4/g + s/range\(([^,()]+), ([^,()]+)\)/(Range){\1, \2}/g + ' $i >likeplan9/$i + done + +diffplan9:V: + mk likeplan9 + 9 diff -n plan9 likeplan9 | sed 's;likeplan9/;;' diff --git a/src/cmd/acme/rows.c b/src/cmd/acme/rows.c index c60f4102..50990d78 100644 --- a/src/cmd/acme/rows.c +++ b/src/cmd/acme/rows.c @@ -217,8 +217,8 @@ rowclose(Row *row, Column *c, int dofree) r = c->r; if(dofree) colcloseall(c); - memmove(row->col+i, row->col+i+1, (row->ncol-i)*sizeof(Column*)); row->ncol--; + memmove(row->col+i, row->col+i+1, (row->ncol-i)*sizeof(Column*)); row->col = realloc(row->col, row->ncol*sizeof(Column*)); if(row->ncol == 0){ draw(screen, r, display->white, nil, ZP); @@ -282,17 +282,13 @@ rowtype(Row *row, Rune r, Point p) else{ winlock(w, 'K'); wintype(w, t, r); -/* - * TAG If we typed in the tag, might need to make it - * bigger to show text. \n causes tag to expand. - */ + /* Expand tag if necessary */ if(t->what == Tag){ t->w->tagsafe = FALSE; if(r == '\n') t->w->tagexpand = TRUE; winresize(w, w->r, TRUE, TRUE); } -/* END TAG */ winunlock(w); } } @@ -319,7 +315,7 @@ rowdump(Row *row, char *file) uint q0, q1; Biobuf *b; char *buf, *a, *fontname; - Rune *r, *rp; + Rune *r; Column *c; Window *w, *w1; Text *t; @@ -417,17 +413,10 @@ rowdump(Row *row, char *file) Bwrite(b, buf, strlen(buf)); m = min(RBUFSIZE, w->tag.file->b.nc); bufread(&w->tag.file->b, 0, r, m); - if(dodollarsigns && r[0] == '$'){ - rp = runestrdup(r); - expandenv(&rp, (uint*)&m); - }else - rp = r; n = 0; - while(nfile->b.nc; @@ -705,6 +694,7 @@ rowload(Row *row, char *file, int initing) Bterm(bout); free(bout); close(fd); + remove(buf); goto Rescue2; } Bputrune(bout, rune); @@ -731,7 +721,6 @@ rowload(Row *row, char *file, int initing) w->maxlines = min(w->body.fr.nlines, max(w->maxlines, w->body.fr.maxlines)); } Bterm(b); - fbuffree(buf); return TRUE; diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c index 1a6c09e4..729e4303 100644 --- a/src/cmd/acme/text.c +++ b/src/cmd/acme/text.c @@ -75,7 +75,7 @@ textresize(Text *t, Rectangle r, int keepextra) if(Dy(r) <= 0) r.max.y = r.min.y; - if(!keepextra) + else if(!keepextra) r.max.y -= Dy(r)%t->fr.font->height; odx = Dx(t->all); t->all = r; @@ -84,8 +84,9 @@ textresize(Text *t, Rectangle r, int keepextra) t->lastsr = nullrect; r.min.x += Scrollwid+Scrollgap; frclear(&t->fr, 0); - textredraw(t, r, t->fr.font, screen, odx); + textredraw(t, r, t->fr.font, t->fr.b, odx); if(keepextra && t->fr.r.max.y < t->all.max.y){ + /* draw background in bottom fringe of window */ r.min.x -= Scrollgap; r.min.y = t->fr.r.max.y; r.max.y = t->all.max.y; @@ -197,7 +198,7 @@ textload(Text *t, uint q0, char *file, int setqid) char *tmp; Text *u; - if(t->ncache!=0 || t->file->b.nc || t->w==nil || t!=&t->w->body || (t->w->isdir && t->file->nname==0)) + if(t->ncache!=0 || t->file->b.nc || t->w==nil || t!=&t->w->body) error("text.load"); if(t->w->isdir && t->file->nname==0){ warning(nil, "empty directory name"); @@ -653,20 +654,13 @@ texttype(Text *t, Rune r) uint q0, q1; int nnb, nb, n, i; int nr; - Point p; Rune *rp; Text *u; -/* - * TAG - * Used to disallow \n in tag here. - * Also if typing in tag, mark that resize might be necessary. - */ if(t->what!=Body && t->what!=Tag && r=='\n') return; if(t->what == Tag) t->w->tagsafe = FALSE; -/* END TAG */ nr = 1; rp = &r; @@ -684,17 +678,13 @@ texttype(Text *t, Rune r) } return; case Kdown: -/* TAG */ if(t->what == Tag) goto Tagdown; -/* END TAG */ n = t->fr.maxlines/3; goto case_Down; case Kscrollonedown: -/* TAG */ if(t->what == Tag) goto Tagdown; -/* END TAG */ n = mousescrollsize(t->fr.maxlines); if(n <= 0) n = 1; @@ -706,17 +696,13 @@ texttype(Text *t, Rune r) textsetorigin(t, q0, TRUE); return; case Kup: -/* TAG */ if(t->what == Tag) goto Tagup; -/* END TAG */ n = t->fr.maxlines/3; goto case_Up; case Kscrolloneup: -/* TAG */ if(t->what == Tag) goto Tagup; -/* END TAG */ n = mousescrollsize(t->fr.maxlines); goto case_Up; case Kpgup: @@ -748,7 +734,6 @@ texttype(Text *t, Rune r) q0++; textshow(t, q0, q0, TRUE); return; -/* TAG policy here */ Tagdown: /* expand tag to show all text */ if(!t->w->tagexpand){ @@ -762,17 +747,9 @@ texttype(Text *t, Rune r) if(t->w->tagexpand){ t->w->tagexpand = FALSE; t->w->taglines = 1; - /* move mouse to stay in tag */ - p = mouse->xy; - if(ptinrect(p, t->w->tag.all) - && !ptinrect(p, t->w->tagtop)){ - p.y = t->w->tagtop.min.y + Dy(t->w->tagtop)/2; - moveto(mousectl, p); - } winresize(t->w, t->w->r, FALSE, TRUE); } return; -/* END TAG */ } if(t->what == Body){ seq++; diff --git a/src/cmd/acme/wind.c b/src/cmd/acme/wind.c index ccb1aaac..afd21afc 100644 --- a/src/cmd/acme/wind.c +++ b/src/cmd/acme/wind.c @@ -36,8 +36,8 @@ wininit(Window *w, Window *clone, Rectangle r) w->tagtop = r; w->tagtop.max.y = r.min.y + font->height; - r1.max.y = r1.min.y + w->taglines*font->height; + incref(&reffont.ref); f = fileaddtext(nil, &w->tag); textinit(&w->tag, f, r1, &reffont, tagcols); @@ -53,7 +53,6 @@ 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 += w->taglines*font->height + 1; if(r1.max.y < r1.min.y) @@ -66,7 +65,6 @@ 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); @@ -82,7 +80,6 @@ wininit(Window *w, Window *clone, Rectangle r) w->filemenu = TRUE; w->maxlines = w->body.fr.maxlines; w->autoindent = globalautoindent; -/*assert(w->body.w == w); */ if(clone){ w->dirty = clone->dirty; w->autoindent = clone->autoindent; @@ -119,8 +116,6 @@ wintaglines(Window *w, Rectangle r) int n; Rune rune; -/* TAG policy here */ - if(!w->tagexpand) return 1; w->tag.fr.noredraw = 1; @@ -151,57 +146,50 @@ winresize(Window *w, Rectangle r, int safe, int keepextra) Point p; Rectangle r1; -if(0) fprint(2, "winresize %d %R safe=%d keep=%d h=%d\n", w->id, r, safe, keepextra, font->height); + /* tagtop is first line of tag */ w->tagtop = r; w->tagtop.max.y = r.min.y+font->height; -/* - * TAG If necessary, recompute the number of lines that should - * be in the tag. - */ r1 = r; r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height); - y = r1.max.y; mouseintag = ptinrect(mouse->xy, w->tag.all); - if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)) + + /* If needed, recompute number of lines in tag. */ + if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){ w->taglines = wintaglines(w, r); -/* END TAG */ + r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height); + } - r1 = r; - r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height); + /* If needed, resize & redraw tag. */ y = r1.max.y; tagresized = 0; -if(0) fprint(2, "winresize tag %R %R\n", w->tag.all, r1); if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){ tagresized = 1; -if(0) fprint(2, "resize tag %R => %R\n", w->tag.all, r1); textresize(&w->tag, r1, TRUE); -if(0) fprint(2, "=> %R (%R)\n", w->tag.all, w->tag.fr.r); y = w->tag.fr.r.max.y; windrawbutton(w); w->tagsafe = TRUE; -/* TAG */ + /* If mouse is in tag, pull up as tag closes. */ if(mouseintag && !ptinrect(mouse->xy, w->tag.all)){ p = mouse->xy; p.y = w->tag.all.max.y-3; moveto(mousectl, p); } + /* If mouse is in body, push down as tag expands. */ if(!mouseintag && ptinrect(mouse->xy, w->tag.all)){ p = mouse->xy; p.y = w->tag.all.max.y+3; moveto(mousectl, p); } -/* END TAG */ } - + /* If needed, resize & redraw body. */ r1 = r; r1.min.y = y; if(tagresized || !safe || !eqrect(w->body.all, r1)){ oy = y; -if(0) fprint(2, "resizing body; safe=%d all=%R r1=%R\n", safe, w->body.all, r1); if(y+1+w->body.fr.font->height <= r.max.y){ /* room for one line */ r1.min.y = y; r1.max.y = y+1; @@ -213,10 +201,9 @@ if(0) fprint(2, "resizing body; safe=%d all=%R r1=%R\n", safe, w->body.all, r1); r1.min.y = y; r1.max.y = y; } -if(0) fprint(2, "resizing body; new r=%R; r1=%R\n", r, r1); + y = textresize(&w->body, r1, keepextra); w->r = r; - w->r.max.y = textresize(&w->body, r1, keepextra); -if(0) fprint(2, "after textresize: body.all=%R\n", w->body.all); + w->r.max.y = y; textscrdraw(&w->body); w->body.all.min.y = oy; } @@ -354,6 +341,7 @@ winsetname(Window *w, Rune *name, int n) int i; static Rune Lslashguide[] = { '/', 'g', 'u', 'i', 'd', 'e', 0 }; static Rune Lpluserrors[] = { '+', 'E', 'r', 'r', 'o', 'r', 's', 0 }; + t = &w->body; if(runeeq(t->file->name, t->file->nname, name, n) == TRUE) return; @@ -559,7 +547,6 @@ wincommit(Window *w, Text *t) for(i=0; itag.file->b.nc; i++) if(r[i]==' ' || r[i]=='\t') break; - expandenv(&r, (uint*)&i); if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){ seq++; filemark(w->body.file); @@ -678,4 +665,3 @@ winevent(Window *w, char *fmt, ...) sendp(x->c, nil); } } - -- cgit v1.2.3